mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] sched_ext: Skip per-CPU data allocation for built-in DSQs
@ 2026-08-27  8:23 Qiurong Fang
  2026-08-27  9:38 ` Zhan Xusheng
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Qiurong Fang @ 2026-08-27  8:23 UTC (permalink / raw)
  To: tj; +Cc: void, arighi, changwoo, sched-ext, linux-kernel

From: fangqiurong <fangqiurong@kylinos.cn>

Deferred reenqueue tracking is only supported for user DSQs:
schedule_dsq_reenq() serves the local DSQ through
sch->pcpu->deferred_reenq_local and rejects all other built-in DSQ
ids. Every built-in DSQ still carries nr_cpu_ids * sizeof(struct
scx_dsq_pcpu) bytes of dead per-CPU memory.

Skip the allocation for built-in DSQ ids.

Fixes: 30b0515342db ("sched_ext: Add per-CPU data to DSQs")
Signed-off-by: fangqiurong <fangqiurong@kylinos.cn>
---
 kernel/sched/ext/ext.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index c539d15cda63..eaa64b8193e1 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -5048,6 +5048,10 @@ s32 scx_init_dsq(struct scx_dispatch_q *dsq, u64 dsq_id, struct scx_sched *sch)
 	dsq->id = dsq_id;
 	dsq->sched = sch;
 
+	/* Deferred reenqueue tracking is only supported for user DSQs */
+	if (dsq_id & SCX_DSQ_FLAG_BUILTIN)
+		return 0;
+
 	dsq->pcpu = alloc_percpu(struct scx_dsq_pcpu);
 	if (!dsq->pcpu)
 		return -ENOMEM;
@@ -5066,6 +5070,9 @@ static void exit_dsq(struct scx_dispatch_q *dsq)
 {
 	s32 cpu;
 
+	if (!dsq->pcpu)
+		return;
+
 	for_each_possible_cpu(cpu) {
 		struct scx_dsq_pcpu *pcpu = per_cpu_ptr(dsq->pcpu, cpu);
 		struct scx_deferred_reenq_user *dru = &pcpu->deferred_reenq_user;
-- 
2.43.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] sched_ext: Skip per-CPU data allocation for built-in DSQs
  2026-08-27  8:23 [PATCH] sched_ext: Skip per-CPU data allocation for built-in DSQs Qiurong Fang
@ 2026-08-27  9:38 ` Zhan Xusheng
  2026-08-31 16:13 ` Tejun Heo
  2026-09-01  1:32 ` [PATCH v2] " Qiurong Fang
  2 siblings, 0 replies; 6+ messages in thread
From: Zhan Xusheng @ 2026-08-27  9:38 UTC (permalink / raw)
  To: fangqiurong
  Cc: tj, void, arighi, changwoo, sched-ext, linux-kernel, zhanxusheng

From: Zhan Xusheng <zhanxusheng@xiaomi.com>

On Thu, 27 Aug 2026 16:23:29 +0800, Qiurong Fang wrote:
> Every built-in DSQ still carries nr_cpu_ids * sizeof(struct
> scx_dsq_pcpu) bytes of dead per-CPU memory.

It is quadratic rather than linear, which is worth saying.  The number of
built-in DSQs scales with nr_cpu_ids too, because most of them are
initialised inside for_each_possible_cpu():

  ext.c:8681  SCX_DSQ_LOCAL
  ext.c:8683  SCX_DSQ_REJECT   (CONFIG_EXT_SUB_SCHED)
  ext.c:7172  SCX_DSQ_BYPASS
  sub.c:672   SCX_DSQ_RESCUE   (per rq, via scx_rescue_init())

Only SCX_DSQ_GLOBAL is a single instance.  Each of those then allocates
nr_cpu_ids entries, so what you drop is on the order of nr_cpu_ids^2
struct scx_dsq_pcpu, which on a large machine is a very different number
from the one the changelog suggests.

The guard holds.  ext.c:1130 is the only read of dsq->pcpu, and it already
sits under !(dsq->id & SCX_DSQ_FLAG_BUILTIN) at 1127, the complement of
what you skip on; the local DSQ branch above uses sch->pcpu instead.  All
five ids passed to scx_init_dsq() carry the flag (sched/ext.h:58-62), so
nothing is missed either.  exit_dsq() contains nothing but the pcpu walk
and the free, so the early return skips nothing else, and it is needed
rather than tidy: per_cpu_ptr(NULL, cpu) hands the loop an offset pointer
and list_empty() would read it, so relying on free_percpu(NULL) alone
would not do.

Two smaller things.  A Fixes: tag routes this to stable, which is more
than a memory saving asks for unless you see a correctness angle.  And the
mail header says "Qiurong Fang" while the From: and Signed-off-by in the
body say "fangqiurong".

