Re: [PATCH v4 sched_ext/for-7.3 05/40] sched_ext: Add SCX_CALL_CID_OP_TASK() for cid-form op dispatch

Andrea Righi <[email protected]>
Newsgroups dev.linux.lists.sched-ext,org.kernel.vger.linux-kernel
Message-ID <alAHbgsxUZgAtMMW@gpd4>
On Wed, Jul 08, 2026 at 11:23:54AM -1000, Tejun Heo wrote:
> The cid-form ops overlay their cpu-form siblings at the same struct slot.
> Ops whose signature matches the sibling are invoked through the cpu-form
> call sites unchanged, but set_cmask() takes an arena cmask address rather
> than a cpumask, so scx_call_op_set_cpumask() calls ops_cid.set_cmask()
> directly and hand-rolled the kf_tasks[] and locked_rq bracket that
> SCX_CALL_OP_TASK() provides. The hand-rolled bracket reset locked_rq to
> NULL on exit instead of restoring the saved value, so a nested call would
> clobber the outer op's locked-rq tracking.
> 
> Parameterize the dispatch macros by the ops-table member and add
> SCX_CALL_CID_OP_TASK(), which routes through sch->ops_cid. Convert
> scx_call_op_set_cpumask() to it and drop the hand-rolled bracket. The only
> behavioral change is that locked_rq is now saved and restored like every
> other op call site.
> 
> Signed-off-by: Tejun Heo <[email protected]>

Reviewed-by: Andrea Righi <[email protected]>

Thanks,
-Andrea

> ---
>  kernel/sched/ext/ext.c      | 14 +++-----------
>  kernel/sched/ext/internal.h | 23 ++++++++++++++++++++---
>  2 files changed, 23 insertions(+), 14 deletions(-)
> 
> diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
> index f4725698f5ef..c050a68189d4 100644
> --- a/kernel/sched/ext/ext.c
> +++ b/kernel/sched/ext/ext.c
> @@ -410,11 +410,6 @@ static inline void scx_call_op_set_cpumask(struct scx_sched *sch, struct rq *rq,
>  					   struct task_struct *task,
>  					   const struct cpumask *cpumask)
>  {
> -	WARN_ON_ONCE(current->scx.kf_tasks[0]);
> -	current->scx.kf_tasks[0] = task;
> -	if (rq)
> -		update_locked_rq(rq);
> -
>  	if (scx_is_cid_type()) {
>  		struct scx_cmask *kern_va = *this_cpu_ptr(sch->set_cmask_scratch);
>  		/*
> @@ -423,14 +418,11 @@ static inline void scx_call_op_set_cpumask(struct scx_sched *sch, struct rq *rq,
>  		 * the sole user of the scratch area.
>  		 */
>  		scx_cpumask_to_cmask(cpumask, kern_va);
> -		sch->ops_cid.set_cmask(task, scx_kaddr_to_arena(sch, kern_va));
> +		SCX_CALL_CID_OP_TASK(sch, set_cmask, rq, task,
> +				     scx_kaddr_to_arena(sch, kern_va));
>  	} else {
> -		sch->ops.set_cpumask(task, cpumask);
> +		SCX_CALL_OP_TASK(sch, set_cpumask, rq, task, cpumask);
>  	}
> -
> -	if (rq)
> -		update_locked_rq(NULL);
> -	current->scx.kf_tasks[0] = NULL;
>  }
>  
>  enum scx_dsq_iter_flags {
> diff --git a/kernel/sched/ext/internal.h b/kernel/sched/ext/internal.h
> index f9fe7c6ebc4b..5ca44ad88786 100644
> --- a/kernel/sched/ext/internal.h
> +++ b/kernel/sched/ext/internal.h
> @@ -1751,8 +1751,11 @@ static inline void update_locked_rq(struct rq *rq)
>  /*
>   * SCX ops can recurse via scx_bpf_sub_dispatch() - the inner call must not
>   * clobber the outer's scx_locked_rq_state. Save it on entry, restore on exit.
> + *
> + * @ops is the ops table to dispatch through: ops for the cpu form, ops_cid
> + * for the cid form.
>   */
> -#define SCX_CALL_OP(sch, op, locked_rq, args...)				\
> +#define __SCX_CALL_OP(sch, ops, op, locked_rq, args...)				\
>  do {										\
>  	struct rq *__prev_locked_rq;						\
>  										\
> @@ -1765,6 +1768,9 @@ do {										\
>  		update_locked_rq(__prev_locked_rq);				\
>  } while (0)
>  
> +#define SCX_CALL_OP(sch, op, locked_rq, args...)				\
> +	__SCX_CALL_OP(sch, ops, op, locked_rq, ##args)
> +
>  #define SCX_CALL_OP_RET(sch, op, locked_rq, args...)				\
>  ({										\
>  	struct rq *__prev_locked_rq;						\
> @@ -1796,14 +1802,25 @@ do {										\
>   * WARN_ON_ONCE() in each macro catches a re-entry of any of the three variants
>   * while a previous one is still in progress.
>   */
> -#define SCX_CALL_OP_TASK(sch, op, locked_rq, task, args...)			\
> +#define __SCX_CALL_OP_TASK(sch, ops, op, locked_rq, task, args...)		\
>  do {										\
>  	WARN_ON_ONCE(current->scx.kf_tasks[0]);					\
>  	current->scx.kf_tasks[0] = task;					\
> -	SCX_CALL_OP((sch), op, locked_rq, task, ##args);			\
> +	__SCX_CALL_OP((sch), ops, op, locked_rq, task, ##args);			\
>  	current->scx.kf_tasks[0] = NULL;					\
>  } while (0)
>  
> +#define SCX_CALL_OP_TASK(sch, op, locked_rq, task, args...)			\
> +	__SCX_CALL_OP_TASK(sch, ops, op, locked_rq, task, ##args)
> +
> +/*
> + * Dispatch a task op through the cid-form ops_cid table. Only set_cmask() needs
> + * this: it takes an arena cmask address instead of a cpumask, so it cannot be
> + * invoked via its cpu-form set_cpumask() slot.
> + */
> +#define SCX_CALL_CID_OP_TASK(sch, op, locked_rq, task, args...)			\
> +	__SCX_CALL_OP_TASK(sch, ops_cid, op, locked_rq, task, ##args)
> +
>  #define SCX_CALL_OP_TASK_RET(sch, op, locked_rq, task, args...)			\
>  ({										\
>  	__typeof__((sch)->ops.op(task, ##args)) __ret;				\
> -- 
> 2.54.0
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.