@@ -525,7 +525,7 @@ static int se_is_idle(struct sched_entity *se)
525525#endif /* !CONFIG_FAIR_GROUP_SCHED */
526526
527527static __always_inline
528- void account_cfs_rq_runtime (struct cfs_rq * cfs_rq , u64 delta_exec );
528+ bool account_cfs_rq_runtime (struct cfs_rq * cfs_rq , u64 delta_exec );
529529
530530/**************************************************************
531531 * Scheduling class tree data structure manipulation methods:
@@ -6388,8 +6388,6 @@ pick_next_entity(struct rq *rq, struct cfs_rq *cfs_rq, bool protect)
63886388 return se ;
63896389}
63906390
6391- static bool check_cfs_rq_runtime (struct cfs_rq * cfs_rq );
6392-
63936391static void put_prev_entity (struct cfs_rq * cfs_rq , struct sched_entity * prev )
63946392{
63956393 /*
@@ -6399,9 +6397,6 @@ static void put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev)
63996397 if (prev -> on_rq )
64006398 update_curr (cfs_rq );
64016399
6402- /* throttle cfs_rqs exceeding runtime */
6403- check_cfs_rq_runtime (cfs_rq );
6404-
64056400 if (prev -> on_rq ) {
64066401 update_stats_wait_start_fair (cfs_rq , prev );
64076402 /* Put 'current' back into the tree. */
@@ -6536,41 +6531,32 @@ static int __assign_cfs_rq_runtime(struct cfs_bandwidth *cfs_b,
65366531 return cfs_rq -> runtime_remaining > 0 ;
65376532}
65386533
6539- /* returns 0 on failure to allocate runtime */
6540- static int assign_cfs_rq_runtime (struct cfs_rq * cfs_rq )
6541- {
6542- struct cfs_bandwidth * cfs_b = tg_cfs_bandwidth (cfs_rq -> tg );
6543-
6544- guard (raw_spinlock )(& cfs_b -> lock );
6534+ static bool throttle_cfs_rq (struct cfs_rq * cfs_rq );
65456535
6546- return __assign_cfs_rq_runtime (cfs_b , cfs_rq , sched_cfs_bandwidth_slice ());
6547- }
6548-
6549- static void __account_cfs_rq_runtime (struct cfs_rq * cfs_rq , u64 delta_exec )
6536+ static bool __account_cfs_rq_runtime (struct cfs_rq * cfs_rq , u64 delta_exec )
65506537{
65516538 /* dock delta_exec before expiring quota (as it could span periods) */
65526539 cfs_rq -> runtime_remaining -= delta_exec ;
65536540
65546541 if (likely (cfs_rq -> runtime_remaining > 0 ))
6555- return ;
6542+ return false ;
65566543
65576544 if (cfs_rq -> throttled )
6558- return ;
6545+ return true ;
65596546 /*
6560- * if we're unable to extend our runtime we resched so that the active
6561- * hierarchy can be throttled
6547+ * throttle_cfs_rq() will try to extend the runtime first
6548+ * before throttling the hierarchy.
65626549 */
6563- if (!assign_cfs_rq_runtime (cfs_rq ) && likely (cfs_rq -> curr ))
6564- resched_curr (rq_of (cfs_rq ));
6550+ return throttle_cfs_rq (cfs_rq );
65656551}
65666552
65676553static __always_inline
6568- void account_cfs_rq_runtime (struct cfs_rq * cfs_rq , u64 delta_exec )
6554+ bool account_cfs_rq_runtime (struct cfs_rq * cfs_rq , u64 delta_exec )
65696555{
65706556 if (!cfs_bandwidth_used () || !cfs_rq -> runtime_enabled )
6571- return ;
6557+ return false ;
65726558
6573- __account_cfs_rq_runtime (cfs_rq , delta_exec );
6559+ return __account_cfs_rq_runtime (cfs_rq , delta_exec );
65746560}
65756561
65766562static inline int cfs_rq_throttled (struct cfs_rq * cfs_rq )
@@ -6858,10 +6844,24 @@ static int tg_throttle_down(struct task_group *tg, void *data)
68586844
68596845static bool throttle_cfs_rq (struct cfs_rq * cfs_rq )
68606846{
6861- struct rq * rq = rq_of (cfs_rq );
68626847 struct cfs_bandwidth * cfs_b = tg_cfs_bandwidth (cfs_rq -> tg );
6848+ struct sched_entity * curr = cfs_rq -> curr ;
6849+ struct rq * rq = rq_of (cfs_rq );
68636850
68646851 scoped_guard (raw_spinlock , & cfs_b -> lock ) {
6852+ u64 target_runtime = 1 ;
6853+
6854+ /*
6855+ * If cfs_rq->curr is still runnable, we are here from an
6856+ * update_curr(). Request sysctl_sched_cfs_bandwidth_slice
6857+ * worth of bandwidth to continue running.
6858+ *
6859+ * If the curr is not runnable, just request enough bandwidth
6860+ * to be runnable next time the pick selects this cfs_rq.
6861+ */
6862+ if (curr && curr -> on_rq )
6863+ target_runtime = sched_cfs_bandwidth_slice ();
6864+
68656865 /*
68666866 * Check if We have raced with bandwidth becoming available. If
68676867 * we actually throttled the timer might not unthrottle us for
@@ -6872,7 +6872,7 @@ static bool throttle_cfs_rq(struct cfs_rq *cfs_rq)
68726872 *
68736873 * This will start the period timer if necessary.
68746874 */
6875- if (__assign_cfs_rq_runtime (cfs_b , cfs_rq , 1 ))
6875+ if (__assign_cfs_rq_runtime (cfs_b , cfs_rq , target_runtime ))
68766876 return false;
68776877
68786878 /*
@@ -6893,6 +6893,17 @@ static bool throttle_cfs_rq(struct cfs_rq *cfs_rq)
68936893 */
68946894 cfs_rq -> throttled = 1 ;
68956895 WARN_ON_ONCE (cfs_rq -> throttled_clock );
6896+
6897+ /*
6898+ * If current hierarchy was throttled, add throttle work to the
6899+ * current donor. In case of proxy-execution, the execution
6900+ * context cannot exit to the userspace while holding a mutex
6901+ * and the rule of throttle deferral to only throttle the
6902+ * throttled context at exit to userspace is still preserved.
6903+ */
6904+ if (curr && curr -> on_rq )
6905+ task_throttle_setup_work (rq -> donor );
6906+
68966907 return true;
68976908}
68986909
@@ -7283,7 +7294,7 @@ static void check_enqueue_throttle(struct cfs_rq *cfs_rq)
72837294 if (!cfs_bandwidth_used ())
72847295 return ;
72857296
7286- /* an active group must be handled by the update_curr()->put() path */
7297+ /* an active group must be handled by the update_curr() path */
72877298 if (!cfs_rq -> runtime_enabled || cfs_rq -> curr )
72887299 return ;
72897300
@@ -7293,8 +7304,6 @@ static void check_enqueue_throttle(struct cfs_rq *cfs_rq)
72937304
72947305 /* update runtime allocation */
72957306 account_cfs_rq_runtime (cfs_rq , 0 );
7296- if (cfs_rq -> runtime_remaining <= 0 )
7297- throttle_cfs_rq (cfs_rq );
72987307}
72997308
73007309static void sync_throttle (struct task_group * tg , int cpu )
@@ -7324,25 +7333,6 @@ static void sync_throttle(struct task_group *tg, int cpu)
73247333 cfs_rq -> pelt_clock_throttled = 1 ;
73257334}
73267335
7327- /* conditionally throttle active cfs_rq's from put_prev_entity() */
7328- static bool check_cfs_rq_runtime (struct cfs_rq * cfs_rq )
7329- {
7330- if (!cfs_bandwidth_used ())
7331- return false;
7332-
7333- if (likely (!cfs_rq -> runtime_enabled || cfs_rq -> runtime_remaining > 0 ))
7334- return false;
7335-
7336- /*
7337- * it's possible for a throttled entity to be forced into a running
7338- * state (e.g. set_curr_task), in this case we're finished.
7339- */
7340- if (cfs_rq_throttled (cfs_rq ))
7341- return true;
7342-
7343- return throttle_cfs_rq (cfs_rq );
7344- }
7345-
73467336static enum hrtimer_restart sched_cfs_slack_timer (struct hrtimer * timer )
73477337{
73487338 struct cfs_bandwidth * cfs_b =
@@ -7596,8 +7586,7 @@ static void sched_fair_update_stop_tick(struct rq *rq, struct task_struct *p)
75967586
75977587#else /* !CONFIG_CFS_BANDWIDTH: */
75987588
7599- static void account_cfs_rq_runtime (struct cfs_rq * cfs_rq , u64 delta_exec ) {}
7600- static bool check_cfs_rq_runtime (struct cfs_rq * cfs_rq ) { return false; }
7589+ static bool account_cfs_rq_runtime (struct cfs_rq * cfs_rq , u64 delta_exec ) { return false; }
76017590static void check_enqueue_throttle (struct cfs_rq * cfs_rq ) {}
76027591static inline void sync_throttle (struct task_group * tg , int cpu ) {}
76037592static __always_inline void return_cfs_rq_runtime (struct cfs_rq * cfs_rq ) {}
@@ -9934,8 +9923,6 @@ struct task_struct *pick_task_fair(struct rq *rq, struct rq_flags *rf)
99349923 if (cfs_rq -> curr && cfs_rq -> curr -> on_rq )
99359924 update_curr (cfs_rq );
99369925
9937- throttled |= check_cfs_rq_runtime (cfs_rq );
9938-
99399926 se = pick_next_entity (rq , cfs_rq , true);
99409927 if (!se )
99419928 goto again ;
@@ -14853,8 +14840,8 @@ static inline void task_tick_core(struct rq *rq, struct task_struct *curr) {}
1485314840 */
1485414841static void task_tick_fair (struct rq * rq , struct task_struct * curr , int queued )
1485514842{
14856- struct cfs_rq * cfs_rq ;
1485714843 struct sched_entity * se = & curr -> se ;
14844+ struct cfs_rq * cfs_rq ;
1485814845
1485914846 for_each_sched_entity (se ) {
1486014847 cfs_rq = cfs_rq_of (se );
@@ -15036,6 +15023,7 @@ static void switched_to_fair(struct rq *rq, struct task_struct *p)
1503615023static void set_next_task_fair (struct rq * rq , struct task_struct * p , bool first )
1503715024{
1503815025 struct sched_entity * se = & p -> se ;
15026+ bool throttled = false;
1503915027
1504015028 for_each_sched_entity (se ) {
1504115029 struct cfs_rq * cfs_rq = cfs_rq_of (se );
@@ -15046,9 +15034,12 @@ static void set_next_task_fair(struct rq *rq, struct task_struct *p, bool first)
1504615034
1504715035 set_next_entity (cfs_rq , se , first );
1504815036 /* ensure bandwidth has been allocated on our new cfs_rq */
15049- account_cfs_rq_runtime (cfs_rq , 0 );
15037+ throttled |= account_cfs_rq_runtime (cfs_rq , 0 );
1505015038 }
1505115039
15040+ if (throttled )
15041+ task_throttle_setup_work (p );
15042+
1505215043 se = & p -> se ;
1505315044
1505415045 if (task_on_rq_queued (p )) {
0 commit comments