@@ -748,6 +748,8 @@ u64 avg_vruntime(struct cfs_rq *cfs_rq)
748748 return cfs_rq -> zero_vruntime ;
749749}
750750
751+ static inline u64 cfs_rq_max_slice (struct cfs_rq * cfs_rq );
752+
751753/*
752754 * lag_i = S - s_i = w_i * (V - v_i)
753755 *
@@ -761,17 +763,16 @@ u64 avg_vruntime(struct cfs_rq *cfs_rq)
761763 * EEVDF gives the following limit for a steady state system:
762764 *
763765 * -r_max < lag < max(r_max, q)
764- *
765- * XXX could add max_slice to the augmented data to track this.
766766 */
767767static void update_entity_lag (struct cfs_rq * cfs_rq , struct sched_entity * se )
768768{
769+ u64 max_slice = cfs_rq_max_slice (cfs_rq ) + TICK_NSEC ;
769770 s64 vlag , limit ;
770771
771772 WARN_ON_ONCE (!se -> on_rq );
772773
773774 vlag = avg_vruntime (cfs_rq ) - se -> vruntime ;
774- limit = calc_delta_fair (max_t ( u64 , 2 * se -> slice , TICK_NSEC ) , se );
775+ limit = calc_delta_fair (max_slice , se );
775776
776777 se -> vlag = clamp (vlag , - limit , limit );
777778}
@@ -829,6 +830,21 @@ static inline u64 cfs_rq_min_slice(struct cfs_rq *cfs_rq)
829830 return min_slice ;
830831}
831832
833+ static inline u64 cfs_rq_max_slice (struct cfs_rq * cfs_rq )
834+ {
835+ struct sched_entity * root = __pick_root_entity (cfs_rq );
836+ struct sched_entity * curr = cfs_rq -> curr ;
837+ u64 max_slice = 0ULL ;
838+
839+ if (curr && curr -> on_rq )
840+ max_slice = curr -> slice ;
841+
842+ if (root )
843+ max_slice = max (max_slice , root -> max_slice );
844+
845+ return max_slice ;
846+ }
847+
832848static inline bool __entity_less (struct rb_node * a , const struct rb_node * b )
833849{
834850 return entity_before (__node_2_se (a ), __node_2_se (b ));
@@ -853,13 +869,23 @@ static inline void __min_slice_update(struct sched_entity *se, struct rb_node *n
853869 }
854870}
855871
872+ static inline void __max_slice_update (struct sched_entity * se , struct rb_node * node )
873+ {
874+ if (node ) {
875+ struct sched_entity * rse = __node_2_se (node );
876+ if (rse -> max_slice > se -> max_slice )
877+ se -> max_slice = rse -> max_slice ;
878+ }
879+ }
880+
856881/*
857882 * se->min_vruntime = min(se->vruntime, {left,right}->min_vruntime)
858883 */
859884static inline bool min_vruntime_update (struct sched_entity * se , bool exit )
860885{
861886 u64 old_min_vruntime = se -> min_vruntime ;
862887 u64 old_min_slice = se -> min_slice ;
888+ u64 old_max_slice = se -> max_slice ;
863889 struct rb_node * node = & se -> run_node ;
864890
865891 se -> min_vruntime = se -> vruntime ;
@@ -870,8 +896,13 @@ static inline bool min_vruntime_update(struct sched_entity *se, bool exit)
870896 __min_slice_update (se , node -> rb_right );
871897 __min_slice_update (se , node -> rb_left );
872898
899+ se -> max_slice = se -> slice ;
900+ __max_slice_update (se , node -> rb_right );
901+ __max_slice_update (se , node -> rb_left );
902+
873903 return se -> min_vruntime == old_min_vruntime &&
874- se -> min_slice == old_min_slice ;
904+ se -> min_slice == old_min_slice &&
905+ se -> max_slice == old_max_slice ;
875906}
876907
877908RB_DECLARE_CALLBACKS (static , min_vruntime_cb , struct sched_entity ,
0 commit comments