2016-04-08 24 views
1

Ich suchte Linux Kernel-Code, um den nr_cpus Boot-Parameter zu verstehen. Gemäß der Dokumentation, (https://www.kernel.org/doc/Documentation/kernel-parameters.txt)nr_cpus Boot-Parameter im Linux-Kernel

[SMP] Maximum number of processors that an SMP kernel 
      could support. nr_cpus=n : n >= 1 limits the kernel to 
      supporting 'n' processors. Later in runtime you can not 
      use hotplug cpu feature to put more cpu back to online. 
      just like you compile the kernel NR_CPUS=n 

Im smp.c Code, wird der Wert auf nr_cpu_ids gesetzt, die dann überall im Kernel verwendet wird.
http://lxr.free-electrons.com/source/kernel/smp.c

527 static int __init nrcpus(char *str) 
528 { 
529   int nr_cpus; 
530 
531   get_option(&str, &nr_cpus); 
532   if (nr_cpus > 0 && nr_cpus < nr_cpu_ids) 
533     nr_cpu_ids = nr_cpus; 
534 
535   return 0; 
536 } 
537 
538 early_param("nr_cpus", nrcpus); 

Was ich nicht verstehen, die nr_cpu_ids auch durch setup_nr_cpu_ids eingestellt.

555 /* An arch may set nr_cpu_ids earlier if needed, so this would be redundant */ 
556 void __init setup_nr_cpu_ids(void) 
557 { 
558   nr_cpu_ids = find_last_bit(cpumask_bits(cpu_possible_mask),NR_CPUS) + 1; 
559 } 

Zunächst dachte ich, dass dies vor der early_param Aufruf aufgerufen wird. Nach dem Hinzufügen von Protokollen habe ich festgestellt, dass setup_nr_cpu_ids() nach nr_cpus() aufgerufen wird. nr_cpu_ids wird immer auf die Wertesätze in setup_nr_cpu_ids() statt nr_cpus() gesetzt. Ich habe sogar seinen Wert in smp_init() überprüft.

Kann jemand bitte klären, ob meine Beobachtung richtig ist oder nicht?
Was ist die genaue Verwendung von nr_cpu_ids?

+0

Das hört sich seltsam an, da setup_nr_cpu_ids in Zeile 531 hier http://lxr.free-electron.com/source/init/main.c#L531 aufgerufen wird, während die early_param-Funktionen in Zeile 539 ausgeführt werden. – nos

+0

Das passiert weil jede Architektur eine Funktion setup_arch() implementiert hat, die parse_early_param() aufruft. http://lxr.free-electronics.com/source/arch/x86/kernel/setup.c#L983 setup_arch() wird auf Linie 528 – alex

Antwort

1

In der Regel erkennt arch die Anzahl der auf dem System verfügbaren CPUs. Aber es ist möglich, die Anzahl der CPUs zu reduzieren, die Sie verwenden möchten. Und aus diesem Grund wurde nr_cpus Parameter eingeführt. Standardmäßig verwendet niemand diesen Parameter, und in diesem Fall ist der Bogencode für das Erkennen der Anzahl der im System verfügbaren CPUs zuständig, d. H. Für den x86-Bogen-Look prefill_possible_map, wo ein check gemacht wird, um zu sehen, ob nr_cpus bestanden wurde oder nicht. Wenn nr_cpus übergeben wurde, wird that Wert verwendet. Nachdem der Bogen die Anzahl der möglichen verfügbaren CPUs ermittelt hat, wird der Wert nr_cpu_ids durch setup_nr_cpu_ids in kenrel/smp.c endgültig festgelegt. Beachten Sie, dass es vielleicht überflüssig klingt, aber da es funktioniert, beschwert sich niemand.

So ist Ihre Beobachtung teilweise richtig, weil Sie den Punkt, wie Arch Smpboot Code integriert nr_cpus integriert. Hoffe das klärt Sie Verständnis.

+0

aufgerufen Vielen Dank für die Erklärung. Ich habe die Funktion prefill_possible_map verpasst, die den Wert cpu_possible_max in nr_cpus umwandelt. – alex

3

Im Rahmen der Dokumentation aus Ihrer Frage beschreibt:

Maximum number of processors that an SMP kernel could support 

die gleiche Eigentlich tun beide dieser Funktion. Die early_param() bietet die Möglichkeit, den ersten Parameter in der Kernel-Befehlszeile zu suchen, und wenn die Suche erfolgreich war, wird die Funktion aufgerufen, die im zweiten Parameter der early_param() notiert ist.

Alle Funktionen, die mit early_param markiert sind, werden in den do_early_param() vom init/main.c genannt werden, die von der setup_arch Funktion aufgerufen wird. Die setup_arch-Funktion ist architekturspezifisch und jede Architektur stellt eine eigene Implementierung des setup_arch() bereit. Nach dem Aufruf der Funktion nrcpus() wird nr_cpu_ids die Anzahl der Prozessoren enthalten, die der Kernel unterstützen könnte.

Wenn Sie an dem Linux-Kernel-Quellcode schauen, werden Sie feststellen, dass die setup_nr_cpu_ids() Funktion wird von den init/main.c nach Funktionen aufgerufen werden, die mit early_param gekennzeichnet sind. Also in diesem Fall ist es überflüssig.Aber manchmal kann es nützlich sein, die Anzahl der Prozessoren früher zu bekommen.

Zum Beispiel können Sie es in der powerpc Architektur sehen. Wie in den comment der smp_setup_cpu_maps() Funktionen beschrieben, wo die setup_nr_cpu_ids() genannt wird:

die mögliche Karte Mit uns früh ermöglicht eingerichtet, um Zuweisungen von Dingen wie irqstacks zu nr_cpu_ids statt NR_CPUS zu beschränken.

0

Kasse cpumask.h, insbesondere dieser ...

787 #define for_each_cpu_mask_nr(cpu, mask)     \ 
788   for ((cpu) = -1;        \ 
789     (cpu) = __next_cpu_nr((cpu), &(mask)), \ 
790     (cpu) < nr_cpu_ids;) 

nr_cpu_ids ist die maximale nutzbare CPUs und nr_cpus, die Sie als Boot-param geben wird verwendet, um sie einzustellen. Das macht es für mich im Kernel 3.16.

Der Kommentar hier

555 /* An arch may set nr_cpu_ids earlier if needed, so this would be redundant */ 
556 void __init setup_nr_cpu_ids(void) 
557 { 
558   nr_cpu_ids = find_last_bit(cpumask_bits(cpu_possible_mask),NR_CPUS) + 1; 
559 } 

sagt, dass, wenn Sie bereits nr_cpu_ids, dass dieser Aufruf redundant eingestellt haben. Der Grund dafür ist die cpu_possible_mask wurde bereits auf nr_cpu_id festgelegt.