rcu.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: paulmck@kernel.org
To: rcu@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, kernel-team@fb.com,
	mingo@kernel.org, jiangshanlai@gmail.com,
	akpm@linux-foundation.org, mathieu.desnoyers@efficios.com,
	josh@joshtriplett.org, tglx@linutronix.de, peterz@infradead.org,
	rostedt@goodmis.org, dhowells@redhat.com, edumazet@google.com,
	fweisbec@gmail.com, oleg@redhat.com, joel@joelfernandes.org,
	"Paul E. McKenney" <paulmck@kernel.org>
Subject: [PATCH tip/core/rcu 16/17] torture: Break affinity of kthreads last running on outgoing CPU
Date: Wed,  6 Jan 2021 09:17:09 -0800	[thread overview]
Message-ID: <20210106171710.22239-16-paulmck@kernel.org> (raw)
In-Reply-To: <20210106171532.GA20769@paulmck-ThinkPad-P72>

From: "Paul E. McKenney" <paulmck@kernel.org>

The advent of commit 06249738a41a ("workqueue: Manually break affinity
on hotplug") means that the scheduler no longer silently breaks affinity
for kthreads pinned to the outgoing CPU.  This can happen for many of
rcutorture's kthreads due to shuffling, which periodically affinities
these ktheads away from a randomly chosen CPU.  This usually works fine
because these kthreads are allowed to run on any other CPU and because
shuffling is a no-op any time there is but one online CPU.

However, consider the following sequence of events:

1.	CPUs 0 and 1 are initially online.

2.	The torture_shuffle_tasks() function affinities all the tasks
	away from CPU 0.

3.	CPU 1 goes offline.

4.	All the tasks are now affinitied to an offline CPU, triggering
	the warning added by the commit noted above.

This can trigger the following in sched_cpu_dying() in kernel/sched/core.c:

	BUG_ON(rq->nr_running != 1 || rq_has_pinned_tasks(rq))

This commit therefore adds a new torture_shuffle_tasks_offline() function
that is invoked from torture_offline() prior to offlining a CPU.  This new
function scans the list of shuffled kthreads and for any thread that
last ran (or is set to run) on the outgoing CPU, sets its affinity to
all online CPUs.  Thus there will never be a kthread that is affinitied
only to the outgoing CPU.

Of course, if the sysadm manually applies affinity to any of these
kthreads, all bets are off.  However, such a sysadm must be fast because
the torture_shuffle_tasks_offline() function is invoked immediately before
offlining the outgoing CPU.  Therefore, let it be known that with great
speed and great power comes great responsibility.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
 kernel/torture.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/kernel/torture.c b/kernel/torture.c
index 01e336f..40c5c68 100644
--- a/kernel/torture.c
+++ b/kernel/torture.c
@@ -155,6 +155,8 @@ EXPORT_SYMBOL_GPL(torture_hrtimeout_s);
 
 #ifdef CONFIG_HOTPLUG_CPU
 
+static void torture_shuffle_tasks_offline(int cpu);
+
 /*
  * Variables for online-offline handling.  Only present if CPU hotplug
  * is enabled, otherwise does nothing.
@@ -212,6 +214,7 @@ bool torture_offline(int cpu, long *n_offl_attempts, long *n_offl_successes,
 			 torture_type, cpu);
 	starttime = jiffies;
 	(*n_offl_attempts)++;
+	torture_shuffle_tasks_offline(cpu);
 	ret = remove_cpu(cpu);
 	if (ret) {
 		s = "";
@@ -512,6 +515,20 @@ static void torture_shuffle_task_unregister_all(void)
 	mutex_unlock(&shuffle_task_mutex);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+// Unbind all tasks from a CPU that is to be taken offline.
+static void torture_shuffle_tasks_offline(int cpu)
+{
+	struct shuffle_task *stp;
+
+	mutex_lock(&shuffle_task_mutex);
+	list_for_each_entry(stp, &shuffle_task_list, st_l)
+		if (task_cpu(stp->st_t) == cpu)
+			set_cpus_allowed_ptr(stp->st_t, cpu_online_mask);
+	mutex_unlock(&shuffle_task_mutex);
+}
+#endif // #ifdef CONFIG_HOTPLUG_CPU
+
 /* Shuffle tasks such that we allow shuffle_idle_cpu to become idle.
  * A special case is when shuffle_idle_cpu = -1, in which case we allow
  * the tasks to run on all CPUs.
-- 
2.9.5


  parent reply	other threads:[~2021-01-06 17:19 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-06 17:15 [PATCH tip/core/rcu 0/17] Torture-test updates for v5.12 Paul E. McKenney
2021-01-06 17:16 ` [PATCH tip/core/rcu 01/17] rcutorture: Add testing for RCU's global memory ordering paulmck
2021-01-06 17:16 ` [PATCH tip/core/rcu 02/17] scftorture: Add debug output for wrong-CPU warning paulmck
2021-01-06 17:16 ` [PATCH tip/core/rcu 03/17] refscale: Allow summarization of verbose output paulmck
2021-01-06 17:16 ` [PATCH tip/core/rcu 04/17] rcutorture: Require entire stutter period be post-boot paulmck
2021-01-06 17:16 ` [PATCH tip/core/rcu 05/17] rcutorture: Make synctype[] and nsynctype be static global paulmck
2021-01-06 17:16 ` [PATCH tip/core/rcu 06/17] rcutorture: Make rcu_torture_fakewriter() use blocking wait primitives paulmck
2021-01-06 17:17 ` [PATCH tip/core/rcu 07/17] torture: Add fuzzed hrtimer-based sleep functions paulmck
2021-01-06 17:17 ` [PATCH tip/core/rcu 08/17] rcutorture: Use torture_hrtimeout_jiffies() to avoid busy-waits paulmck
2021-01-06 17:17 ` [PATCH tip/core/rcu 09/17] torture: Make stutter use torture_hrtimeout_*() functions paulmck
2021-01-06 17:17 ` [PATCH tip/core/rcu 10/17] rcutorture: Use hrtimers for reader and writer delays paulmck
2021-01-06 17:17 ` [PATCH tip/core/rcu 11/17] torture: Make refscale throttle high-rate printk()s paulmck
2021-01-06 17:17 ` [PATCH tip/core/rcu 12/17] torture: Throttle VERBOSE_TOROUT_*() output paulmck
2021-01-06 17:17 ` [PATCH tip/core/rcu 13/17] rcutorture: Make object_debug also double call_rcu() heap object paulmck
2021-01-06 17:17 ` [PATCH tip/core/rcu 14/17] torture: Clean up after torture-test CPU hotplugging paulmck
2021-01-06 17:17 ` [PATCH tip/core/rcu 15/17] torture: Maintain torture-specific set of CPUs-online books paulmck
2021-01-06 17:17 ` paulmck [this message]
2021-01-06 17:17 ` [PATCH tip/core/rcu 17/17] rcutorture: Add rcutree.use_softirq=0 to RUDE01 and TASKS01 paulmck

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=20210106171710.22239-16-paulmck@kernel.org \
    --to=paulmck@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=dhowells@redhat.com \
    --cc=edumazet@google.com \
    --cc=fweisbec@gmail.com \
    --cc=jiangshanlai@gmail.com \
    --cc=joel@joelfernandes.org \
    --cc=josh@joshtriplett.org \
    --cc=kernel-team@fb.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=mingo@kernel.org \
    --cc=oleg@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rcu@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    /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).