Linux内核中的nr_cpus引导参数

时间:2016-04-08 18:38:21

标签: linux linux-kernel smp

我正在浏览Linux内核代码以了解nr_cpus启动参数。 根据文档, (https://www.kernel.org/doc/Documentation/kernel-parameters.txt

[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调用之前调用的。添加日志后,我发现在setup_nr_cpu_ids()之后调用nr_cpus()nr_cpu_ids始终设置为setup_nr_cpu_ids()中的值集,而不是nr_cpus()。我甚至在smp_init()验证了它的价值。

任何人都可以澄清我的观察结果是否正确? nr_cpu_ids的确切用法是什么?

3 个答案:

答案 0 :(得分:4)

正如文档的一部分描述的那样:

Maximum number of processors that an SMP kernel could support

实际上这两个功能都是一样的。 early_param()提供了在内核命令行中搜索第一个参数的功能,如果搜索成功,将调用early_param()的第二个参数中记录的函数。

所有标有early_param的功能都将在do_early_param()的{​​{1}}中调用,setup_arch将从setup_arch功能调用。 setup_arch()函数是特定于体系结构的,每个体系结构都提供nrcpus()的自己的实现。因此,在调用nr_cpu_ids函数之后,setup_nr_cpu_ids()将包含内核可以支持的处理器数量。

如果您要查看Linux内核源代码,您会注意到early_param函数将在标有smp_setup_cpu_maps()的函数之后从init/main.c调用。所以在这种情况下它是多余的。但有时,提前获得多个处理器可能会有所帮助。

例如,您可以在init/main.c架构中看到它。如调用setup_nr_cpu_ids()的{​​{1}}函数的powerpc中所述:

  

尽早设置可能的地图允许我们限制分配   像irqstacks到nr_cpu_ids而不是NR_CPUS。

答案 1 :(得分:1)

通常,arch会检测系统上可用的cpu数。但是,它可以减少你想要使用的cpu数量。因此,引入了nr_cpus参数。默认情况下,没有人使用此参数,在这种情况下,arch代码负责检测系统上可用的cpu数量,即x86 arch查看prefill_possible_map,其中check用于查看{是否{ {1}}是否通过了。如果nr_cpus已通过,则使用that值。在arch检测到可用的cpu数后,nr_cpus中的setup_nr_cpu_ids最终确定kenrel/smp.c的值。请注意,这可能听起来多余,但因为它有效,所以没有人抱怨。

所以,你的观察是部分正确的,因为你错过了这一点,arch smpboot代码如何集成nr_cpu_ids。希望这能澄清你的理解。

答案 2 :(得分: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是您传递的最大可用cpus和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