* [PATCH 0/2] CSD-lock updates for v7.3
@ 2026-07-16 0:44 Paul E. McKenney
2026-07-16 0:45 ` [PATCH 1/2] smp: Avoid invalid per-CPU CSD lookup with CSD lock debug Paul E. McKenney
2026-07-16 0:45 ` [PATCH 2/2] smp: Make CSD lock acquisition atomic for debug mode Paul E. McKenney
0 siblings, 2 replies; 6+ messages in thread
From: Paul E. McKenney @ 2026-07-16 0:44 UTC (permalink / raw)
To: linux-kernel
Cc: Thomas Gleixner, Chuyi Zhou, Ulf Hansson, Muchun Song,
Joel Fernandes, Marco Crivellari, Rafael J. Wysocki
Hello!
This series provides CSD-lock diagnostic updates for v7.3:
1. Avoid invalid per-CPU CSD lookup with CSD lock debug, courtesy
of Chuyi Zhou.
2. Make CSD lock acquisition atomic for debug mode, courtesy of
Chuyi Zhou.
Thanx, Paul
------------------------------------------------------------------------
b/kernel/smp.c | 3 ++-
kernel/smp.c | 26 ++++++++++++++++++++++----
2 files changed, 24 insertions(+), 5 deletions(-)
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] smp: Avoid invalid per-CPU CSD lookup with CSD lock debug
2026-07-16 0:44 [PATCH 0/2] CSD-lock updates for v7.3 Paul E. McKenney
@ 2026-07-16 0:45 ` Paul E. McKenney
2026-07-22 18:58 ` [tip: smp/urgent] " tip-bot2 for Chuyi Zhou
2026-07-16 0:45 ` [PATCH 2/2] smp: Make CSD lock acquisition atomic for debug mode Paul E. McKenney
1 sibling, 1 reply; 6+ messages in thread
From: Paul E. McKenney @ 2026-07-16 0:45 UTC (permalink / raw)
To: linux-kernel
Cc: Thomas Gleixner, Chuyi Zhou, Ulf Hansson, Muchun Song,
Joel Fernandes, Marco Crivellari, Rafael J. Wysocki,
Paul E . McKenney
From: Chuyi Zhou <zhouchuyi@bytedance.com>
Commit b0473dcd4b1d ("smp: Improve smp_call_function_single()
CSD-lock diagnostics") made smp_call_function_single() use the destination
CPU's csd_data when CSD lock debugging is enabled. That lets the debug code
associate a stuck CSD lock with the target CPU, but it also means the CPU
argument is used in per_cpu_ptr() before generic_exec_single() has a chance
to validate it.
This becomes unsafe when smp_call_function_any() cannot find an online CPU
in the supplied mask. In that case the selected CPU can be nr_cpu_ids, and
the !wait path calls get_single_csd_data(cpu) before generic_exec_single()
returns -ENXIO. With csdlock_debug_enabled set, that indexes the per-CPU
offset array with an invalid CPU number.
Use the destination CPU's csd_data only when the CPU number is within
nr_cpu_ids. For invalid CPU numbers, fall back to the local CPU's csd_data
and let generic_exec_single() perform the existing validation and return
-ENXIO.
Fixes: b0473dcd4b1d ("smp: Improve smp_call_function_single() CSD-lock diagnostics")
Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com>
Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
Acked-by: Muchun Song <muchun.song@linux.dev>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
kernel/smp.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/smp.c b/kernel/smp.c
index a0bb56bd8ddadb..dc6582bb35d084 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -380,7 +380,8 @@ static DEFINE_PER_CPU_SHARED_ALIGNED(call_single_data_t, csd_data);
#ifdef CONFIG_CSD_LOCK_WAIT_DEBUG
static call_single_data_t *get_single_csd_data(int cpu)
{
- if (static_branch_unlikely(&csdlock_debug_enabled))
+ if (static_branch_unlikely(&csdlock_debug_enabled) &&
+ (unsigned int)cpu < nr_cpu_ids)
return per_cpu_ptr(&csd_data, cpu);
return this_cpu_ptr(&csd_data);
}
--
2.40.1
^ permalink raw reply [flat|nested] 6+ messages in thread* [tip: smp/urgent] smp: Avoid invalid per-CPU CSD lookup with CSD lock debug
2026-07-16 0:45 ` [PATCH 1/2] smp: Avoid invalid per-CPU CSD lookup with CSD lock debug Paul E. McKenney
@ 2026-07-22 18:58 ` tip-bot2 for Chuyi Zhou
0 siblings, 0 replies; 6+ messages in thread
From: tip-bot2 for Chuyi Zhou @ 2026-07-22 18:58 UTC (permalink / raw)
To: linux-tip-commits
Cc: Chuyi Zhou, Paul E. McKenney, Thomas Gleixner, Muchun Song, x86,
linux-kernel
The following commit has been merged into the smp/urgent branch of tip:
Commit-ID: c58ea9adf7342508c6ac0b7ad79ef10d589f9c6e
Gitweb: https://git.kernel.org/tip/c58ea9adf7342508c6ac0b7ad79ef10d589f9c6e
Author: Chuyi Zhou <zhouchuyi@bytedance.com>
AuthorDate: Wed, 15 Jul 2026 17:45:38 -07:00
Committer: Thomas Gleixner <tglx@kernel.org>
CommitterDate: Wed, 22 Jul 2026 20:57:07 +02:00
smp: Avoid invalid per-CPU CSD lookup with CSD lock debug
Commit b0473dcd4b1d ("smp: Improve smp_call_function_single()
CSD-lock diagnostics") made smp_call_function_single() use the destination
CPU's csd_data when CSD lock debugging is enabled. That lets the debug code
associate a stuck CSD lock with the target CPU, but it also means the CPU
argument is used in per_cpu_ptr() before generic_exec_single() has a chance
to validate it.
This becomes unsafe when smp_call_function_any() cannot find an online CPU
in the supplied mask. In that case the selected CPU can be nr_cpu_ids, and
the !wait path calls get_single_csd_data(cpu) before generic_exec_single()
returns -ENXIO. With csdlock_debug_enabled set, that indexes the per-CPU
offset array with an invalid CPU number.
Use the destination CPU's csd_data only when the CPU number is within
nr_cpu_ids. For invalid CPU numbers, fall back to the local CPU's csd_data
and let generic_exec_single() perform the existing validation and return
-ENXIO.
Fixes: b0473dcd4b1d ("smp: Improve smp_call_function_single() CSD-lock diagnostics")
Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
Acked-by: Muchun Song <muchun.song@linux.dev>
Link: https://patch.msgid.link/20260716004539.13983-1-paulmck@kernel.org
---
kernel/smp.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/smp.c b/kernel/smp.c
index a0bb56b..dc6582b 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -380,7 +380,8 @@ static DEFINE_PER_CPU_SHARED_ALIGNED(call_single_data_t, csd_data);
#ifdef CONFIG_CSD_LOCK_WAIT_DEBUG
static call_single_data_t *get_single_csd_data(int cpu)
{
- if (static_branch_unlikely(&csdlock_debug_enabled))
+ if (static_branch_unlikely(&csdlock_debug_enabled) &&
+ (unsigned int)cpu < nr_cpu_ids)
return per_cpu_ptr(&csd_data, cpu);
return this_cpu_ptr(&csd_data);
}
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] smp: Make CSD lock acquisition atomic for debug mode
2026-07-16 0:44 [PATCH 0/2] CSD-lock updates for v7.3 Paul E. McKenney
2026-07-16 0:45 ` [PATCH 1/2] smp: Avoid invalid per-CPU CSD lookup with CSD lock debug Paul E. McKenney
@ 2026-07-16 0:45 ` Paul E. McKenney
2026-07-22 18:58 ` [tip: smp/urgent] " tip-bot2 for Chuyi Zhou
1 sibling, 1 reply; 6+ messages in thread
From: Paul E. McKenney @ 2026-07-16 0:45 UTC (permalink / raw)
To: linux-kernel
Cc: Thomas Gleixner, Chuyi Zhou, Ulf Hansson, Muchun Song,
Joel Fernandes, Marco Crivellari, Rafael J. Wysocki,
Paul E . McKenney
From: Chuyi Zhou <zhouchuyi@bytedance.com>
Commit b0473dcd4b1d ("smp: Improve smp_call_function_single()
CSD-lock diagnostics") changed smp_call_function_single() so that,
when CSD lock debugging is enabled, async !wait calls use the
destination CPU csd_data. That improves diagnostics, but it also removes
the single-writer property that made the old csd_lock() safe: multiple
CPUs can now prepare the same destination CPU CSD concurrently.
csd_lock() currently waits for CSD_FLAG_LOCK to clear and then sets the
bit with a non-atomic read-modify-write. Two senders can both see an
unlocked CSD, set the bit, overwrite the callback fields, and enqueue
the same llist node. Re-adding a node that is already the queue head can
make node->next point to itself, leaving the target CPU stuck walking
call_single_queue. Later synchronous work, such as a TLB shootdown, can
then remain queued and trigger soft-lockup warnings or panics.
Keep the single csd_lock() implementation, but when CSD lock debugging is
enabled, acquire CSD_FLAG_LOCK with try_cmpxchg_acquire(). This makes the
destination CPU CSD a real atomic lock in the only configuration where it
can be shared by multiple remote senders, while preserving the existing
non-debug fast path.
Fixes: b0473dcd4b1d ("smp: Improve smp_call_function_single() CSD-lock diagnostics")
Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
kernel/smp.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/kernel/smp.c b/kernel/smp.c
index dc6582bb35d084..b9448fe3b84ff5 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -137,10 +137,10 @@ csd_do_func(smp_call_func_t func, void *info, call_single_data_t *csd)
trace_csd_function_exit(func, csd);
}
-#ifdef CONFIG_CSD_LOCK_WAIT_DEBUG
-
static DEFINE_STATIC_KEY_MAYBE(CONFIG_CSD_LOCK_WAIT_DEBUG_DEFAULT, csdlock_debug_enabled);
+#ifdef CONFIG_CSD_LOCK_WAIT_DEBUG
+
/*
* Parse the csdlock_debug= kernel boot parameter.
*
@@ -342,6 +342,10 @@ static __always_inline void csd_lock_wait(call_single_data_t *csd)
smp_cond_load_acquire(&csd->node.u_flags, !(VAL & CSD_FLAG_LOCK));
}
#else
+static __always_inline void __csd_lock_wait(call_single_data_t *csd)
+{
+}
+
static void csd_lock_record(call_single_data_t *csd)
{
}
@@ -354,8 +358,22 @@ static __always_inline void csd_lock_wait(call_single_data_t *csd)
static __always_inline void csd_lock(call_single_data_t *csd)
{
- csd_lock_wait(csd);
- csd->node.u_flags |= CSD_FLAG_LOCK;
+ if (IS_ENABLED(CONFIG_CSD_LOCK_WAIT_DEBUG) &&
+ static_branch_unlikely(&csdlock_debug_enabled)) {
+ unsigned int flags;
+
+ for (;;) {
+ __csd_lock_wait(csd);
+ flags = READ_ONCE(csd->node.u_flags);
+ if (!(flags & CSD_FLAG_LOCK) &&
+ try_cmpxchg_acquire(&csd->node.u_flags, &flags,
+ flags | CSD_FLAG_LOCK))
+ break;
+ }
+ } else {
+ csd_lock_wait(csd);
+ csd->node.u_flags |= CSD_FLAG_LOCK;
+ }
/*
* prevent CPU from reordering the above assignment
--
2.40.1
^ permalink raw reply [flat|nested] 6+ messages in thread* [tip: smp/urgent] smp: Make CSD lock acquisition atomic for debug mode
2026-07-16 0:45 ` [PATCH 2/2] smp: Make CSD lock acquisition atomic for debug mode Paul E. McKenney
@ 2026-07-22 18:58 ` tip-bot2 for Chuyi Zhou
0 siblings, 0 replies; 6+ messages in thread
From: tip-bot2 for Chuyi Zhou @ 2026-07-22 18:58 UTC (permalink / raw)
To: linux-tip-commits
Cc: Chuyi Zhou, Paul E. McKenney, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the smp/urgent branch of tip:
Commit-ID: 35551efb155e3b83445a6c3f66cb498d5efc182c
Gitweb: https://git.kernel.org/tip/35551efb155e3b83445a6c3f66cb498d5efc182c
Author: Chuyi Zhou <zhouchuyi@bytedance.com>
AuthorDate: Wed, 15 Jul 2026 17:45:39 -07:00
Committer: Thomas Gleixner <tglx@kernel.org>
CommitterDate: Wed, 22 Jul 2026 20:57:08 +02:00
smp: Make CSD lock acquisition atomic for debug mode
Commit b0473dcd4b1d ("smp: Improve smp_call_function_single()
CSD-lock diagnostics") changed smp_call_function_single() so that,
when CSD lock debugging is enabled, async !wait calls use the
destination CPU csd_data. That improves diagnostics, but it also removes
the single-writer property that made the old csd_lock() safe: multiple
CPUs can now prepare the same destination CPU CSD concurrently.
csd_lock() currently waits for CSD_FLAG_LOCK to clear and then sets the
bit with a non-atomic read-modify-write. Two senders can both see an
unlocked CSD, set the bit, overwrite the callback fields, and enqueue
the same llist node. Re-adding a node that is already the queue head can
make node->next point to itself, leaving the target CPU stuck walking
call_single_queue. Later synchronous work, such as a TLB shootdown, can
then remain queued and trigger soft-lockup warnings or panics.
Keep the single csd_lock() implementation, but when CSD lock debugging is
enabled, acquire CSD_FLAG_LOCK with try_cmpxchg_acquire(). This makes the
destination CPU CSD a real atomic lock in the only configuration where it
can be shared by multiple remote senders, while preserving the existing
non-debug fast path.
Fixes: b0473dcd4b1d ("smp: Improve smp_call_function_single() CSD-lock diagnostics")
Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Link: https://patch.msgid.link/20260716004539.13983-2-paulmck@kernel.org
---
kernel/smp.c | 27 +++++++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/kernel/smp.c b/kernel/smp.c
index dc6582b..52dffc8 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -137,10 +137,10 @@ csd_do_func(smp_call_func_t func, void *info, call_single_data_t *csd)
trace_csd_function_exit(func, csd);
}
-#ifdef CONFIG_CSD_LOCK_WAIT_DEBUG
-
static DEFINE_STATIC_KEY_MAYBE(CONFIG_CSD_LOCK_WAIT_DEBUG_DEFAULT, csdlock_debug_enabled);
+#ifdef CONFIG_CSD_LOCK_WAIT_DEBUG
+
/*
* Parse the csdlock_debug= kernel boot parameter.
*
@@ -342,6 +342,10 @@ static __always_inline void csd_lock_wait(call_single_data_t *csd)
smp_cond_load_acquire(&csd->node.u_flags, !(VAL & CSD_FLAG_LOCK));
}
#else
+static __always_inline void __csd_lock_wait(call_single_data_t *csd)
+{
+}
+
static void csd_lock_record(call_single_data_t *csd)
{
}
@@ -354,8 +358,23 @@ static __always_inline void csd_lock_wait(call_single_data_t *csd)
static __always_inline void csd_lock(call_single_data_t *csd)
{
- csd_lock_wait(csd);
- csd->node.u_flags |= CSD_FLAG_LOCK;
+ if (IS_ENABLED(CONFIG_CSD_LOCK_WAIT_DEBUG) &&
+ static_branch_unlikely(&csdlock_debug_enabled)) {
+
+ for (;;) {
+ unsigned int flags;
+
+ __csd_lock_wait(csd);
+ flags = READ_ONCE(csd->node.u_flags);
+
+ if (!(flags & CSD_FLAG_LOCK) &&
+ try_cmpxchg_acquire(&csd->node.u_flags, &flags, flags | CSD_FLAG_LOCK))
+ break;
+ }
+ } else {
+ csd_lock_wait(csd);
+ csd->node.u_flags |= CSD_FLAG_LOCK;
+ }
/*
* prevent CPU from reordering the above assignment
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 0/2] smp: Fix CSD lock debug regressions
@ 2026-06-08 11:23 Chuyi Zhou
2026-06-08 11:23 ` [PATCH 1/2] smp: Avoid invalid per-CPU CSD lookup with CSD lock debug Chuyi Zhou
0 siblings, 1 reply; 6+ messages in thread
From: Chuyi Zhou @ 2026-06-08 11:23 UTC (permalink / raw)
To: tglx, mingo, luto, peterz, paulmck, muchun.song; +Cc: linux-kernel, Chuyi Zhou
This series fixes two regressions introduced by commit b0473dcd4b1d
("smp: Improve smp_call_function_single() CSD-lock diagnostics").
That commit made smp_call_function_single() use the destination CPU's
csd_data while CSD lock debugging is enabled. This improves diagnostics,
but it changes two assumptions that the existing code relied on.
The first patch keeps invalid CPU numbers from being used for the
destination CPU csd_data lookup before generic_exec_single() has a chance
to reject them. This preserves the existing -ENXIO path for callers such
as smp_call_function_any() when no online CPU can be selected.
The second patch makes csd_lock() acquire CSD_FLAG_LOCK atomically in the
debug configuration. With destination CPU csd_data, multiple remote CPUs
can concurrently send async calls to the same target CPU and therefore
contend for the same CSD object. The old non-atomic wait-then-set sequence
can let two senders enqueue the same llist node, corrupting
call_single_queue and leaving later synchronous callbacks stuck behind it.
The non-debug fast path keeps the existing wait-then-set sequence.
Chuyi Zhou (2):
smp: Avoid invalid per-CPU CSD lookup with CSD lock debug
smp: Make CSD lock acquisition atomic for debug mode
kernel/smp.c | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)
--
2.20.1
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 1/2] smp: Avoid invalid per-CPU CSD lookup with CSD lock debug
2026-06-08 11:23 [PATCH 0/2] smp: Fix CSD lock debug regressions Chuyi Zhou
@ 2026-06-08 11:23 ` Chuyi Zhou
0 siblings, 0 replies; 6+ messages in thread
From: Chuyi Zhou @ 2026-06-08 11:23 UTC (permalink / raw)
To: tglx, mingo, luto, peterz, paulmck, muchun.song; +Cc: linux-kernel, Chuyi Zhou
Commit b0473dcd4b1d ("smp: Improve smp_call_function_single()
CSD-lock diagnostics") made smp_call_function_single() use the destination
CPU's csd_data when CSD lock debugging is enabled. That lets the debug code
associate a stuck CSD lock with the target CPU, but it also means the CPU
argument is used in per_cpu_ptr() before generic_exec_single() has a chance
to validate it.
This becomes unsafe when smp_call_function_any() cannot find an online CPU
in the supplied mask. In that case the selected CPU can be nr_cpu_ids, and
the !wait path calls get_single_csd_data(cpu) before generic_exec_single()
returns -ENXIO. With csdlock_debug_enabled set, that indexes the per-CPU
offset array with an invalid CPU number.
Use the destination CPU's csd_data only when the CPU number is within
nr_cpu_ids. For invalid CPU numbers, fall back to the local CPU's csd_data
and let generic_exec_single() perform the existing validation and return
-ENXIO.
Fixes: b0473dcd4b1d ("smp: Improve smp_call_function_single() CSD-lock diagnostics")
Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com>
Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
Acked-by: Muchun Song <muchun.song@linux.dev>
---
kernel/smp.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/smp.c b/kernel/smp.c
index a0bb56bd8dda..dc6582bb35d0 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -380,7 +380,8 @@ static DEFINE_PER_CPU_SHARED_ALIGNED(call_single_data_t, csd_data);
#ifdef CONFIG_CSD_LOCK_WAIT_DEBUG
static call_single_data_t *get_single_csd_data(int cpu)
{
- if (static_branch_unlikely(&csdlock_debug_enabled))
+ if (static_branch_unlikely(&csdlock_debug_enabled) &&
+ (unsigned int)cpu < nr_cpu_ids)
return per_cpu_ptr(&csd_data, cpu);
return this_cpu_ptr(&csd_data);
}
--
2.20.1
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-07-22 18:58 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-16 0:44 [PATCH 0/2] CSD-lock updates for v7.3 Paul E. McKenney
2026-07-16 0:45 ` [PATCH 1/2] smp: Avoid invalid per-CPU CSD lookup with CSD lock debug Paul E. McKenney
2026-07-22 18:58 ` [tip: smp/urgent] " tip-bot2 for Chuyi Zhou
2026-07-16 0:45 ` [PATCH 2/2] smp: Make CSD lock acquisition atomic for debug mode Paul E. McKenney
2026-07-22 18:58 ` [tip: smp/urgent] " tip-bot2 for Chuyi Zhou
-- strict thread matches above, loose matches on Subject: below --
2026-06-08 11:23 [PATCH 0/2] smp: Fix CSD lock debug regressions Chuyi Zhou
2026-06-08 11:23 ` [PATCH 1/2] smp: Avoid invalid per-CPU CSD lookup with CSD lock debug Chuyi Zhou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®