Merge branch 'sched/urgent' into sched/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
@@ -735,8 +735,6 @@ void post_init_entity_util_avg(struct sched_entity *se)
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned long cfs_rq_runnable_load_avg(struct cfs_rq *cfs_rq);
|
||||
static inline unsigned long cfs_rq_load_avg(struct cfs_rq *cfs_rq);
|
||||
#else
|
||||
void init_entity_runnable_average(struct sched_entity *se)
|
||||
{
|
||||
@@ -2473,28 +2471,22 @@ account_entity_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||
|
||||
#ifdef CONFIG_FAIR_GROUP_SCHED
|
||||
# ifdef CONFIG_SMP
|
||||
static inline long calc_tg_weight(struct task_group *tg, struct cfs_rq *cfs_rq)
|
||||
{
|
||||
long tg_weight;
|
||||
|
||||
/*
|
||||
* Use this CPU's real-time load instead of the last load contribution
|
||||
* as the updating of the contribution is delayed, and we will use the
|
||||
* the real-time load to calc the share. See update_tg_load_avg().
|
||||
*/
|
||||
tg_weight = atomic_long_read(&tg->load_avg);
|
||||
tg_weight -= cfs_rq->tg_load_avg_contrib;
|
||||
tg_weight += cfs_rq->load.weight;
|
||||
|
||||
return tg_weight;
|
||||
}
|
||||
|
||||
static long calc_cfs_shares(struct cfs_rq *cfs_rq, struct task_group *tg)
|
||||
{
|
||||
long tg_weight, load, shares;
|
||||
|
||||
tg_weight = calc_tg_weight(tg, cfs_rq);
|
||||
load = cfs_rq->load.weight;
|
||||
/*
|
||||
* This really should be: cfs_rq->avg.load_avg, but instead we use
|
||||
* cfs_rq->load.weight, which is its upper bound. This helps ramp up
|
||||
* the shares for small weight interactive tasks.
|
||||
*/
|
||||
load = scale_load_down(cfs_rq->load.weight);
|
||||
|
||||
tg_weight = atomic_long_read(&tg->load_avg);
|
||||
|
||||
/* Ensure tg_weight >= load */
|
||||
tg_weight -= cfs_rq->tg_load_avg_contrib;
|
||||
tg_weight += load;
|
||||
|
||||
shares = (tg->shares * load);
|
||||
if (tg_weight)
|
||||
@@ -2513,6 +2505,7 @@ static inline long calc_cfs_shares(struct cfs_rq *cfs_rq, struct task_group *tg)
|
||||
return tg->shares;
|
||||
}
|
||||
# endif /* CONFIG_SMP */
|
||||
|
||||
static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
|
||||
unsigned long weight)
|
||||
{
|
||||
@@ -2878,6 +2871,23 @@ static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Unsigned subtract and clamp on underflow.
|
||||
*
|
||||
* Explicitly do a load-store to ensure the intermediate value never hits
|
||||
* memory. This allows lockless observations without ever seeing the negative
|
||||
* values.
|
||||
*/
|
||||
#define sub_positive(_ptr, _val) do { \
|
||||
typeof(_ptr) ptr = (_ptr); \
|
||||
typeof(*ptr) val = (_val); \
|
||||
typeof(*ptr) res, var = READ_ONCE(*ptr); \
|
||||
res = var - val; \
|
||||
if (res > var) \
|
||||
res = 0; \
|
||||
WRITE_ONCE(*ptr, res); \
|
||||
} while (0)
|
||||
|
||||
/* Group cfs_rq's load_avg is used for task_h_load and update_cfs_share */
|
||||
static inline int
|
||||
update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq, bool update_freq)
|
||||
@@ -2887,15 +2897,15 @@ update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq, bool update_freq)
|
||||
|
||||
if (atomic_long_read(&cfs_rq->removed_load_avg)) {
|
||||
s64 r = atomic_long_xchg(&cfs_rq->removed_load_avg, 0);
|
||||
sa->load_avg = max_t(long, sa->load_avg - r, 0);
|
||||
sa->load_sum = max_t(s64, sa->load_sum - r * LOAD_AVG_MAX, 0);
|
||||
sub_positive(&sa->load_avg, r);
|
||||
sub_positive(&sa->load_sum, r * LOAD_AVG_MAX);
|
||||
removed_load = 1;
|
||||
}
|
||||
|
||||
if (atomic_long_read(&cfs_rq->removed_util_avg)) {
|
||||
long r = atomic_long_xchg(&cfs_rq->removed_util_avg, 0);
|
||||
sa->util_avg = max_t(long, sa->util_avg - r, 0);
|
||||
sa->util_sum = max_t(s32, sa->util_sum - r * LOAD_AVG_MAX, 0);
|
||||
sub_positive(&sa->util_avg, r);
|
||||
sub_positive(&sa->util_sum, r * LOAD_AVG_MAX);
|
||||
removed_util = 1;
|
||||
}
|
||||
|
||||
@@ -2968,10 +2978,10 @@ static void detach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *s
|
||||
&se->avg, se->on_rq * scale_load_down(se->load.weight),
|
||||
cfs_rq->curr == se, NULL);
|
||||
|
||||
cfs_rq->avg.load_avg = max_t(long, cfs_rq->avg.load_avg - se->avg.load_avg, 0);
|
||||
cfs_rq->avg.load_sum = max_t(s64, cfs_rq->avg.load_sum - se->avg.load_sum, 0);
|
||||
cfs_rq->avg.util_avg = max_t(long, cfs_rq->avg.util_avg - se->avg.util_avg, 0);
|
||||
cfs_rq->avg.util_sum = max_t(s32, cfs_rq->avg.util_sum - se->avg.util_sum, 0);
|
||||
sub_positive(&cfs_rq->avg.load_avg, se->avg.load_avg);
|
||||
sub_positive(&cfs_rq->avg.load_sum, se->avg.load_sum);
|
||||
sub_positive(&cfs_rq->avg.util_avg, se->avg.util_avg);
|
||||
sub_positive(&cfs_rq->avg.util_sum, se->avg.util_sum);
|
||||
|
||||
cfs_rq_util_change(cfs_rq);
|
||||
}
|
||||
@@ -3220,7 +3230,7 @@ static inline void check_schedstat_required(void)
|
||||
trace_sched_stat_iowait_enabled() ||
|
||||
trace_sched_stat_blocked_enabled() ||
|
||||
trace_sched_stat_runtime_enabled()) {
|
||||
pr_warn_once("Scheduler tracepoints stat_sleep, stat_iowait, "
|
||||
printk_deferred_once("Scheduler tracepoints stat_sleep, stat_iowait, "
|
||||
"stat_blocked and stat_runtime require the "
|
||||
"kernel parameter schedstats=enabled or "
|
||||
"kernel.sched_schedstats=1\n");
|
||||
@@ -4157,6 +4167,26 @@ static void check_enqueue_throttle(struct cfs_rq *cfs_rq)
|
||||
if (!cfs_bandwidth_used())
|
||||
return;
|
||||
|
||||
/* Synchronize hierarchical throttle counter: */
|
||||
if (unlikely(!cfs_rq->throttle_uptodate)) {
|
||||
struct rq *rq = rq_of(cfs_rq);
|
||||
struct cfs_rq *pcfs_rq;
|
||||
struct task_group *tg;
|
||||
|
||||
cfs_rq->throttle_uptodate = 1;
|
||||
|
||||
/* Get closest up-to-date node, because leaves go first: */
|
||||
for (tg = cfs_rq->tg->parent; tg; tg = tg->parent) {
|
||||
pcfs_rq = tg->cfs_rq[cpu_of(rq)];
|
||||
if (pcfs_rq->throttle_uptodate)
|
||||
break;
|
||||
}
|
||||
if (tg) {
|
||||
cfs_rq->throttle_count = pcfs_rq->throttle_count;
|
||||
cfs_rq->throttled_clock_task = rq_clock_task(rq);
|
||||
}
|
||||
}
|
||||
|
||||
/* an active group must be handled by the update_curr()->put() path */
|
||||
if (!cfs_rq->runtime_enabled || cfs_rq->curr)
|
||||
return;
|
||||
@@ -4472,15 +4502,14 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags)
|
||||
|
||||
/* Don't dequeue parent if it has other entities besides us */
|
||||
if (cfs_rq->load.weight) {
|
||||
/* Avoid re-evaluating load for this entity: */
|
||||
se = parent_entity(se);
|
||||
/*
|
||||
* Bias pick_next to pick a task from this cfs_rq, as
|
||||
* p is sleeping when it is within its sched_slice.
|
||||
*/
|
||||
if (task_sleep && parent_entity(se))
|
||||
set_next_buddy(parent_entity(se));
|
||||
|
||||
/* avoid re-evaluating load for this entity */
|
||||
se = parent_entity(se);
|
||||
if (task_sleep && se && !throttled_hierarchy(cfs_rq))
|
||||
set_next_buddy(se);
|
||||
break;
|
||||
}
|
||||
flags |= DEQUEUE_SLEEP;
|
||||
@@ -4882,19 +4911,24 @@ static long effective_load(struct task_group *tg, int cpu, long wl, long wg)
|
||||
return wl;
|
||||
|
||||
for_each_sched_entity(se) {
|
||||
long w, W;
|
||||
struct cfs_rq *cfs_rq = se->my_q;
|
||||
long W, w = cfs_rq_load_avg(cfs_rq);
|
||||
|
||||
tg = se->my_q->tg;
|
||||
tg = cfs_rq->tg;
|
||||
|
||||
/*
|
||||
* W = @wg + \Sum rw_j
|
||||
*/
|
||||
W = wg + calc_tg_weight(tg, se->my_q);
|
||||
W = wg + atomic_long_read(&tg->load_avg);
|
||||
|
||||
/* Ensure \Sum rw_j >= rw_i */
|
||||
W -= cfs_rq->tg_load_avg_contrib;
|
||||
W += w;
|
||||
|
||||
/*
|
||||
* w = rw_i + @wl
|
||||
*/
|
||||
w = cfs_rq_load_avg(se->my_q) + wl;
|
||||
w += wl;
|
||||
|
||||
/*
|
||||
* wl = S * s'_i; see (2)
|
||||
|
مرجع در شماره جدید
Block a user