1、worker線程的建立node
1. 建立流程spa
//調用這個接口建立內核工做線程,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 循環監聽是否有工做須要處理: code
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; }
2、worker的使用blog
未完待續。。。。。接口