kthread: add kthread_destroy_worker()
authorPetr Mladek <[email protected]>
Tue, 11 Oct 2016 20:55:33 +0000 (13:55 -0700)
committerLinus Torvalds <[email protected]>
Tue, 11 Oct 2016 22:06:33 +0000 (15:06 -0700)
The current kthread worker users call flush() and stop() explicitly.
This function does the same plus it frees the kthread_worker struct
in one call.

It is supposed to be used together with kthread_create_worker*() that
allocates struct kthread_worker.

Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Petr Mladek <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: Tejun Heo <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Cc: "Paul E. McKenney" <[email protected]>
Cc: Josh Triplett <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Jiri Kosina <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Michal Hocko <[email protected]>
Cc: Vlastimil Babka <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
include/linux/kthread.h
kernel/kthread.c

index daeb2befbabffb844087d9ced1ef9ef23ce37bf0..afc8939da8613db1a3c59b1de287c2a8127a2408 100644 (file)
@@ -136,4 +136,6 @@ bool kthread_queue_work(struct kthread_worker *worker,
 void kthread_flush_work(struct kthread_work *work);
 void kthread_flush_worker(struct kthread_worker *worker);
 
+void kthread_destroy_worker(struct kthread_worker *worker);
+
 #endif /* _LINUX_KTHREAD_H */
index 12695e68ed00d43345ef3595bb1d9ecb3084e5c0..f874300dfce5e1c946e36df1827aea97a1107e31 100644 (file)
@@ -823,3 +823,26 @@ void kthread_flush_worker(struct kthread_worker *worker)
        wait_for_completion(&fwork.done);
 }
 EXPORT_SYMBOL_GPL(kthread_flush_worker);
+
+/**
+ * kthread_destroy_worker - destroy a kthread worker
+ * @worker: worker to be destroyed
+ *
+ * Flush and destroy @worker.  The simple flush is enough because the kthread
+ * worker API is used only in trivial scenarios.  There are no multi-step state
+ * machines needed.
+ */
+void kthread_destroy_worker(struct kthread_worker *worker)
+{
+       struct task_struct *task;
+
+       task = worker->task;
+       if (WARN_ON(!task))
+               return;
+
+       kthread_flush_worker(worker);
+       kthread_stop(task);
+       WARN_ON(!list_empty(&worker->work_list));
+       kfree(worker);
+}
+EXPORT_SYMBOL(kthread_destroy_worker);