79 关于 kthreadd 进程

前言

这个 主要是 最开始的时候了解驱动的时候, 看到的一系列的 case, 这里 来大致剖析一下 相关的道理

这些模块 是怎么和内核交互的, 内核的这些业务是怎么实现的 

这里主要是一个模块创建了一个 kthread 的线程, 然后 执行目标函数

然后这里主要是设计了 模块来调用 linux 的相关系统函数, 以及 kthread 的相关知识  

 

 

测试用例

测试模块如下, 模块主要是来自于 某git仓库, 这里未记录信息, 感谢原作者 

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/rwlock.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/delay.h>

struct task_struct *my_task;
static int k_thread_cycle_count = 0;
static int mykthread(void *unused)
{
        
        for (;;) {
                pr_info("mykthread is living!, count: %d\n", k_thread_cycle_count);
                ssleep(3);
                k_thread_cycle_count++;
//                if(k_thread_cycle_count > 5)
//                        kthread_stop(my_task);
        }
        return 0;
}


static int __init k_thread_init(void)
{

        my_task = kthread_run(mykthread, NULL,
                              "mykthread");
   if (my_task == ERR_PTR(-ENOMEM)) {
      printk(KERN_INFO " mykthread creation failed\n");
      my_task = NULL;
      return -ENOMEM;
   }

        return 0;
}

module_init(k_thread_init);

static void __exit k_thread_exit(void)
{
        kthread_stop(my_task);
        printk(KERN_INFO "k_thread exit\n ");
}


module_exit(k_thread_exit);

MODULE_AUTHOR("e665106");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("A simple k-thread Module");
MODULE_ALIAS("a simplest module"); 

 

 

kthreadd, kworker 的初始化 

kthreadd 的进程如下 

(initramfs) ps -l | grep kthread
S     0     2     0     0     0 0:0   16:55 00:00:00 [kthreadd]
S     0   250   246  4676   680 0:0   16:57 00:00:00 {exe} grep kthread

 

kthreadd 的初始化如下, 设置了 执行程序名称

然后就是处理 kthreadd 的相关业务 

 

kthreadd 的主要工作主要是创建相关 kernel_thread

比如我们下面的 kworker 就属于 kthread, 这里我们可以看见的是 这里是在创建一个 kworker 它的执行函数是 worker_thread, 它的进程号是 3

 

kworker 列表如下 

(initramfs) ps -l | grep work
# cpu_worker_pools[HIPRI_NICE] 
S     0     4     2     0     0 0:0   14:35 00:00:00 [kworker/0:0H]
S     0   138     2     0     0 0:0   14:36 00:00:00 [kworker/0:1H]

# cpu_worker_pools[STD_NICE] 
S     0   289     2     0     0 0:0   14:45 00:00:00 [kworker/0:0]
S     0    29     2     0     0 0:0   14:35 00:00:00 [kworker/0:1]
S     0   295     2     0     0 0:0   15:08 00:00:00 [kworker/0:2]

# unbound_pools[NUMA_NO_NODE]
S     0     5     2     0     0 0:0   14:35 00:00:00 [kworker/u2:0]
S     0    66     2     0     0 0:0   14:36 00:00:00 [kworker/u2:2]

 

kthread 的初始化主要是在这里

假设我这里 只有一个 cpu 

这里 for_each_cpu_worker_pool 中循环了两个 pool, 一个是标准优先级的, 一个是高优先级的, 指定 0号 cpu 执行

hash_for_each 主要是初始化其他的 pool, 这里默认会创建一个 pool 在任意 cpu 执行 

 

对应的进程的名称规则如下

前两个 pool 是指定 cpu#0, 因此名称是 ”0:0H” 或者 ”0:0”

后面一个 pool 是任意 cpu 执行, pool 的 id 为 2, 因此名称是 “u2:0”

 

 

my_kthread 进程的创建

 thread_run 宏定义如下, 调用了 kthread_create 来创建进程 

 

这里将需要创建的信息放入 thread_create_list, 具体的创建进程是交给 kthreadd 

这里会 唤醒 kthreadd 干活, 然后 等待 进程创建成功

然后 开始调度 新建的 my_kthread 进程 

 

然后 这里是 my_kthread 中输出 “mykthread is living!, count” 的相关信息 

可以看到 上层函数基本上是在 传入的 threadfin 的函数片段中 

然后 执行完成之后, my_kthread 对应的进程就完成任务了 

 

 查看创建的 my_kthread

(initramfs) ps -l | grep kthread
[   89.312961] mykthread is living!, count: 5
S     0     2     0     0     0 0:0   17:51 00:00:00 [kthreadd]
D     0   261     2     0     0 0:0   17:53 00:00:00 [mykthread]
R     0   263   247  4676   700 0:0   17:53 00:00:00 {exe} grep kthread
(initramfs) [   92.384636] mykthread is living!, count: 6

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值