online 可以被调度的
active 可以被迁移的
present 内核已接管的
possible 系统存在的CPU,但没有被内核接管
cpu_down\->_cpu_down(cpu, 0)\->take_cpu_down\->__cpu_disable()\->mp_ops->cpu_disable()\->__cpu_die(cpu)cpu_up\->_cpu_up\->__cpu_up\->mp_ops->boot_secondary(cpu, tidle)
start_kernelsetup_archarch_call_rest_init()--rest_initkernel_thread(kernel_init)kernel_initkernel_init_freeablesmp_prepare_cpusinit_cpu_topology();this_cpu = smp_processor_idstore_cpu_topology(this_cpu);numa_store_cpu_info(this_cpu);numa_add_cpu(this_cpu);set_cpu_present(cpu, true);numa_store_cpu_info(cpu);smp_initidle_threads_init(); /*初始化各个cpu上的idle thread*/cpuhp_threads_init(); /*初始化各个cpu上的hotplug thread*/smpboot_register_percpu_thread /*smp thread 即是 cpuhp_threads--> cpuhp_thread_fun?*/cpu_up(cpu);do_cpu_up(CPUHP_ONLINE)try_online_node_cpu_upcpus_write_lockidle_thread_getcpuhp_set_statecpuhp_kick_ap_workcpuhp_kick_ap__cpuhp_kick_ap(st);smp_mbwake_up_process(st-thread)wait_for_ap_thread(st, st->bringup);if ((ret = st->result)) {cpuhp_reset_state__cpuhp_kick_ap}cpuhp_up_callbackscpuhp_invoke_callback(cpu, st->state, true, NULL, NULL);cbm(cpu, node)smp_cpus_done(setup_max_cpus); /*Total of %d processors activated*/setup_cpu_features();hyp_mode_check();apply_alternatives_all();mark_linear_text_alias_ro();cpu_startup_entry()do_idle(CPU_ONLINE)
st-thread---------->cpuhp_thread_funsmp_mbcpuhp_lock_acquirecpuhp_invoke_callbackhlist_for_each(node, &step->list) cbm(cpu, node);******************.bringup_cpu__cpu_upsecondary_data.task = idle; /*设置起来的第一个task idle, stack, 关闭其MMU, 将dcache flush掉*/secondary_data.stack = task_stack_page(idle) + THREAD_SIZE;update_cpu_boot_status(CPU_MMU_OFF);__flush_dcache_area(&secondary_data, sizeof(secondary_data));boot_secondarycpu_ops[cpu]->cpu_boot(cpu);psci_ops.cpu_on(cpu_logical_map(cpu), __pa_symbol(secondary_entry)); /*从这里将回kernel的地址带下去, ENDPROC(secondary_entry)
定义在head.S里面*/bringup_wait_for_apwait_for_ap_thread /*Wait for the CPU to reach CPUHP_AP_ONLINE_IDLE*/cpuhp_kick_apcpuhp_lock_releasecomplete_ap_thread
static struct cpuhp_step cpuhp_hp_states[] = {[CPUHP_OFFLINE] = {.name = "offline",.startup.single = NULL,.teardown.single = NULL,},
#ifdef CONFIG_SMP[CPUHP_CREATE_THREADS]= {.name = "threads:prepare",.startup.single = smpboot_create_threads,.teardown.single = NULL,.cant_stop = true,},[CPUHP_PERF_PREPARE] = {.name = "perf:prepare",.startup.single = perf_event_init_cpu,.teardown.single = perf_event_exit_cpu,},[CPUHP_WORKQUEUE_PREP] = {.name = "workqueue:prepare",.startup.single = workqueue_prepare_cpu,.teardown.single = NULL,},[CPUHP_HRTIMERS_PREPARE] = {.name = "hrtimers:prepare",.startup.single = hrtimers_prepare_cpu,.teardown.single = hrtimers_dead_cpu,},[CPUHP_SMPCFD_PREPARE] = {.name = "smpcfd:prepare",.startup.single = smpcfd_prepare_cpu,.teardown.single = smpcfd_dead_cpu,},[CPUHP_RELAY_PREPARE] = {.name = "relay:prepare",.startup.single = relay_prepare_cpu,.teardown.single = NULL,},[CPUHP_SLAB_PREPARE] = {.name = "slab:prepare",.startup.single = slab_prepare_cpu,.teardown.single = slab_dead_cpu,},[CPUHP_RCUTREE_PREP] = {.name = "RCU/tree:prepare",.startup.single = rcutree_prepare_cpu,.teardown.single = rcutree_dead_cpu,},/** On the tear-down path, timers_dead_cpu() must be invoked* before blk_mq_queue_reinit_notify() from notify_dead(),* otherwise a RCU stall occurs.*/[CPUHP_TIMERS_PREPARE] = {.name = "timers:prepare",.startup.single = timers_prepare_cpu,.teardown.single = timers_dead_cpu,},/* Kicks the plugged cpu into life */[CPUHP_BRINGUP_CPU] = {.name = "cpu:bringup",.startup.single = bringup_cpu,.teardown.single = NULL,.cant_stop = true,},/* Final state before CPU kills itself */[CPUHP_AP_IDLE_DEAD] = {.name = "idle:dead",},/** Last state before CPU enters the idle loop to die. Transient state* for synchronization.*/[CPUHP_AP_OFFLINE] = {.name = "ap:offline",.cant_stop = true,},/* First state is scheduler control. Interrupts are disabled */[CPUHP_AP_SCHED_STARTING] = {.name = "sched:starting",.startup.single = sched_cpu_starting,.teardown.single = sched_cpu_dying,},[CPUHP_AP_RCUTREE_DYING] = {.name = "RCU/tree:dying",.startup.single = NULL,.teardown.single = rcutree_dying_cpu,},[CPUHP_AP_SMPCFD_DYING] = {.name = "smpcfd:dying",.startup.single = NULL,.teardown.single = smpcfd_dying_cpu,},/* Entry state on starting. Interrupts enabled from here on. Transient* state for synchronsization */[CPUHP_AP_ONLINE] = {.name = "ap:online",},/** Handled on controll processor until the plugged processor manages* this itself.*/[CPUHP_TEARDOWN_CPU] = {.name = "cpu:teardown",.startup.single = NULL,.teardown.single = takedown_cpu,.cant_stop = true,},/* Handle smpboot threads park/unpark */[CPUHP_AP_SMPBOOT_THREADS] = {.name = "smpboot/threads:online",.startup.single = smpboot_unpark_threads,.teardown.single = smpboot_park_threads,},[CPUHP_AP_IRQ_AFFINITY_ONLINE] = {.name = "irq/affinity:online",.startup.single = irq_affinity_online_cpu,.teardown.single = NULL,},[CPUHP_AP_PERF_ONLINE] = {.name = "perf:online",.startup.single = perf_event_init_cpu,.teardown.single = perf_event_exit_cpu,},[CPUHP_AP_WATCHDOG_ONLINE] = {.name = "lockup_detector:online",.startup.single = lockup_detector_online_cpu,.teardown.single = lockup_detector_offline_cpu,},[CPUHP_AP_WORKQUEUE_ONLINE] = {.name = "workqueue:online",.startup.single = workqueue_online_cpu,.teardown.single = workqueue_offline_cpu,},[CPUHP_AP_RCUTREE_ONLINE] = {.name = "RCU/tree:online",.startup.single = rcutree_online_cpu,.teardown.single = rcutree_offline_cpu,},
#endif/** The dynamically registered state space is here*/#ifdef CONFIG_SMP/* Last state is scheduler control setting the cpu active */[CPUHP_AP_ACTIVE] = {.name = "sched:active",.startup.single = sched_cpu_activate,.teardown.single = sched_cpu_deactivate,},
#endif/* CPU is fully up and running. */[CPUHP_ONLINE] = {.name = "online",.startup.single = NULL,.teardown.single = NULL,},
};
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!