From nobody Thu Dec 18 19:04:46 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5DCD7EEB593 for ; Mon, 11 Sep 2023 20:47:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229734AbjIKUrB (ORCPT ); Mon, 11 Sep 2023 16:47:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46606 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236734AbjIKLS3 (ORCPT ); Mon, 11 Sep 2023 07:18:29 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 7D8E4CDD for ; Mon, 11 Sep 2023 04:17:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1694431054; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=kLYWjYvFwv4/s+HtYDIjsdK1LYTgvhIhfGvJ4mVWT5Q=; b=Qovzk81U+4/4XR7+8MJZ6LWYcENKpFKBa0cOev8kSzNIcUqoE5/cZTpq6kChwoZuWFhFmF U6AO0mfVMO3MYLpUG42VAqzW6k7RBBZVRr1DyUUNMV/M5QzwTA6YRy4QeubZBew0WaxyUx p16mAdyix1yubNC6RsPOFh+0KRco0r4= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-60-iP-LBR5kODm1LSeCIuktlA-1; Mon, 11 Sep 2023 07:17:32 -0400 X-MC-Unique: iP-LBR5kODm1LSeCIuktlA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D8B643803902; Mon, 11 Sep 2023 11:17:31 +0000 (UTC) Received: from pasta.redhat.com (unknown [10.45.226.29]) by smtp.corp.redhat.com (Postfix) with ESMTP id D42E42156701; Mon, 11 Sep 2023 11:17:30 +0000 (UTC) From: Andreas Gruenbacher To: Andrew Morton Cc: Andreas Gruenbacher , mm-commits@vger.kernel.org, Linus Torvalds , linux-kernel@vger.kernel.org Subject: [PATCH v2] kthread: Add kthread_stop_put Date: Mon, 11 Sep 2023 13:17:30 +0200 Message-Id: <20230911111730.2565537-1-agruenba@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Hi Andrew, thanks for picking this up. The kernel test robot has since told me that it's uhappy about the kerneldoc comment I've added for kthread_stio_put(). So here's an updated version that has the comment fixed, rebased against the latest for-next kernel. https://lore.kernel.org/oe-kbuild-all/202309081653.IMl41FhS-lkp@intel.com/ Thanks, Andreas -- 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(). Signed-off-by: Andreas Gruenbacher --- drivers/accel/ivpu/ivpu_job.c | 3 +-- drivers/dma-buf/st-dma-fence-chain.c | 12 ++++-------- drivers/dma-buf/st-dma-fence.c | 4 +--- drivers/gpu/drm/i915/gt/selftest_migrate.c | 4 +--- drivers/net/xen-netback/interface.c | 3 +-- drivers/usb/usbip/usbip_common.h | 6 ------ fs/gfs2/ops_fstype.c | 9 +++------ include/linux/kthread.h | 1 + kernel/irq/manage.c | 15 +++++---------- kernel/kthread.c | 17 +++++++++++++++++ kernel/smpboot.c | 3 +-- mm/damon/core.c | 3 +-- net/core/pktgen.c | 3 +-- 13 files changed, 37 insertions(+), 46 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index de9e69f70af7..76f468c9f761 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -618,6 +618,5 @@ int ivpu_job_done_thread_init(struct ivpu_device *vdev) =20 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); } diff --git a/drivers/dma-buf/st-dma-fence-chain.c b/drivers/dma-buf/st-dma-= fence-chain.c index c0979c8049b5..9c2a0c082a76 100644 --- a/drivers/dma-buf/st-dma-fence-chain.c +++ b/drivers/dma-buf/st-dma-fence-chain.c @@ -476,10 +476,9 @@ static int find_race(void *arg) for (i =3D 0; i < ncpus; i++) { int ret; =20 - ret =3D kthread_stop(threads[i]); + ret =3D kthread_stop_put(threads[i]); if (ret && !err) err =3D ret; - put_task_struct(threads[i]); } kfree(threads); =20 @@ -591,8 +590,7 @@ static int wait_forward(void *arg) for (i =3D 0; i < fc.chain_length; i++) dma_fence_signal(fc.fences[i]); =20 - err =3D kthread_stop(tsk); - put_task_struct(tsk); + err =3D kthread_stop_put(tsk); =20 err: fence_chains_fini(&fc); @@ -621,8 +619,7 @@ static int wait_backward(void *arg) for (i =3D fc.chain_length; i--; ) dma_fence_signal(fc.fences[i]); =20 - err =3D kthread_stop(tsk); - put_task_struct(tsk); + err =3D kthread_stop_put(tsk); =20 err: fence_chains_fini(&fc); @@ -669,8 +666,7 @@ static int wait_random(void *arg) for (i =3D 0; i < fc.chain_length; i++) dma_fence_signal(fc.fences[i]); =20 - err =3D kthread_stop(tsk); - put_task_struct(tsk); + err =3D kthread_stop_put(tsk); =20 err: fence_chains_fini(&fc); diff --git a/drivers/dma-buf/st-dma-fence.c b/drivers/dma-buf/st-dma-fence.c index fb6e0a6ae2c9..b7c6f7ea9e0c 100644 --- a/drivers/dma-buf/st-dma-fence.c +++ b/drivers/dma-buf/st-dma-fence.c @@ -548,11 +548,9 @@ static int race_signal_callback(void *arg) for (i =3D 0; i < ARRAY_SIZE(t); i++) { int err; =20 - err =3D kthread_stop(t[i].task); + err =3D kthread_stop_put(t[i].task); if (err && !ret) ret =3D err; - - put_task_struct(t[i].task); } } =20 diff --git a/drivers/gpu/drm/i915/gt/selftest_migrate.c b/drivers/gpu/drm/i= 915/gt/selftest_migrate.c index 3def5ca72dec..0fb07f073baa 100644 --- a/drivers/gpu/drm/i915/gt/selftest_migrate.c +++ b/drivers/gpu/drm/i915/gt/selftest_migrate.c @@ -719,11 +719,9 @@ static int threaded_migrate(struct intel_migrate *migr= ate, if (IS_ERR_OR_NULL(tsk)) continue; =20 - status =3D kthread_stop(tsk); + status =3D kthread_stop_put(tsk); if (status && !err) err =3D status; - - put_task_struct(tsk); } =20 kfree(thread); diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/= interface.c index f3f2c07423a6..33c8143619f0 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -672,8 +672,7 @@ int xenvif_connect_ctrl(struct xenvif *vif, grant_ref_t= ring_ref, 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 =3D NULL; } =20 diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_com= mon.h index d8cbd2dfc2c2..282efca64a01 100644 --- a/drivers/usb/usbip/usbip_common.h +++ b/drivers/usb/usbip/usbip_common.h @@ -298,12 +298,6 @@ struct usbip_device { __k; \ }) =20 -#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); diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 33ca04733e93..ecf789b7168c 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1126,8 +1126,7 @@ static int init_threads(struct gfs2_sbd *sdp) return 0; =20 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 =3D NULL; return error; } @@ -1135,13 +1134,11 @@ static int init_threads(struct gfs2_sbd *sdp) 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 =3D 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 =3D NULL; } } diff --git a/include/linux/kthread.h b/include/linux/kthread.h index 2c30ade43bc8..b11f53c1ba2e 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -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); diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index d309ba84e08a..1782f90cd8c6 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -1852,15 +1852,13 @@ __setup_irq(unsigned int irq, struct irq_desc *desc= , struct irqaction *new) struct task_struct *t =3D new->thread; =20 new->thread =3D NULL; - kthread_stop(t); - put_task_struct(t); + kthread_stop_put(t); } if (new->secondary && new->secondary->thread) { struct task_struct *t =3D new->secondary->thread; =20 new->secondary->thread =3D 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); } =20 /* Last action releases resources */ diff --git a/kernel/kthread.c b/kernel/kthread.c index c46128ec0c0a..c4453181daf9 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -715,6 +715,23 @@ int kthread_stop(struct task_struct *k) } EXPORT_SYMBOL(kthread_stop); =20 +/** + * kthread_stop_put - stop a thread and put its task struct + * + * 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 =3D kthread_stop(k); + put_task_struct(k); + return ret; +} +EXPORT_SYMBOL(kthread_stop_put); + int kthreadd(void *unused) { struct task_struct *tsk =3D current; diff --git a/kernel/smpboot.c b/kernel/smpboot.c index f47d8f375946..1992b62e980b 100644 --- a/kernel/smpboot.c +++ b/kernel/smpboot.c @@ -272,8 +272,7 @@ static void smpboot_destroy_threads(struct smp_hotplug_= thread *ht) struct task_struct *tsk =3D *per_cpu_ptr(ht->store, cpu); =20 if (tsk) { - kthread_stop(tsk); - put_task_struct(tsk); + kthread_stop_put(tsk); *per_cpu_ptr(ht->store, cpu) =3D NULL; } } diff --git a/mm/damon/core.c b/mm/damon/core.c index bcd2bd9d6c10..2f54f153d7f5 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -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); diff --git a/net/core/pktgen.c b/net/core/pktgen.c index f56b8d697014..826250a0f5b1 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -3982,8 +3982,7 @@ static void __net_exit pg_net_exit(struct net *net) list_for_each_safe(q, n, &list) { t =3D 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); } =20 --=20 2.40.1