On Fri, Dec 2, 2011 at 3:56 PM, Dan Williams <dan.j.williams@xxxxxxxxx> wrote: [..] > @@ -2405,7 +2434,7 @@ void drain_workqueue(struct workqueue_struct *wq) > */ > spin_lock_irq(&workqueue_lock); > if (!wq->nr_drainers++) > - wq->flags |= WQ_DRAINING; > + wq->flags |= WQ_DRAINING | flags; > spin_unlock_irq(&workqueue_lock); > reflush: > flush_workqueue(wq); > @@ -2429,9 +2458,25 @@ reflush: > } > > spin_lock_irq(&workqueue_lock); > - if (!--wq->nr_drainers) > - wq->flags &= ~WQ_DRAINING; > + if (!--wq->nr_drainers) { > + wq->flags &= ~(WQ_DRAINING | WQ_NO_DEFER); > + list_splice_init(&wq->drain_defer, &drain_defer); > + ret = !list_empty(&drain_defer); > + } > spin_unlock_irq(&workqueue_lock); > + > + /* requeue work on this queue provided it was not being destroyed */ > + list_for_each_entry_safe(work, w, &drain_defer, entry) { > + list_del_init(&work->entry); > + queue_work(wq, work); > + } Actually, this won't work. The queuing of deferred work would need to be under the lock and then flushed again to guarantee workqueue semantics which just devolves into a "wait until all work stops being submitted to the queue for one drain_workqueue() duration". Which is more than what we need for libsas. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html