From nobody Mon Jun 15 18:06:00 2026 Received: from outboundhk.mxmail.xiaomi.com (outboundhk.mxmail.xiaomi.com [118.143.206.90]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 27E2A78F26 for ; Mon, 13 Apr 2026 02:49:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=118.143.206.90 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776048548; cv=none; b=t1cL5OE5EwT3Rm5H9xzr4U3LUfGZHam0Ih8bmJ3bDCAk4T2Gd/wwvJNbhhxD5kkgndaNd1MhyJ1pE1VNCl9bGjXyW9AvTgaV3ewCzRhaYOiXGHFyYYMTaf5hrrCj8UIafK9Pm6bkej9H+BSnYdIG0bnPx+7TnGJnHIA1mI4KTKw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776048548; c=relaxed/simple; bh=o3yN7ywJC7xhw5RtMghAwZbQAi0Ev9EY0iX8z5HAjOA=; h=From:To:CC:Subject:Date:Message-ID:MIME-Version:Content-Type; b=SbABSnKCyPewp0tGfiYSdtAP12ohhEAPfoJRFjP8U5wAC0+Ccfd8Iiw7aTkWusAFqF7ntGz3Huf//hvWBkDmMe5eya+Fu3SFPBDMHISw6tTTd6OvdUQYb2UqA4qM69dfejl5bMy64AMCU2b2hYZwunNz4+6fk9/zhK8Y7HQle3g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=xiaomi.com; spf=pass smtp.mailfrom=xiaomi.com; arc=none smtp.client-ip=118.143.206.90 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=xiaomi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=xiaomi.com X-CSE-ConnectionGUID: hd7Yngu+TyiCOs65SGTXAQ== X-CSE-MsgGUID: dj5Ez201Tj+n6/YqlNPL4w== X-IronPort-AV: E=Sophos;i="6.23,176,1770566400"; d="scan'208";a="146411986" From: Fang Xiang To: , , , , CC: , , , , , Subject: [PATCH] sched/fair: Add per-cgroup CPU bandwidth slice control via cpuctl.slice_ns Date: Mon, 13 Apr 2026 10:48:44 +0800 Message-ID: <20260413024844.12864-1-fangxiang3@xiaomi.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BJ-MBX05.mioffice.cn (10.237.8.125) To BJ-MBX15.mioffice.cn (10.237.8.135) Content-Type: text/plain; charset="utf-8" Introduce a new cgroup interface "cpu.slice_ns" that allows setting a per-task-group CPU scheduling slice in nanoseconds. This enables fine-grained control over CFS scheduler time slices on a per-cgroup basis, complementing the existing cpu.weight and cpu.max controls. The slice value is enforced within 0.1ms to 100ms. When set, all tasks within the cgroup inherit the custom slice, and newly added tasks are assigned the group's slice during sched_change_group(). Usage: # Set 10ms slice for a cgroup echo 10000000 > cpu.slice_ns # Read current slice (0 means default) cat cpu.slice_ns Signed-off-by: Fang Xiang --- kernel/sched/core.c | 24 ++++++++++++++++++++++++ kernel/sched/fair.c | 34 ++++++++++++++++++++++++++++++++++ kernel/sched/sched.h | 4 ++++ 3 files changed, 62 insertions(+) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 582c3847f483..14986786f98e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -9197,6 +9197,13 @@ static void sched_change_group(struct task_struct *t= sk) tg =3D autogroup_task_group(tsk, tg); tsk->sched_task_group =3D tg; =20 + if (tg->slice_ns) { + tsk->se.custom_slice =3D 1; + tsk->se.slice =3D tg->slice_ns; + } else { + tsk->se.custom_slice =3D 0; + } + #ifdef CONFIG_FAIR_GROUP_SCHED if (tsk->sched_class->task_change_group) tsk->sched_class->task_change_group(tsk); @@ -9974,6 +9981,18 @@ static int cpu_idle_write_s64(struct cgroup_subsys_s= tate *css, } #endif /* CONFIG_GROUP_SCHED_WEIGHT */ =20 +static u64 slice_ns_read_u64(struct cgroup_subsys_state *css, + struct cftype *cft) +{ + return css_tg(css)->slice_ns; +} + +static int slice_ns_write_u64(struct cgroup_subsys_state *css, + struct cftype *cft, u64 slice) +{ + return sched_group_set_slice(css, slice); +} + static struct cftype cpu_legacy_files[] =3D { #ifdef CONFIG_GROUP_SCHED_WEIGHT { @@ -10028,6 +10047,11 @@ static struct cftype cpu_legacy_files[] =3D { .write =3D cpu_uclamp_max_write, }, #endif + { + .name =3D "slice_ns", + .read_u64 =3D slice_ns_read_u64, + .write_u64 =3D slice_ns_write_u64, + }, { } /* Terminate */ }; =20 diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 292141f4aaa5..081ba87ca435 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -13798,6 +13798,40 @@ int sched_group_set_shares(struct task_group *tg, = unsigned long shares) return ret; } =20 +int sched_group_set_slice(struct cgroup_subsys_state *css, u64 slice) +{ + struct css_task_iter it; + struct task_struct *task; + struct task_group *tg =3D css_tg(css); + + if (tg =3D=3D &root_task_group) + return -EINVAL; + + if (slice < NSEC_PER_MSEC / 10 || + slice > NSEC_PER_MSEC * 100) + return -EINVAL; + + mutex_lock(&shares_mutex); + + if (tg->slice_ns =3D=3D slice) { + mutex_unlock(&shares_mutex); + return 0; + } + + tg->slice_ns =3D slice; + + css_task_iter_start(css, 0, &it); + while ((task =3D css_task_iter_next(&it))) { + task->se.custom_slice =3D 1; + task->se.slice =3D slice; + } + css_task_iter_end(&it); + + mutex_unlock(&shares_mutex); + + return 0; +} + int sched_group_set_idle(struct task_group *tg, long idle) { int i; diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index ed37ab9209e5..0ce806062864 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -512,6 +512,7 @@ struct task_group { #endif =20 struct cfs_bandwidth cfs_bandwidth; + u64 slice_ns; =20 #ifdef CONFIG_UCLAMP_TASK_GROUP /* The two decimal precision [%] value requested from user-space */ @@ -611,9 +612,12 @@ extern int sched_group_set_idle(struct task_group *tg,= long idle); =20 extern void set_task_rq_fair(struct sched_entity *se, struct cfs_rq *prev, struct cfs_rq *next); + +extern int sched_group_set_slice(struct cgroup_subsys_state *css, u64 slic= e); #else /* !CONFIG_FAIR_GROUP_SCHED: */ static inline int sched_group_set_shares(struct task_group *tg, unsigned l= ong shares) { return 0; } static inline int sched_group_set_idle(struct task_group *tg, long idle) {= return 0; } +static inline int sched_group_set_slice(struct cgroup_subsys_state *css, u= 64 slice) { return 0; } #endif /* !CONFIG_FAIR_GROUP_SCHED */ =20 #else /* !CONFIG_CGROUP_SCHED: */ --=20 2.34.1