|
@@ -283,7 +283,7 @@ static void update_min_vruntime(struct cfs_rq *cfs_rq)
|
|
struct sched_entity,
|
|
struct sched_entity,
|
|
run_node);
|
|
run_node);
|
|
|
|
|
|
- if (vruntime == cfs_rq->min_vruntime)
|
|
|
|
|
|
+ if (!cfs_rq->curr)
|
|
vruntime = se->vruntime;
|
|
vruntime = se->vruntime;
|
|
else
|
|
else
|
|
vruntime = min_vruntime(vruntime, se->vruntime);
|
|
vruntime = min_vruntime(vruntime, se->vruntime);
|
|
@@ -429,7 +429,10 @@ static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
|
u64 slice = __sched_period(cfs_rq->nr_running + !se->on_rq);
|
|
u64 slice = __sched_period(cfs_rq->nr_running + !se->on_rq);
|
|
|
|
|
|
for_each_sched_entity(se) {
|
|
for_each_sched_entity(se) {
|
|
- struct load_weight *load = &cfs_rq->load;
|
|
|
|
|
|
+ struct load_weight *load;
|
|
|
|
+
|
|
|
|
+ cfs_rq = cfs_rq_of(se);
|
|
|
|
+ load = &cfs_rq->load;
|
|
|
|
|
|
if (unlikely(!se->on_rq)) {
|
|
if (unlikely(!se->on_rq)) {
|
|
struct load_weight lw = cfs_rq->load;
|
|
struct load_weight lw = cfs_rq->load;
|
|
@@ -677,9 +680,13 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
|
|
unsigned long thresh = sysctl_sched_latency;
|
|
unsigned long thresh = sysctl_sched_latency;
|
|
|
|
|
|
/*
|
|
/*
|
|
- * convert the sleeper threshold into virtual time
|
|
|
|
|
|
+ * Convert the sleeper threshold into virtual time.
|
|
|
|
+ * SCHED_IDLE is a special sub-class. We care about
|
|
|
|
+ * fairness only relative to other SCHED_IDLE tasks,
|
|
|
|
+ * all of which have the same weight.
|
|
*/
|
|
*/
|
|
- if (sched_feat(NORMALIZED_SLEEPER))
|
|
|
|
|
|
+ if (sched_feat(NORMALIZED_SLEEPER) &&
|
|
|
|
+ task_of(se)->policy != SCHED_IDLE)
|
|
thresh = calc_delta_fair(thresh, se);
|
|
thresh = calc_delta_fair(thresh, se);
|
|
|
|
|
|
vruntime -= thresh;
|
|
vruntime -= thresh;
|
|
@@ -1340,14 +1347,18 @@ wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se)
|
|
|
|
|
|
static void set_last_buddy(struct sched_entity *se)
|
|
static void set_last_buddy(struct sched_entity *se)
|
|
{
|
|
{
|
|
- for_each_sched_entity(se)
|
|
|
|
- cfs_rq_of(se)->last = se;
|
|
|
|
|
|
+ if (likely(task_of(se)->policy != SCHED_IDLE)) {
|
|
|
|
+ for_each_sched_entity(se)
|
|
|
|
+ cfs_rq_of(se)->last = se;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
static void set_next_buddy(struct sched_entity *se)
|
|
static void set_next_buddy(struct sched_entity *se)
|
|
{
|
|
{
|
|
- for_each_sched_entity(se)
|
|
|
|
- cfs_rq_of(se)->next = se;
|
|
|
|
|
|
+ if (likely(task_of(se)->policy != SCHED_IDLE)) {
|
|
|
|
+ for_each_sched_entity(se)
|
|
|
|
+ cfs_rq_of(se)->next = se;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1393,12 +1404,18 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync)
|
|
return;
|
|
return;
|
|
|
|
|
|
/*
|
|
/*
|
|
- * Batch tasks do not preempt (their preemption is driven by
|
|
|
|
|
|
+ * Batch and idle tasks do not preempt (their preemption is driven by
|
|
* the tick):
|
|
* the tick):
|
|
*/
|
|
*/
|
|
- if (unlikely(p->policy == SCHED_BATCH))
|
|
|
|
|
|
+ if (unlikely(p->policy != SCHED_NORMAL))
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
+ /* Idle tasks are by definition preempted by everybody. */
|
|
|
|
+ if (unlikely(curr->policy == SCHED_IDLE)) {
|
|
|
|
+ resched_task(curr);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (!sched_feat(WAKEUP_PREEMPT))
|
|
if (!sched_feat(WAKEUP_PREEMPT))
|
|
return;
|
|
return;
|
|
|
|
|