当前位置: 首页 > news >正文

smp_init过程解析

当你看到这样的log,会不会很慌张?

竟然由CPU没有启动成功,除了什么故障?

本文将结合我遇到的一个问题,将启动过程中bringup secondary cpu的过程分析一下。

smp_init代码如下:

602 void __init smp_init(void)
603 {
604     int num_nodes, num_cpus;
605     unsigned int cpu;
606 
607     idle_threads_init();
608     cpuhp_threads_init();
609 
610     pr_info("====cpuhp-walk:Bringing up secondary CPUs ...\n");
611 
612     /* FIXME: This should be done in userspace --RR */
613     for_each_present_cpu(cpu) {
614         if (num_online_cpus() >= setup_max_cpus)
615             break;
616         pr_info("====cpuhp-walk:before bringing up cpu:%d\n", cpu);
617         if (!cpu_online(cpu))
618             cpu_up(cpu);
619         pr_info("====cpuhp-walk:after bringing up cpu:%d\n", cpu);
620     }
621 
622     num_nodes = num_online_nodes();
623     num_cpus  = num_online_cpus();
624     pr_info("====cpuhp-walk:Brought up %d node%s, %d CPU%s\n",
625         num_nodes, (num_nodes > 1 ? "s" : ""),
626         num_cpus,  (num_cpus  > 1 ? "s" : ""));
627 
628     /* Any cleanup work */
629     smp_cpus_done(setup_max_cpus);
630 }

可以看得出在smp_init中,cpu0依次调用cpu_up启动其他的cpu,启动完成一个,再启动下一个,直到所有cpu都启动完毕,才继续内核剩余的启动流程,整个过程从smp_init开始,从smp_init结束。

下面分析具体的过程,我们将启动其他cpu成为BP(boot cpu),将被启动的cpu成为AP(不知道A表示哪个单词):

BP                                                                                                        AP
smp_init                                                                                                         |    do_cpu_up|        --> cpuhp_invoke_callback|            --> smpboot_create_threads|                perf_event_init_cpu|                workqueue_prepare_cpu|                hrtimers_prepare_cpu|                ...|                bringup_cpu|                    -->__cpu_up|                        -->boot_secondary (cpu_ops[cpu]->cpu_boot(cpu))|                            --> cpu_psci_cpu_boot|                                -->psci_cpu_on (invoke_psci_fn(0xc4000003, cpuid, secondary_entry, 0);)|                                                                                                            secondary_entrynext cpu                                                                                                        --> secondary_startup|                                                                                                                    --> __secondary_switched|                                                                                                                        -->secondary_start_kernel          |                                                                                                                            --> notify_cpu_starting|                                                                                                                                -->cpuhp_invoke_callback|                                                                                                                                    -->sched_cpu_starting|                                                                                                                                        gic_starting_cpu|                                                                                                                                        arch_timer_starting_cpu|                                                                                                                                        dummy_timer_starting_cpu|            |            bringup_wait_for_ap

可以看出,BP通过bringup_cpu函数,调用psci的函数,请求firmware启动AP,然后原地等待AP启动的结果。

firmware给AP上电之后,AP进入head.S中的secondary_entry,然后进入secondary_start_kernel,完成一系列回调之后,通知BP自己启动成功。BP从bringup_wait_for_ap返回,继续启动下一个cpu。

在cpuhp_invoke_callback所调用的回调函数的定义在这:

