@@ -9082,8 +9082,8 @@ static void nohz_balancer_kick(void)
9082
9082
if (ilb_cpu >= nr_cpu_ids )
9083
9083
return ;
9084
9084
9085
- flags = atomic_fetch_or (NOHZ_BALANCE_KICK , nohz_flags (ilb_cpu ));
9086
- if (flags & NOHZ_BALANCE_KICK )
9085
+ flags = atomic_fetch_or (NOHZ_KICK_MASK , nohz_flags (ilb_cpu ));
9086
+ if (flags & NOHZ_KICK_MASK )
9087
9087
return ;
9088
9088
/*
9089
9089
* Use smp_send_reschedule() instead of resched_cpu().
@@ -9202,8 +9202,6 @@ static void rebalance_domains(struct rq *rq, enum cpu_idle_type idle)
9202
9202
int need_serialize , need_decay = 0 ;
9203
9203
u64 max_cost = 0 ;
9204
9204
9205
- update_blocked_averages (cpu );
9206
-
9207
9205
rcu_read_lock ();
9208
9206
for_each_domain (cpu , sd ) {
9209
9207
/*
@@ -9298,20 +9296,27 @@ static void rebalance_domains(struct rq *rq, enum cpu_idle_type idle)
9298
9296
* In CONFIG_NO_HZ_COMMON case, the idle balance kickee will do the
9299
9297
* rebalancing for all the CPUs for whom scheduler ticks are stopped.
9300
9298
*/
9301
- static void nohz_idle_balance (struct rq * this_rq , enum cpu_idle_type idle )
9299
+ static bool nohz_idle_balance (struct rq * this_rq , enum cpu_idle_type idle )
9302
9300
{
9303
- int this_cpu = this_rq -> cpu ;
9304
- struct rq * rq ;
9305
- int balance_cpu ;
9306
9301
/* Earliest time when we have to do rebalance again */
9307
9302
unsigned long next_balance = jiffies + 60 * HZ ;
9308
9303
int update_next_balance = 0 ;
9304
+ int this_cpu = this_rq -> cpu ;
9305
+ unsigned int flags ;
9306
+ int balance_cpu ;
9307
+ struct rq * rq ;
9309
9308
9310
- if (!(atomic_read (nohz_flags (this_cpu )) & NOHZ_BALANCE_KICK ))
9311
- return ;
9309
+ if (!(atomic_read (nohz_flags (this_cpu )) & NOHZ_KICK_MASK ))
9310
+ return false ;
9312
9311
9313
- if (idle != CPU_IDLE )
9314
- goto end ;
9312
+ if (idle != CPU_IDLE ) {
9313
+ atomic_andnot (NOHZ_KICK_MASK , nohz_flags (this_cpu ));
9314
+ return false;
9315
+ }
9316
+
9317
+ flags = atomic_fetch_andnot (NOHZ_KICK_MASK , nohz_flags (this_cpu ));
9318
+
9319
+ SCHED_WARN_ON ((flags & NOHZ_KICK_MASK ) == NOHZ_BALANCE_KICK );
9315
9320
9316
9321
for_each_cpu (balance_cpu , nohz .idle_cpus_mask ) {
9317
9322
if (balance_cpu == this_cpu || !idle_cpu (balance_cpu ))
@@ -9339,7 +9344,9 @@ static void nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle)
9339
9344
cpu_load_update_idle (rq );
9340
9345
rq_unlock_irq (rq , & rf );
9341
9346
9342
- rebalance_domains (rq , CPU_IDLE );
9347
+ update_blocked_averages (rq -> cpu );
9348
+ if (flags & NOHZ_BALANCE_KICK )
9349
+ rebalance_domains (rq , CPU_IDLE );
9343
9350
}
9344
9351
9345
9352
if (time_after (next_balance , rq -> next_balance )) {
@@ -9348,15 +9355,19 @@ static void nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle)
9348
9355
}
9349
9356
}
9350
9357
9358
+ update_blocked_averages (this_cpu );
9359
+ if (flags & NOHZ_BALANCE_KICK )
9360
+ rebalance_domains (this_rq , CPU_IDLE );
9361
+
9351
9362
/*
9352
9363
* next_balance will be updated only when there is a need.
9353
9364
* When the CPU is attached to null domain for ex, it will not be
9354
9365
* updated.
9355
9366
*/
9356
9367
if (likely (update_next_balance ))
9357
9368
nohz .next_balance = next_balance ;
9358
- end :
9359
- atomic_andnot ( NOHZ_BALANCE_KICK , nohz_flags ( this_cpu )) ;
9369
+
9370
+ return true ;
9360
9371
}
9361
9372
9362
9373
/*
@@ -9443,7 +9454,10 @@ static inline bool nohz_kick_needed(struct rq *rq)
9443
9454
return kick ;
9444
9455
}
9445
9456
#else
9446
- static void nohz_idle_balance (struct rq * this_rq , enum cpu_idle_type idle ) { }
9457
+ static bool nohz_idle_balance (struct rq * this_rq , enum cpu_idle_type idle )
9458
+ {
9459
+ return false;
9460
+ }
9447
9461
#endif
9448
9462
9449
9463
/*
@@ -9464,7 +9478,11 @@ static __latent_entropy void run_rebalance_domains(struct softirq_action *h)
9464
9478
* load balance only within the local sched_domain hierarchy
9465
9479
* and abort nohz_idle_balance altogether if we pull some load.
9466
9480
*/
9467
- nohz_idle_balance (this_rq , idle );
9481
+ if (nohz_idle_balance (this_rq , idle ))
9482
+ return ;
9483
+
9484
+ /* normal load balance */
9485
+ update_blocked_averages (this_rq -> cpu );
9468
9486
rebalance_domains (this_rq , idle );
9469
9487
}
9470
9488
0 commit comments