OK6410A 开发板 (八) 29 linux-5.11 OK6410A 主要内核线程解析

2024-05-27 15:48

本文主要是介绍OK6410A 开发板 (八) 29 linux-5.11 OK6410A 主要内核线程解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • kthreadd这篇博客简述了 一下 系统内创建的 所有内核线程
// 进程 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_worker4 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_workqueue10 root         0 SW   [oom_reaper] 		// mm/oom_kill.c kthread_run11 root         0 IW<  [writeback] 		// mm/backing-dev.c alloc_workqueue12 root         0 SW   [kcompactd0] 		// mm/compaction.c kthread_run19 root         0 SW   [kswapd0] 		// mm/vmscan.c kthread_run// 用于内存回收// 网络相关进程20 root         0 IW<  [nfsiod] 			 // fs/nfs/inode.c alloc_workqueue21 root         0 IW<  [ipv6_addrconf] 	 // net/ipv6/addrconf.c create_workqueue8 root         0 IW<  [netns] 			 // net/core/net_namespace.c create_singlethread_workqueue9 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_workqueue18 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_workqueue24 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 -df64 root     19388 S    /usr/bin/Xorg :0.0 vt01 -s 0 -noreset -allowMouseOpe// 后期 需 重点关注 这些进程
// init kthreadd 
// kworker ksoftirqd 
// mem(5个) kblockd mmc(3个) watchdogd 
  • idle线程

  • init线程

  • kthreadd线程

  • kworker线程

入口是 worker_threadkthreadcreate->threadfn/即worker_threadwoke_up:...recheck:if (!need_more_worker(pool))goto sleep;if (unlikely(!may_start_working(pool)) && manage_workers(worker))goto recheck;do{process_scheduled_worksprocess_one_workworker->current_func(work);}while(keep_working(pool));sleep:schedule();goto woke_up;
  • ksoftirqd 线程
kthreadcreate->threadfn/即run_ksoftirqd__do_softirqstruct softirq_action *h;h = softirq_vec;while ((softirq_bit = ffs(pending))) { h += softirq_bit - 1;h->action(h);h++;}
  • watchdogd 线程

总结 : 
1.watchdogd 线程 是个 kworker 线程
2.定时器的处理函数会提交喂狗任务给 watchdogd 线程
4.watchdogd 线程被调入后喂狗---- 初始化时subsys_initcall_sync(watchdog_init);watchdog_initwatchdog_dev_initwatchdog_kworker = kthread_create_worker(0, "watchdogd"); // 即 kthread -> (create->threadfn/即worker_thread)module_platform_driver(s3c2410wdt_driver).probe      = s3c2410wdt_probe,s3c2410wdt_probewatchdog_register_device__watchdog_register_devicewatchdog_dev_registerwatchdog_cdev_register// 喂狗任务kthread_init_work(&wd_data->work, watchdog_ping_work);// 定时器hrtimer_init(&wd_data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD);wd_data->timer.function = watchdog_timer_expired;----运行时// 定时器时间到了,watchdog_timer_expired被调用
// watchdog_timer_expired 提交喂狗任务 给 watchdog_kworker
watchdog_timer_expiredkthread_queue_work(watchdog_kworker, &wd_data->work);// 喂狗任务 被调用 
watchdog_ping_work__watchdog_ping(wd_data->wdd);wdd->ops->ping(wdd)/即s3c2410wdt_keepalivewritel(wdt->count, wdt->reg_base + S3C2410_WTCNT);
  • mmc 相关线程
//等涉及到 mmc 分析了再说
// 设备驱动相关
  • kblockd 线程
// 等涉及 ext3 分析了再说
// 文件系统相关
  • mem 相关线程
// 等涉及到内存分析了再说
// 内存相关
其他
  • 创建内核线程的API是什么
A.比较高级的API : kernel_thread
B.比较中级的API : kthread_create
C.比较简单的API : alloc_workqueue/create_workqueue/smpboot_register_percpu_thread/request_threaded_irq使用A 的 场景 : 就 两个
使用B 的 场景 : 不超过20个
使用C 的 场景 : 很多,有超过200个内核建议我们使用CC 对于 我们来说是什么
一个创建线程的方法(包括3方面)1.工作者线程的创建 					// 任务的创建完全是内核处理的,我们不需要关心2.工作任务的提交(当然先要创建任务) 	// 任务的创建和提交是我们处理的,需要关心 // 有些是内核处理的3.工作者线程的唤醒 					// 唤醒 是 我们处理的,需要关心 // 有些是内核处理的C 创建的线程(名为target)  会 查询 队列(名为queue)中的任务,然后没有任务(task
)就睡眠
如果有代码将任务(task)插入了该队列(queue),然后唤醒target,此时 target 会执行任务(task)中的处理函数对于内核,这个框架的实现有好几种1. 工作队列2. softirq工作队列1.利用 alloc_workqueue/create_workqueue 完成 工作者线程的创建2.利用 insert_work 						完成 工作任务的提交 	// queue_work 调用的深层函数3.利用 wake_up_worker 					完成 工作者线程的唤醒 // queue_work 调用的深层函数softirq1. 利用 smpboot_register_percpu_thread 	完成 工作者线程的创建2. 利用 or_softirq_pending 				完成 工作任务的提交3. 利用 wakeup_softirqd 				完成 工作者线程的唤醒
softirq机制
处理函数的调用分为两种1. 直接处理 // 对应 __do_softirq  ,但是 __do_softirq  中也会 有 该动作(唤醒 softirqd 处理)执行的条件判断2. 唤醒 softirqd 处理 // 对应 __do_softirqd  , 该函数位于 softirqd 中,是主体函数
原因:处理函数的调用A :1.__do_softirq // 一个函数,直接调用即可,该函数可以直接处理softirq,而不用唤醒 softirqd2.__do_softirqd // 在一个线程里面,使其被调用只能先 唤醒该线程1// linux-5.11 中没有这个函数,而是用的__do_softirq // TODO 
处理函数的调用A的封装:1.invoke_softirq/do_softirq2.wakeup_softirqd
处理函数的调用A的封装的封装:1.irq_exit/netif_rx_ni/local_bn_enable2.raise_softirq/__do_softirq 
处理函数的调用A的封装的封装的封装:1.2.invoke_softirq/do_softirq
处理函数的调用A的封装的封装的封装的封装:1.2.irq_exit/netif_rx_ni/local_bn_enable
  • 引起 __do_softirq 运行的函数
