X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=kernel%2Fworkqueue.c;h=3bebf73be976592cab56a218e93b7449a5de7df4;hb=dd7f2928d834f7ac67202bcdf24a44ba9b138f08;hp=0611de815a8f921a4d2215f52959de832acb5c9d;hpb=23b2e5991afde5af91a1a661d7f47ee56120759e;p=linux-2.6-omap-h63xx.git diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 0611de815a8..3bebf73be97 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -47,7 +47,6 @@ struct cpu_workqueue_struct { struct workqueue_struct *wq; struct task_struct *thread; - int should_stop; int run_depth; /* Detect run_workqueue() recursion depth */ } ____cacheline_aligned; @@ -71,7 +70,13 @@ static LIST_HEAD(workqueues); static int singlethread_cpu __read_mostly; static cpumask_t cpu_singlethread_map __read_mostly; -/* optimization, we could use cpu_possible_map */ +/* + * _cpu_down() first removes CPU from cpu_online_map, then CPU_DEAD + * flushes cwq->worklist. This means that flush_workqueue/wait_on_work + * which comes in between can't use for_each_online_cpu(). We could + * use cpu_possible_map, the cpumask below is more a documentation + * than optimization. + */ static cpumask_t cpu_populated_map __read_mostly; /* If it's single threaded, it isn't in the list of workqueues. */ @@ -120,6 +125,11 @@ static void insert_work(struct cpu_workqueue_struct *cwq, struct work_struct *work, int tail) { set_wq_data(work, cwq); + /* + * Ensure that we get the right work->data if we see the + * result of list_add() below, see try_to_grab_pending(). + */ + smp_wmb(); if (tail) list_add_tail(&work->entry, &cwq->worklist); else @@ -267,63 +277,27 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq) spin_unlock_irq(&cwq->lock); } -/* - * NOTE: the caller must not touch *cwq if this func returns true - */ -static int cwq_should_stop(struct cpu_workqueue_struct *cwq) -{ - int should_stop = cwq->should_stop; - - if (unlikely(should_stop)) { - spin_lock_irq(&cwq->lock); - should_stop = cwq->should_stop && list_empty(&cwq->worklist); - if (should_stop) - cwq->thread = NULL; - spin_unlock_irq(&cwq->lock); - } - - return should_stop; -} - static int worker_thread(void *__cwq) { struct cpu_workqueue_struct *cwq = __cwq; DEFINE_WAIT(wait); - struct k_sigaction sa; - sigset_t blocked; if (!cwq->wq->freezeable) current->flags |= PF_NOFREEZE; set_user_nice(current, -5); - /* Block and flush all signals */ - sigfillset(&blocked); - sigprocmask(SIG_BLOCK, &blocked, NULL); - flush_signals(current); - - /* - * We inherited MPOL_INTERLEAVE from the booting kernel. - * Set MPOL_DEFAULT to insure node local allocations. - */ - numa_default_policy(); - - /* SIG_IGN makes children autoreap: see do_notify_parent(). */ - sa.sa.sa_handler = SIG_IGN; - sa.sa.sa_flags = 0; - siginitset(&sa.sa.sa_mask, sigmask(SIGCHLD)); - do_sigaction(SIGCHLD, &sa, (struct k_sigaction *)0); - for (;;) { - if (cwq->wq->freezeable) - try_to_freeze(); - prepare_to_wait(&cwq->more_work, &wait, TASK_INTERRUPTIBLE); - if (!cwq->should_stop && list_empty(&cwq->worklist)) + if (!freezing(current) && + !kthread_should_stop() && + list_empty(&cwq->worklist)) schedule(); finish_wait(&cwq->more_work, &wait); - if (cwq_should_stop(cwq)) + try_to_freeze(); + + if (kthread_should_stop()) break; run_workqueue(cwq); @@ -354,18 +328,21 @@ static void insert_wq_barrier(struct cpu_workqueue_struct *cwq, insert_work(cwq, &barr->work, tail); } -static void flush_cpu_workqueue(struct cpu_workqueue_struct *cwq) +static int flush_cpu_workqueue(struct cpu_workqueue_struct *cwq) { + int active; + if (cwq->thread == current) { /* * Probably keventd trying to flush its own queue. So simply run * it by hand rather than deadlocking. */ run_workqueue(cwq); + active = 1; } else { struct wq_barrier barr; - int active = 0; + active = 0; spin_lock_irq(&cwq->lock); if (!list_empty(&cwq->worklist) || cwq->current_work != NULL) { insert_wq_barrier(cwq, &barr, 1); @@ -376,6 +353,8 @@ static void flush_cpu_workqueue(struct cpu_workqueue_struct *cwq) if (active) wait_for_completion(&barr.done); } + + return active; } /** @@ -402,7 +381,46 @@ void fastcall flush_workqueue(struct workqueue_struct *wq) } EXPORT_SYMBOL_GPL(flush_workqueue); -static void wait_on_work(struct cpu_workqueue_struct *cwq, +/* + * Upon a successful return, the caller "owns" WORK_STRUCT_PENDING bit, + * so this work can't be re-armed in any way. + */ +static int try_to_grab_pending(struct work_struct *work) +{ + struct cpu_workqueue_struct *cwq; + int ret = 0; + + if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) + return 1; + + /* + * The queueing is in progress, or it is already queued. Try to + * steal it from ->worklist without clearing WORK_STRUCT_PENDING. + */ + + cwq = get_wq_data(work); + if (!cwq) + return ret; + + spin_lock_irq(&cwq->lock); + if (!list_empty(&work->entry)) { + /* + * This work is queued, but perhaps we locked the wrong cwq. + * In that case we must see the new value after rmb(), see + * insert_work()->wmb(). + */ + smp_rmb(); + if (cwq == get_wq_data(work)) { + list_del_init(&work->entry); + ret = 1; + } + } + spin_unlock_irq(&cwq->lock); + + return ret; +} + +static void wait_on_cpu_work(struct cpu_workqueue_struct *cwq, struct work_struct *work) { struct wq_barrier barr; @@ -419,49 +437,72 @@ static void wait_on_work(struct cpu_workqueue_struct *cwq, wait_for_completion(&barr.done); } -/** - * flush_work - block until a work_struct's callback has terminated - * @wq: the workqueue on which the work is queued - * @work: the work which is to be flushed - * - * flush_work() will attempt to cancel the work if it is queued. If the work's - * callback appears to be running, flush_work() will block until it has - * completed. - * - * flush_work() is designed to be used when the caller is tearing down data - * structures which the callback function operates upon. It is expected that, - * prior to calling flush_work(), the caller has arranged for the work to not - * be requeued. - */ -void flush_work(struct workqueue_struct *wq, struct work_struct *work) +static void wait_on_work(struct work_struct *work) { - const cpumask_t *cpu_map = wq_cpu_map(wq); struct cpu_workqueue_struct *cwq; + struct workqueue_struct *wq; + const cpumask_t *cpu_map; int cpu; might_sleep(); cwq = get_wq_data(work); - /* Was it ever queued ? */ if (!cwq) return; - /* - * This work can't be re-queued, no need to re-check that - * get_wq_data() is still the same when we take cwq->lock. - */ - spin_lock_irq(&cwq->lock); - list_del_init(&work->entry); - work_clear_pending(work); - spin_unlock_irq(&cwq->lock); + wq = cwq->wq; + cpu_map = wq_cpu_map(wq); for_each_cpu_mask(cpu, *cpu_map) - wait_on_work(per_cpu_ptr(wq->cpu_wq, cpu), work); + wait_on_cpu_work(per_cpu_ptr(wq->cpu_wq, cpu), work); +} + +/** + * cancel_work_sync - block until a work_struct's callback has terminated + * @work: the work which is to be flushed + * + * cancel_work_sync() will cancel the work if it is queued. If the work's + * callback appears to be running, cancel_work_sync() will block until it + * has completed. + * + * It is possible to use this function if the work re-queues itself. It can + * cancel the work even if it migrates to another workqueue, however in that + * case it only guarantees that work->func() has completed on the last queued + * workqueue. + * + * cancel_work_sync(&delayed_work->work) should be used only if ->timer is not + * pending, otherwise it goes into a busy-wait loop until the timer expires. + * + * The caller must ensure that workqueue_struct on which this work was last + * queued can't be destroyed before this function returns. + */ +void cancel_work_sync(struct work_struct *work) +{ + while (!try_to_grab_pending(work)) + cpu_relax(); + wait_on_work(work); + work_clear_pending(work); } -EXPORT_SYMBOL_GPL(flush_work); +EXPORT_SYMBOL_GPL(cancel_work_sync); +/** + * cancel_rearming_delayed_work - reliably kill off a delayed work. + * @dwork: the delayed work struct + * + * It is possible to use this function if @dwork rearms itself via queue_work() + * or queue_delayed_work(). See also the comment for cancel_work_sync(). + */ +void cancel_rearming_delayed_work(struct delayed_work *dwork) +{ + while (!del_timer(&dwork->timer) && + !try_to_grab_pending(&dwork->work)) + cpu_relax(); + wait_on_work(&dwork->work); + work_clear_pending(&dwork->work); +} +EXPORT_SYMBOL(cancel_rearming_delayed_work); -static struct workqueue_struct *keventd_wq; +static struct workqueue_struct *keventd_wq __read_mostly; /** * schedule_work - put work task in global workqueue @@ -547,33 +588,6 @@ void flush_scheduled_work(void) } EXPORT_SYMBOL(flush_scheduled_work); -void flush_work_keventd(struct work_struct *work) -{ - flush_work(keventd_wq, work); -} -EXPORT_SYMBOL(flush_work_keventd); - -/** - * cancel_rearming_delayed_work - kill off a delayed work whose handler rearms the delayed work. - * @dwork: the delayed work struct - * - * Note that the work callback function may still be running on return from - * cancel_delayed_work(). Run flush_workqueue() or flush_work() to wait on it. - */ -void cancel_rearming_delayed_work(struct delayed_work *dwork) -{ - struct cpu_workqueue_struct *cwq = get_wq_data(&dwork->work); - - /* Was it ever queued ? */ - if (cwq != NULL) { - struct workqueue_struct *wq = cwq->wq; - - while (!cancel_delayed_work(dwork)) - flush_workqueue(wq); - } -} -EXPORT_SYMBOL(cancel_rearming_delayed_work); - /** * execute_in_process_context - reliably execute the routine with user context * @fn: the function to execute @@ -653,7 +667,6 @@ static int create_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu) return PTR_ERR(p); cwq->thread = p; - cwq->should_stop = 0; return 0; } @@ -719,29 +732,27 @@ EXPORT_SYMBOL_GPL(__create_workqueue); static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu) { - struct wq_barrier barr; - int alive = 0; - - spin_lock_irq(&cwq->lock); - if (cwq->thread != NULL) { - insert_wq_barrier(cwq, &barr, 1); - cwq->should_stop = 1; - alive = 1; - } - spin_unlock_irq(&cwq->lock); + /* + * Our caller is either destroy_workqueue() or CPU_DEAD, + * workqueue_mutex protects cwq->thread + */ + if (cwq->thread == NULL) + return; - if (alive) { - wait_for_completion(&barr.done); + /* + * If the caller is CPU_DEAD the single flush_cpu_workqueue() + * is not enough, a concurrent flush_workqueue() can insert a + * barrier after us. + * When ->worklist becomes empty it is safe to exit because no + * more work_structs can be queued on this cwq: flush_workqueue + * checks list_empty(), and a "normal" queue_work() can't use + * a dead CPU. + */ + while (flush_cpu_workqueue(cwq)) + ; - while (unlikely(cwq->thread != NULL)) - cpu_relax(); - /* - * Wait until cwq->thread unlocks cwq->lock, - * it won't touch *cwq after that. - */ - smp_rmb(); - spin_unlock_wait(&cwq->lock); - } + kthread_stop(cwq->thread); + cwq->thread = NULL; } /** @@ -778,6 +789,8 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, struct cpu_workqueue_struct *cwq; struct workqueue_struct *wq; + action &= ~CPU_TASKS_FROZEN; + switch (action) { case CPU_LOCK_ACQUIRE: mutex_lock(&workqueue_mutex);