启动secondary cpu内核在启动secondary cpu之前当然需要为其准备好执行环境,因为内核中cpu最终都将由调度器管理,故此时调度子系统应该要初始化完成。
同时cpu启动完成转交给调度器之前,并没有实际的业务进程,而我们知道内核中cpu在空闲时会执行idle进程。因此,在其启动之前需要为每个cpu初始化一个idle进程。
另外,由于将一个cpu通过热插拔方式移除后,再次启动该cpu的流程,与secondary cpu的启动流程是相同的,因此内核复用了cpu hotplug框架用于启动secondary cpu。
而内核为每个cpu都分配了一个独立的hotplug线程,用于执行本cpu相关的热插拔流程。为此,内核通过以下流程执行secondary cpu启动操作:
idle进程初始化以下代码为每个非boot cpu分配一个idle进程
void __init idle_threads_init(void){ … boot_cpu = smp_processor_id(); for_each_possible_cpu(cpu) { (1) if (cpu != boot_cpu) idle_init(cpu); (2) }}(1)遍历系统中所有的possible cpu
(2)若该cpu为secondary cpu,则为其初始化一个idle进程
hotplug线程初始化以下代码为每个cpu初始化一个hotplug线程
void __init cpuhp_threads_init(void){ bug_on(smpboot_register_percpu_thread(&cpuhp_threads)); kthread_unpark(this_cpu_read(cpuhp_state.thread));}其中线程的描述结构体定义如下:
static struct smp_hotplug_thread cpuhp_threads = { .store = &cpuhp_state.thread, (1) .create = &cpuhp_create, (2) .thread_should_run = cpuhp_should_run, (3) .thread_fn = cpuhp_thread_fun, (4) .thread_comm = cpuhp/%u, (5) .selfparking = true, (6)}(1)用于保存cpu上的task struct指针
(2)线程创建时调用的回调
(3)该回调用于获取线程是否需要退出标志
(4)cpu hotplug主函数,执行实际的hotplug操作
(5)该线程的线程名
(6)用于设置线程创建完成后,是否将其设置为park状态
激光熔覆技术在船舶修复中的应用
西门子预计明年中国销售额复苏,给出增长8%乐观预测
德州仪器推出全新的可编程前照灯系统
电子灭蚊灯拆装要领和维修技巧
从2019 达沃斯论坛看人工智能如何发现下一个趋势
如何在内核中启动secondary cpu
水货笔记本硬盘鉴别方法
浅析滑台模组的五大选型要素!
知性女工程师的热敏研发人生 | 技术用语篇Vol.4
基于CAN通信的电源监控系统的设计
印度电信BSNL与中兴通讯进行5G建设合作方面持“谨慎”态度
2016年音视频及家电行业应用文章精选
低温等离子体技术的应用
[图文]使W317稳压器从零伏起调
小米6将于3月发布惊艳新机,会有三个版本随你选
诺基亚5G核心网解决方案帮助软银提供先进服务
智能镜子电视机将带领我们开启智能生活的新体验
电气设备过热主要原因
M480系列特色功能Trust Boot,让您每次开机运行的程序都是可信赖的
华为与泰国劳工部签署数字技能发展谅解备忘录