Thanks,
Zhan Xusheng

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] sched_ext: Skip per-CPU data allocation for built-in DSQs
  2026-08-27  8:23 [PATCH] sched_ext: Skip per-CPU data allocation for built-in DSQs Qiurong Fang
  2026-08-27  9:38 ` Zhan Xusheng
@ 2026-08-31 16:13 ` Tejun Heo
  2026-09-01  1:32 ` [PATCH v2] " Qiurong Fang
  2 siblings, 0 replies; 6+ messages in thread
From: Tejun Heo @ 2026-08-31 16:13 UTC (permalink / raw)
  To: Qiurong Fang; +Cc: void, arighi, changwoo, sched-ext, linux-kernel

Hello,

On Thu, Aug 27, 2026 at 04:23:29PM +0800, Qiurong Fang wrote:
> From: fangqiurong <fangqiurong@kylinos.cn>
> 
> Deferred reenqueue tracking is only supported for user DSQs:
> schedule_dsq_reenq() serves the local DSQ through
> sch->pcpu->deferred_reenq_local and rejects all other built-in DSQ
> ids. Every built-in DSQ still carries nr_cpu_ids * sizeof(struct
> scx_dsq_pcpu) bytes of dead per-CPU memory.
> 
> Skip the allocation for built-in DSQ ids.

Let's rename it to dsq->pcpu_user while at it.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2] sched_ext: Skip per-CPU data allocation for built-in DSQs
  2026-08-27  8:23 [PATCH] sched_ext: Skip per-CPU data allocation for built-in DSQs Qiurong Fang
  2026-08-27  9:38 ` Zhan Xusheng
  2026-08-31 16:13 ` Tejun Heo
@ 2026-09-01  1:32 ` Qiurong Fang
  2026-09-01  2:20   ` Zhan Xusheng
  2026-09-02  6:57   ` Tejun Heo
  2 siblings, 2 replies; 6+ messages in thread
From: Qiurong Fang @ 2026-09-01  1:32 UTC (permalink / raw)
  To: tj
  Cc: fangqiurong, void, arighi, changwoo, sched-ext, linux-kernel,
	zhanxusheng

From: fangqiurong <fangqiurong@kylinos.cn>

Deferred reenqueue tracking is only supported for user DSQs:
schedule_dsq_reenq() serves the local DSQ through
sch->pcpu->deferred_reenq_local and rejects all other built-in DSQ
ids. Every DSQ still allocates nr_cpu_ids * sizeof(struct scx_dsq_pcpu)
bytes of per-CPU memory for it.

Skip the allocation for built-in DSQ ids. While at it, rename ->pcpu to
->pcpu_user so that the per-CPU data reads as user-DSQ only.

Signed-off-by: fangqiurong <fangqiurong@kylinos.cn>
---
v2: Rename ->pcpu to ->pcpu_user as suggested by Tejun. Describe the
    memory waste as quadratic as pointed out by Zhan Xusheng. Drop the
    Fixes: tag as this is a plain memory saving with no correctness
    impact.
---
 include/linux/sched/ext.h |  2 +-
 kernel/sched/ext/ext.c    | 20 ++++++++++++++------
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/include/linux/sched/ext.h b/include/linux/sched/ext.h
index 582d7cd4a983..3c793d51c000 100644
--- a/include/linux/sched/ext.h
+++ b/include/linux/sched/ext.h
@@ -91,7 +91,7 @@ struct scx_dispatch_q {
 	struct rhash_head	hash_node;
 	struct llist_node	free_node;
 	struct scx_sched	*sched;
-	struct scx_dsq_pcpu __percpu *pcpu;
+	struct scx_dsq_pcpu __percpu *pcpu_user;
 	struct rcu_head		rcu;
 };
 
diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index c539d15cda63..efb492876cd6 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -1127,7 +1127,8 @@ void schedule_dsq_reenq(struct scx_sched *sch, struct scx_dispatch_q *dsq,
 	} else if (!(dsq->id & SCX_DSQ_FLAG_BUILTIN)) {
 		rq = this_rq();
 
-		struct scx_dsq_pcpu *dsq_pcpu = per_cpu_ptr(dsq->pcpu, cpu_of(rq));
+		struct scx_dsq_pcpu *dsq_pcpu =
+			per_cpu_ptr(dsq->pcpu_user, cpu_of(rq));
 		struct scx_deferred_reenq_user *dru = &dsq_pcpu->deferred_reenq_user;
 
 		/*
@@ -5048,12 +5049,16 @@ s32 scx_init_dsq(struct scx_dispatch_q *dsq, u64 dsq_id, struct scx_sched *sch)
 	dsq->id = dsq_id;
 	dsq->sched = sch;
 
-	dsq->pcpu = alloc_percpu(struct scx_dsq_pcpu);
-	if (!dsq->pcpu)
+	/* Deferred reenqueue tracking is only supported for user DSQs */
+	if (dsq_id & SCX_DSQ_FLAG_BUILTIN)
+		return 0;
+
+	dsq->pcpu_user = alloc_percpu(struct scx_dsq_pcpu);
+	if (!dsq->pcpu_user)
 		return -ENOMEM;
 
 	for_each_possible_cpu(cpu) {
-		struct scx_dsq_pcpu *pcpu = per_cpu_ptr(dsq->pcpu, cpu);
+		struct scx_dsq_pcpu *pcpu = per_cpu_ptr(dsq->pcpu_user, cpu);
 
 		pcpu->dsq = dsq;
 		INIT_LIST_HEAD(&pcpu->deferred_reenq_user.node);
@@ -5066,8 +5071,11 @@ static void exit_dsq(struct scx_dispatch_q *dsq)
 {
 	s32 cpu;
 
+	if (!dsq->pcpu_user)
+		return;
+
 	for_each_possible_cpu(cpu) {
-		struct scx_dsq_pcpu *pcpu = per_cpu_ptr(dsq->pcpu, cpu);
+		struct scx_dsq_pcpu *pcpu = per_cpu_ptr(dsq->pcpu_user, cpu);
 		struct scx_deferred_reenq_user *dru = &pcpu->deferred_reenq_user;
 		struct rq *rq = cpu_rq(cpu);
 
@@ -5081,7 +5089,7 @@ static void exit_dsq(struct scx_dispatch_q *dsq)
 		}
 	}
 
-	free_percpu(dsq->pcpu);
+	free_percpu(dsq->pcpu_user);
 }
 
 static void free_dsq_rcufn(struct rcu_head *rcu)
-- 
2.43.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] sched_ext: Skip per-CPU data allocation for built-in DSQs
  2026-09-01  1:32 ` [PATCH v2] " Qiurong Fang
@ 2026-09-01  2:20   ` Zhan Xusheng
  2026-09-02  6:57   ` Tejun Heo
  1 sibling, 0 replies; 6+ messages in thread
From: Zhan Xusheng @ 2026-09-01  2:20 UTC (permalink / raw)
  To: fangqiurong
  Cc: tj, void, arighi, changwoo, sched-ext, linux-kernel, zhanxusheng

The v2 note says the waste is described as quadratic, but the changelog
still gives it per DSQ:

> Every DSQ still allocates nr_cpu_ids * sizeof(struct scx_dsq_pcpu)
> bytes of per-CPU memory for it.

Four of the five built-in ids come one per CPU: SCX_DSQ_BYPASS in the
for_each_possible_cpu() at ext.c:7173, SCX_DSQ_LOCAL and SCX_DSQ_REJECT in
the one at 8679, SCX_DSQ_RESCUE per rq in scx_rescue_init().  Only
SCX_DSQ_GLOBAL is per node.  So the total is nr_cpu_ids squared, and a
reader of the changelog as it stands will work out a factor of nr_cpu_ids.
Worth spelling out, since that is where the saving is.

The code is right.  scx_init_dsq() memsets the whole dsq first
(ext.c:5046) and sets lock, list, id and sched before the new early
return, so nothing a built-in id needs is skipped, and exit_dsq()'s
->pcpu_user test is the load-bearing kind: 7101, 5367 and 7334 all call it
with built-in DSQs.  The only reader of the per-CPU data, ext.c:1130, was
already behind the !(dsq->id & SCX_DSQ_FLAG_BUILTIN) test above it.

Reviewed-by: Zhan Xusheng <zhanxusheng@xiaomi.com>

Thanks,
Zhan Xusheng

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] sched_ext: Skip per-CPU data allocation for built-in DSQs
  2026-09-01  1:32 ` [PATCH v2] " Qiurong Fang
  2026-09-01  2:20   ` Zhan Xusheng
@ 2026-09-02  6:57   ` Tejun Heo
  1 sibling, 0 replies; 6+ messages in thread
From: Tejun Heo @ 2026-09-02  6:57 UTC (permalink / raw)
  To: Qiurong Fang
  Cc: void, arighi, changwoo, emil, zhanxusheng, sched-ext, linux-kernel

Applied to sched_ext/for-7.4 with Zhan's Reviewed-by added, the description
reworded to say the waste is quadratic in the CPU count, and the
scx_init_dsq() comment reworded as the local DSQ does track deferred reenqs,
just through sch->pcpu.

Thanks.

--
tejun

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-09-02  6:57 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-27  8:23 [PATCH] sched_ext: Skip per-CPU data allocation for built-in DSQs Qiurong Fang
2026-08-27  9:38 ` Zhan Xusheng
2026-08-31 16:13 ` Tejun Heo
2026-09-01  1:32 ` [PATCH v2] " Qiurong Fang
2026-09-01  2:20   ` Zhan Xusheng
2026-09-02  6:57   ` Tejun Heo

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®