diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 507e4866ebb2..53b9e8218a2b 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c @@ -634,9 +634,11 @@ static void debugfs_fair_server_init(void) } #ifdef CONFIG_FAIR_GROUP_SCHED -static int cgroup_mode = 0; +static int cgroup_mode = 1; +/* See __sched_cgroup_mode_update(). */ static const char *cgroup_mode_str[] = { + "up", "smp", }; @@ -666,6 +668,7 @@ static ssize_t sched_cgroup_write(struct file *filp, const char __user *ubuf, if (mode < 0) return mode; + __sched_cgroup_mode_update(mode); WRITE_ONCE(cgroup_mode, mode); *ppos += cnt; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index e89edbd3ac38..3f8a2801f23e 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -4800,7 +4801,7 @@ static inline int throttled_hierarchy(struct cfs_rq *cfs_rq); * * hence icky! */ -static long calc_group_shares(struct cfs_rq *cfs_rq) +static long calc_smp_shares(struct cfs_rq *cfs_rq) { long tg_weight, tg_shares, load, shares; struct task_group *tg = cfs_rq->tg; @@ -4834,6 +4835,32 @@ static long calc_group_shares(struct cfs_rq *cfs_rq) return clamp_t(long, shares, MIN_SHARES, tg_shares); } +/* + * Ignore this pesky SMP stuff, use (4). + */ +static long calc_up_shares(struct cfs_rq *cfs_rq) +{ + struct task_group *tg = cfs_rq->tg; + return READ_ONCE(tg->shares); +} + +DEFINE_STATIC_CALL(calc_group_shares, calc_smp_shares); + +void __sched_cgroup_mode_update(int mode) +{ + long (*func)(struct cfs_rq *); + switch (mode) { + case 0: + func = &calc_up_shares; + break; + case 1: + default: + func = &calc_smp_shares; + break; + } + static_call_update(calc_group_shares, func); +} + /* * Recomputes the group entity based on the current state of its group * runqueue. @@ -4850,7 +4877,7 @@ static void update_cfs_group(struct sched_entity *se) if (!gcfs_rq || !gcfs_rq->load.weight) return; - shares = calc_group_shares(gcfs_rq); + shares = static_call(calc_group_shares)(gcfs_rq); if (unlikely(se->load.weight != shares)) reweight_entity(cfs_rq_of(se), se, shares); } diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 56acf502ba26..922170b2bf93 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -571,6 +571,7 @@ extern void free_fair_sched_group(struct task_group *tg); extern int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent); extern void online_fair_sched_group(struct task_group *tg); extern void unregister_fair_sched_group(struct task_group *tg); +extern void __sched_cgroup_mode_update(int mode); #else /* !CONFIG_FAIR_GROUP_SCHED: */ static inline void free_fair_sched_group(struct task_group *tg) { } static inline int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent)