smp启动-smp_init_cpus

上一篇: cpu_ops

https://www.cnblogs.com/zhangzhiwei122/p/16090770.html

 

setup_arch -> smp_init_cpus

arch/arm64/kernel/setup.c

 

284void __init __no_sanitize_address setup_arch(char **cmdline_p)
 285{

 339
 340       if (acpi_disabled) 
 341             unflatten_device_tree();


 347        request_standard_resources();
 348
 349        early_ioremap_reset();
 350
 351        if (acpi_disabled)
 352                psci_dt_init();
 353        else
 354                psci_acpi_init();
 355
 356        init_bootcpu_ops();
 357        smp_init_cpus();
 358        smp_build_mpidr_hash();

 

 

smp_init_cpus

 710void __init smp_init_cpus(void)
 711{
 714        if (acpi_disabled)
 715                of_parse_and_init_cpus();
 719        if (cpu_count > nr_cpu_ids)
 720                pr_warn("Number of cores (%d) exceeds configured maximum of %u - clipping\n",
 721                        cpu_count, nr_cpu_ids);
 722
 727
 728        /*
 729         * We need to set the cpu_logical_map entries before enabling
 730         * the cpus so that cpu processor description entries (DT cpu nodes
 731         * and ACPI MADT entries) can be retrieved by matching the cpu hwid
 732         * with entries in cpu_logical_map while initializing the cpus.
 733         * If the cpu set-up fails, invalidate the cpu_logical_map entry.
 734         */
 735        for (i = 1; i < nr_cpu_ids; i++) {
 736                if (cpu_logical_map(i) != INVALID_HWID) {
 737                        if (smp_cpu_setup(i))
 738                                set_cpu_logical_map(i, INVALID_HWID);
 739                }
 740        }
 741}

715 行,调用 of_parse_and_init_cpus (本文件,static 函数)进行 dtb的解析,并 初始化解析到的 cpu .

719  - 如果 715 行解析得到的 cpu_count 大于 nr_cpu_ids ,则 告警

728 ~ 740 ,注释清楚,在 使能 cpu 之前,先要把 找到的 cpu 都给 放到 cpu logical map 里面。

          下面的 for 循环默认cpu logical map 里面已经放了对应的 cpu hwid 了。 (由 of_parse_and_init_cpus 放入到 logical map 里面

          for 循环,遍历,对于不是 invalid hwid 的项,调用 smp_cpu_setup(i) 进行初始化,如果初始化失败,则设置 这个 idx 对应的 cpu hwid 为 invalid hwid .

 

of_parse_and_init_cpus

 530 static bool bootcpu_valid   __initdata;
 531 static unsigned int cpu_count = 1;

652static void __init of_parse_and_init_cpus(void) 653{ 654 struct device_node *dn; 655 656 for_each_of_cpu_node(dn) { 657 u64 hwid = of_get_cpu_mpidr(dn); 658 659 if (hwid == INVALID_HWID) 660 goto next; 661 662 if (is_mpidr_duplicate(cpu_count, hwid)) { 663 pr_err("%pOF: duplicate cpu reg properties in the DT\n", 664 dn); 665 goto next; 666 } 667 668 /* 669 * The numbering scheme requires that the boot CPU 670 * must be assigned logical id 0. Record it so that 671 * the logical map built from DT is validated and can 672 * be used. 673 */ 674 if (hwid == cpu_logical_map(0)) { 675 if (bootcpu_valid) { 676 pr_err("%pOF: duplicate boot cpu reg property in DT\n", 677 dn); 678 goto next; 679 } 680 681 bootcpu_valid = true; 682 early_map_cpu_to_node(0, of_node_to_nid(dn)); 683 684 /* 685 * cpu_logical_map has already been 686 * initialized and the boot cpu doesn't need 687 * the enable-method so continue without 688 * incrementing cpu. 689 */ 690 continue; 691 } 692 693 if (cpu_count >= NR_CPUS) 694 goto next; 695 696 pr_debug("cpu logical map 0x%llx\n", hwid); 697 set_cpu_logical_map(cpu_count, hwid); 698 699 early_map_cpu_to_node(cpu_count, of_node_to_nid(dn)); 700next: 701 cpu_count++; 702 } 703}

530 ~ 531 定义了两个 static 变量, bootcpu_valid ( false) , cpu_count ( 1 )

656 行开始for 循环,

657 - of_get_cpu_mpidr 返回 dts cpu 节点的 reg 属性值  或者  invalid hwid .

659 ~ 660 ,如果是 invalid hwid , 则到 700 行,将 cpu_count ++ 后,继续for 循环。

662 ~ 666 ,id_mpidr_duplicate  检查 新的 hwid 和 之前存下的 hwid 【cpu logical map 从 0 到 cpu_count 】都不相同,如果相同,则打印信息后,跳转到 700 行

674 ~ 691 行,cpu logical map 0 里面,填入的是 boot cpu 的 mpidr 寄存器里面 得到的 hwid 值(见:  https://www.cnblogs.com/zhangzhiwei122/p/16051676.html) 。假设是 0, 则和 dts 中 cpu0 的reg 里面的0 相同,

      681 设置 bootcpu_valid 为true . 如果在此之前,bootcpu_valid 已经是 true , 675 ~ 678, 则打印告警后,转到 700行 。

     690行,continue, 不对 cpu_count 进行增加

 

693 ~ 694 检查,对于大于 menuconfig 里面配置的 cpu, 直接转到 700 行,

697 对新的hwid ,以 cpu_count 为 idx, 放入到 cpu logical map 里面。

 

682 ~ 699 行,map cpu to node, 在 smp ,单个CPU ,多核心 情况下,都在 node 0 里面。暂时不关心。

 

smp_cpu_setup

 514static int __init smp_cpu_setup(int cpu)
 515{
 516        const struct cpu_operations *ops;
 517
 518        if (init_cpu_ops(cpu))
 519                return -ENODEV;
 520
 521        ops = get_cpu_ops(cpu);
 522        if (ops->cpu_init(cpu))
 523                return -ENODEV;
 524
 525        set_cpu_possible(cpu, true);
 526
 527        return 0;
 528}

518 - init_cpu_ops 初始化 指定 cpu的 cpu operations ,和 init_bootcpu_ops  https://www.cnblogs.com/zhangzhiwei122/p/16090770.html 类似

521 ~ 523 ,调用 cpu operations 结构体里面的 cpu_init 函数,对于psci 启动的cpu 则是  arch/arm64/kernel/psci.c 中的 cpu_psci_cpu_init 函数。

525 设置 possble cpu  bitmap ,对应 bit 设置为 1  ,后面for each possible cpu 循环可以找到。

 

下一篇: smp_prepare_boot_cpu boot cpu 相关的一些初始化 cpu_data, feature alternative instruction; priority masking

https://www.cnblogs.com/zhangzhiwei122/p/16091458.html

 

posted @ 2022-04-02 11:10  张志伟122  阅读(245)  评论(0编辑  收藏  举报