@@ -4001,7 +4001,7 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
4001
4001
* put back on, and if we advance min_vruntime, we'll be placed back
4002
4002
* further than we started -- ie. we'll be penalized.
4003
4003
*/
4004
- if ((flags & (DEQUEUE_SAVE | DEQUEUE_MOVE )) = = DEQUEUE_SAVE )
4004
+ if ((flags & (DEQUEUE_SAVE | DEQUEUE_MOVE )) ! = DEQUEUE_SAVE )
4005
4005
update_min_vruntime (cfs_rq );
4006
4006
}
4007
4007
@@ -4476,9 +4476,13 @@ static void throttle_cfs_rq(struct cfs_rq *cfs_rq)
4476
4476
4477
4477
/*
4478
4478
* Add to the _head_ of the list, so that an already-started
4479
- * distribute_cfs_runtime will not see us
4479
+ * distribute_cfs_runtime will not see us. If disribute_cfs_runtime is
4480
+ * not running add to the tail so that later runqueues don't get starved.
4480
4481
*/
4481
- list_add_rcu (& cfs_rq -> throttled_list , & cfs_b -> throttled_cfs_rq );
4482
+ if (cfs_b -> distribute_running )
4483
+ list_add_rcu (& cfs_rq -> throttled_list , & cfs_b -> throttled_cfs_rq );
4484
+ else
4485
+ list_add_tail_rcu (& cfs_rq -> throttled_list , & cfs_b -> throttled_cfs_rq );
4482
4486
4483
4487
/*
4484
4488
* If we're the first throttled task, make sure the bandwidth
@@ -4622,14 +4626,16 @@ static int do_sched_cfs_period_timer(struct cfs_bandwidth *cfs_b, int overrun)
4622
4626
* in us over-using our runtime if it is all used during this loop, but
4623
4627
* only by limited amounts in that extreme case.
4624
4628
*/
4625
- while (throttled && cfs_b -> runtime > 0 ) {
4629
+ while (throttled && cfs_b -> runtime > 0 && ! cfs_b -> distribute_running ) {
4626
4630
runtime = cfs_b -> runtime ;
4631
+ cfs_b -> distribute_running = 1 ;
4627
4632
raw_spin_unlock (& cfs_b -> lock );
4628
4633
/* we can't nest cfs_b->lock while distributing bandwidth */
4629
4634
runtime = distribute_cfs_runtime (cfs_b , runtime ,
4630
4635
runtime_expires );
4631
4636
raw_spin_lock (& cfs_b -> lock );
4632
4637
4638
+ cfs_b -> distribute_running = 0 ;
4633
4639
throttled = !list_empty (& cfs_b -> throttled_cfs_rq );
4634
4640
4635
4641
cfs_b -> runtime -= min (runtime , cfs_b -> runtime );
@@ -4740,6 +4746,11 @@ static void do_sched_cfs_slack_timer(struct cfs_bandwidth *cfs_b)
4740
4746
4741
4747
/* confirm we're still not at a refresh boundary */
4742
4748
raw_spin_lock (& cfs_b -> lock );
4749
+ if (cfs_b -> distribute_running ) {
4750
+ raw_spin_unlock (& cfs_b -> lock );
4751
+ return ;
4752
+ }
4753
+
4743
4754
if (runtime_refresh_within (cfs_b , min_bandwidth_expiration )) {
4744
4755
raw_spin_unlock (& cfs_b -> lock );
4745
4756
return ;
@@ -4749,6 +4760,9 @@ static void do_sched_cfs_slack_timer(struct cfs_bandwidth *cfs_b)
4749
4760
runtime = cfs_b -> runtime ;
4750
4761
4751
4762
expires = cfs_b -> runtime_expires ;
4763
+ if (runtime )
4764
+ cfs_b -> distribute_running = 1 ;
4765
+
4752
4766
raw_spin_unlock (& cfs_b -> lock );
4753
4767
4754
4768
if (!runtime )
@@ -4759,6 +4773,7 @@ static void do_sched_cfs_slack_timer(struct cfs_bandwidth *cfs_b)
4759
4773
raw_spin_lock (& cfs_b -> lock );
4760
4774
if (expires == cfs_b -> runtime_expires )
4761
4775
cfs_b -> runtime -= min (runtime , cfs_b -> runtime );
4776
+ cfs_b -> distribute_running = 0 ;
4762
4777
raw_spin_unlock (& cfs_b -> lock );
4763
4778
}
4764
4779
@@ -4867,6 +4882,7 @@ void init_cfs_bandwidth(struct cfs_bandwidth *cfs_b)
4867
4882
cfs_b -> period_timer .function = sched_cfs_period_timer ;
4868
4883
hrtimer_init (& cfs_b -> slack_timer , CLOCK_MONOTONIC , HRTIMER_MODE_REL );
4869
4884
cfs_b -> slack_timer .function = sched_cfs_slack_timer ;
4885
+ cfs_b -> distribute_running = 0 ;
4870
4886
}
4871
4887
4872
4888
static void init_cfs_rq_runtime (struct cfs_rq * cfs_rq )
0 commit comments