maxcpus
来源:互联网 发布:网络维护维护什么 编辑:程序博客网 时间:2024/05/23 15:53
当uboot 通过bootargs传给给kernel的参数包含maxcpus=n时,就是想动态改变cpu 的个数,由于我们可以停在uboot shell 通过修改maxcpus,就可以动态控制当前kernel smp中cpu的个数。
当uboot 中传给maxcpus=3是,kernel在如下的函数中接收这个字符串并将3存到setup_max_cpus这个变量中
http://lxr.free-electrons.com/source/kernel/smp.c
539 static int __init maxcpus(char *str)
540 {
541 get_option(&str, &setup_max_cpus);
542 if (setup_max_cpus == 0)
543 arch_disable_smp_support();
544
545 return 0;
546 }
547
548 early_param("maxcpus", maxcpus);
而setup_max_cpus 默认是NR_CPUS,这个值是在kernel的defconfig文件中定义的
350 static const unsigned int setup_max_cpus = NR_CPUS;
当从start_kernel中调用smp_prepare_cpus 时会根据max_cpus 来设定cpu_present_mask,最终影响boot的cpu。
如下函数最终smp_prepare_cpus
437 void __init smp_prepare_cpus(unsigned int max_cpus)
438 {
439 unsigned int ncores = num_possible_cpus();
440
441 init_cpu_topology();
442
443 smp_store_cpu_info(smp_processor_id());
444
445 /*
446 * are we trying to boot more cores than exist?
447 */
448 if (max_cpus > ncores)
449 max_cpus = ncores;
450 if (ncores > 1 && max_cpus) {
451 /*
452 * Initialise the present map, which describes the set of CPUs
453 * actually populated at the present time. A platform should
454 * re-initialize the map in the platforms smp_prepare_cpus()
455 * if present != possible (e.g. physical hotplug).
456 */
457 init_cpu_present(cpu_possible_mask);
458
459 /*
460 * Initialise the SCU if there are more than one CPU
461 * and let them know where to start.
462 */
463 if (smp_ops.smp_prepare_cpus)
464 smp_ops.smp_prepare_cpus(max_cpus);
465 }
466 }
smp_prepare_cpus 这个函数是和IC相关的实现,我们以下面的为例
http://lxr.free-electrons.com/source/arch/arc/kernel/smp.c#L65
65 void __init smp_prepare_cpus(unsigned int max_cpus)
66 {
67 int i;
68
69 /*
70 * Initialise the present map, which describes the set of CPUs
71 * actually populated at the present time.
72 */
73 for (i = 0; i < max_cpus; i++)
74 set_cpu_present(i, true);
75 }
这个函数根据max_cpus来说设定好cpu_present_mask。
这样当我们在从start_kernel中调用smp_init 来boot其他cpu的时候,就会根据这个数来决定要唤醒几个cpu.
566 void __init smp_init(void)
567 {
568 unsigned int cpu;
569
570 idle_threads_init();
571 cpuhp_threads_init();
572
573 /* FIXME: This should be done in userspace --RR */
574 for_each_present_cpu(cpu) {
575 if (num_online_cpus() >= setup_max_cpus)
576 break;
577 if (!cpu_online(cpu))
578 cpu_up(cpu);
579 }
580
581 /* Any cleanup work */
582 smp_announce();
583 smp_cpus_done(setup_max_cpus);
584 }
关键是574 行的#define for_each_present_cpu(cpu) for_each_cpu((cpu), cpu_present_mask)
可见主要是cpu 是否在cpu_present_mask中如果在的话,就调用cpu_up来boot cpu。而cpu_present_mask又是被uboot 传递的maxcpus影响的.
当uboot 中传给maxcpus=3是,kernel在如下的函数中接收这个字符串并将3存到setup_max_cpus这个变量中
http://lxr.free-electrons.com/source/kernel/smp.c
539 static int __init maxcpus(char *str)
540 {
541 get_option(&str, &setup_max_cpus);
542 if (setup_max_cpus == 0)
543 arch_disable_smp_support();
544
545 return 0;
546 }
547
548 early_param("maxcpus", maxcpus);
而setup_max_cpus 默认是NR_CPUS,这个值是在kernel的defconfig文件中定义的
350 static const unsigned int setup_max_cpus = NR_CPUS;
当从start_kernel中调用smp_prepare_cpus 时会根据max_cpus 来设定cpu_present_mask,最终影响boot的cpu。
如下函数最终smp_prepare_cpus
437 void __init smp_prepare_cpus(unsigned int max_cpus)
438 {
439 unsigned int ncores = num_possible_cpus();
440
441 init_cpu_topology();
442
443 smp_store_cpu_info(smp_processor_id());
444
445 /*
446 * are we trying to boot more cores than exist?
447 */
448 if (max_cpus > ncores)
449 max_cpus = ncores;
450 if (ncores > 1 && max_cpus) {
451 /*
452 * Initialise the present map, which describes the set of CPUs
453 * actually populated at the present time. A platform should
454 * re-initialize the map in the platforms smp_prepare_cpus()
455 * if present != possible (e.g. physical hotplug).
456 */
457 init_cpu_present(cpu_possible_mask);
458
459 /*
460 * Initialise the SCU if there are more than one CPU
461 * and let them know where to start.
462 */
463 if (smp_ops.smp_prepare_cpus)
464 smp_ops.smp_prepare_cpus(max_cpus);
465 }
466 }
smp_prepare_cpus 这个函数是和IC相关的实现,我们以下面的为例
http://lxr.free-electrons.com/source/arch/arc/kernel/smp.c#L65
65 void __init smp_prepare_cpus(unsigned int max_cpus)
66 {
67 int i;
68
69 /*
70 * Initialise the present map, which describes the set of CPUs
71 * actually populated at the present time.
72 */
73 for (i = 0; i < max_cpus; i++)
74 set_cpu_present(i, true);
75 }
这个函数根据max_cpus来说设定好cpu_present_mask。
这样当我们在从start_kernel中调用smp_init 来boot其他cpu的时候,就会根据这个数来决定要唤醒几个cpu.
566 void __init smp_init(void)
567 {
568 unsigned int cpu;
569
570 idle_threads_init();
571 cpuhp_threads_init();
572
573 /* FIXME: This should be done in userspace --RR */
574 for_each_present_cpu(cpu) {
575 if (num_online_cpus() >= setup_max_cpus)
576 break;
577 if (!cpu_online(cpu))
578 cpu_up(cpu);
579 }
580
581 /* Any cleanup work */
582 smp_announce();
583 smp_cpus_done(setup_max_cpus);
584 }
关键是574 行的#define for_each_present_cpu(cpu) for_each_cpu((cpu), cpu_present_mask)
可见主要是cpu 是否在cpu_present_mask中如果在的话,就调用cpu_up来boot cpu。而cpu_present_mask又是被uboot 传递的maxcpus影响的.
0 0
- maxcpus
- 开始学习Linux的一些建议
- Ubuntu14.04下SVN的搭建及使用
- android <activity-alias/>的用法,是否让你想起了什么
- 数据库SQL优化
- 解决LisTview 和gridView在ScrollView中显示不全和其他异常的问题
- maxcpus
- 面试问题解答记录(2016-08-23)
- JavaScript高级程序设计学习(一)
- Android——Launcher(桌面启动器)相关知识总结贴
- LCD的ESD防护
- 测试C51stc板的流水灯、数码管、按键
- JSP---EL表达式中文乱码(Tomcat服务器)解决方法
- linux c语言 select函数用法
- 计算机的启动流程