kthread: add kthread_stop_put
authorAndreas Gruenbacher <agruenba@redhat.com>
Thu, 7 Sep 2023 23:40:48 +0000 (01:40 +0200)
committerAndrew Morton <akpm@linux-foundation.org>
Wed, 4 Oct 2023 17:41:57 +0000 (10:41 -0700)
Add a kthread_stop_put() helper that stops a thread and puts its task
struct.  Use it to replace the various instances of kthread_stop()
followed by put_task_struct().

Remove the kthread_stop_put() macro in usbip that is similar but doesn't
return the result of kthread_stop().

[agruenba@redhat.com: fix kerneldoc comment]
Link: https://lkml.kernel.org/r/20230911111730.2565537-1-agruenba@redhat.com
[akpm@linux-foundation.org: document kthread_stop_put()'s argument]
Link: https://lkml.kernel.org/r/20230907234048.2499820-1-agruenba@redhat.com
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
13 files changed:
drivers/accel/ivpu/ivpu_job.c
drivers/dma-buf/st-dma-fence-chain.c
drivers/dma-buf/st-dma-fence.c
drivers/gpu/drm/i915/gt/selftest_migrate.c
drivers/net/xen-netback/interface.c
drivers/usb/usbip/usbip_common.h
fs/gfs2/ops_fstype.c
include/linux/kthread.h
kernel/irq/manage.c
kernel/kthread.c
kernel/smpboot.c
mm/damon/core.c
net/core/pktgen.c

index de9e69f70af7e215ff6f85812473158890ccef68..76f468c9f761bfedfcb5cc5f17825e7b5ce4d0db 100644 (file)
@@ -618,6 +618,5 @@ int ivpu_job_done_thread_init(struct ivpu_device *vdev)
 
 void ivpu_job_done_thread_fini(struct ivpu_device *vdev)
 {
-       kthread_stop(vdev->job_done_thread);
-       put_task_struct(vdev->job_done_thread);
+       kthread_stop_put(vdev->job_done_thread);
 }
index c0979c8049b5a3b071b90acceab1e70f51796ed4..9c2a0c082a768f89ddba627e6a5d61edac512f1b 100644 (file)
@@ -476,10 +476,9 @@ static int find_race(void *arg)
        for (i = 0; i < ncpus; i++) {
                int ret;
 
-               ret = kthread_stop(threads[i]);
+               ret = kthread_stop_put(threads[i]);
                if (ret && !err)
                        err = ret;
-               put_task_struct(threads[i]);
        }
        kfree(threads);
 
@@ -591,8 +590,7 @@ static int wait_forward(void *arg)
        for (i = 0; i < fc.chain_length; i++)
                dma_fence_signal(fc.fences[i]);
 
-       err = kthread_stop(tsk);
-       put_task_struct(tsk);
+       err = kthread_stop_put(tsk);
 
 err:
        fence_chains_fini(&fc);
@@ -621,8 +619,7 @@ static int wait_backward(void *arg)
        for (i = fc.chain_length; i--; )
                dma_fence_signal(fc.fences[i]);
 
-       err = kthread_stop(tsk);
-       put_task_struct(tsk);
+       err = kthread_stop_put(tsk);
 
 err:
        fence_chains_fini(&fc);
@@ -669,8 +666,7 @@ static int wait_random(void *arg)
        for (i = 0; i < fc.chain_length; i++)
                dma_fence_signal(fc.fences[i]);
 
-       err = kthread_stop(tsk);
-       put_task_struct(tsk);
+       err = kthread_stop_put(tsk);
 
 err:
        fence_chains_fini(&fc);
index fb6e0a6ae2c96e34a5627884952637d024d9ceba..b7c6f7ea9e0c83910b5a7d5001c25e0b96fa7492 100644 (file)
@@ -548,11 +548,9 @@ static int race_signal_callback(void *arg)
                for (i = 0; i < ARRAY_SIZE(t); i++) {
                        int err;
 
-                       err = kthread_stop(t[i].task);
+                       err = kthread_stop_put(t[i].task);
                        if (err && !ret)
                                ret = err;
-
-                       put_task_struct(t[i].task);
                }
        }
 
index 3def5ca72decfd32295cd46d0e9f7bba73c69d65..0fb07f073baa61f0fb68138b3cf429b4ff4b0ee4 100644 (file)
@@ -719,11 +719,9 @@ static int threaded_migrate(struct intel_migrate *migrate,
                if (IS_ERR_OR_NULL(tsk))
                        continue;
 
-               status = kthread_stop(tsk);
+               status = kthread_stop_put(tsk);
                if (status && !err)
                        err = status;
-
-               put_task_struct(tsk);
        }
 
        kfree(thread);
index f3f2c07423a6ac34f7266d68c65b52c38c961727..33c8143619f002ae9a42c63cd150fde3471f529e 100644 (file)
@@ -672,8 +672,7 @@ err:
 static void xenvif_disconnect_queue(struct xenvif_queue *queue)
 {
        if (queue->task) {
-               kthread_stop(queue->task);
-               put_task_struct(queue->task);
+               kthread_stop_put(queue->task);
                queue->task = NULL;
        }
 
index d8cbd2dfc2c256da2a9cf7780907b58a98112b6b..282efca64a01208cf5b189e177ffec53ba9aea00 100644 (file)
@@ -298,12 +298,6 @@ struct usbip_device {
        __k;                                                               \
 })
 
-#define kthread_stop_put(k)            \
-       do {                            \
-               kthread_stop(k);        \
-               put_task_struct(k);     \
-       } while (0)
-
 /* usbip_common.c */
 void usbip_dump_urb(struct urb *purb);
 void usbip_dump_header(struct usbip_header *pdu);
