@@ -932,7 +932,7 @@ static inline void cancel_protect_slice(struct sched_entity *se)
932932 *
933933 * Which allows tree pruning through eligibility.
934934 */
935- static struct sched_entity * pick_eevdf (struct cfs_rq * cfs_rq )
935+ static struct sched_entity * __pick_eevdf (struct cfs_rq * cfs_rq , bool protect )
936936{
937937 struct rb_node * node = cfs_rq -> tasks_timeline .rb_root .rb_node ;
938938 struct sched_entity * se = __pick_first_entity (cfs_rq );
@@ -949,7 +949,7 @@ static struct sched_entity *pick_eevdf(struct cfs_rq *cfs_rq)
949949 if (curr && (!curr -> on_rq || !entity_eligible (cfs_rq , curr )))
950950 curr = NULL ;
951951
952- if (curr && protect_slice (curr ))
952+ if (curr && protect && protect_slice (curr ))
953953 return curr ;
954954
955955 /* Pick the leftmost entity if it's eligible */
@@ -993,6 +993,11 @@ static struct sched_entity *pick_eevdf(struct cfs_rq *cfs_rq)
993993 return best ;
994994}
995995
996+ static struct sched_entity * pick_eevdf (struct cfs_rq * cfs_rq )
997+ {
998+ return __pick_eevdf (cfs_rq , true);
999+ }
1000+
9961001struct sched_entity * __pick_last_entity (struct cfs_rq * cfs_rq )
9971002{
9981003 struct rb_node * last = rb_last (& cfs_rq -> tasks_timeline .rb_root );
@@ -1176,27 +1181,6 @@ static inline bool resched_next_slice(struct cfs_rq *cfs_rq, struct sched_entity
11761181 return !entity_eligible (cfs_rq , curr );
11771182}
11781183
1179- static inline bool do_preempt_short (struct cfs_rq * cfs_rq ,
1180- struct sched_entity * pse , struct sched_entity * se )
1181- {
1182- if (!sched_feat (PREEMPT_SHORT ))
1183- return false;
1184-
1185- if (pse -> slice >= se -> slice )
1186- return false;
1187-
1188- if (!entity_eligible (cfs_rq , pse ))
1189- return false;
1190-
1191- if (entity_before (pse , se ))
1192- return true;
1193-
1194- if (!entity_eligible (cfs_rq , se ))
1195- return true;
1196-
1197- return false;
1198- }
1199-
12001184/*
12011185 * Used by other classes to account runtime.
12021186 */
@@ -8658,6 +8642,7 @@ static void check_preempt_wakeup_fair(struct rq *rq, struct task_struct *p, int
86588642 struct sched_entity * se = & donor -> se , * pse = & p -> se ;
86598643 struct cfs_rq * cfs_rq = task_cfs_rq (donor );
86608644 int cse_is_idle , pse_is_idle ;
8645+ bool do_preempt_short = false;
86618646
86628647 if (unlikely (se == pse ))
86638648 return ;
@@ -8706,7 +8691,7 @@ static void check_preempt_wakeup_fair(struct rq *rq, struct task_struct *p, int
87068691 * When non-idle entity preempt an idle entity,
87078692 * don't give idle entity slice protection.
87088693 */
8709- cancel_protect_slice ( se ) ;
8694+ do_preempt_short = true ;
87108695 goto preempt ;
87118696 }
87128697
@@ -8724,22 +8709,21 @@ static void check_preempt_wakeup_fair(struct rq *rq, struct task_struct *p, int
87248709 /*
87258710 * If @p has a shorter slice than current and @p is eligible, override
87268711 * current's slice protection in order to allow preemption.
8727- *
8728- * Note that even if @p does not turn out to be the most eligible
8729- * task at this moment, current's slice protection will be lost.
87308712 */
8731- if (do_preempt_short (cfs_rq , pse , se ))
8732- cancel_protect_slice (se );
8713+ do_preempt_short = sched_feat (PREEMPT_SHORT ) && (pse -> slice < se -> slice );
87338714
87348715 /*
87358716 * If @p has become the most eligible task, force preemption.
87368717 */
8737- if (pick_eevdf (cfs_rq ) == pse )
8718+ if (__pick_eevdf (cfs_rq , ! do_preempt_short ) == pse )
87388719 goto preempt ;
87398720
87408721 return ;
87418722
87428723preempt :
8724+ if (do_preempt_short )
8725+ cancel_protect_slice (se );
8726+
87438727 resched_curr_lazy (rq );
87448728}
87458729
0 commit comments