处理函数的调用A :1.__do_softirq // 一个函数,直接调用即可处理函数的调用A的封装:1.invoke_softirq/do_softirq处理函数的调用A的封装的封装:1.irq_exit/netif_rx_ni/local_bn_enable
  • 引起 __do_softirqd 运行的函数
处理函数的调用A :2.__do_softirqd // 在一个线程里面,使其被调用只能先 唤醒该线程1
处理函数的调用A的封装:2.wakeup_softirqd
处理函数的调用A的封装的封装:2.raise_softirq/__do_softirq 
处理函数的调用A的封装的封装的封装:2.invoke_softirq/do_softirq
处理函数的调用A的封装的封装的封装的封装:2.irq_exit/netif_rx_ni/local_bn_enable
  • 同时引起 两者 运行的函数
irq_exit/netif_rx_ni/local_bn_enable
invoke_softirq/do_softirq
__do_softirq 
  • 只引起 __do_softirq(绝对不会引起唤醒softirqd的函数) 运行的函数
  • 只引起 __do_softirqd 运行的函数
raise_softirq
wakeup_softirqd
__do_softirqd 

softirqinit_timers->open_softirq(TIMER_SOFTIRQ, run_timer_softirq);raise_softirq(TIMER_SOFTIRQ);tasklet由软中断实现softirq_init->open_softirq(TASKLET_SOFTIRQ, tasklet_action);tasklet_schedule__tasklet_scheduleraise_softirq_irqoff(TASKLET_SOFTIRQ)内核版本中定义了10个软中断,并且系统不建议用户自己添加软中断,
所以对于软中断基本用于已定义好的功用
而如果用户需要,可以使用其中的一个类型即TASKLET_SOFTIRQinclude/linux/interrupt.h531 /* PLEASE, avoid to allocate new softirqs, if you need not _really_ high         
532    frequency threaded job scheduling. For almost all the purposes                
533    tasklets are more than enough. F.e. all serial device BHs et                  
534    al. should be converted to tasklets, not to softirqs.                         
535  */                                                                              
536                                                                                  
537 enum                                                                             
538 {                                                                                
539     HI_SOFTIRQ=0,                                                                
540     TIMER_SOFTIRQ,                                                               
541     NET_TX_SOFTIRQ,                                                              
542     NET_RX_SOFTIRQ,                                                              
543     BLOCK_SOFTIRQ,                                                               
544     IRQ_POLL_SOFTIRQ,                                                            
545     TASKLET_SOFTIRQ,                                                             
546     SCHED_SOFTIRQ,                                                               
547     HRTIMER_SOFTIRQ,                                                             
548     RCU_SOFTIRQ,    /* Preferable RCU should always be the last softirq */       
549                                                                                  
550     NR_SOFTIRQS                                                                  
551 };
  • __do_softirq运行过程
1.首先调用local_softirq_pending函数取得目前有哪些位存在软件中断2.调用local_bh_disable关闭软中断,其实就是设置正在处理软件中断标记,在同一个CPU上使得不能重入do_softirq函数3.重新设置软中断标记为0,set_softirq_pending重新设置软中断标记为0,这样在之后重新开启中断之后硬件中断中又可以设置软件中断位。3.开启硬件中断4.之后在一个循环中,遍历pending标志的每一位,如果这一位设置就会调用软件中断的处理函数。在这个过程中硬件中断是开启的,随时可以打断软件中断。这样保证硬件中断不会丢失。5.之后关闭硬件中断,查看是否又有软件中断处于pending状态,5.1如果是且restart没有超过10次,并且在本次调用__do_softirq函数过程中没有累计重复进入软件中断处理的次数超过10次,就可以重新调用软件中断处理。5.2如果没有,或超过10,就调用wakeup_softirqd();唤醒内核的一个进程来处理软件中断。// 设立10次的限制,也是为了避免影响系统响应时间。

在这里插入图片描述

这篇关于OK6410A 开发板 (八) 29 linux-5.11 OK6410A 主要内核线程解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1007909

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

linux-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

便携式气象仪器的主要特点

TH-BQX9】便携式气象仪器,也称为便携式气象仪或便携式自动气象站,是一款高度集成、低功耗、可快速安装、便于野外监测使用的高精度自动气象观测设备。以下是关于便携式气象仪器的详细介绍:   主要特点   高精度与多功能:便携式气象仪器能够采集多种气象参数,包括但不限于风速、风向、温度、湿度、气压等,部分高级型号还能监测雨量和辐射等。数据采集与存储:配备微电脑气象数据采集仪,具有实时时钟、数据存

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta