/* * linux/kernel/workqueue.c * * Generic mechanism for defining kernel helper threads for running * arbitrary tasks in process context. * * Started by Ingo Molnar, Copyright (C) 2002 * * Derived from the taskqueue/keventd code by: * * David Woodhouse <dwmw2@infradead.org> * Andrew Morton * Kai Petzke <wpp@marie.physik.tu-berlin.de> * Theodore Ts'o <tytso@mit.edu> * * Made to use alloc_percpu by Christoph Lameter. */ #include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/init.h>#include <linux/signal.h>#include <linux/completion.h>#include <linux/workqueue.h>#include <linux/slab.h>#include <linux/cpu.h>#include <linux/notifier.h>#include <linux/kthread.h>#include <linux/hardirq.h>#include <linux/mempolicy.h>#include <linux/freezer.h>#include <linux/kallsyms.h>#include <linux/debug_locks.h>#include <linux/lockdep.h>#include <linux/idr.h> /* * Structure fields follow one of the following exclusion rules. * * I: Set during initialization and read-only afterwards. * * L: cwq->lock protected. Access with cwq->lock held. * * F: wq->flush_mutex protected. * * W: workqueue_lock protected. */ struct cpu_workqueue_struct; struct worker { struct work_struct *current_work; /* L: work being processed */ struct list_head scheduled; /* L: scheduled works */ struct task_struct *task; /* I: worker task */ struct cpu_workqueue_struct *cwq; /* I: the associated cwq */ int id; /* I: worker id */}; /* * The per-CPU workqueue (if single thread, we always use the first * possible cpu). The lower WORK_STRUCT_FLAG_BITS of * work_struct->data are used for flags and thus cwqs need to be * aligned at two's power of the number of flag bits. */struct cpu_workqueue_struct { spinlock_t lock; struct list_head worklist; wait_queue_head_t more_work; unsigned int cpu; struct worker *worker; struct workqueue_struct *wq; /* I: the owning workqueue */ int work_color; /* L: current color */ int flush_color; /* L: flushing color */ int nr_in_flight[WORK_NR_COLORS]; /* L: nr of in_flight works */}; /* * Structure used to wait for workqueue flush. */struct wq_flusher { struct list_head list; /* F: list of flushers */ int flush_color; /* F: flush color waiting for */ struct completion done; /* flush completion */}; /* * The externally visible workqueue abstraction is an array of * per-CPU workqueues: */struct workqueue_struct { unsigned int flags; /* I: WQ_* flags */ struct cpu_workqueue_struct *cpu_wq; /* I: cwq's */ struct list_head list; /* W: list of all workqueues */ struct mutex flush_mutex; /* protects wq flushing */ int work_color; /* F: current work color */ int flush_color; /* F: current flush color */ atomic_t nr_cwqs_to_flush; /* flush in progress */ struct wq_flusher *first_flusher; /* F: first flusher */ struct list_head flusher_queue; /* F: flush waiters */ struct list_head flusher_overflow; /* F: flush overflow list */ const char *name; /* I: workqueue name */#ifdef CONFIG_LOCKDEP struct lockdep_map lockdep_map;#endif}; #ifdef CONFIG_DEBUG_OBJECTS_WORK static struct debug_obj_descr work_debug_descr; /* * fixup_init is called when: * - an active object is initialized */static int work_fixup_init(void *addr, enum debug_obj_state state){ struct work_struct *work = addr; switch (state) { case ODEBUG_STATE_ACTIVE: cancel_work_sync(work); debug_object_init(work, &work_debug_descr); return 1; default: return 0; }} /* * fixup_activate is called when: * - an active object is activated * - an unknown object is activated (might be a statically initialized object) */static int work_fixup_activate(void *addr, enum debug_obj_state state){ struct work_struct *work = addr; switch (state) { case ODEBUG_STATE_NOTAVAILABLE: /* * This is not really a fixup. The work struct was * statically initialized. We just make sure that it * is tracked in the object tracker. */ if (test_bit(WORK_STRUCT_STATIC_BIT, work_data_bits(work))) { debug_object_init(work, &work_debug_descr); debug_object_activate(work, &work_debug_descr); return 0; } WARN_ON_ONCE(1); return 0; case ODEBUG_STATE_ACTIVE: WARN_ON(1); default: return 0; }} /* * fixup_free is called when: * - an active object is freed */static int work_fixup_free(void *addr, enum debug_obj_state state){ struct work_struct *work = addr; switch (state) { case ODEBUG_STATE_ACTIVE: cancel_work_sync(work); debug_object_free(work, &work_debug_descr); return 1; default: return 0; }} static struct debug_obj_descr work_debug_descr = { .name = "work_struct", .fixup_init = work_fixup_init, .fixup_activate = work_fixup_activate, .fixup_free = work_fixup_free,}; static inline void debug_work_activate(struct work_struct *work){ debug_object_activate(work, &work_debug_descr);} static inline void debug_work_deactivate(struct work_struct *work){ debug_object_deactivate(work, &work_debug_descr);} void __init_work(struct work_struct *work, int onstack){ if (onstack) debug_object_init_on_stack(work, &work_debug_descr); else debug_object_init(work, &work_debug_descr);}EXPORT_SYMBOL_GPL(__init_work); void destroy_work_on_stack(struct work_struct *work){ debug_object_free(work, &work_debug_descr);}EXPORT_SYMBOL_GPL(destroy_work_on_stack); #elsestatic inline void debug_work_activate(struct work_struct *work) { }static inline void debug_work_deactivate(struct work_struct *work) { }#endif /* Serializes the accesses to the list of workqueues. */static DEFINE_SPINLOCK(workqueue_lock);static LIST_HEAD(workqueues);static DEFINE_PER_CPU(struct ida, worker_ida); static int worker_thread(void *__worker); static int singlethread_cpu __read_mostly; static struct cpu_workqueue_struct *get_cwq(unsigned int cpu, struct workqueue_struct *wq){ return per_cpu_ptr(wq->cpu_wq, cpu);} static struct cpu_workqueue_struct *target_cwq(unsigned int cpu, struct workqueue_struct *wq){ if (unlikely(wq->flags & WQ_SINGLE_THREAD)) cpu = singlethread_cpu; return get_cwq(cpu, wq);} static unsigned int work_color_to_flags(int color){ return color << WORK_STRUCT_COLOR_SHIFT;} static int get_work_color(struct work_struct *work){ return (*work_data_bits(work) >> WORK_STRUCT_COLOR_SHIFT) & ((1 << WORK_STRUCT_COLOR_BITS) - 1);} static int work_next_color(int color){ return (color + 1) % WORK_NR_COLORS;} /* * Set the workqueue on which a work item is to be run * - Must *only* be called if the pending flag is set */static inline void set_wq_data(struct work_struct *work, struct cpu_workqueue_struct *cwq, unsigned long extra_flags){ BUG_ON(!work_pending(work)); atomic_long_set(&work->data, (unsigned long)cwq | work_static(work) | WORK_STRUCT_PENDING | extra_flags);} /* * Clear WORK_STRUCT_PENDING and the workqueue on which it was queued. */static inline void clear_wq_data(struct work_struct *work){ atomic_long_set(&work->data, work_static(work));} static inline struct cpu_workqueue_struct *get_wq_data(struct work_struct *work){ return (void *)(atomic_long_read(&work->data) & WORK_STRUCT_WQ_DATA_MASK);} /** * insert_work - insert a work into cwq * @cwq: cwq @work belongs to * @work: work to insert * @head: insertion point * @extra_flags: extra WORK_STRUCT_* flags to set * * Insert @work into @cwq after @head. * * CONTEXT: * spin_lock_irq(cwq->lock). */static void insert_work(struct cpu_workqueue_struct *cwq, struct work_struct *work, struct list_head *head, unsigned int extra_flags){ /* we own @work, set data and link */ set_wq_data(work, cwq, extra_flags); /* * Ensure that we get the right work->data if we see the * result of list_add() below, see try_to_grab_pending(). */ smp_wmb(); list_add_tail(&work->entry, head); wake_up(&cwq->more_work);} static void __queue_work(unsigned int cpu, struct workqueue_struct *wq, struct work_struct *work){ struct cpu_workqueue_struct *cwq = target_cwq(cpu, wq); unsigned long flags; debug_work_activate(work); spin_lock_irqsave(&cwq->lock, flags); BUG_ON(!list_empty(&work->entry)); cwq->nr_in_flight[cwq->work_color]++; insert_work(cwq, work, &cwq->worklist, work_color_to_flags(cwq->work_color)); spin_unlock_irqrestore(&cwq->lock, flags);} /** * queue_work - queue work on a workqueue * @wq: workqueue to use * @work: work to queue * * Returns 0 if @work was already on a queue, non-zero otherwise. * * We queue the work to the CPU on which it was submitted, but if the CPU dies * it can be processed by another CPU. */int queue_work(struct workqueue_struct *wq, struct work_struct *work){ int ret; ret = queue_work_on(get_cpu(), wq, work); put_cpu(); return ret;}EXPORT_SYMBOL_GPL(queue_work); /** * queue_work_on - queue work on specific cpu * @cpu: CPU number to execute work on * @wq: workqueue to use * @work: work to queue * * Returns 0 if @work was already on a queue, non-zero otherwise. * * We queue the work to a specific CPU, the caller must ensure it * can't go away. */intqueue_work_on(int cpu, struct workqueue_struct *wq, struct work_struct *work){ int ret = 0; if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) { __queue_work(cpu, wq, work); ret = 1; } return ret;}EXPORT_SYMBOL_GPL(queue_work_on); static void delayed_work_timer_fn(unsigned long __data){ struct delayed_work *dwork = (struct delayed_work *)__data; struct cpu_workqueue_struct *cwq = get_wq_data(&dwork->work); __queue_work(smp_processor_id(), cwq->wq, &dwork->work);} /** * queue_delayed_work - queue work on a workqueue after delay * @wq: workqueue to use * @dwork: delayable work to queue * @delay: number of jiffies to wait before queueing * * Returns 0 if @work was already on a queue, non-zero otherwise. */int queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay){ if (delay == 0) return queue_work(wq, &dwork->work); return queue_delayed_work_on(-1, wq, dwork, delay);}EXPORT_SYMBOL_GPL(queue_delayed_work); /** * queue_delayed_work_on - queue work on specific CPU after delay * @cpu: CPU number to execute work on * @wq: workqueue to use * @dwork: work to queue * @delay: number of jiffies to wait before queueing * * Returns 0 if @work was already on a queue, non-zero otherwise. */int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay){ int ret = 0; struct timer_list *timer = &dwork->timer; struct work_struct *work = &dwork->work; if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) { BUG_ON(timer_pending(timer)); BUG_ON(!list_empty(&work->entry)); timer_stats_timer_set_start_info(&dwork->timer); /* This stores cwq for the moment, for the timer_fn */ set_wq_data(work, target_cwq(raw_smp_processor_id(), wq), 0); timer->expires = jiffies + delay; timer->data = (unsigned long)dwork; timer->function = delayed_work_timer_fn; if (unlikely(cpu >= 0)) add_timer_on(timer, cpu); else add_timer(timer); ret = 1; } return ret;}EXPORT_SYMBOL_GPL(queue_delayed_work_on); static struct worker *alloc_worker(void){ struct worker *worker; worker = kzalloc(sizeof(*worker), GFP_KERNEL); if (worker) INIT_LIST_HEAD(&worker->scheduled); return worker;} /** * create_worker - create a new workqueue worker * @cwq: cwq the new worker will belong to * @bind: whether to set affinity to @cpu or not * * Create a new worker which is bound to @cwq. The returned worker * can be started by calling start_worker() or destroyed using * destroy_worker(). * * CONTEXT: * Might sleep. Does GFP_KERNEL allocations. * * RETURNS: * Pointer to the newly created worker. */static struct worker *create_worker(struct cpu_workqueue_struct *cwq, bool bind){ int id = -1; struct worker *worker = NULL; spin_lock(&workqueue_lock); while (ida_get_new(&per_cpu(worker_ida, cwq->cpu), &id)) { spin_unlock(&workqueue_lock); if (!ida_pre_get(&per_cpu(worker_ida, cwq->cpu), GFP_KERNEL)) goto fail; spin_lock(&workqueue_lock); } spin_unlock(&workqueue_lock); worker = alloc_worker(); if (!worker) goto fail; worker->cwq = cwq; worker->id = id; worker->task = kthread_create(worker_thread, worker, "kworker/%u:%d", cwq->cpu, id); if (IS_ERR(worker->task)) goto fail; if (bind) kthread_bind(worker->task, cwq->cpu); return worker;fail: if (id >= 0) {Lines 1–500 of 1701. Load more
/* * linux/kernel/workqueue.c * * Generic mechanism for defining kernel helper threads for running * arbitrary tasks in process context. * * Started by Ingo Molnar, Copyright (C) 2002 * * Derived from the taskqueue/keventd code by: * * David Woodhouse <dwmw2@infradead.org> * Andrew Morton * Kai Petzke <wpp@marie.physik.tu-berlin.de> * Theodore Ts'o <tytso@mit.edu> * * Made to use alloc_percpu by Christoph Lameter. */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/init.h> #include <linux/signal.h> #include <linux/completion.h> #include <linux/workqueue.h> #include <linux/slab.h> #include <linux/cpu.h> #include <linux/notifier.h> #include <linux/kthread.h> #include <linux/hardirq.h> #include <linux/mempolicy.h> #include <linux/freezer.h> #include <linux/kallsyms.h> #include <linux/debug_locks.h> #include <linux/lockdep.h> #include <linux/idr.h> /* * Structure fields follow one of the following exclusion rules. * * I: Set during initialization and read-only afterwards. * * L: cwq->lock protected. Access with cwq->lock held. * * F: wq->flush_mutex protected. * * W: workqueue_lock protected. */ struct cpu_workqueue_struct; struct worker { struct work_struct *current_work; /* L: work being processed */ struct list_head scheduled; /* L: scheduled works */ struct task_struct *task; /* I: worker task */ struct cpu_workqueue_struct *cwq; /* I: the associated cwq */ int id; /* I: worker id */ }; /* * The per-CPU workqueue (if single thread, we always use the first * possible cpu). The lower WORK_STRUCT_FLAG_BITS of * work_struct->data are used for flags and thus cwqs need to be * aligned at two's power of the number of flag bits. */ struct cpu_workqueue_struct { spinlock_t lock; struct list_head worklist; wait_queue_head_t more_work; unsigned int cpu; struct worker *worker; struct workqueue_struct *wq; /* I: the owning workqueue */ int work_color; /* L: current color */ int flush_color; /* L: flushing color */ int nr_in_flight[WORK_NR_COLORS]; /* L: nr of in_flight works */ }; /* * Structure used to wait for workqueue flush. */ struct wq_flusher { struct list_head list; /* F: list of flushers */ int flush_color; /* F: flush color waiting for */ struct completion done; /* flush completion */ }; /* * The externally visible workqueue abstraction is an array of * per-CPU workqueues: */ struct workqueue_struct { unsigned int flags; /* I: WQ_* flags */ struct cpu_workqueue_struct *cpu_wq; /* I: cwq's */ struct list_head list; /* W: list of all workqueues */ struct mutex flush_mutex; /* protects wq flushing */ int work_color; /* F: current work color */ int flush_color; /* F: current flush color */ atomic_t nr_cwqs_to_flush; /* flush in progress */ struct wq_flusher *first_flusher; /* F: first flusher */ struct list_head flusher_queue; /* F: flush waiters */ struct list_head flusher_overflow; /* F: flush overflow list */ const char *name; /* I: workqueue name */ #ifdef CONFIG_LOCKDEP struct lockdep_map lockdep_map; #endif }; #ifdef CONFIG_DEBUG_OBJECTS_WORK static struct debug_obj_descr work_debug_descr; /* * fixup_init is called when: * - an active object is initialized */ static int work_fixup_init(void *addr, enum debug_obj_state state) { struct work_struct *work = addr; switch (state) { case ODEBUG_STATE_ACTIVE: cancel_work_sync(work); debug_object_init(work, &work_debug_descr); return 1; default: return 0; } } /* * fixup_activate is called when: * - an active object is activated * - an unknown object is activated (might be a statically initialized object) */ static int work_fixup_activate(void *addr, enum debug_obj_state state) { struct work_struct *work = addr; switch (state) { case ODEBUG_STATE_NOTAVAILABLE: /* * This is not really a fixup. The work struct was * statically initialized. We just make sure that it * is tracked in the object tracker. */ if (test_bit(WORK_STRUCT_STATIC_BIT, work_data_bits(work))) { debug_object_init(work, &work_debug_descr); debug_object_activate(work, &work_debug_descr); return 0; } WARN_ON_ONCE(1); return 0; case ODEBUG_STATE_ACTIVE: WARN_ON(1); default: return 0; } } /* * fixup_free is called when: * - an active object is freed */ static int work_fixup_free(void *addr, enum debug_obj_state state) { struct work_struct *work = addr; switch (state) { case ODEBUG_STATE_ACTIVE: cancel_work_sync(work); debug_object_free(work, &work_debug_descr); return 1; default: return 0; } } static struct debug_obj_descr work_debug_descr = { .name = "work_struct", .fixup_init = work_fixup_init, .fixup_activate = work_fixup_activate, .fixup_free = work_fixup_free, }; static inline void debug_work_activate(struct work_struct *work) { debug_object_activate(work, &work_debug_descr); } static inline void debug_work_deactivate(struct work_struct *work) { debug_object_deactivate(work, &work_debug_descr); } void __init_work(struct work_struct *work, int onstack) { if (onstack) debug_object_init_on_stack(work, &work_debug_descr); else debug_object_init(work, &work_debug_descr); } EXPORT_SYMBOL_GPL(__init_work); void destroy_work_on_stack(struct work_struct *work) { debug_object_free(work, &work_debug_descr); } EXPORT_SYMBOL_GPL(destroy_work_on_stack); #else static inline void debug_work_activate(struct work_struct *work) { } static inline void debug_work_deactivate(struct work_struct *work) { } #endif /* Serializes the accesses to the list of workqueues. */ static DEFINE_SPINLOCK(workqueue_lock); static LIST_HEAD(workqueues); static DEFINE_PER_CPU(struct ida, worker_ida); static int worker_thread(void *__worker); static int singlethread_cpu __read_mostly; static struct cpu_workqueue_struct *get_cwq(unsigned int cpu, struct workqueue_struct *wq) { return per_cpu_ptr(wq->cpu_wq, cpu); } static struct cpu_workqueue_struct *target_cwq(unsigned int cpu, struct workqueue_struct *wq) { if (unlikely(wq->flags & WQ_SINGLE_THREAD)) cpu = singlethread_cpu; return get_cwq(cpu, wq); } static unsigned int work_color_to_flags(int color) { return color << WORK_STRUCT_COLOR_SHIFT; } static int get_work_color(struct work_struct *work) { return (*work_data_bits(work) >> WORK_STRUCT_COLOR_SHIFT) & ((1 << WORK_STRUCT_COLOR_BITS) - 1); } static int work_next_color(int color) { return (color + 1) % WORK_NR_COLORS; } /* * Set the workqueue on which a work item is to be run * - Must *only* be called if the pending flag is set */ static inline void set_wq_data(struct work_struct *work, struct cpu_workqueue_struct *cwq, unsigned long extra_flags) { BUG_ON(!work_pending(work)); atomic_long_set(&work->data, (unsigned long)cwq | work_static(work) | WORK_STRUCT_PENDING | extra_flags); } /* * Clear WORK_STRUCT_PENDING and the workqueue on which it was queued. */ static inline void clear_wq_data(struct work_struct *work) { atomic_long_set(&work->data, work_static(work)); } static inline struct cpu_workqueue_struct *get_wq_data(struct work_struct *work) { return (void *)(atomic_long_read(&work->data) & WORK_STRUCT_WQ_DATA_MASK); } /** * insert_work - insert a work into cwq * @cwq: cwq @work belongs to * @work: work to insert * @head: insertion point * @extra_flags: extra WORK_STRUCT_* flags to set * * Insert @work into @cwq after @head. * * CONTEXT: * spin_lock_irq(cwq->lock). */ static void insert_work(struct cpu_workqueue_struct *cwq, struct work_struct *work, struct list_head *head, unsigned int extra_flags) { /* we own @work, set data and link */ set_wq_data(work, cwq, extra_flags); /* * Ensure that we get the right work->data if we see the * result of list_add() below, see try_to_grab_pending(). */ smp_wmb(); list_add_tail(&work->entry, head); wake_up(&cwq->more_work); } static void __queue_work(unsigned int cpu, struct workqueue_struct *wq, struct work_struct *work) { struct cpu_workqueue_struct *cwq = target_cwq(cpu, wq); unsigned long flags; debug_work_activate(work); spin_lock_irqsave(&cwq->lock, flags); BUG_ON(!list_empty(&work->entry)); cwq->nr_in_flight[cwq->work_color]++; insert_work(cwq, work, &cwq->worklist, work_color_to_flags(cwq->work_color)); spin_unlock_irqrestore(&cwq->lock, flags); } /** * queue_work - queue work on a workqueue * @wq: workqueue to use * @work: work to queue * * Returns 0 if @work was already on a queue, non-zero otherwise. * * We queue the work to the CPU on which it was submitted, but if the CPU dies * it can be processed by another CPU. */ int queue_work(struct workqueue_struct *wq, struct work_struct *work) { int ret; ret = queue_work_on(get_cpu(), wq, work); put_cpu(); return ret; } EXPORT_SYMBOL_GPL(queue_work); /** * queue_work_on - queue work on specific cpu * @cpu: CPU number to execute work on * @wq: workqueue to use * @work: work to queue * * Returns 0 if @work was already on a queue, non-zero otherwise. * * We queue the work to a specific CPU, the caller must ensure it * can't go away. */ int queue_work_on(int cpu, struct workqueue_struct *wq, struct work_struct *work) { int ret = 0; if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) { __queue_work(cpu, wq, work); ret = 1; } return ret; } EXPORT_SYMBOL_GPL(queue_work_on); static void delayed_work_timer_fn(unsigned long __data) { struct delayed_work *dwork = (struct delayed_work *)__data; struct cpu_workqueue_struct *cwq = get_wq_data(&dwork->work); __queue_work(smp_processor_id(), cwq->wq, &dwork->work); } /** * queue_delayed_work - queue work on a workqueue after delay * @wq: workqueue to use * @dwork: delayable work to queue * @delay: number of jiffies to wait before queueing * * Returns 0 if @work was already on a queue, non-zero otherwise. */ int queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay) { if (delay == 0) return queue_work(wq, &dwork->work); return queue_delayed_work_on(-1, wq, dwork, delay); } EXPORT_SYMBOL_GPL(queue_delayed_work); /** * queue_delayed_work_on - queue work on specific CPU after delay * @cpu: CPU number to execute work on * @wq: workqueue to use * @dwork: work to queue * @delay: number of jiffies to wait before queueing * * Returns 0 if @work was already on a queue, non-zero otherwise. */ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay) { int ret = 0; struct timer_list *timer = &dwork->timer; struct work_struct *work = &dwork->work; if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) { BUG_ON(timer_pending(timer)); BUG_ON(!list_empty(&work->entry)); timer_stats_timer_set_start_info(&dwork->timer); /* This stores cwq for the moment, for the timer_fn */ set_wq_data(work, target_cwq(raw_smp_processor_id(), wq), 0); timer->expires = jiffies + delay; timer->data = (unsigned long)dwork; timer->function = delayed_work_timer_fn; if (unlikely(cpu >= 0)) add_timer_on(timer, cpu); else add_timer(timer); ret = 1; } return ret; } EXPORT_SYMBOL_GPL(queue_delayed_work_on); static struct worker *alloc_worker(void) { struct worker *worker; worker = kzalloc(sizeof(*worker), GFP_KERNEL); if (worker) INIT_LIST_HEAD(&worker->scheduled); return worker; } /** * create_worker - create a new workqueue worker * @cwq: cwq the new worker will belong to * @bind: whether to set affinity to @cpu or not * * Create a new worker which is bound to @cwq. The returned worker * can be started by calling start_worker() or destroyed using * destroy_worker(). * * CONTEXT: * Might sleep. Does GFP_KERNEL allocations. * * RETURNS: * Pointer to the newly created worker. */ static struct worker *create_worker(struct cpu_workqueue_struct *cwq, bool bind) { int id = -1; struct worker *worker = NULL; spin_lock(&workqueue_lock); while (ida_get_new(&per_cpu(worker_ida, cwq->cpu), &id)) { spin_unlock(&workqueue_lock); if (!ida_pre_get(&per_cpu(worker_ida, cwq->cpu), GFP_KERNEL)) goto fail; spin_lock(&workqueue_lock); } spin_unlock(&workqueue_lock); worker = alloc_worker(); if (!worker) goto fail; worker->cwq = cwq; worker->id = id; worker->task = kthread_create(worker_thread, worker, "kworker/%u:%d", cwq->cpu, id); if (IS_ERR(worker->task)) goto fail; if (bind) kthread_bind(worker->task, cwq->cpu); return worker; fail: if (id >= 0) {