* [PATCH 0/3] sched_ext: Harden scx_bpf_cpu_rq()
@ 2025-08-01 14:17 Christian Loehle
2025-08-01 14:17 ` [PATCH 1/3] sched_ext: Mark scx_bpf_cpu_rq as NULL returnable Christian Loehle
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Christian Loehle @ 2025-08-01 14:17 UTC (permalink / raw)
To: christian.loehle, linux-kernel, sched-ext, tj, void, arighi; +Cc: mingo, peterz
scx_bpf_cpu_rq() currently allows accessing struct rq fields without
holding the associated rq.
It is being used by scx_cosmos, scx_flash, scx_lavd, scx_layered, and
scx_tickless. Fortunately it is only ever used to fetch rq->curr.
So provide an alternative scx_bpf_remote_curr() that doesn't expose
struct rq and harden scx_bpf_cpu_rq() by ensuring we hold the rq lock.
This also simplifies scx code from:
rq = scx_bpf_cpu_rq(cpu);
if (!rq)
return;
p = rq->curr
if (!p)
return;
/* ... Do something with p */
into:
p = scx_bpf_remote_curr(cpu);
if (!p)
return;
/* ... Do something with p */
Patch 1 was previously submitted and can be applied independently of
the other two.
https://lore.kernel.org/lkml/43a9cbdc-5121-4dc8-8438-0f01c90a4687@arm.com/
https://lore.kernel.org/lkml/0b8111c6-1b14-41dc-a674-14a6361992b3@arm.com/
Christian Loehle (3):
sched_ext: Mark scx_bpf_cpu_rq as NULL returnable
sched_ext: Provide scx_bpf_remote_curr()
sched_ext: Guarantee rq lock on scx_bpf_cpu_rq()
kernel/sched/ext.c | 21 ++++++++++++++++++---
tools/sched_ext/include/scx/common.bpf.h | 1 +
2 files changed, 19 insertions(+), 3 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/3] sched_ext: Mark scx_bpf_cpu_rq as NULL returnable
2025-08-01 14:17 [PATCH 0/3] sched_ext: Harden scx_bpf_cpu_rq() Christian Loehle
@ 2025-08-01 14:17 ` Christian Loehle
2025-08-01 14:17 ` [PATCH 2/3] sched_ext: Provide scx_bpf_remote_curr() Christian Loehle
` (2 subsequent siblings)
3 siblings, 0 replies; 9+ messages in thread
From: Christian Loehle @ 2025-08-01 14:17 UTC (permalink / raw)
To: christian.loehle, linux-kernel, sched-ext, tj, void, arighi; +Cc: mingo, peterz
scx_bpf_cpu_rq() obviously returns NULL on invalid cpu.
Mark it as such.
While kf_cpu_valid() will trigger scx_ops_error() that leads
to the BPF scheduler exiting, this isn't guaranteed to be immediate,
allowing for a dereference of a NULL scx_bpf_cpu_rq() return value.
Cc: stable@vger.kernel.org
Fixes: 6203ef73fa5c ("sched/ext: Add BPF function to fetch rq")
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
Acked-by: Andrea Righi <arighi@nvidia.com>
---
kernel/sched/ext.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
index 7dd5cbcb7a06..b734f55f3318 100644
--- a/kernel/sched/ext.c
+++ b/kernel/sched/ext.c
@@ -7599,7 +7599,7 @@ BTF_ID_FLAGS(func, scx_bpf_get_online_cpumask, KF_ACQUIRE)
BTF_ID_FLAGS(func, scx_bpf_put_cpumask, KF_RELEASE)
BTF_ID_FLAGS(func, scx_bpf_task_running, KF_RCU)
BTF_ID_FLAGS(func, scx_bpf_task_cpu, KF_RCU)
-BTF_ID_FLAGS(func, scx_bpf_cpu_rq)
+BTF_ID_FLAGS(func, scx_bpf_cpu_rq, KF_RET_NULL)
#ifdef CONFIG_CGROUP_SCHED
BTF_ID_FLAGS(func, scx_bpf_task_cgroup, KF_RCU | KF_ACQUIRE)
#endif
--
2.34.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] sched_ext: Provide scx_bpf_remote_curr()
2025-08-01 14:17 [PATCH 0/3] sched_ext: Harden scx_bpf_cpu_rq() Christian Loehle
2025-08-01 14:17 ` [PATCH 1/3] sched_ext: Mark scx_bpf_cpu_rq as NULL returnable Christian Loehle
@ 2025-08-01 14:17 ` Christian Loehle
2025-08-01 14:47 ` Andrea Righi
2025-08-01 14:17 ` [PATCH 3/3] sched_ext: Guarantee rq lock on scx_bpf_cpu_rq() Christian Loehle
2025-08-01 14:39 ` [PATCH 0/3] sched_ext: Harden scx_bpf_cpu_rq() Andrea Righi
3 siblings, 1 reply; 9+ messages in thread
From: Christian Loehle @ 2025-08-01 14:17 UTC (permalink / raw)
To: christian.loehle, linux-kernel, sched-ext, tj, void, arighi; +Cc: mingo, peterz
Provide scx_bpf_remote_curr() as a way for scx schedulers to
check the curr task of a remote rq, without assuming its lock
or acquiring any.
Many scx schedulers make use of scx_bpf_cpu_rq() to check a
remote curr (e.g. to see if it should be preempted). This is
problematic because scx_bpf_cpu_rq() provides access to all
fields of struct rq, most of which aren't safe to use without
holding the associated rq lock.
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
---
kernel/sched/ext.c | 15 +++++++++++++++
tools/sched_ext/include/scx/common.bpf.h | 1 +
2 files changed, 16 insertions(+)
diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
index b734f55f3318..92e66bb0b5f2 100644
--- a/kernel/sched/ext.c
+++ b/kernel/sched/ext.c
@@ -7436,6 +7436,20 @@ __bpf_kfunc struct rq *scx_bpf_cpu_rq(s32 cpu)
return cpu_rq(cpu);
}
+/**
+ * scx_bpf_remote_curr - Fetch the curr of a rq without acquiring its rq lock
+ * @cpu: CPU of the rq
+ *
+ * Neither a rq lock nor a task reference is acquired.
+ */
+__bpf_kfunc struct task_struct *scx_bpf_remote_curr(s32 cpu)
+{
+ if (!kf_cpu_valid(cpu, NULL))
+ return NULL;
+
+ return cpu_rq(cpu)->curr;
+}
+
/**
* scx_bpf_task_cgroup - Return the sched cgroup of a task
* @p: task of interest
@@ -7600,6 +7614,7 @@ BTF_ID_FLAGS(func, scx_bpf_put_cpumask, KF_RELEASE)
BTF_ID_FLAGS(func, scx_bpf_task_running, KF_RCU)
BTF_ID_FLAGS(func, scx_bpf_task_cpu, KF_RCU)
BTF_ID_FLAGS(func, scx_bpf_cpu_rq, KF_RET_NULL)
+BTF_ID_FLAGS(func, scx_bpf_remote_curr, KF_RET_NULL)
#ifdef CONFIG_CGROUP_SCHED
BTF_ID_FLAGS(func, scx_bpf_task_cgroup, KF_RCU | KF_ACQUIRE)
#endif
diff --git a/tools/sched_ext/include/scx/common.bpf.h b/tools/sched_ext/include/scx/common.bpf.h
index d4e21558e982..e5d4ef124532 100644
--- a/tools/sched_ext/include/scx/common.bpf.h
+++ b/tools/sched_ext/include/scx/common.bpf.h
@@ -91,6 +91,7 @@ s32 scx_bpf_pick_any_cpu(const cpumask_t *cpus_allowed, u64 flags) __ksym;
bool scx_bpf_task_running(const struct task_struct *p) __ksym;
s32 scx_bpf_task_cpu(const struct task_struct *p) __ksym;
struct rq *scx_bpf_cpu_rq(s32 cpu) __ksym;
+struct task_struct *scx_bpf_remote_curr(s32 cpu) __ksym;
struct cgroup *scx_bpf_task_cgroup(struct task_struct *p) __ksym __weak;
u64 scx_bpf_now(void) __ksym __weak;
void scx_bpf_events(struct scx_event_stats *events, size_t events__sz) __ksym __weak;
--
2.34.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/3] sched_ext: Guarantee rq lock on scx_bpf_cpu_rq()
2025-08-01 14:17 [PATCH 0/3] sched_ext: Harden scx_bpf_cpu_rq() Christian Loehle
2025-08-01 14:17 ` [PATCH 1/3] sched_ext: Mark scx_bpf_cpu_rq as NULL returnable Christian Loehle
2025-08-01 14:17 ` [PATCH 2/3] sched_ext: Provide scx_bpf_remote_curr() Christian Loehle
@ 2025-08-01 14:17 ` Christian Loehle
2025-08-01 14:51 ` Andrea Righi
2025-08-01 14:39 ` [PATCH 0/3] sched_ext: Harden scx_bpf_cpu_rq() Andrea Righi
3 siblings, 1 reply; 9+ messages in thread
From: Christian Loehle @ 2025-08-01 14:17 UTC (permalink / raw)
To: christian.loehle, linux-kernel, sched-ext, tj, void, arighi; +Cc: mingo, peterz
Most fields in scx_bpf_cpu_rq() assume that its rq_lock is held.
Furthermore they become meaningless without rq lock, too.
Only return scx_bpf_cpu_rq() when we hold rq lock of that rq.
All upstream scx schedulers can be converted into the new
scx_bpf_remote_curr() instead.
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
---
kernel/sched/ext.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
index 92e66bb0b5f2..627df3088fd0 100644
--- a/kernel/sched/ext.c
+++ b/kernel/sched/ext.c
@@ -7425,7 +7425,7 @@ __bpf_kfunc s32 scx_bpf_task_cpu(const struct task_struct *p)
}
/**
- * scx_bpf_cpu_rq - Fetch the rq of a CPU
+ * scx_bpf_cpu_rq - Fetch the rq of a CPU if its rq lock is currently held
* @cpu: CPU of the rq
*/
__bpf_kfunc struct rq *scx_bpf_cpu_rq(s32 cpu)
@@ -7433,7 +7433,7 @@ __bpf_kfunc struct rq *scx_bpf_cpu_rq(s32 cpu)
if (!kf_cpu_valid(cpu, NULL))
return NULL;
- return cpu_rq(cpu);
+ return this_cpu_read(locked_rq) == cpu_rq(cpu) ? cpu_rq(cpu) : NULL;
}
/**
--
2.34.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/3] sched_ext: Harden scx_bpf_cpu_rq()
2025-08-01 14:17 [PATCH 0/3] sched_ext: Harden scx_bpf_cpu_rq() Christian Loehle
` (2 preceding siblings ...)
2025-08-01 14:17 ` [PATCH 3/3] sched_ext: Guarantee rq lock on scx_bpf_cpu_rq() Christian Loehle
@ 2025-08-01 14:39 ` Andrea Righi
3 siblings, 0 replies; 9+ messages in thread
From: Andrea Righi @ 2025-08-01 14:39 UTC (permalink / raw)
To: Christian Loehle; +Cc: linux-kernel, sched-ext, tj, void, mingo, peterz
Hi Christian,
thanks for tackling this! Comments below.
On Fri, Aug 01, 2025 at 03:17:38PM +0100, Christian Loehle wrote:
> scx_bpf_cpu_rq() currently allows accessing struct rq fields without
> holding the associated rq.
> It is being used by scx_cosmos, scx_flash, scx_lavd, scx_layered, and
> scx_tickless. Fortunately it is only ever used to fetch rq->curr.
> So provide an alternative scx_bpf_remote_curr() that doesn't expose
> struct rq and harden scx_bpf_cpu_rq() by ensuring we hold the rq lock.
>
> This also simplifies scx code from:
>
> rq = scx_bpf_cpu_rq(cpu);
> if (!rq)
> return;
> p = rq->curr
> if (!p)
> return;
> /* ... Do something with p */
>
> into:
>
> p = scx_bpf_remote_curr(cpu);
> if (!p)
> return;
> /* ... Do something with p */
To be 100% correct I think we should do something similar to
bpf_task_from_pid(), acquire a reference to the task and release it via
bpf_task_release().
Basically:
p = scx_bpf_remote_curr(cpu);
if (!p)
return;
/* ... Do something with p */
bpf_task_release(p);
Thanks
-Andrea
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/3] sched_ext: Provide scx_bpf_remote_curr()
2025-08-01 14:17 ` [PATCH 2/3] sched_ext: Provide scx_bpf_remote_curr() Christian Loehle
@ 2025-08-01 14:47 ` Andrea Righi
2025-08-01 14:58 ` Christian Loehle
0 siblings, 1 reply; 9+ messages in thread
From: Andrea Righi @ 2025-08-01 14:47 UTC (permalink / raw)
To: Christian Loehle; +Cc: linux-kernel, sched-ext, tj, void, mingo, peterz
On Fri, Aug 01, 2025 at 03:17:40PM +0100, Christian Loehle wrote:
> Provide scx_bpf_remote_curr() as a way for scx schedulers to
> check the curr task of a remote rq, without assuming its lock
> or acquiring any.
>
> Many scx schedulers make use of scx_bpf_cpu_rq() to check a
> remote curr (e.g. to see if it should be preempted). This is
> problematic because scx_bpf_cpu_rq() provides access to all
> fields of struct rq, most of which aren't safe to use without
> holding the associated rq lock.
>
> Signed-off-by: Christian Loehle <christian.loehle@arm.com>
> ---
> kernel/sched/ext.c | 15 +++++++++++++++
> tools/sched_ext/include/scx/common.bpf.h | 1 +
> 2 files changed, 16 insertions(+)
>
> diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
> index b734f55f3318..92e66bb0b5f2 100644
> --- a/kernel/sched/ext.c
> +++ b/kernel/sched/ext.c
> @@ -7436,6 +7436,20 @@ __bpf_kfunc struct rq *scx_bpf_cpu_rq(s32 cpu)
> return cpu_rq(cpu);
> }
>
> +/**
> + * scx_bpf_remote_curr - Fetch the curr of a rq without acquiring its rq lock
> + * @cpu: CPU of the rq
> + *
> + * Neither a rq lock nor a task reference is acquired.
> + */
> +__bpf_kfunc struct task_struct *scx_bpf_remote_curr(s32 cpu)
> +{
> + if (!kf_cpu_valid(cpu, NULL))
> + return NULL;
> +
> + return cpu_rq(cpu)->curr;
> +}
As mentioned in my previou comment, this should be something like:
if (!kf_cpu_valid(cpu, NULL))
return NULL;
rcu_read_lock();
p = cpu_rq(cpu)->curr;
if (p)
p = bpf_task_acquire(p);
rcu_read_unlock();
return p;
We may still race with CPU hotplugging, but I think it's not always
possible to use cpus_read_lock/unlock() here. Also, most of the scx
schedulers are restarted on CPU hotplugging events, so... one thing at a
time. :)
> +
> /**
> * scx_bpf_task_cgroup - Return the sched cgroup of a task
> * @p: task of interest
> @@ -7600,6 +7614,7 @@ BTF_ID_FLAGS(func, scx_bpf_put_cpumask, KF_RELEASE)
> BTF_ID_FLAGS(func, scx_bpf_task_running, KF_RCU)
> BTF_ID_FLAGS(func, scx_bpf_task_cpu, KF_RCU)
> BTF_ID_FLAGS(func, scx_bpf_cpu_rq, KF_RET_NULL)
> +BTF_ID_FLAGS(func, scx_bpf_remote_curr, KF_RET_NULL)
> #ifdef CONFIG_CGROUP_SCHED
> BTF_ID_FLAGS(func, scx_bpf_task_cgroup, KF_RCU | KF_ACQUIRE)
> #endif
> diff --git a/tools/sched_ext/include/scx/common.bpf.h b/tools/sched_ext/include/scx/common.bpf.h
> index d4e21558e982..e5d4ef124532 100644
> --- a/tools/sched_ext/include/scx/common.bpf.h
> +++ b/tools/sched_ext/include/scx/common.bpf.h
> @@ -91,6 +91,7 @@ s32 scx_bpf_pick_any_cpu(const cpumask_t *cpus_allowed, u64 flags) __ksym;
> bool scx_bpf_task_running(const struct task_struct *p) __ksym;
> s32 scx_bpf_task_cpu(const struct task_struct *p) __ksym;
> struct rq *scx_bpf_cpu_rq(s32 cpu) __ksym;
> +struct task_struct *scx_bpf_remote_curr(s32 cpu) __ksym;
> struct cgroup *scx_bpf_task_cgroup(struct task_struct *p) __ksym __weak;
> u64 scx_bpf_now(void) __ksym __weak;
> void scx_bpf_events(struct scx_event_stats *events, size_t events__sz) __ksym __weak;
> --
> 2.34.1
>
-Andrea
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] sched_ext: Guarantee rq lock on scx_bpf_cpu_rq()
2025-08-01 14:17 ` [PATCH 3/3] sched_ext: Guarantee rq lock on scx_bpf_cpu_rq() Christian Loehle
@ 2025-08-01 14:51 ` Andrea Righi
2025-08-01 14:54 ` Christian Loehle
0 siblings, 1 reply; 9+ messages in thread
From: Andrea Righi @ 2025-08-01 14:51 UTC (permalink / raw)
To: Christian Loehle; +Cc: linux-kernel, sched-ext, tj, void, mingo, peterz
On Fri, Aug 01, 2025 at 03:17:41PM +0100, Christian Loehle wrote:
> Most fields in scx_bpf_cpu_rq() assume that its rq_lock is held.
> Furthermore they become meaningless without rq lock, too.
> Only return scx_bpf_cpu_rq() when we hold rq lock of that rq.
>
> All upstream scx schedulers can be converted into the new
> scx_bpf_remote_curr() instead.
>
> Signed-off-by: Christian Loehle <christian.loehle@arm.com>
> ---
> kernel/sched/ext.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
> index 92e66bb0b5f2..627df3088fd0 100644
> --- a/kernel/sched/ext.c
> +++ b/kernel/sched/ext.c
> @@ -7425,7 +7425,7 @@ __bpf_kfunc s32 scx_bpf_task_cpu(const struct task_struct *p)
> }
>
> /**
> - * scx_bpf_cpu_rq - Fetch the rq of a CPU
> + * scx_bpf_cpu_rq - Fetch the rq of a CPU if its rq lock is currently held
> * @cpu: CPU of the rq
> */
> __bpf_kfunc struct rq *scx_bpf_cpu_rq(s32 cpu)
> @@ -7433,7 +7433,7 @@ __bpf_kfunc struct rq *scx_bpf_cpu_rq(s32 cpu)
> if (!kf_cpu_valid(cpu, NULL))
> return NULL;
>
> - return cpu_rq(cpu);
> + return this_cpu_read(locked_rq) == cpu_rq(cpu) ? cpu_rq(cpu) : NULL;
Maybe we should consider an access to an unlocked rq as invalid and trigger
scx_exit(), similar to what we do with the kf_cpu_valid() check?
Also heads up that locked_rq has been renamed scx_locked_rq_state in 6.17.
> }
>
> /**
> --
> 2.34.1
>
Thanks,
-Andrea
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] sched_ext: Guarantee rq lock on scx_bpf_cpu_rq()
2025-08-01 14:51 ` Andrea Righi
@ 2025-08-01 14:54 ` Christian Loehle
0 siblings, 0 replies; 9+ messages in thread
From: Christian Loehle @ 2025-08-01 14:54 UTC (permalink / raw)
To: Andrea Righi; +Cc: linux-kernel, sched-ext, tj, void, mingo, peterz
On 8/1/25 15:51, Andrea Righi wrote:
> On Fri, Aug 01, 2025 at 03:17:41PM +0100, Christian Loehle wrote:
>> Most fields in scx_bpf_cpu_rq() assume that its rq_lock is held.
>> Furthermore they become meaningless without rq lock, too.
>> Only return scx_bpf_cpu_rq() when we hold rq lock of that rq.
>>
>> All upstream scx schedulers can be converted into the new
>> scx_bpf_remote_curr() instead.
>>
>> Signed-off-by: Christian Loehle <christian.loehle@arm.com>
>> ---
>> kernel/sched/ext.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
>> index 92e66bb0b5f2..627df3088fd0 100644
>> --- a/kernel/sched/ext.c
>> +++ b/kernel/sched/ext.c
>> @@ -7425,7 +7425,7 @@ __bpf_kfunc s32 scx_bpf_task_cpu(const struct task_struct *p)
>> }
>>
>> /**
>> - * scx_bpf_cpu_rq - Fetch the rq of a CPU
>> + * scx_bpf_cpu_rq - Fetch the rq of a CPU if its rq lock is currently held
>> * @cpu: CPU of the rq
>> */
>> __bpf_kfunc struct rq *scx_bpf_cpu_rq(s32 cpu)
>> @@ -7433,7 +7433,7 @@ __bpf_kfunc struct rq *scx_bpf_cpu_rq(s32 cpu)
>> if (!kf_cpu_valid(cpu, NULL))
>> return NULL;
>>
>> - return cpu_rq(cpu);
>> + return this_cpu_read(locked_rq) == cpu_rq(cpu) ? cpu_rq(cpu) : NULL;
>
> Maybe we should consider an access to an unlocked rq as invalid and trigger
> scx_exit(), similar to what we do with the kf_cpu_valid() check?
Makes sense to me!
>
> Also heads up that locked_rq has been renamed scx_locked_rq_state in 6.17.
Ah, thanks! I'll rebase!
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/3] sched_ext: Provide scx_bpf_remote_curr()
2025-08-01 14:47 ` Andrea Righi
@ 2025-08-01 14:58 ` Christian Loehle
0 siblings, 0 replies; 9+ messages in thread
From: Christian Loehle @ 2025-08-01 14:58 UTC (permalink / raw)
To: Andrea Righi; +Cc: linux-kernel, sched-ext, tj, void, mingo, peterz
On 8/1/25 15:47, Andrea Righi wrote:
> On Fri, Aug 01, 2025 at 03:17:40PM +0100, Christian Loehle wrote:
>> Provide scx_bpf_remote_curr() as a way for scx schedulers to
>> check the curr task of a remote rq, without assuming its lock
>> or acquiring any.
>>
>> Many scx schedulers make use of scx_bpf_cpu_rq() to check a
>> remote curr (e.g. to see if it should be preempted). This is
>> problematic because scx_bpf_cpu_rq() provides access to all
>> fields of struct rq, most of which aren't safe to use without
>> holding the associated rq lock.
>>
>> Signed-off-by: Christian Loehle <christian.loehle@arm.com>
>> ---
>> kernel/sched/ext.c | 15 +++++++++++++++
>> tools/sched_ext/include/scx/common.bpf. | 1 +
>> 2 files changed, 16 insertions(+)
>>
>> diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
>> index b734f55f3318..92e66bb0b5f2 100644
>> --- a/kernel/sched/ext.c
>> +++ b/kernel/sched/ext.c
>> @@ -7436,6 +7436,20 @@ __bpf_kfunc struct rq *scx_bpf_cpu_rq(s32 cpu)
>> return cpu_rq(cpu);
>> }
>>
>> +/**
>> + * scx_bpf_remote_curr - Fetch the curr of a rq without acquiring its rq lock
>> + * @cpu: CPU of the rq
>> + *
>> + * Neither a rq lock nor a task reference is acquired.
>> + */
>> +__bpf_kfunc struct task_struct *scx_bpf_remote_curr(s32 cpu)
>> +{
>> + if (!kf_cpu_valid(cpu, NULL))
>> + return NULL;
>> +
>> + return cpu_rq(cpu)->curr;
>> +}
>
> As mentioned in my previou comment, this should be something like:
>
> if (!kf_cpu_valid(cpu, NULL))
> return NULL;
>
> rcu_read_lock();
> p = cpu_rq(cpu)->curr;
> if (p)
> p = bpf_task_acquire(p);
> rcu_read_unlock();
>
> return p;
Alright, that's actually what I had at first, but went with the
drop-in-replacement that doesn't acquire.
I'll resend with an acquire.
Thanks, Andrea!
>
> We may still race with CPU hotplugging, but I think it's not always
> possible to use cpus_read_lock/unlock() here. Also, most of the scx
> schedulers are restarted on CPU hotplugging events, so... one thing at a
> time. :)
>
>> +
>> /**
>> * scx_bpf_task_cgroup - Return the sched cgroup of a task
>> * @p: task of interest
>> @@ -7600,6 +7614,7 @@ BTF_ID_FLAGS(func, scx_bpf_put_cpumask, KF_RELEASE)
>> BTF_ID_FLAGS(func, scx_bpf_task_running, KF_RCU)
>> BTF_ID_FLAGS(func, scx_bpf_task_cpu, KF_RCU)
>> BTF_ID_FLAGS(func, scx_bpf_cpu_rq, KF_RET_NULL)
>> +BTF_ID_FLAGS(func, scx_bpf_remote_curr, KF_RET_NULL)
>> #ifdef CONFIG_CGROUP_SCHED
>> BTF_ID_FLAGS(func, scx_bpf_task_cgroup, KF_RCU | KF_ACQUIRE)
>> #endif
>> diff --git a/tools/sched_ext/include/scx/common.bpf.h b/tools/sched_ext/include/scx/common.bpf.h
>> index d4e21558e982..e5d4ef124532 100644
>> --- a/tools/sched_ext/include/scx/common.bpf.h
>> +++ b/tools/sched_ext/include/scx/common.bpf.h
>> @@ -91,6 +91,7 @@ s32 scx_bpf_pick_any_cpu(const cpumask_t *cpus_allowed, u64 flags) __ksym;
>> bool scx_bpf_task_running(const struct task_struct *p) __ksym;
>> s32 scx_bpf_task_cpu(const struct task_struct *p) __ksym;
>> struct rq *scx_bpf_cpu_rq(s32 cpu) __ksym;
>> +struct task_struct *scx_bpf_remote_curr(s32 cpu) __ksym;
>> struct cgroup *scx_bpf_task_cgroup(struct task_struct *p) __ksym __weak;
>> u64 scx_bpf_now(void) __ksym __weak;
>> void scx_bpf_events(struct scx_event_stats *events, size_t events__sz) __ksym __weak;
>> --
>> 2.34.1
>>
>
> -Andrea
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-08-01 14:58 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-08-01 14:17 [PATCH 0/3] sched_ext: Harden scx_bpf_cpu_rq() Christian Loehle
2025-08-01 14:17 ` [PATCH 1/3] sched_ext: Mark scx_bpf_cpu_rq as NULL returnable Christian Loehle
2025-08-01 14:17 ` [PATCH 2/3] sched_ext: Provide scx_bpf_remote_curr() Christian Loehle
2025-08-01 14:47 ` Andrea Righi
2025-08-01 14:58 ` Christian Loehle
2025-08-01 14:17 ` [PATCH 3/3] sched_ext: Guarantee rq lock on scx_bpf_cpu_rq() Christian Loehle
2025-08-01 14:51 ` Andrea Righi
2025-08-01 14:54 ` Christian Loehle
2025-08-01 14:39 ` [PATCH 0/3] sched_ext: Harden scx_bpf_cpu_rq() Andrea Righi
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®