kernel/cpu.c1426 /* Boot processor state steps */
1427 static struct cpuhp_step cpuhp_hp_states[] = {
1428     [CPUHP_OFFLINE] = {
1429         .name           = "offline",
1430         .startup.single     = NULL,
1431         .teardown.single    = NULL,
1432     },
1433 #ifdef CONFIG_SMP
1434     [CPUHP_CREATE_THREADS]= {
1435         .name           = "threads:prepare",
1436         .startup.single     = smpboot_create_threads,
1437         .teardown.single    = NULL,
1438         .cant_stop      = true,
1439     },
1440     [CPUHP_PERF_PREPARE] = {
1441         .name           = "perf:prepare",
1442         .startup.single     = perf_event_init_cpu,
1443         .teardown.single    = perf_event_exit_cpu,
1444     },
1445     [CPUHP_WORKQUEUE_PREP] = {
1446         .name           = "workqueue:prepare",
1447         .startup.single     = workqueue_prepare_cpu,
1448         .teardown.single    = NULL,
1449     },
1450     [CPUHP_HRTIMERS_PREPARE] = {
1451         .name           = "hrtimers:prepare",
1452         .startup.single     = hrtimers_prepare_cpu,
1453         .teardown.single    = hrtimers_dead_cpu,
1454     },
1455     [CPUHP_SMPCFD_PREPARE] = {
1456         .name           = "smpcfd:prepare",
1457         .startup.single     = smpcfd_prepare_cpu,
1458         .teardown.single    = smpcfd_dead_cpu,
1459     },
1460     [CPUHP_RELAY_PREPARE] = {
1461         .name           = "relay:prepare",
1462         .startup.single     = relay_prepare_cpu,
1463         .teardown.single    = NULL,
1464     },
1465     [CPUHP_SLAB_PREPARE] = {
1466         .name           = "slab:prepare",
1467         .startup.single     = slab_prepare_cpu,
1468         .teardown.single    = slab_dead_cpu,
1469     },
1470     [CPUHP_RCUTREE_PREP] = {
1471         .name           = "RCU/tree:prepare",
...
1485     /* Kicks the plugged cpu into life */
1486     [CPUHP_BRINGUP_CPU] = {
1487         .name           = "cpu:bringup",
1488         .startup.single     = bringup_cpu,
1489         .teardown.single    = NULL,
1490         .cant_stop      = true,
1491     },
1492     /* Final state before CPU kills itself */
1493     [CPUHP_AP_IDLE_DEAD] = {
1494         .name           = "idle:dead",
1495     },
1496     /*
1497      * Last state before CPU enters the idle loop to die. Transient state
1498      * for synchronization.
1499      */
1500     [CPUHP_AP_OFFLINE] = {
1501         .name           = "ap:offline",
1502         .cant_stop      = true,
1503     },
1504     /* First state is scheduler control. Interrupts are disabled */
1505     [CPUHP_AP_SCHED_STARTING] = {
1506         .name           = "sched:starting",
1507         .startup.single     = sched_cpu_starting,
1508         .teardown.single    = sched_cpu_dying,
1509     },
1510     [CPUHP_AP_RCUTREE_DYING] = {
1511         .name           = "RCU/tree:dying",
1512         .startup.single     = NULL,
1513         .teardown.single    = rcutree_dying_cpu,
1514     },
1515     [CPUHP_AP_SMPCFD_DYING] = {
1516         .name           = "smpcfd:dying",
1517         .startup.single     = NULL,
1518         .teardown.single    = smpcfd_dying_cpu,
1519     },
1520     /* Entry state on starting. Interrupts enabled from here on. Transient
1521      * state for synchronsization */
1522     [CPUHP_AP_ONLINE] = {
1523         .name           = "ap:online",
1524     },
1525     /*
1526      * Handled on controll processor until the plugged processor manages
1527      * this itself.
1528      */
1529     [CPUHP_TEARDOWN_CPU] = {
1530         .name           = "cpu:teardown",
1531         .startup.single     = NULL,
...
1535     /* Handle smpboot threads park/unpark */
1536     [CPUHP_AP_SMPBOOT_THREADS] = {
1537         .name           = "smpboot/threads:online",
1538         .startup.single     = smpboot_unpark_threads,
1539         .teardown.single    = smpboot_park_threads,
1540     },
1541     [CPUHP_AP_IRQ_AFFINITY_ONLINE] = {
1542         .name           = "irq/affinity:online",
1543         .startup.single     = irq_affinity_online_cpu,
1544         .teardown.single    = NULL,
1545     },
1546     [CPUHP_AP_PERF_ONLINE] = {
1547         .name           = "perf:online",
1548         .startup.single     = perf_event_init_cpu,
1549         .teardown.single    = perf_event_exit_cpu,
1550     },
1551     [CPUHP_AP_WATCHDOG_ONLINE] = {
1552         .name           = "lockup_detector:online",
1553         .startup.single     = lockup_detector_online_cpu,
1554         .teardown.single    = lockup_detector_offline_cpu,
1555     },
1556     [CPUHP_AP_WORKQUEUE_ONLINE] = {
1557         .name           = "workqueue:online",
1558         .startup.single     = workqueue_online_cpu,
1559         .teardown.single    = workqueue_offline_cpu,
1560     },
1561     [CPUHP_AP_RCUTREE_ONLINE] = {
1562         .name           = "RCU/tree:online",
1563         .startup.single     = rcutree_online_cpu,
1564         .teardown.single    = rcutree_offline_cpu,
1565     },
1566 #endif
1567     /*
1568      * The dynamically registered state space is here
1569      */
1570 
1571 #ifdef CONFIG_SMP
1572     /* Last state is scheduler control setting the cpu active */
1573     [CPUHP_AP_ACTIVE] = {
1574         .name           = "sched:active",
1575         .startup.single     = sched_cpu_activate,
1576         .teardown.single    = sched_cpu_deactivate,
1577     },
1578 #endif
1579 
1580     /* CPU is fully up and running. */
1581     [CPUHP_ONLINE] = {
1582         .name           = "online",
1583         .startup.single     = NULL,
1584         .teardown.single    = NULL,
1585     },
1586 };1482,3-9      60

所有的回调函数一次调用,最重要的是bringup_cpu,这个是通过firmware直接给cpu上电启动的过程。

psci通过设备树节点获取与固件通信的方法(method:smc),smc具体的操作指令,可以在include/uapi/linux/psci.h中查找.

我在代码中增加一些打印语句,完整的smp_init的过程如下:

[    0.064050] smp: ====cpuhp-walk:Bringing up secondary CPUs ...
[    0.064051] smp: ====cpuhp-walk:before bringing up cpu:0
[    0.064052] smp: ====cpuhp-walk:after bringing up cpu:0
[    0.064053] smp: ====cpuhp-walk:before bringing up cpu:1
[    0.064053] cpuhp_walk:cpu:1,do_cpu_up
[    0.064060] cphp_walk:cpu:1,cpuhp_up_callbacks
[    0.064061] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:smpboot_create_threads+0x0/0xe0
[    0.104074] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:perf_event_init_cpu+0x0/0x140
[    0.104080] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:workqueue_prepare_cpu+0x0/0x98
[    0.112080] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:hrtimers_prepare_cpu+0x0/0xb0
[    0.112084] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:smpcfd_prepare_cpu+0x0/0x70
[    0.112089] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:relay_prepare_cpu+0x0/0xf8
[    0.112092] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:rcutree_prepare_cpu+0x0/0x1c0
[    0.112099] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:timers_prepare_cpu+0x0/0x80
[    0.112101] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:bringup_cpu+0x0/0x140
[    0.112104] cpuhp_walk:cpu:1,bringup_cpu
[    0.112105] cpuhp_walk:cpu:1,__cpu_up
[    0.112106] cpuhp_walk:cpu:1,boot_secondary, cpu_boot:cpu_psci_cpu_boot+0x0/0x94
[    0.112109] psci: cpuhp_walk:cpu:1,cpu_psci_cpu_boot, cpu_on:psci_cpu_on+0x0/0x94
[    0.112112] psci: cphp_walk:cpuid:1,psci_cpu_on, fn:0xc4000003
[    0.145924] cphp_walk:cpu:1,secondary_start_kernel
[    0.145934] Detected PIPT I-cache on CPU1
[    0.145942] cpuhp_walk:cpu:1,notify_cpu_starting
[    0.145943] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:sched_cpu_starting+0x0/0x120
[    0.145946] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:gic_starting_cpu+0x0/0x40
[    0.145950] GICv3: CPU1: found redistributor 1 region 1:0x00000000299a0000
[    0.145958] GICv3: CPU1: using allocated LPI pending table @0x0000002176620000
[    0.145964] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:arch_timer_starting_cpu+0x0/0x318
[    0.145971] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:dummy_timer_starting_cpu+0x0/0x88
[    0.145973] cpuhp_walk, CPU1: Booted secondary processor 0x0000000001 [0x701f6633]
[    0.145978] cpuhp_walk:cpu:1,bringup_cpu, wait ap
[    0.145980] cphp_walk:cpu:1,bringup_wait_for_ap, 1
[    0.145984] cphp_walk:cpu:1,bringup_wait_for_ap, 2
[    0.145987] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:smpboot_unpark_threads+0x0/0xb0
[    0.145994] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:irq_affinity_online_cpu+0x0/0x110
[    0.145998] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:perf_event_init_cpu+0x0/0x140
[    0.146002] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:workqueue_online_cpu+0x0/0x228
[    0.146019] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:rcutree_online_cpu+0x0/0x98
[    0.146022] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:page_writeback_cpu_online+0x0/0x20
[    0.146025] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:vmstat_cpu_online+0x0/0x70
[    0.146029] cphp_walk:cpu:1,cpuhp_invoke_callback, 1.1, cb:sched_cpu_activate+0x0/0x168
[    0.146035] smp: ====cpuhp-walk:after bringing up cpu:1
[    0.146036] smp: ====cpuhp-walk:before bringing up cpu:2
[    0.146037] cpuhp_walk:cpu:2,do_cpu_up
[    0.146041] cphp_walk:cpu:2,cpuhp_up_callbacks
[    0.146042] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:smpboot_create_threads+0x0/0xe0
[    0.185939] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:perf_event_init_cpu+0x0/0x140
[    0.185943] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:workqueue_prepare_cpu+0x0/0x98
[    0.193946] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:hrtimers_prepare_cpu+0x0/0xb0
[    0.193949] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:smpcfd_prepare_cpu+0x0/0x70
[    0.193952] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:relay_prepare_cpu+0x0/0xf8
[    0.193954] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:rcutree_prepare_cpu+0x0/0x1c0
[    0.193959] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:timers_prepare_cpu+0x0/0x80
[    0.193961] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:bringup_cpu+0x0/0x140
[    0.193964] cpuhp_walk:cpu:2,bringup_cpu
[    0.193964] cpuhp_walk:cpu:2,__cpu_up
[    0.193965] cpuhp_walk:cpu:2,boot_secondary, cpu_boot:cpu_psci_cpu_boot+0x0/0x94
[    0.193967] psci: cpuhp_walk:cpu:2,cpu_psci_cpu_boot, cpu_on:psci_cpu_on+0x0/0x94
[    0.193969] psci: cphp_walk:cpuid:256,psci_cpu_on, fn:0xc4000003
[    0.227952] cphp_walk:cpu:2,secondary_start_kernel
[    0.227961] Detected PIPT I-cache on CPU2
[    0.227967] cpuhp_walk:cpu:2,notify_cpu_starting
[    0.227968] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:sched_cpu_starting+0x0/0x120
[    0.227972] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:gic_starting_cpu+0x0/0x40
[    0.227976] GICv3: CPU2: found redistributor 100 region 2:0x00000000299c0000
[    0.227994] GICv3: CPU2: using allocated LPI pending table @0x0000002176630000
[    0.227999] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:arch_timer_starting_cpu+0x0/0x318
[    0.228007] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:dummy_timer_starting_cpu+0x0/0x88
[    0.228010] cpuhp_walk, CPU2: Booted secondary processor 0x0000000100 [0x701f6633]
[    0.228017] cpuhp_walk:cpu:2,bringup_cpu, wait ap
[    0.228019] cphp_walk:cpu:2,bringup_wait_for_ap, 1
[    0.228022] cphp_walk:cpu:2,bringup_wait_for_ap, 2
[    0.228029] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:smpboot_unpark_threads+0x0/0xb0
[    0.228039] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:irq_affinity_online_cpu+0x0/0x110
[    0.228042] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:perf_event_init_cpu+0x0/0x140
[    0.228047] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:workqueue_online_cpu+0x0/0x228
[    0.228070] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:rcutree_online_cpu+0x0/0x98
[    0.228073] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:page_writeback_cpu_online+0x0/0x20
[    0.228076] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:vmstat_cpu_online+0x0/0x70
[    0.228080] cphp_walk:cpu:2,cpuhp_invoke_callback, 1.1, cb:sched_cpu_activate+0x0/0x168
[    0.228086] smp: ====cpuhp-walk:after bringing up cpu:2
[    0.228087] smp: ====cpuhp-walk:before bringing up cpu:3
[    0.228088] cpuhp_walk:cpu:3,do_cpu_up
[    0.228092] cphp_walk:cpu:3,cpuhp_up_callbacks
[    0.228093] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:smpboot_create_threads+0x0/0xe0
[    0.267968] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:perf_event_init_cpu+0x0/0x140
[    0.267972] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:workqueue_prepare_cpu+0x0/0x98
[    0.275974] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:hrtimers_prepare_cpu+0x0/0xb0
[    0.275977] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:smpcfd_prepare_cpu+0x0/0x70
[    0.275980] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:relay_prepare_cpu+0x0/0xf8
[    0.275983] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:rcutree_prepare_cpu+0x0/0x1c0
[    0.275988] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:timers_prepare_cpu+0x0/0x80
[    0.275990] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:bringup_cpu+0x0/0x140
[    0.275993] cpuhp_walk:cpu:3,bringup_cpu
[    0.275994] cpuhp_walk:cpu:3,__cpu_up
[    0.275995] cpuhp_walk:cpu:3,boot_secondary, cpu_boot:cpu_psci_cpu_boot+0x0/0x94
[    0.275996] psci: cpuhp_walk:cpu:3,cpu_psci_cpu_boot, cpu_on:psci_cpu_on+0x0/0x94
[    0.275998] psci: cphp_walk:cpuid:257,psci_cpu_on, fn:0xc4000003
[    0.309980] cphp_walk:cpu:3,secondary_start_kernel
[    0.309985] Detected PIPT I-cache on CPU3
[    0.309989] cpuhp_walk:cpu:3,notify_cpu_starting
[    0.309990] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:sched_cpu_starting+0x0/0x120
[    0.309993] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:gic_starting_cpu+0x0/0x40
[    0.309996] GICv3: CPU3: found redistributor 101 region 3:0x00000000299e0000
[    0.310002] GICv3: CPU3: using allocated LPI pending table @0x0000002176640000
[    0.310007] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:arch_timer_starting_cpu+0x0/0x318
[    0.310012] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:dummy_timer_starting_cpu+0x0/0x88
[    0.310014] cpuhp_walk, CPU3: Booted secondary processor 0x0000000101 [0x701f6633]
[    0.310019] cpuhp_walk:cpu:3,bringup_cpu, wait ap
[    0.310021] cphp_walk:cpu:3,bringup_wait_for_ap, 1
[    0.310024] cphp_walk:cpu:3,bringup_wait_for_ap, 2
[    0.310028] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:smpboot_unpark_threads+0x0/0xb0
[    0.310036] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:irq_affinity_online_cpu+0x0/0x110
[    0.310039] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:perf_event_init_cpu+0x0/0x140
[    0.310043] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:workqueue_online_cpu+0x0/0x228
[    0.310050] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:rcutree_online_cpu+0x0/0x98
[    0.310052] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:page_writeback_cpu_online+0x0/0x20
[    0.310054] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:vmstat_cpu_online+0x0/0x70
[    0.310057] cphp_walk:cpu:3,cpuhp_invoke_callback, 1.1, cb:sched_cpu_activate+0x0/0x168
[    0.310063] smp: ====cpuhp-walk:after bringing up cpu:3
[    0.310064] smp: ====cpuhp-walk:Brought up 1 node, 4 CPUs
[    0.310066] SMP: Total of 4 processors activated.
[    0.310067] CPU features: detected: 32-bit EL0 Support
[    0.310069] CPU features: detected: CRC32 instructions
[    0.310303] CPU: All CPU(s) started at EL2

经查,是CPU厂商firmware的问题, 也就是psci_cpu_on, fn:0xc4000003的问题。

所以以后遇到这样的问题,熟悉了过程,就不慌了。

本文的psci部分由我的同事提供,同时,在阅读和分析代码之前,我还参照了如下链接的信息:

https://www.cnblogs.com/pengdonglin137/p/11925299.html

https://zhuanlan.zhihu.com/p/538782115

https://blog.csdn.net/weixin_45264425/article/details/127895018

https://zhuanlan.zhihu.com/p/545550388

此外,由于功耗控制的原因,系统运行期间,还会通过cpu idle来间断的关闭和打开cpu,也就是cpu hotplug,打开cpu的操作和上述过程相同,关闭cpu的过程与cpu up相反,读者自行阅读代码,也是通过psci来关闭cpu。

相关文章:

smp_init过程解析

当你看到这样的log,会不会很慌张?竟然由CPU没有启动成功,除了什么故障?本文将结合我遇到的一个问题,将启动过程中bringup secondary cpu的过程分析一下。smp_init代码如下:602 void __init smp_init(void) …...

判断推理之逻辑判断

考点一翻译推理(一)题目特征题干或选项中出现多组“逻辑关联词”,如:“如果……那么……”、“只要……就……”、“只有……才……”、“所有”、“有些”、“……且……”、“ ……或……”等典型逻辑关联词。(二&am…...

2023金三银四常见Handler面试总结,附带答案

以下的Handler的面试题都是在面试过程中总结出来比较常见的面试题,现在分享给大家,希望可以帮助你们!1.Handler的实现原理从四个方面看Handler、Message、MessageQueue 和 Looper Handler:负责消息的发送和处理 Message:消息对象,…...

为什么机器人操作系统ROS1、ROS2这么难学

AI回复:ROS1、ROS2是机器人操作系统,涉及到很多复杂的概念和技术,需要有一定的编程和机器人知识基础才能学习。此外,ROS1和ROS2的架构和设计也有很大的不同,需要花费一定的时间和精力去学习和适应。但是,一…...

day01

授课老师 :陶国荣 联系方式 : taogrtedu.cn 授课阶段 : Web前端基础 授课内容 : HTML CSS JavaScript 文章目录一、讲师和课程介绍二、Web前端介绍1. 什么是网页2. 网页的组成3. 网页的优势4. 开发前的准备三、 HTML语法介绍…...

第四十章 linux-并发解决方法五(顺序锁seqlock)

第四十章 linux-并发解决方法四(顺序锁seqlock) 文章目录第四十章 linux-并发解决方法四(顺序锁seqlock)顺序锁的设计思想是,对某一共享数据读取时不加锁,写的时候加锁。为了保证读取的过程中不会因为写入名…...

【SPSS】交叉设计方差分析和协方差分析详细操作教程(附案例实战)

🤵‍♂️ 个人主页:@艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ 目录 方差分析概述 交叉设计方差分析...

playwright--核心概念和Selector定位

文章目录前言一、浏览器二、浏览器上下文三、页面和框架四、Selectors1、data-test-id selector2、CSS and XPath selector3、text 文本selector4、id定位selector5、Selector 组合定位五、内置Selector前言 Playwright提供了一组API可自动化操作Chromium,Firefox和…...

响应式操作实战案例

Project Reactor 框架 在Spring Boot 项目 Maven 中添加依赖管理。 <dependency><groupId>io.projectreactor</groupId><artifactId>reactor-core</artifactId> </dependency><dependency><groupId>io.projectreactor</g…...

NetApp AFF A900:针对任务关键型应用程序的解决方案

NetApp AFF A900&#xff1a;适用于数据中心的解决方案 AFF A 系列中的 AFF A900 高端 NVMe 闪存存储功能强大、安全可靠、具有故障恢复能力&#xff0c;提供您为任务关键型企业级应用程序提供动力并保持数据始终可用且安全所需的一切。 AFF A900&#xff1a;针对任务关键型应…...

使用Houdini输出四面体网格并输出tetgen格式

我们的目标是从houdini输出生成的四面体&#xff0c;希望是tetgen格式的。 众所周知&#xff0c;houdini是不能直接输出四面体的。 有三方案去解决&#xff1a; 输出点云ply文件&#xff0c;然后利用tetgen生成网格。输出Hounidi内置的.geo格式文件&#xff0c;然后写个脚本…...

组合预测 | MATLAB实现EMD-KPCA-LSTM、EMD-LSTM、LSTM多输入单输出回归预测对比

组合预测 | MATLAB实现EMD-KPCA-LSTM、EMD-LSTM、LSTM多输入单输出回归预测对比 目录 组合预测 | MATLAB实现EMD-KPCA-LSTM、EMD-LSTM、LSTM多输入单输出回归预测对比预测效果基本介绍模型描述程序设计参考资料预测效果 基本介绍 MATLAB实现EMD-KP...

【C语言】操作符详解总结(万字)

操作符详解1. 操作符分类2. 算术操作符3. 移位操作符3.1 整数的二进制是怎么形成的3.2 左移操作符3.3 右移操作符4. 位操作符5. 赋值操作符6. 单目操作符6.1 单目操作符介绍6.2 sizeof 和 数组7. 关系操作符8. 逻辑操作符9. 条件操作符9.1 练习19.2 练习210. 逗号表达式11. 下标…...

mac系统手册(帮助/说明)

文章目录1. mac自带的帮助文档2. Mac使用技巧&#xff08;提示&#xff09;2.1 聚焦搜索2.2 截图&#xff08;录制屏幕&#xff09;2.3 调出右键菜单2.4 快速查看2.5 翻译2.5.1 词典解释2.5.2 翻译&#xff08;字、词和句&#xff09;3. macOS使用手册3.1 在聚焦中进行计算和转…...

VLC播放器Demo(录像,截图等功能),Android播放器Demo可二次开发。

VLC播放器Demo&#xff08;录像&#xff0c;截图等功能&#xff09;&#xff0c;可二次开发。 GitHub地址:https://github.com/ILoveLin/VlcRecordPlayer GitHub地址:https://github.com/ILoveLin/VlcRecordPlayer GitHub地址:https://github.com/ILoveLin/VlcRecordPlayer …...

WeSpeaker支持C++部署链路

WeSpeaker正式更新C部署链路&#xff0c;推理引擎使用OnnxRuntime&#xff0c;支持从语音中提取Speaker Embedding信息&#xff0c;代码详见WeSpeaker/runtime[1]。 Libtorch和onnx的选择? Speaker Embedding提取任务流程简单&#xff0c;并且声纹模型&#xff08;如ResNet\E…...

window vscode编辑appsmith源码

前言 本来最开始用的idea打开wsl中的appsmith&#xff0c;卡得一批。最后没办法&#xff0c;用自己的电脑装成ubuntu server&#xff0c;然后vscode的远程开发对appsmith源码进行编辑。如果自己电脑内存16个G或者更大可能打开wsl中的估计会还好&#xff0c;我公司电脑只有8g所…...

操作系统面试题

操作系统一、简介篇1.解释一下什么是操作系统2.操作系统的主要功能3.软件访问硬件的几种方式4.操作系统的主要目的是什么5.为什么Linux系统下的应用程序不能直接在Windows下运行6.什么是用户态和内核态7.用户态和内核态如何切换8.什么是内核二、进程和线程篇1.多处理系统的优势…...

Kafka入门(七)

下面聊聊Kafka的配置参数&#xff0c;包括生产者的配置参数、Broker的配置参数、消费者的配置参数。 1、生产者配置参数 acks 该参数控制了生产者的消息发送确认机制&#xff0c;用于指定分区中必须有多少个副本成功接收到消息后生产者才会认为这条消息写入是成功的&#xff0c…...

微服务介绍

微服务 微服务架构发展 微服务这个概念最早是在2011年5月威尼斯的一个软件架构会议上讨论提出的&#xff0c;用于描述一些作为通用架构风格的设计原则&#xff1b;2012年3月在波兰举行的Degree Conference大会&#xff0c;james lewis做演讲&#xff0c;讨论了微服务一些原则…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...