idle 进程 相关的打印: 无
idle 进程相关的 函数__mmap_switched 中的 ARM( ldmia r4!, {r0, r1, sp} ) sched_init
idle 相关函数
start_kernelsched_initinit_idle(current, smp_processor_id()); struct rq *rq = cpu_rq(cpu);__sched_fork(0, idle);上锁idle->state = TASK_RUNNING;rq->idle = idle;解锁idle->sched_class = &idle_sched_class;fork_inittask_struct_cachep = kmem_cache_create_usercopy("task_struct"set_max_threads(MAX_THREADS);init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;arch_call_rest_initrest_initpid = kernel_thread(kernel_init, NULL, CLONE_FS);pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);cpu_startup_entry(CPUHP_ONLINE);从 stext就开始了到 start_kernel->rest_init->schedule_preempt_disabled -> schedule -> __schedule -> context_switch 结束早先版本中,idle是参与调度的,所以将其优先级设为最低,当没有其他进程可以运行时,才会调度执行 idle而目前的版本中idle并不在运行队列中参与调度,而是在cpu全局运行队列rq中含idle指针,指向idle进程, 在调度器发现运行队列为空的时候运行, 调入运行init_idle -> rq->idle = idle;idle 进程的建立的 过程 1.sp 的初始化2.TCB(init_task&init_thread_info)结构体的建立3.TCB(init_task&init_thread_info)结构体的定位4. init_idle:idle 进程的 信息1(init_task) 的初始化6. schedule:idle 进程的 信息2(init_thread_info.cpu_context) 的初始化7. 其他进程调用 schedule , 选中 init_task 为 下一个 进程8. 将 init_task 对应的 init_thread_info.cpu_context 恢复到寄存器中
进程idle的建立
创建过程
与cpu 的关系cpu0 上的 idle进程内核裸机程序(在 创建init 进程之前可以这么称呼吧) 在调用 sched_init 之后将自己变成了 0 号内核进程idlestart_kernel -> sched_init -> init_idle(current, smp_processor_id());-> __sched_fork(0, idle);-> idle->state = TASK_RUNNING;0号内核进程 在创建了init和kthreadd进程后, 调用cpu_idle()开始做idle循环start_kernel -> arch_call_rest_init -> rest_init-> cpu_startup_entry-> do_idle
cpu1 上的 idle 进程cpu0 上的 init内核进程在演变成/sbin/init之前&#xff0c;会调用 smp_init(),让cpu1,cpu2 ... 开始启动cpu1,cpu2 ... 启动过程中 会调用 如下函数,创建 对应cpu上的 idle进程task &#61; copy_process(CLONE_VM, 0, idle_regs(®s), 0, NULL, NULL, 0); init_idle(task, cpu);从而创建 cpu1 上的 idle进程,cpu2 上的 idle进程, ...cpu0:smp_initidle_threads_initfor_each_possible_cpu idle_initfork_idlecopy_processbringup_nonboot_cpuscpu_up_cpu_upsmp_ops.smp_boot_secondary(cpu, idle); / 即 psci_boot_secondarypsci_ops.cpu_on psci_0_1_cpu_on__psci_cpu_oninvoke_psci_fn __invoke_psci_fn_smcarm_smccc_smc__arm_smccc_smcSMCCC SMCCC_SMC__SMC0xE1600070 | (((imm4) & 0xF) << 0),0xF7F08000 | (((imm4) & 0xF) << 16)cpu1:secondary_startup__secondary_switchedsecondary_start_kernelpr_debug("CPU%u: Booted secondary processor\n", cpu);cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);do_idle
前两次调度时机
start_kernel->rest_init->schedule_preempt_disabled -> schedule -> __schedule -> context_switch调度到了 kthreadd
kthreadd -> schedule -> __schedule -> context_switch
调度到了 kernel_init
idle 流程
当需要调度时 , need_resched() 为 1
cpu_startup_entryschedule_preempt_disabledschedule当不需要调度时, need_resched() 为 0cpu_startup_entrycpu_idle_loopcpuidle_idle_callarch_cpu_idlecpu_do_idlecpu_v7_do_idledsbwfiret lr
TODO
其他
kernel_init : r4:0,r5:c0535d3c(kernel_init),pc:c010015c(ret_from_fork)
kthreadd : r4:0,r5:c012cc14(kthreadd),pc:c010015c(ret_from_fork)
---
idle
rest_init : r4:0,r5:0,pc:0
schedule_preempt_disabled -> schedule -> __schedule -> context_switch 中设置了 r4 r5 r6
do_idle : r4:c0e55d08(init_stack/init_thread_info/init_thread_union),r5:c0805980(init_task),pc:c0536778(__schedule中)
Freeing unused kernel memory: 1024K 前的堆栈
[14:57:54]CPU: 0 PID: 0 Comm: swapper Not tainted 5.11.0-00008-g0cf53aa024f-dirty #180
[14:57:54]Hardware name: SMDK6410
[14:57:54][<c0105b60>] (unwind_backtrace) from [<c010477c>] (show_stack&#43;0x10/0x14)
[14:57:54][<c010477c>] (show_stack) from [<c0135434>] (do_idle&#43;0x8/0xd4)
[14:57:54][<c0135434>] (do_idle) from [<c01357d0>] (cpu_startup_entry&#43;0x10/0x14)
[14:57:54][<c01357d0>] (cpu_startup_entry) from [<c07016c8>] (start_kernel&#43;0xbf4/0xe0c)
[14:57:54][<c07016c8>] (start_kernel) from [<00000000>] (0x0)Freeing unused kernel memory: 1024K 后的堆栈
[14:57:54]CPU: 0 PID: 0 Comm: swapper Not tainted 5.11.0-00008-g0cf53aa024f-dirty #180
[14:57:54]Hardware name: SMDK6410
[14:57:54][<c0105b60>] (unwind_backtrace) from [<c010477c>] (show_stack&#43;0x10/0x14)
[14:57:54][<c010477c>] (show_stack) from [<c0135434>] (do_idle&#43;0x8/0xd4)
[14:57:54][<c0135434>] (do_idle) from [<c01357d0>] (cpu_startup_entry&#43;0x10/0x14)
[14:57:54][<c01357d0>] (cpu_startup_entry) from [<c07016c8>] (start_kernel&#43;0xbf4/0xe0c)
[14:57:47]CPU: 0 PID: 1 Comm: swapper Not tainted 5.11.0-00008-g0cf53aa024f-dirty #180
[14:57:47]Hardware name: SMDK6410
[14:57:47][<c0105b60>] (unwind_backtrace) from [<c010477c>] (show_stack&#43;0x10/0x14)
[14:57:47][<c010477c>] (show_stack) from [<c015a7f4>] (__clocksource_update_freq_scale&#43;0x8c/0x224)
[14:57:47][<c015a7f4>] (__clocksource_update_freq_scale) from [<c015a9bc>] (__clocksource_register_scale&#43;0x30/0x104)
[14:57:47][<c015a9bc>] (__clocksource_register_scale) from [<c0701954>] (do_one_initcall&#43;0x74/0x18c)
[14:57:47][<c0701954>] (do_one_initcall) from [<c0701bf0>] (kernel_init_freeable&#43;0x130/0x1b0)
[14:57:47][<c0701bf0>] (kernel_init_freeable) from [<c0535c4c>] (kernel_init&#43;0x8/0x11c)
[14:57:47][<c0535c4c>] (kernel_init) from [<c0100170>] (ret_from_fork&#43;0x14/0x24)
[14:57:47]Exception stack(0xc144bfb0 to 0xc144bff8)
[14:57:47]bfa0: 00000000 00000000 00000000 00000000
[14:57:47]bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[14:57:47]bfe0: 00000000 00000000 00000000 00000000 00000013 00000000
有五种调度类&#xff1a;fair_sched_class&#xff0c;现在较高版本的Linux上也就是CFS(Completely Fair Scheduler)&#xff0c;Linux上面主要的调度方式&#xff0c;由CONFIG_FAIR_GROUP_SCHED宏控制
rt_sched_class&#xff0c;由CONFIG_RT_GROUP_SCHED宏控制&#xff0c;实时调度类型。
dl_sched_class&#xff0c;deadline调度类&#xff0c;实时调度中较高级别的调度类型&#xff0c;一般之后在系统紧急情况下会调用&#xff1b;
stop_sched_class&#xff0c;最高优先级的调度类型&#xff0c;属于实时调度类型的一种&#xff0c;在系统终止时会在其上创建进程进入调度。
idle_sched_class&#xff0c;优先级最低&#xff0c;在系统空闲时才会进入该调度类型调度&#xff0c;一般系统中只有一个idle&#xff0c;那就是初始化进程init_task&#xff0c;在初始化完成后它将自己设置为idle进程&#xff0c;并不做更多工作。