|
@@ -3798,6 +3798,19 @@ static void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b)
|
|
|
hrtimer_cancel(&cfs_b->slack_timer);
|
|
|
}
|
|
|
|
|
|
+static void __maybe_unused update_runtime_enabled(struct rq *rq)
|
|
|
+{
|
|
|
+ struct cfs_rq *cfs_rq;
|
|
|
+
|
|
|
+ for_each_leaf_cfs_rq(rq, cfs_rq) {
|
|
|
+ struct cfs_bandwidth *cfs_b = &cfs_rq->tg->cfs_bandwidth;
|
|
|
+
|
|
|
+ raw_spin_lock(&cfs_b->lock);
|
|
|
+ cfs_rq->runtime_enabled = cfs_b->quota != RUNTIME_INF;
|
|
|
+ raw_spin_unlock(&cfs_b->lock);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void __maybe_unused unthrottle_offline_cfs_rqs(struct rq *rq)
|
|
|
{
|
|
|
struct cfs_rq *cfs_rq;
|
|
@@ -3811,6 +3824,12 @@ static void __maybe_unused unthrottle_offline_cfs_rqs(struct rq *rq)
|
|
|
* there's some valid quota amount
|
|
|
*/
|
|
|
cfs_rq->runtime_remaining = 1;
|
|
|
+ /*
|
|
|
+ * Offline rq is schedulable till cpu is completely disabled
|
|
|
+ * in take_cpu_down(), so we prevent new cfs throttling here.
|
|
|
+ */
|
|
|
+ cfs_rq->runtime_enabled = 0;
|
|
|
+
|
|
|
if (cfs_rq_throttled(cfs_rq))
|
|
|
unthrottle_cfs_rq(cfs_rq);
|
|
|
}
|
|
@@ -3854,6 +3873,7 @@ static inline struct cfs_bandwidth *tg_cfs_bandwidth(struct task_group *tg)
|
|
|
return NULL;
|
|
|
}
|
|
|
static inline void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b) {}
|
|
|
+static inline void update_runtime_enabled(struct rq *rq) {}
|
|
|
static inline void unthrottle_offline_cfs_rqs(struct rq *rq) {}
|
|
|
|
|
|
#endif /* CONFIG_CFS_BANDWIDTH */
|
|
@@ -7362,6 +7382,8 @@ void trigger_load_balance(struct rq *rq)
|
|
|
static void rq_online_fair(struct rq *rq)
|
|
|
{
|
|
|
update_sysctl();
|
|
|
+
|
|
|
+ update_runtime_enabled(rq);
|
|
|
}
|
|
|
|
|
|
static void rq_offline_fair(struct rq *rq)
|