我正在浏览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
的确切用法是什么?
答案 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
。