sched/fair: Add cgroup_mode: tasks

Since we are exploring this space; include a scheme that scales by total number
of runnable tasks. This results in:

	F_g_n' = M * F_g_n

This will obviously have: avg(F_g_n') > 1, (it will be ~M/N in fact).

And while that sounds odd, it actually has a fairly straight foward meaning for
"cpu.weight": average weight per member task.

This is an entirely valid and workable option, it is however wildly different
from the traditional meaning.

Included for completeness (and curiosity).

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260605124051.921991975%40infradead.org
This commit is contained in:
Peter Zijlstra
2026-06-05 10:35:01 +02:00
parent 5c0b58bd1c
commit 507f910a4e
2 changed files with 17 additions and 0 deletions

View File

@@ -642,6 +642,7 @@ static const char *cgroup_mode_str[] = {
"smp",
"concur",
"max",
"tasks",
};
static int sched_cgroup_mode(const char *str)

View File

@@ -4851,6 +4851,19 @@ static inline int tg_tasks(struct task_group *tg)
return max(1, atomic_long_read(&tg->runnable_avg) >> SCHED_CAPACITY_SHIFT);
}
/*
* Func: fraction(nr_tasks * tg->shares)
*
* Scale tg->shares by the number of tasks.
*/
static long calc_tasks_shares(struct cfs_rq *cfs_rq)
{
struct task_group *tg = cfs_rq->tg;
int nr = tg_tasks(tg);
long tg_shares = READ_ONCE(tg->shares);
return __calc_smp_shares(cfs_rq, nr * tg_shares, nr * tg_shares);
}
/*
* Func: min(fraction(nr_cpus * tg->shares), nice -20)
*
@@ -4921,6 +4934,9 @@ void __sched_cgroup_mode_update(int mode)
case 3:
func = &calc_max_shares;
break;
case 4:
func = &calc_tasks_shares;
break;
}
static_call_update(calc_group_shares, func);
}