2016-04-08 679 views
1

我在瀏覽Linux內核代碼以瞭解啓動參數nr_cpus。 作爲每文檔, (https://www.kernel.org/doc/Documentation/kernel-parameters.txtLinux內核中的nr_cpus啓動參數

[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 

smp.c碼,該值被設置爲nr_cpu_ids,然後將其在內核中使用隨處可見。
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); 

我不明白nr_cpu_ids也被setup_nr_cpu_ids設置。

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 } 

最初,我認爲這是在調用early_param之前調用的。添加日誌後,我發現在nr_cpus()之後調用setup_nr_cpu_ids()nr_cpu_ids始終設置爲setup_nr_cpu_ids()中的值集而不是nr_cpus()。我甚至在smp_init()中驗證了它的價值。

任何人都可以請澄清,如果我的觀察是正確的?
nr_cpu_ids的確切用途是什麼?

+0

這聽起來有點奇怪,因爲setup_nr_cpu_ids在531行被調用,這裏http://lxr.free-electrons.com/source/init/main.c#L531而early_param函數在539行運行 – nos

+0

發生這種情況因爲每個架構都有一個調用parse_early_param()的setup_arch()函數。 http://lxr.free-electrons.com/source/arch/x86/kernel/setup.c#L983 setup_arch()在528行調用 – alex

回答

1

通常,arch會檢測系統上可用的cpu數量。但是,它可能會減少要使用的cpus的數量。並且,由於這個原因nr_cpus參數被引入。默認情況下,沒有人使用該參數,在這種情況下,拱碼負責檢測系統上可用的cpu數量,例如,對於x86 arch,查看prefill_possible_map,其中check用於查看nr_cpus是否通過。如果nr_cpus通過,則使用that值。在arch檢測到可用的可用cpus數後,setup_nr_cpu_idskenrel/smp.c完成nr_cpu_ids的值。請注意,它可能聽起來多餘,但因爲它工作,所以沒有人抱怨。

所以,你的觀察是部分正確的,因爲你錯過了這一點,如何拱smpboot代碼集成nr_cpus。希望這可以澄清你的理解。

+0

感謝您的解釋。我錯過了將cpu_possible_max更改爲nr_cpus值的prefill_possible_map函數。 – alex

3

作爲文件的一部分,從你的問題描述:

Maximum number of processors that an SMP kernel could support 

其實這兩種功能的這樣做。 early_param()提供了在內核命令行中搜索第一個參數的功能,如果搜索成功,將會調用early_param()的第二個參數中記錄的功能。

所有標記爲early_param的功能將在do_early_param()中調用init/main.c,該功能將從setup_arch函數調用。 setup_arch函數是特定於體系結構的,每個體系結構都提供了自己的setup_arch()實現。因此,在調用nrcpus()函數後,nr_cpu_ids將包含內核可支持的處理器數量。

如果您將看看Linux內核源代碼,您會注意到setup_nr_cpu_ids()函數將在標記爲early_param的函數之後從init/main.c調用。所以在這種情況下,這是多餘的。但有時候可能會提前獲得處理器數量。

例如,您可以在powerpc體系結構中看到它。正如在本smp_setup_cpu_maps()功能comment描述了setup_nr_cpu_ids()被稱爲:

具有可能的地圖年初成立使我們能夠限制分配之類的東西irqstacks 到nr_cpu_ids而非NR_CPUS。

0

結帳cpumask.h,尤其是這...

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是最大可用的CPU和nr_cpus你傳遞的啓動參數是用來設置它。這是它在內核3.16中爲我做的。

這裏

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 } 

的評論是說,如果你已經設置nr_cpu_ids,這個調用是多餘的。原因是cpu_possible_mask已被設置爲nr_cpu_id