@@ -12186,11 +12186,27 @@ void update_max_interval(void)
1218612186 max_load_balance_interval = HZ * num_online_cpus ()/10 ;
1218712187}
1218812188
12189- static inline bool update_newidle_cost (struct sched_domain * sd , u64 cost )
12189+ static inline void update_newidle_stats (struct sched_domain * sd , unsigned int success )
12190+ {
12191+ sd -> newidle_call ++ ;
12192+ sd -> newidle_success += success ;
12193+
12194+ if (sd -> newidle_call >= 1024 ) {
12195+ sd -> newidle_ratio = sd -> newidle_success ;
12196+ sd -> newidle_call /= 2 ;
12197+ sd -> newidle_success /= 2 ;
12198+ }
12199+ }
12200+
12201+ static inline bool
12202+ update_newidle_cost (struct sched_domain * sd , u64 cost , unsigned int success )
1219012203{
1219112204 unsigned long next_decay = sd -> last_decay_max_lb_cost + HZ ;
1219212205 unsigned long now = jiffies ;
1219312206
12207+ if (cost )
12208+ update_newidle_stats (sd , success );
12209+
1219412210 if (cost > sd -> max_newidle_lb_cost ) {
1219512211 /*
1219612212 * Track max cost of a domain to make sure to not delay the
@@ -12238,7 +12254,7 @@ static void sched_balance_domains(struct rq *rq, enum cpu_idle_type idle)
1223812254 * Decay the newidle max times here because this is a regular
1223912255 * visit to all the domains.
1224012256 */
12241- need_decay = update_newidle_cost (sd , 0 );
12257+ need_decay = update_newidle_cost (sd , 0 , 0 );
1224212258 max_cost += sd -> max_newidle_lb_cost ;
1224312259
1224412260 /*
@@ -12896,17 +12912,37 @@ static int sched_balance_newidle(struct rq *this_rq, struct rq_flags *rf)
1289612912 break ;
1289712913
1289812914 if (sd -> flags & SD_BALANCE_NEWIDLE ) {
12915+ unsigned int weight = 1 ;
12916+
12917+ if (sched_feat (NI_RANDOM )) {
12918+ /*
12919+ * Throw a 1k sided dice; and only run
12920+ * newidle_balance according to the success
12921+ * rate.
12922+ */
12923+ u32 d1k = sched_rng () % 1024 ;
12924+ weight = 1 + sd -> newidle_ratio ;
12925+ if (d1k > weight ) {
12926+ update_newidle_stats (sd , 0 );
12927+ continue ;
12928+ }
12929+ weight = (1024 + weight /2 ) / weight ;
12930+ }
1289912931
1290012932 pulled_task = sched_balance_rq (this_cpu , this_rq ,
1290112933 sd , CPU_NEWLY_IDLE ,
1290212934 & continue_balancing );
1290312935
1290412936 t1 = sched_clock_cpu (this_cpu );
1290512937 domain_cost = t1 - t0 ;
12906- update_newidle_cost (sd , domain_cost );
12907-
1290812938 curr_cost += domain_cost ;
1290912939 t0 = t1 ;
12940+
12941+ /*
12942+ * Track max cost of a domain to make sure to not delay the
12943+ * next wakeup on the CPU.
12944+ */
12945+ update_newidle_cost (sd , domain_cost , weight * !!pulled_task );
1291012946 }
1291112947
1291212948 /*
0 commit comments