arch_call_rest_init
rest_init
pid = kernel_thread(kernel_init, NULL, CLONE_FS);
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
cpu_startup_entry(CPUHP_ONLINE);
内核进程2的创建过程
arm linux 内核源码剖析.pdf P407
内核进程2开始运行的时刻
start_kernel->rest_init->schedule_preempt_disabled -> schedule -> __schedule -> context_switch
此函数执行后, kthreadd 开始运行
内核进程2应该负责的任务
帮助 创建内核线程的人(该人调用kernel_create) 创建(kernel_thread)内核线程
---------------------------------------------------
1 2 3 为 kthreadd 进程的流程
A B C 为 内核使用者 调用kernel_create的进程
a b c 为 内核使用者 创建的进程
1.idle 调用 kernel_thread 创建 kthreadd 进程 , 入口为 kthreadd 函数
2.kthreadd 进程 循环检测 kthread_create_list,为空,睡眠
A.我们(内核使用者) 调用 kernel_create 创建一个内核进程 xxx ,kernel_create 将 xxx 的信息(其中包括入口函数 mythread)填充到 kthread_create_list , 并 唤醒(wake_up) kthreadd 进程
3.kthreadd 进程 苏醒,检查 kthread_create_list ,看到其中 有 xxx ,根据 xxx 获得 struct kthread_create_info *create , 并调用 create_kthread(create);
4.create_kthread 调用 kernel_thread 创建 xxx 内核进程,入口为 kthread 函数
B.我们调用 wake_up_process 来唤醒 xxx 内核进程
a.xxx 内核进程 苏醒(被唤醒), 调用 create->threadfn/即mythread , mythread 开始执行
其他
kernel_create 创建的内核线程入口都是 kthread
kthread_create 创建的内核线程不会立刻运行.需要手工 wake up.
kthread_create 创建的内核线程有可能不会执行相应线程函数threadfn而直接退出
kthread_create 比 kernel_thread 更上层,不建议使用 kernel_thread
---
其他的创建线程的函数
kthread_run 是 kthread_create 的封装
kthread_create_on_node 和 kthread_create 类似
其他
kernel_thread 的消费者
kernel_thread 的消费者
1. kernel_init kthreadd 的创建
2. kthread 的创建
3. call_usermodehelper_exec_work,用于
3.1.do_coredump
3.2.__orderly_reboot/__orderly_poweroff
3.3.kobject_uevent_env(mdev)
3.4.LKM的request_module
------
do_coredump 的消费者
vector_swi
local_restart:
__sys_trace
syscall_trace_enter
secure_computing
__secure_computing
__seccomp_filter
do_coredump
ret_fast_syscall
do_work_pending
do_signal
get_signal
do_coredump
kthread_create 的消费者
fs/lockd/svc.c:400: nlmsvc_task = kthread_create(lockd, nlmsvc_rqst, "%s", serv->sv_name);
fs/io_uring.c:8208: sqd->thread = kthread_create(io_sq_thread, sqd,
fs/io-wq.c:1107: wq->manager = kthread_create(io_wq_manager, wq, "io_wq_manager");
kernel/irq/manage.c:1383: t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
kernel/irq/manage.c:1386: t = kthread_create(irq_thread, new, "irq/%d-s-%s", irq,
request_threaded_irq
request_nmi
setup_percpu_irq
request_percpu_irq
request_percpu_nmi
kernel/workqueue.c:4236: rescuer->task = kthread_create(rescuer_thread, rescuer, "%s", wq->name);
消费者(包括 events 内核线程workqueue_init_early->system_wq = alloc_workqueue("events", 0, 0);)
alloc_workqueue
init_rescuer
kthread_create(rescuer_thread, rescuer, "%s", wq->name)
list_add_tail_rcu(&wq->list, &workqueues);
kernel_init
kernel_init_freeable
workqueue_init
list_for_each_entry(wq, &workqueues, list) init_rescuer
kthread_create(rescuer_thread, rescuer, "%s", wq->name)
kthread_run 的消费者
// 驱动相关
drivers/mmc/core/sdio_irq.c:234: kthread_run(sdio_irq_thread, host,
drivers/media/common/videobuf2/videobuf2-core.c:2925: threadio->thread = kthread_run(vb2_thread, q, "vb2-%s", thread_name);
drivers/char/hw_random/core.c:461: hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng");
// 文件系统相关
fs/jbd2/journal.c:280: t = kthread_run(kjournald2, journal, "jbd2/%s",
fs/lockd/clntlock.c:220: task = kthread_run(reclaimer, host, "%s-reclaim", host->h_name);
fs/lockd/svc.c:404: "lockd_up: kthread_run failed, error=%dn", error);
fs/ext4/super.c:3622: ext4_lazyinit_task = kthread_run(ext4_lazyinit_thread,
fs/ext4/mmp.c:378: EXT4_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, mmpd_data, "kmmpd-%.*s",
kernel/time/clocksource.c:142: kthread_run(clocksource_watchdog_kthread, NULL, "kwatchdog");
看门狗内核进程
kernel/rcu/tasks.h:249: t = kthread_run(rcu_tasks_kthread, rtp, "%s_kthread", rtp->kname);
内存管理相关的内核进程
mm/oom_kill.c:680: oom_reaper_th = kthread_run(oom_reaper, NULL, "oom_reaper");
// oom_reaper 内核进程
mm/page_alloc.c:2107: kthread_run(deferred_init_memmap, NODE_DATA(nid), "pgdatinit%d", nid);
mm/compaction.c:2903: pgdat->kcompactd = kthread_run(kcompactd, pgdat, "kcompactd%d", nid);
mm/vmscan.c:4052: pgdat->kswapd = kthread_run(kswapd, pgdat, "kswapd%d", nid);
kthread_create_on_node 的消费者
net/sunrpc/svc.c:730: task = kthread_create_on_node(serv->sv_ops->svo_function, rqstp,
fs/io-wq.c:690: worker->task = kthread_create_on_node(io_wqe_worker, worker, wqe->node,
kernel/kthread.c:490: p = kthread_create_on_node(threadfn, data, cpu_to_node(cpu), namefmt,
// 封装出了 kthread_create_on_cpu smpboot_register_percpu_thread
// spawn_ksoftirqd -> smpboot_register_percpu_thread(&softirq_threads)
kernel/workqueue.c:1935: worker->task = kthread_create_on_node(worker_thread, worker, pool->node,
// 创建 kworker/xxx
// workqueue_init -> create_worker -> kthread_create_on_node
有多少内核进程
// 进程 1 2 的 父进程为 0
// 其他所有内核线程(被[]包括的) 父进程都是 kthreadd
进程ID 所属用户 状态 COMMAND进程名 进程创建文件 进程创建函数
// 1号用户进程
1 root 1412 S {linuxrc} init //init/main.c kernel_thread
// 1号用户进程
// 2号内核进程
2 root 0 SW [kthreadd] // init/main.c kernel_thread
// 2号内核线程,负责 创建所有的内核线程
// 内核的管家进程
3 root 0 IW [kworker/0:0-eve] //kernel/workqueue.c create_worker
4 root 0 IW< [kworker/0:0H-kb]
5 root 0 IW [kworker/u2:0-ev]
16 root 0 IW [kworker/0:1-eve]
30 root 0 IW< [kworker/0:1H-kb]
31 root 0 IW< [kworker/u3:1-xp]
48 root 0 IW [kworker/u2:7-nf]
67 root 0 IW< [kworker/u3:4-xp]
// "kworker" is a placeholder process for kernel worker threads, which perform most of the actual processing for the kernel, especially in cases where there are interrupts, timers, I/O, etc.
// These typically correspond to the vast majority of any allocated "system" time to running processes.
// It is not something that can be safely removed from the system in any way, and is completely unrelated to nepomuk or KDE (except in that these programs may make system calls, which may require the kernel to do something).
// 用于执行内核工作队列,分为绑定 CPU (名称格式为 kworker/0:0-eve)和未绑定 CPU(名称格式为 kworker/u3:4-xp)两类。
7 root 0 SW [ksoftirqd/0] // kernel/softirq.c smpboot_register_percpu_thread
// ksoftirqd以与kworker几乎相同的方式处理 softirq
// softirq 使用的内核线程ksoftirqd
// 模块相关进程
// 内存相关进程
6 root 0 IW< [mm_percpu_wq] // mm/vmstat.c alloc_workqueue
10 root 0 SW [oom_reaper] // mm/oom_kill.c kthread_run
11 root 0 IW< [writeback] // mm/backing-dev.c alloc_workqueue
12 root 0 SW [kcompactd0] // mm/compaction.c kthread_run
19 root 0 SW [kswapd0] // mm/vmscan.c kthread_run
// 用于内存回收
// 网络相关进程
20 root 0 IW< [nfsiod] // fs/nfs/inode.c alloc_workqueue
21 root 0 IW< [ipv6_addrconf] // net/ipv6/addrconf.c create_workqueue
8 root 0 IW< [netns] // net/core/net_namespace.c create_singlethread_workqueue
9 root 0 IW< [inet_frag_wq] // net/ipv4/inet_fragment.c create_workqueue
// 块设备相关进程
13 root 0 IW< [kblockd] // block/blk-core.c alloc_workqueue
// rpc相关
15 root 0 IW< [rpciod] // net/sunrpc/sched.c alloc_workqueue
18 root 0 IW< [xprtiod] // net/sunrpc/sched.c alloc_workqueue
// 防死机看门狗内核进程
14 root 0 SW [watchdogd] // drivers/watchdog/watchdog_dev.c kthread_create_worker
// mmc 相关
23 root 0 IW< [sdhci] // drivers/mmc/host/sdhci.c alloc_workqueue
24 root 0 SW [irq/88-mmc0] // drivers/mmc/host/sdhci.c request_threaded_irq
// 给中断线程化使用的irq内核线程
29 root 0 IW< [mmc_complete] // drivers/mmc/core/block.c alloc_workqueue
// 用户进程
53 root 4100 S /sbin/mdev -df
64 root 19388 S /usr/bin/Xorg :0.0 vt01 -s 0 -noreset -allowMouseOpe
上一篇:OK6410A 开发板 (八) 21 linux-5.11 OK6410A schedule 的 __switch_to 部分
下一篇:OK6410A 开发板 (八) 19 linux-5.11 OK6410A start_kernel 功能角度 第三阶段之init进程
推荐阅读最新更新时间:2024-11-07 17:41
设计资源 培训 开发板 精华推荐
- OM13312: SA636DK评估演示板
- 2 纳秒、0.1% 分辨率的宽带放大器建立时间测量
- LTC3405AES6-1.5 同步降压型稳压器的典型应用电路
- 用于仪表的 8/10/12 位、1 通道 DAC
- DC1121A,使用 LTC3524EUF 可调 TFT 偏置电源和白色 LED 驱动器的演示板,单节锂离子/聚合物电池
- AM2G-4805DZ ±5V 2 瓦 DC/DC 转换器的典型应用
- LT4180EGN 演示板,虚拟远程检测控制器 VIN= 8V 至 36V,VOUT1 = 5V @ 3A
- 使用 Analog Devices 的 AD7303BRMZ 的参考设计
- CN0365
- NCV8163MXTBGEVB:NCV8163 XDFN4 评估板