summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCheng-Yang Chou <yphbchou0911@gmail.com>2026-06-10 23:26:55 +0800
committerTejun Heo <tj@kernel.org>2026-06-24 12:48:32 -1000
commitda428d572e07bb9dd2d076297ef5700f6483aafd (patch)
tree2453f6e24090b95d65496d553148559c1adb733f
parenta5cc43414b38decd50bdd447e558358a6fbd5864 (diff)
sched_ext: Fix exit_cpu accuracy for lockup paths
handle_lockup() uses raw_smp_processor_id() for exit_cpu, which is wrong for two paths: - scx_hardlockup_irq_workfn() has the hung CPU in a local variable but irq_work may run elsewhere. Pass the local cpu explicitly. - scx_rcu_cpu_stall() records the detector CPU rather than the stalled one. Pass -1 for now. The next patch fixes this properly. Signed-off-by: Cheng-Yang Chou <yphbchou0911@gmail.com> Reviewed-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r--kernel/sched/ext/ext.c15
-rw-r--r--kernel/sched/ext/internal.h2
2 files changed, 9 insertions, 8 deletions
diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index f08ef32b9bd6..7044a591e4c5 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -5092,6 +5092,7 @@ bool scx_allow_ttwu_queue(const struct task_struct *p)
/**
* handle_lockup - sched_ext common lockup handler
+ * @exit_cpu: CPU to record in exit_info. Pass the stalled/hung CPU, not current.
* @fmt: format string
*
* Called on system stall or lockup condition and initiates abort of sched_ext
@@ -5101,7 +5102,7 @@ bool scx_allow_ttwu_queue(const struct task_struct *p)
* resolve the lockup. %false if sched_ext is not enabled or abort was already
* initiated by someone else.
*/
-static __printf(1, 2) bool handle_lockup(const char *fmt, ...)
+static __printf(2, 3) bool handle_lockup(int exit_cpu, const char *fmt, ...)
{
struct scx_sched *sch;
va_list args;
@@ -5117,7 +5118,7 @@ static __printf(1, 2) bool handle_lockup(const char *fmt, ...)
case SCX_ENABLING:
case SCX_ENABLED:
va_start(args, fmt);
- ret = scx_verror(sch, fmt, args);
+ ret = scx_vexit(sch, SCX_EXIT_ERROR, 0, exit_cpu, fmt, args);
va_end(args);
return ret;
default:
@@ -5139,7 +5140,7 @@ static __printf(1, 2) bool handle_lockup(const char *fmt, ...)
*/
bool scx_rcu_cpu_stall(void)
{
- return handle_lockup("RCU CPU stall detected!");
+ return handle_lockup(-1, "RCU CPU stall detected!");
}
/**
@@ -5154,11 +5155,13 @@ bool scx_rcu_cpu_stall(void)
*/
void scx_softlockup(u32 dur_s)
{
- if (!handle_lockup("soft lockup - CPU %d stuck for %us", smp_processor_id(), dur_s))
+ int cpu = smp_processor_id();
+
+ if (!handle_lockup(cpu, "soft lockup - CPU %d stuck for %us", cpu, dur_s))
return;
printk_deferred(KERN_ERR "sched_ext: Soft lockup - CPU %d stuck for %us, disabling BPF scheduler\n",
- smp_processor_id(), dur_s);
+ cpu, dur_s);
}
/*
@@ -5173,7 +5176,7 @@ static void scx_hardlockup_irq_workfn(struct irq_work *work)
{
int cpu = atomic_xchg(&scx_hardlockup_cpu, -1);
- if (cpu >= 0 && handle_lockup("hard lockup - CPU %d", cpu))
+ if (cpu >= 0 && handle_lockup(cpu, "hard lockup - CPU %d", cpu))
printk_deferred(KERN_ERR "sched_ext: Hard lockup - CPU %d, disabling BPF scheduler\n",
cpu);
}
diff --git a/kernel/sched/ext/internal.h b/kernel/sched/ext/internal.h
index f4ba67799b0f..65eceefcf5e2 100644
--- a/kernel/sched/ext/internal.h
+++ b/kernel/sched/ext/internal.h
@@ -1543,8 +1543,6 @@ __printf(5, 6) bool __scx_exit(struct scx_sched *sch, enum scx_exit_kind kind,
__scx_exit(sch, kind, exit_code, raw_smp_processor_id(), fmt, ##args)
#define scx_error(sch, fmt, args...) \
scx_exit((sch), SCX_EXIT_ERROR, 0, fmt, ##args)
-#define scx_verror(sch, fmt, args) \
- scx_vexit((sch), SCX_EXIT_ERROR, 0, raw_smp_processor_id(), fmt, args)
/*
* Return the rq currently locked from an scx callback, or NULL if no rq is