On 27/04/2020 10:37, Dietmar Eggemann wrote: [...]
> diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c > index 4ae22bfc37ae..eb23e6921d94 100644 > --- a/kernel/sched/deadline.c > +++ b/kernel/sched/deadline.c > @@ -69,6 +69,25 @@ static inline int dl_bw_cpus(int i) > > return cpus; > } > + > +static inline unsigned long dl_bw_capacity(int i) > +{ > + struct root_domain *rd = cpu_rq(i)->rd; > + unsigned long cap; > + > + RCU_LOCKDEP_WARN(!rcu_read_lock_sched_held(), > + "sched RCU must be held"); > + > + if (cpumask_subset(rd->span, cpu_active_mask)) > + return rd->sum_cpu_capacity; > + > + cap = 0; > + > + for_each_cpu_and(i, rd->span, cpu_active_mask) > + cap += capacity_orig_of(i); > + > + return cap; > +} There is an issue w/ excl. cpusets and cpuset.sched_load_balance=0. The latter is needed to demonstrate the problem since DL task affinity can't be altered. A CPU in such a cpuset has its rq attached to def_root_domain which does not have its 'sum_cpu_capacity' properly set. root@juno:~# bash root@juno:~# ps -eo comm,pid,class | grep bash bash 1661 TS bash 2040 TS bash 2176 TS <-- root@juno:~# echo 2176 > /sys/fs/cgroup/cpuset/B/tasks root@juno:~# chrt -d --sched-runtime 8000 --sched-period 16000 -p 0 2176 chrt: failed to set pid 2176's policy: Device or resource busy ... sched_dl_overflow: [bash 2176] task_cpu=4 cpus_ptr=2,4-5 dl_bw_capacity() CPU4 dflt_rd->sum_cpu_capacity=0 <-- !!! dflt_rd->span=2,4-5 cpu_active_mask=0-5 ... OTHA, rd->span is properly set due to 'cpumask_clear_cpu(rq->cpu, old_rd->span) and cpumask_set_cpu(rq->cpu, rd->span)' in rq_attach_root(). It's not possible to treat 'rd->sum_cpu_capacity' like 'rd->span' since the former changes between sched domain teardown/bringup w/ asymmetric CPU capacity. What could be done is to return 'dl_bw_cpus(i) << SCHED_CAPACITY_SHIFT' w/ symmetric CPU capacity (of 1024) and to loop over rd->span otherwise. Latter includes symmetric cpusets w/ only little CPUs. ---8<--- diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index 575b7d88d839..6d17748cb7a1 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -70,24 +70,28 @@ static inline int dl_bw_cpus(int i) return cpus; } -static inline unsigned long dl_bw_capacity(int i) -{ +static inline unsigned long __dl_bw_capacity(int i) { struct root_domain *rd = cpu_rq(i)->rd; - unsigned long cap; + unsigned long cap = 0; RCU_LOCKDEP_WARN(!rcu_read_lock_sched_held(), "sched RCU must be held"); - if (cpumask_subset(rd->span, cpu_active_mask)) - return rd->sum_cpu_capacity; - - cap = 0; - for_each_cpu_and(i, rd->span, cpu_active_mask) cap += capacity_orig_of(i); return cap; } + +static inline unsigned long dl_bw_capacity(int i) +{ + if (!static_branch_unlikely(&sched_asym_cpucapacity) && + capacity_orig_of(i) == SCHED_CAPACITY_SCALE) { + return dl_bw_cpus(i) << SCHED_CAPACITY_SHIFT; + } else { + return __dl_bw_capacity(i); + } +} #else static inline struct dl_bw *dl_bw_of(int i) { -- 2.17.1