linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Petr Mladek <pmladek@suse.com>, Oleg Nesterov <oleg@redhat.com>,
	Nathan Chancellor <nathan@kernel.org>,
	Nick Desaulniers <ndesaulniers@google.com>,
	Tejun Heo <tj@kernel.org>, Minchan Kim <minchan@google.com>,
	jenhaochen@google.com, Martin Liu <liumartin@google.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH AUTOSEL 5.4 24/26] kthread_worker: fix return value when kthread_mod_delayed_work() races with kthread_cancel_delayed_work_sync()
Date: Mon,  5 Jul 2021 11:30:37 -0400	[thread overview]
Message-ID: <20210705153039.1521781-24-sashal@kernel.org> (raw)
In-Reply-To: <20210705153039.1521781-1-sashal@kernel.org>

From: Petr Mladek <pmladek@suse.com>

[ Upstream commit d71ba1649fa3c464c51ec7163e4b817345bff2c7 ]

kthread_mod_delayed_work() might race with
kthread_cancel_delayed_work_sync() or another kthread_mod_delayed_work()
call.  The function lets the other operation win when it sees
work->canceling counter set.  And it returns @false.

But it should return @true as it is done by the related workqueue API, see
mod_delayed_work_on().

The reason is that the return value might be used for reference counting.
It has to distinguish the case when the number of queued works has changed
or stayed the same.

The change is safe.  kthread_mod_delayed_work() return value is not
checked anywhere at the moment.

Link: https://lore.kernel.org/r/20210521163526.GA17916@redhat.com
Link: https://lkml.kernel.org/r/20210610133051.15337-4-pmladek@suse.com
Signed-off-by: Petr Mladek <pmladek@suse.com>
Reported-by: Oleg Nesterov <oleg@redhat.com>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Minchan Kim <minchan@google.com>
Cc: <jenhaochen@google.com>
Cc: Martin Liu <liumartin@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/kthread.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/kernel/kthread.c b/kernel/kthread.c
index 2eb8d7550324..b2bac5d929d2 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -1083,14 +1083,14 @@ static bool __kthread_cancel_work(struct kthread_work *work)
  * modify @dwork's timer so that it expires after @delay. If @delay is zero,
  * @work is guaranteed to be queued immediately.
  *
- * Return: %true if @dwork was pending and its timer was modified,
- * %false otherwise.
+ * Return: %false if @dwork was idle and queued, %true otherwise.
  *
  * A special case is when the work is being canceled in parallel.
  * It might be caused either by the real kthread_cancel_delayed_work_sync()
  * or yet another kthread_mod_delayed_work() call. We let the other command
- * win and return %false here. The caller is supposed to synchronize these
- * operations a reasonable way.
+ * win and return %true here. The return value can be used for reference
+ * counting and the number of queued works stays the same. Anyway, the caller
+ * is supposed to synchronize these operations a reasonable way.
  *
  * This function is safe to call from any context including IRQ handler.
  * See __kthread_cancel_work() and kthread_delayed_work_timer_fn()
@@ -1102,13 +1102,15 @@ bool kthread_mod_delayed_work(struct kthread_worker *worker,
 {
 	struct kthread_work *work = &dwork->work;
 	unsigned long flags;
-	int ret = false;
+	int ret;
 
 	raw_spin_lock_irqsave(&worker->lock, flags);
 
 	/* Do not bother with canceling when never queued. */
-	if (!work->worker)
+	if (!work->worker) {
+		ret = false;
 		goto fast_queue;
+	}
 
 	/* Work must not be used with >1 worker, see kthread_queue_work() */
 	WARN_ON_ONCE(work->worker != worker);
@@ -1126,8 +1128,11 @@ bool kthread_mod_delayed_work(struct kthread_worker *worker,
 	 * be used for reference counting.
 	 */
 	kthread_cancel_delayed_work_timer(work, &flags);
-	if (work->canceling)
+	if (work->canceling) {
+		/* The number of works in the queue does not change. */
+		ret = true;
 		goto out;
+	}
 	ret = __kthread_cancel_work(work);
 
 fast_queue:
-- 
2.30.2


  parent reply	other threads:[~2021-07-05 15:34 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-05 15:30 [PATCH AUTOSEL 5.4 01/26] HID: do not use down_interruptible() when unbinding devices Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 02/26] EDAC/ti: Add missing MODULE_DEVICE_TABLE Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 03/26] ACPI: processor idle: Fix up C-state latency if not ordered Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 04/26] hv_utils: Fix passing zero to 'PTR_ERR' warning Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 05/26] lib: vsprintf: Fix handling of number field widths in vsscanf Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 06/26] ACPI: EC: Make more Asus laptops use ECDT _GPE Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 07/26] block_dump: remove block_dump feature in mark_inode_dirty() Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 08/26] fs: dlm: cancel work sync othercon Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 09/26] random32: Fix implicit truncation warning in prandom_seed_state() Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 10/26] fs: dlm: fix memory leak when fenced Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 11/26] ACPICA: Fix memory leak caused by _CID repair function Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 12/26] ACPI: bus: Call kobject_put() in acpi_init() error path Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 13/26] ACPI: resources: Add checks for ACPI IRQ override Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 14/26] block: fix race between adding/removing rq qos and normal IO Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 15/26] platform/x86: toshiba_acpi: Fix missing error code in toshiba_acpi_setup_keyboard() Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 16/26] nvmet-fc: do not check for invalid target port in nvmet_fc_handle_fcp_rqst() Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 17/26] EDAC/Intel: Do not load EDAC driver when running as a guest Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 18/26] PCI: hv: Add check for hyperv_initialized in init_hv_pci_drv() Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 19/26] clocksource: Retry clock read if long delays detected Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 20/26] ACPI: tables: Add custom DSDT file as makefile prerequisite Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 21/26] HID: wacom: Correct base usage for capacitive ExpressKey status bits Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 22/26] cifs: fix missing spinlock around update to ses->status Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 23/26] block: fix discard request merge Sasha Levin
2021-07-05 15:30 ` Sasha Levin [this message]
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 25/26] ia64: mca_drv: fix incorrect array size calculation Sasha Levin
2021-07-05 15:30 ` [PATCH AUTOSEL 5.4 26/26] writeback, cgroup: increment isw_nr_in_flight before grabbing an inode Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210705153039.1521781-24-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=jenhaochen@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=liumartin@google.com \
    --cc=minchan@google.com \
    --cc=nathan@kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=oleg@redhat.com \
    --cc=pmladek@suse.com \
    --cc=stable@vger.kernel.org \
    --cc=tj@kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).