index 33ca04733e933e25d6fb1ce88d4f137eef191a9d..ecf789b7168c9d7d644346c49be480d98afa1f37 100644 (file)
@@ -1126,8 +1126,7 @@ static int init_threads(struct gfs2_sbd *sdp)
        return 0;
 
 fail:
-       kthread_stop(sdp->sd_logd_process);
-       put_task_struct(sdp->sd_logd_process);
+       kthread_stop_put(sdp->sd_logd_process);
        sdp->sd_logd_process = NULL;
        return error;
 }
@@ -1135,13 +1134,11 @@ fail:
 void gfs2_destroy_threads(struct gfs2_sbd *sdp)
 {
        if (sdp->sd_logd_process) {
-               kthread_stop(sdp->sd_logd_process);
-               put_task_struct(sdp->sd_logd_process);
+               kthread_stop_put(sdp->sd_logd_process);
                sdp->sd_logd_process = NULL;
        }
        if (sdp->sd_quotad_process) {
-               kthread_stop(sdp->sd_quotad_process);
-               put_task_struct(sdp->sd_quotad_process);
+               kthread_stop_put(sdp->sd_quotad_process);
                sdp->sd_quotad_process = NULL;
        }
 }
index 2c30ade43bc87a1d3ecd44616d3d585433d89558..b11f53c1ba2e6f7f2ad88ba503177535085bbdb5 100644 (file)
@@ -86,6 +86,7 @@ void free_kthread_struct(struct task_struct *k);
 void kthread_bind(struct task_struct *k, unsigned int cpu);
 void kthread_bind_mask(struct task_struct *k, const struct cpumask *mask);
 int kthread_stop(struct task_struct *k);
+int kthread_stop_put(struct task_struct *k);
 bool kthread_should_stop(void);
 bool kthread_should_park(void);
 bool kthread_should_stop_or_park(void);
index d309ba84e08a9d9b0137e82ea2f0209d7afc000e..1782f90cd8c6c7cf7a2b8eaedeb047543d70733a 100644 (file)
@@ -1852,15 +1852,13 @@ out_thread:
                struct task_struct *t = new->thread;
 
                new->thread = NULL;
-               kthread_stop(t);
-               put_task_struct(t);
+               kthread_stop_put(t);
        }
        if (new->secondary && new->secondary->thread) {
                struct task_struct *t = new->secondary->thread;
 
                new->secondary->thread = NULL;
-               kthread_stop(t);
-               put_task_struct(t);
+               kthread_stop_put(t);
        }
 out_mput:
        module_put(desc->owner);
@@ -1971,12 +1969,9 @@ static struct irqaction *__free_irq(struct irq_desc *desc, void *dev_id)
         * the same bit to a newly requested action.
         */
        if (action->thread) {
-               kthread_stop(action->thread);
-               put_task_struct(action->thread);
-               if (action->secondary && action->secondary->thread) {
-                       kthread_stop(action->secondary->thread);
-                       put_task_struct(action->secondary->thread);
-               }
+               kthread_stop_put(action->thread);
+               if (action->secondary && action->secondary->thread)
+                       kthread_stop_put(action->secondary->thread);
        }
 
        /* Last action releases resources */
index 1eea53050babcdccd7a5ab7d2aaf17492fd16b36..290cbc845225e41d39994399e50ae3e82852a685 100644 (file)
@@ -715,6 +715,24 @@ int kthread_stop(struct task_struct *k)
 }
 EXPORT_SYMBOL(kthread_stop);
 
+/**
+ * kthread_stop_put - stop a thread and put its task struct
+ * @k: thread created by kthread_create().
+ *
+ * Stops a thread created by kthread_create() and put its task_struct.
+ * Only use when holding an extra task struct reference obtained by
+ * calling get_task_struct().
+ */
+int kthread_stop_put(struct task_struct *k)
+{
+       int ret;
+
+       ret = kthread_stop(k);
+       put_task_struct(k);
+       return ret;
+}
+EXPORT_SYMBOL(kthread_stop_put);
+
 int kthreadd(void *unused)
 {
        struct task_struct *tsk = current;
index f47d8f375946bd6c315ac7e765825a0a0408cec8..1992b62e980b767a976b288cf981c2ed7b6d513f 100644 (file)
@@ -272,8 +272,7 @@ static void smpboot_destroy_threads(struct smp_hotplug_thread *ht)
                struct task_struct *tsk = *per_cpu_ptr(ht->store, cpu);
 
                if (tsk) {
-                       kthread_stop(tsk);
-                       put_task_struct(tsk);
+                       kthread_stop_put(tsk);
                        *per_cpu_ptr(ht->store, cpu) = NULL;
                }
        }
index bcd2bd9d6c104f234f699a236e2e40f83cd19a07..2f54f153d7f53228fa183ee4f025e3975d72d42f 100644 (file)
@@ -699,8 +699,7 @@ static int __damon_stop(struct damon_ctx *ctx)
        if (tsk) {
                get_task_struct(tsk);
                mutex_unlock(&ctx->kdamond_lock);
-               kthread_stop(tsk);
-               put_task_struct(tsk);
+               kthread_stop_put(tsk);
                return 0;
        }
        mutex_unlock(&ctx->kdamond_lock);
index f56b8d69701475683561032d992c97585320af63..826250a0f5b16e9fea1432faef56967a360f53a5 100644 (file)
@@ -3982,8 +3982,7 @@ static void __net_exit pg_net_exit(struct net *net)
        list_for_each_safe(q, n, &list) {
                t = list_entry(q, struct pktgen_thread, th_list);
                list_del(&t->th_list);
-               kthread_stop(t->tsk);
-               put_task_struct(t->tsk);
+               kthread_stop_put(t->tsk);
                kfree(t);
        }