From: Peter Zijlstra <peterz@infradead.org>
To: Aniket Gattani <aniketgattani@google.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
"Paul E . McKenney" <paulmck@kernel.org>,
Ingo Molnar <mingo@redhat.com>, Ben Segall <bsegall@google.com>,
Josh Don <joshdon@google.com>,
linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org
Subject: Re: [PATCH v2 1/2] sched/membarrier: Use per-CPU mutexes for targeted commands
Date: Tue, 28 Apr 2026 14:48:23 +0200 [thread overview]
Message-ID: <20260428124823.GY3102624@noisy.programming.kicks-ass.net> (raw)
In-Reply-To: <20260415232106.2803644-2-aniketgattani@google.com>
On Wed, Apr 15, 2026 at 11:21:05PM +0000, Aniket Gattani wrote:
> @@ -358,14 +371,19 @@ static int membarrier_private_expedited(int flags, int cpu_id)
> if (cpu_id < 0 && !zalloc_cpumask_var(&tmpmask, GFP_KERNEL))
> return -ENOMEM;
>
> - SERIALIZE_IPI();
> + if ((unsigned int)cpu_id >= nr_cpu_ids || !cpu_possible(cpu_id))
> + return 0;
Right, so this is broken, sorry about that. This makes the whole
cpu_id == -1 branch below dead code, and that cannot be right.
> + SERIALIZE_IPI_CPU(cpu_id);
> +
> cpus_read_lock();
>
> if (cpu_id >= 0) {
> struct task_struct *p;
>
> - if (cpu_id >= nr_cpu_ids || !cpu_online(cpu_id))
> + if (!cpu_online(cpu_id))
> goto out;
> +
> rcu_read_lock();
> p = rcu_dereference(cpu_rq(cpu_id)->curr);
> if (!p || p->mm != mm) {
How about something like so?
---
diff --git a/kernel/sched/membarrier.c b/kernel/sched/membarrier.c
index 623445603725..5b056fff7d1d 100644
--- a/kernel/sched/membarrier.c
+++ b/kernel/sched/membarrier.c
@@ -165,7 +165,20 @@
| MEMBARRIER_CMD_GET_REGISTRATIONS)
static DEFINE_MUTEX(membarrier_ipi_mutex);
+static DEFINE_PER_CPU(struct mutex, membarrier_cpu_mutexes);
+
#define SERIALIZE_IPI() guard(mutex)(&membarrier_ipi_mutex)
+#define SERIALIZE_IPI_CPU(cpu_id) guard(mutex)(&per_cpu(membarrier_cpu_mutexes, cpu_id))
+
+static int __init membarrier_init(void)
+{
+ int i;
+
+ for_each_possible_cpu(i)
+ mutex_init(&per_cpu(membarrier_cpu_mutexes, i));
+ return 0;
+}
+core_initcall(membarrier_init);
static void ipi_mb(void *info)
{
@@ -313,9 +326,10 @@ static int membarrier_global_expedited(void)
return 0;
}
+DEFINE_LOCK_GUARD_0(mb, smp_mb(), smp_mb())
+
static int membarrier_private_expedited(int flags, int cpu_id)
{
- cpumask_var_t tmpmask;
struct mm_struct *mm = current->mm;
smp_call_func_t ipi_func = ipi_mb;
@@ -352,30 +366,46 @@ static int membarrier_private_expedited(int flags, int cpu_id)
* On RISC-V, this barrier pairing is also needed for the
* SYNC_CORE command when switching between processes, cf.
* the inline comments in membarrier_arch_switch_mm().
+ *
+ * Memory barrier on the caller thread _after_ we finished
+ * waiting for the last IPI. Matches memory barriers before
+ * rq->curr modification in scheduler.
*/
- smp_mb(); /* system call entry is not a mb. */
-
- if (cpu_id < 0 && !zalloc_cpumask_var(&tmpmask, GFP_KERNEL))
- return -ENOMEM;
-
- SERIALIZE_IPI();
- cpus_read_lock();
+ guard(mb)();
+ guard(cpus_read_lock)();
if (cpu_id >= 0) {
struct task_struct *p;
- if (cpu_id >= nr_cpu_ids || !cpu_online(cpu_id))
- goto out;
+ if (cpu_id >= nr_cpu_ids)
+ return 0; // -EINVAL ?
+
+ if (!cpu_online(cpu_id))
+ return 0;
+
+ SERIALIZE_IPI_CPU(cpu_id);
+
rcu_read_lock();
p = rcu_dereference(cpu_rq(cpu_id)->curr);
if (!p || p->mm != mm) {
rcu_read_unlock();
- goto out;
+ return 0;
}
rcu_read_unlock();
+ /*
+ * smp_call_function_single() will call ipi_func() if cpu_id
+ * is the calling CPU.
+ */
+ smp_call_function_single(cpu_id, ipi_func, NULL, 1);
} else {
+ cpumask_var_t __free(free_cpumask_var) tmpmask = CPUMASK_VAR_NULL;
int cpu;
+ SERIALIZE_IPI();
+
+ if (!zalloc_cpumask_var(&tmpmask, GFP_KERNEL))
+ return -ENOMEM;
+
rcu_read_lock();
for_each_online_cpu(cpu) {
struct task_struct *p;
@@ -385,15 +415,6 @@ static int membarrier_private_expedited(int flags, int cpu_id)
__cpumask_set_cpu(cpu, tmpmask);
}
rcu_read_unlock();
- }
-
- if (cpu_id >= 0) {
- /*
- * smp_call_function_single() will call ipi_func() if cpu_id
- * is the calling CPU.
- */
- smp_call_function_single(cpu_id, ipi_func, NULL, 1);
- } else {
/*
* For regular membarrier, we can save a few cycles by
* skipping the current cpu -- we're about to do smp_mb()
@@ -420,18 +441,6 @@ static int membarrier_private_expedited(int flags, int cpu_id)
}
}
-out:
- if (cpu_id < 0)
- free_cpumask_var(tmpmask);
- cpus_read_unlock();
-
- /*
- * Memory barrier on the caller thread _after_ we finished
- * waiting for the last IPI. Matches memory barriers before
- * rq->curr modification in scheduler.
- */
- smp_mb(); /* exit from system call is not a mb */
-
return 0;
}
next prev parent reply other threads:[~2026-04-28 12:48 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-15 23:21 [PATCH v2 0/2] sched/membarrier: Use per-CPU mutexes for targeted commands Aniket Gattani
2026-04-15 23:21 ` [PATCH v2 1/2] " Aniket Gattani
2026-04-28 12:48 ` Peter Zijlstra [this message]
2026-04-30 0:12 ` Aniket Gattani
2026-04-15 23:21 ` [PATCH v2 2/2] selftests/membarrier: Add rseq stress test for CFS throttle interactions Aniket Gattani
2026-04-27 20:07 ` [PATCH v2] sched/membarrier: Use per-CPU mutexes for targeted commands Aniket Gattani
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=20260428124823.GY3102624@noisy.programming.kicks-ass.net \
--to=peterz@infradead.org \
--cc=aniketgattani@google.com \
--cc=bsegall@google.com \
--cc=joshdon@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mingo@redhat.com \
--cc=paulmck@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox