一、worker线程的创建
1. 创建流程
//调用这个接口创建内核工作线程,eg: crypto_engine.c中的创建方法: kthread_create_worker(0, "%s", engine->name); //在CPU0上创建一个work线程 kthread_create_worker(unsigned int flags, const char namefmt[], ...) //或kthread_create_worker_on_cpu(int cpu, unsigned int flags, const char namefmt[], ...) __kthread_create_worker(int cpu, unsigned int flags, const char namefmt[], va_list args) __kthread_create_on_node(kthread_worker_fn, worker, node, namefmt, args)
__kthread_create_worker():
/* 若是参数cpu大于等于0就创建特定于某个CPU的工作线程,若是不想创建特定于CPU的工作线程,就将CPU域赋值为-1 */ static struct kthread_worker * __kthread_create_worker(int cpu, unsigned int flags, const char namefmt[], va_list args) { struct kthread_worker *worker; struct task_struct *task; int node = -1; worker = kzalloc(sizeof(*worker), GFP_KERNEL); if (!worker) return ERR_PTR(-ENOMEM); kthread_init_worker(worker); if (cpu >= 0) node = cpu_to_node(cpu); task = __kthread_create_on_node(kthread_worker_fn, worker, node, namefmt, args); if (IS_ERR(task)) goto fail_task; if (cpu >= 0) kthread_bind(task, cpu); worker->flags = flags; worker->task = task; wake_up_process(task); return worker; fail_task: kfree(worker); return ERR_CAST(task); }
kthread_worker_fn 循环监听是否有工作需要处理:
int kthread_worker_fn(void *worker_ptr) { struct kthread_worker *worker = worker_ptr; struct kthread_work *work; /* * FIXME: Update the check and remove the assignment when all kthread * worker users are created using kthread_create_worker*() functions. */ WARN_ON(worker->task && worker->task != current); worker->task = current; if (worker->flags & KTW_FREEZABLE) set_freezable(); repeat: /* 设置进程的状态,不被调度 */ set_current_state(TASK_INTERRUPTIBLE); /* mb paired w/ kthread_stop */ if (kthread_should_stop()) { __set_current_state(TASK_RUNNING); spin_lock_irq(&worker->lock); worker->task = NULL; spin_unlock_irq(&worker->lock); return 0; } work = NULL; spin_lock_irq(&worker->lock); if (!list_empty(&worker->work_list)) { /* 从work_list中取出一个工作 */ work = list_first_entry(&worker->work_list, struct kthread_work, node); list_del_init(&work->node); } worker->current_work = work; spin_unlock_irq(&worker->lock); if (work) { __set_current_state(TASK_RUNNING); /* 执行这个工作上func() */ work->func(work); } else if (!freezing(current)) schedule(); try_to_freeze(); cond_resched(); /* 又跳到repeat位置,进行循环执行 */ goto repeat; }
二、worker的使用
未完待续。。。。。