All of lore.kernel.org
 help / color / mirror / Atom feed
From: "tip-bot2 for Sebastian Andrzej Siewior" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: kernel test robot <lkp@intel.com>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	"Peter Zijlstra (Intel)" <peterz@infradead.org>,
	Ingo Molnar <mingo@kernel.org>, Tejun Heo <tj@kernel.org>,
	x86 <x86@kernel.org>, LKML <linux-kernel@vger.kernel.org>
Subject: [tip: sched/urgent] workqueue: Remove the warning in wq_worker_sleeping()
Date: Wed, 08 Apr 2020 12:20:25 -0000	[thread overview]
Message-ID: <158634842513.28353.14029698174140162537.tip-bot2@tip-bot2> (raw)
In-Reply-To: <20200327074308.GY11705@shao2-debian>

The following commit has been merged into the sched/urgent branch of tip:

Commit-ID:     62849a9612924a655c67cf6962920544aa5c20db
Gitweb:        https://git.kernel.org/tip/62849a9612924a655c67cf6962920544aa5c20db
Author:        Sebastian Andrzej Siewior <bigeasy@linutronix.de>
AuthorDate:    Sat, 28 Mar 2020 00:29:59 +01:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Wed, 08 Apr 2020 11:35:20 +02:00

workqueue: Remove the warning in wq_worker_sleeping()

The kernel test robot triggered a warning with the following race:
   task-ctx A                            interrupt-ctx B
 worker
  -> process_one_work()
    -> work_item()
      -> schedule();
         -> sched_submit_work()
           -> wq_worker_sleeping()
             -> ->sleeping = 1
               atomic_dec_and_test(nr_running)
         __schedule();                *interrupt*
                                       async_page_fault()
                                       -> local_irq_enable();
                                       -> schedule();
                                          -> sched_submit_work()
                                            -> wq_worker_sleeping()
                                               -> if (WARN_ON(->sleeping)) return
                                          -> __schedule()
                                            ->  sched_update_worker()
                                              -> wq_worker_running()
                                                 -> atomic_inc(nr_running);
                                                 -> ->sleeping = 0;

      ->  sched_update_worker()
        -> wq_worker_running()
          if (!->sleeping) return

In this context the warning is pointless everything is fine.
An interrupt before wq_worker_sleeping() will perform the ->sleeping
assignment (0 -> 1 > 0) twice.
An interrupt after wq_worker_sleeping() will trigger the warning and
nr_running will be decremented (by A) and incremented once (only by B, A
will skip it). This is the case until the ->sleeping is zeroed again in
wq_worker_running().

Remove the WARN statement because this condition may happen. Document
that preemption around wq_worker_sleeping() needs to be disabled to
protect ->sleeping and not just as an optimisation.

Fixes: 6d25be5782e48 ("sched/core, workqueues: Distangle worker accounting from rq lock")
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Tejun Heo <tj@kernel.org>
Link: https://lkml.kernel.org/r/20200327074308.GY11705@shao2-debian
---
 kernel/sched/core.c | 3 ++-
 kernel/workqueue.c  | 6 ++++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index f6b329b..c3d12e3 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4120,7 +4120,8 @@ static inline void sched_submit_work(struct task_struct *tsk)
 	 * it wants to wake up a task to maintain concurrency.
 	 * As this function is called inside the schedule() context,
 	 * we disable preemption to avoid it calling schedule() again
-	 * in the possible wakeup of a kworker.
+	 * in the possible wakeup of a kworker and because wq_worker_sleeping()
+	 * requires it.
 	 */
 	if (tsk->flags & (PF_WQ_WORKER | PF_IO_WORKER)) {
 		preempt_disable();
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 3816a18..891ccad 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -858,7 +858,8 @@ void wq_worker_running(struct task_struct *task)
  * @task: task going to sleep
  *
  * This function is called from schedule() when a busy worker is
- * going to sleep.
+ * going to sleep. Preemption needs to be disabled to protect ->sleeping
+ * assignment.
  */
 void wq_worker_sleeping(struct task_struct *task)
 {
@@ -875,7 +876,8 @@ void wq_worker_sleeping(struct task_struct *task)
 
 	pool = worker->pool;
 
-	if (WARN_ON_ONCE(worker->sleeping))
+	/* Return if preempted before wq_worker_running() was reached */
+	if (worker->sleeping)
 		return;
 
 	worker->sleeping = 1;

      parent reply	other threads:[~2020-04-08 12:20 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-27  7:43 6d25be5782 ("sched/core, workqueues: Distangle worker .."): [ 52.816697] WARNING: CPU: 0 PID: 14 at kernel/workqueue.c:882 wq_worker_sleeping kernel test robot
2020-03-27  7:43 ` kernel test robot
2020-03-27 17:53 ` [PATCH] workqueue: Don't double assign worker->sleeping Sebastian Andrzej Siewior
2020-03-27 17:53   ` Sebastian Andrzej Siewior
2020-03-27 23:29   ` [PATCH v2] workqueue: Remove the warning in wq_worker_sleeping() Sebastian Andrzej Siewior
2020-03-27 23:29     ` Sebastian Andrzej Siewior
2020-04-03 14:53     ` Tejun Heo
2020-04-03 14:53       ` Tejun Heo
2020-04-03 19:29       ` Sebastian Andrzej Siewior
2020-04-03 19:29         ` Sebastian Andrzej Siewior
2020-04-03 17:45     ` Daniel Jordan
2020-04-03 17:45       ` Daniel Jordan
2020-04-03 18:25       ` Sebastian Andrzej Siewior
2020-04-03 18:25         ` Sebastian Andrzej Siewior
2020-04-03 19:05         ` Daniel Jordan
2020-04-03 19:05           ` Daniel Jordan
2020-04-01  3:22   ` [PATCH] workqueue: Don't double assign worker->sleeping Lai Jiangshan
2020-04-01  3:44     ` Lai Jiangshan
2020-04-01 13:03       ` Sebastian Andrzej Siewior
2020-04-01 13:03         ` Sebastian Andrzej Siewior
2020-04-02  0:07         ` Lai Jiangshan
2020-04-02  7:29           ` Sebastian Andrzej Siewior
2020-04-02  7:29             ` Sebastian Andrzej Siewior
2020-04-08 12:20 ` tip-bot2 for Sebastian Andrzej Siewior [this message]

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=158634842513.28353.14029698174140162537.tip-bot2@tip-bot2 \
    --to=tip-bot2@linutronix.de \
    --cc=bigeasy@linutronix.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=lkp@intel.com \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=tj@kernel.org \
    --cc=x86@kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.