【问题标题】:nr_cpus boot parameter in Linux kernelLinux 内核中的 nr_cpus 引导参数
【发布时间】:2016-07-30 03:34:19
【问题描述】:

我正在浏览 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的具体用法是什么?

【问题讨论】:

标签: linux linux-kernel smp


【解决方案1】:

作为文档的一部分,从您的问题中描述:

Maximum number of processors that an SMP kernel could support

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

所有标有early_param 的函数都将在do_early_param() 中从init/main.c 中调用,而init/main.c 将在setup_arch 函数中调用。 setup_arch 函数是特定于架构的,每个架构都提供自己的setup_arch() 实现。所以在调用nrcpus() 函数之后,nr_cpu_ids 将包含内核可以支持的处理器数量。

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

例如,您可以在powerpc 架构中看到它。如调用setup_nr_cpu_ids()smp_setup_cpu_maps() 函数的comment 中所述:

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

【讨论】:

    【解决方案2】:

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

    因此,您的观察是部分正确的,因为您忽略了这一点,即arch smpboot 代码如何集成nr_cpus。希望这能澄清你的理解。

    【讨论】:

    • 感谢您的解释。我错过了将 cpu_possible_max 更改为 nr_cpus 值的 prefill_possible_map 函数。
    【解决方案3】:

    结帐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

    【讨论】:

      猜你喜欢
      • 2020-01-18
      • 2019-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 2022-11-12
      • 1970-01-01
      相关资源
      最近更新 更多