Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sched/deadline: Generalize unique visiting of root domains

Bandwidth checks and updates that work on root domains currently employ
a cookie mechanism for efficiency. This mechanism is very much tied to
when root domains are first created and initialized.

Generalize the cookie mechanism so that it can be used also later at
runtime while updating root domains. Also, additionally guard it with
sched_domains_mutex, since domains need to be stable while updating them
(and it will be required for further dynamic changes).

Fixes: 53916d5fd3c0 ("sched/deadline: Check bandwidth overflow earlier for hotplug")
Reported-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Juri Lelli <juri.lelli@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Valentin Schneider <vschneid@redhat.com>
Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Tested-by: Waiman Long <longman@redhat.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Link: https://lore.kernel.org/r/Z9MQaiXPvEeW_v7x@jlelli-thinkpadt14gen4.remote.csb

authored by

Juri Lelli and committed by
Peter Zijlstra
45007c6f 56209334

+20 -12
+3
include/linux/sched/deadline.h
··· 37 37 38 38 #endif /* CONFIG_SMP */ 39 39 40 + extern u64 dl_cookie; 41 + extern bool dl_bw_visited(int cpu, u64 cookie); 42 + 40 43 #endif /* _LINUX_SCHED_DEADLINE_H */
+13 -10
kernel/sched/deadline.c
··· 166 166 } 167 167 } 168 168 169 - static inline bool dl_bw_visited(int cpu, u64 gen) 169 + static inline bool dl_bw_visited(int cpu, u64 cookie) 170 170 { 171 171 struct root_domain *rd = cpu_rq(cpu)->rd; 172 172 173 - if (rd->visit_gen == gen) 173 + if (rd->visit_cookie == cookie) 174 174 return true; 175 175 176 - rd->visit_gen = gen; 176 + rd->visit_cookie = cookie; 177 177 return false; 178 178 } 179 179 ··· 207 207 return SCHED_CAPACITY_SCALE; 208 208 } 209 209 210 - static inline bool dl_bw_visited(int cpu, u64 gen) 210 + static inline bool dl_bw_visited(int cpu, u64 cookie) 211 211 { 212 212 return false; 213 213 } ··· 3171 3171 #endif 3172 3172 }; 3173 3173 3174 - /* Used for dl_bw check and update, used under sched_rt_handler()::mutex */ 3175 - static u64 dl_generation; 3174 + /* 3175 + * Used for dl_bw check and update, used under sched_rt_handler()::mutex and 3176 + * sched_domains_mutex. 3177 + */ 3178 + u64 dl_cookie; 3176 3179 3177 3180 int sched_dl_global_validate(void) 3178 3181 { 3179 3182 u64 runtime = global_rt_runtime(); 3180 3183 u64 period = global_rt_period(); 3181 3184 u64 new_bw = to_ratio(period, runtime); 3182 - u64 gen = ++dl_generation; 3185 + u64 cookie = ++dl_cookie; 3183 3186 struct dl_bw *dl_b; 3184 3187 int cpu, cpus, ret = 0; 3185 3188 unsigned long flags; ··· 3195 3192 for_each_online_cpu(cpu) { 3196 3193 rcu_read_lock_sched(); 3197 3194 3198 - if (dl_bw_visited(cpu, gen)) 3195 + if (dl_bw_visited(cpu, cookie)) 3199 3196 goto next; 3200 3197 3201 3198 dl_b = dl_bw_of(cpu); ··· 3232 3229 void sched_dl_do_global(void) 3233 3230 { 3234 3231 u64 new_bw = -1; 3235 - u64 gen = ++dl_generation; 3232 + u64 cookie = ++dl_cookie; 3236 3233 struct dl_bw *dl_b; 3237 3234 int cpu; 3238 3235 unsigned long flags; ··· 3243 3240 for_each_possible_cpu(cpu) { 3244 3241 rcu_read_lock_sched(); 3245 3242 3246 - if (dl_bw_visited(cpu, gen)) { 3243 + if (dl_bw_visited(cpu, cookie)) { 3247 3244 rcu_read_unlock_sched(); 3248 3245 continue; 3249 3246 }
+2
kernel/sched/rt.c
··· 2910 2910 int ret; 2911 2911 2912 2912 mutex_lock(&mutex); 2913 + sched_domains_mutex_lock(); 2913 2914 old_period = sysctl_sched_rt_period; 2914 2915 old_runtime = sysctl_sched_rt_runtime; 2915 2916 ··· 2937 2936 sysctl_sched_rt_period = old_period; 2938 2937 sysctl_sched_rt_runtime = old_runtime; 2939 2938 } 2939 + sched_domains_mutex_unlock(); 2940 2940 mutex_unlock(&mutex); 2941 2941 2942 2942 return ret;
+1 -1
kernel/sched/sched.h
··· 998 998 * Also, some corner cases, like 'wrap around' is dangerous, but given 999 999 * that u64 is 'big enough'. So that shouldn't be a concern. 1000 1000 */ 1001 - u64 visit_gen; 1001 + u64 visit_cookie; 1002 1002 1003 1003 #ifdef HAVE_RT_PUSH_IPI 1004 1004 /*
+1 -1
kernel/sched/topology.c
··· 568 568 rd->rto_push_work = IRQ_WORK_INIT_HARD(rto_push_irq_work_func); 569 569 #endif 570 570 571 - rd->visit_gen = 0; 571 + rd->visit_cookie = 0; 572 572 init_dl_bw(&rd->dl_bw); 573 573 if (cpudl_init(&rd->cpudl) != 0) 574 574 goto free_rto_mask;