Skip to contentSkip to conversation

workqueue: Separate out drain_workqueue() from destroy_workqueue()

PATCH In review Tejun Heo 2 participants 3 messages Apr 5, 2011 Workqueue

lore
Share & tools
lore

Tejun Heo

author maintainer
#0 lore raw

PATCH 1/1 workqueue: Separate out drain_workqueue() from destroy_workqueue()

There are users which want to drain workqueues without destroying it. Separate out drain functionality from destroy_workqueue() into drain_workqueue() and make it accessible to workqueue users.

To guarantee forward-progress, only chain queueing is allowed while drain is in progress. If a new work item which isn't chained from the running or pending work items is queued while draining is in progress, WARN_ON_ONCE() is triggered.

Cc James Bottomley <[email protected]>

---
James, does this seem to fit your use cases?

Thanks.

 include/linux/workqueue.h |    3 +
 kernel/workqueue.c        |   86 +++++++++++++++++++++++++++++++---------------
 2 files changed, 60 insertions(+), 29 deletions(-)
include/linux/workqueue.h +2 -1
index f7998a3..b5ba4ba 100644
@@ -255,7 +255,7 @@ enum {
 	WQ_HIGHPRI		= 1 << 4, /* high priority */
 	WQ_CPU_INTENSIVE	= 1 << 5, /* cpu instensive workqueue */
 
-	WQ_DYING		= 1 << 6, /* internal: workqueue is dying */
+	WQ_DRAINING		= 1 << 6, /* internal: workqueue is draining */
 	WQ_RESCUER		= 1 << 7, /* internal: workqueue has rescuer */
 
 	WQ_MAX_ACTIVE		= 512,	  /* I like 512, better ideas? */
@@ -351,6 +351,7 @@ extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
 			struct delayed_work *work, unsigned long delay);
 
 extern void flush_workqueue(struct workqueue_struct *wq);
+extern void drain_workqueue(struct workqueue_struct *wq);
 extern void flush_scheduled_work(void);
 
 extern int schedule_work(struct work_struct *work);
kernel/workqueue.c +58 -28

124 lines not on this page · raw message

#1 lore raw
Quoted 9 lines · Tejun Heo

There are users which want to drain workqueues without destroying it. Separate out drain functionality from destroy_workqueue() into drain_workqueue() and make it accessible to workqueue users.

To guarantee forward-progress, only chain queueing is allowed while drain is in progress. If a new work item which isn't chained from the running or pending work items is queued while draining is in progress, WARN_ON_ONCE() is triggered.

Quoted 4 lines
Cc James Bottomley <[email protected]>

---
James, does this seem to fit your use cases?

Perfectly, thanks. It makes sure we have eliminated all work the workqueues generated before we return. This is needed in some of the SCSI waits where we want all discovery to complete, not just the piece the WQ started.

Thanks,

James

author maintainer
#2 lore raw
Quoted 6 lines · James Bottomley
Quoted 1 line

James, does this seem to fit your use cases?

Perfectly, thanks. It makes sure we have eliminated all work the workqueues generated before we return. This is needed in some of the SCSI waits where we want all discovery to complete, not just the piece the WQ started.

Cool, applied to wq#for-2.6.40 with minor printk adjustments. Please feel free to pull into SCSI if necessary. It's a stable branch and currently contains only the single commit.

git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git for-2.6.40

Thanks.

Signature · 1 line
tejun