@@ -4781,9 +4781,7 @@ static inline unsigned long task_runnable(struct task_struct *p)
4781
4781
4782
4782
static inline unsigned long _task_util_est (struct task_struct * p )
4783
4783
{
4784
- struct util_est ue = READ_ONCE (p -> se .avg .util_est );
4785
-
4786
- return max (ue .ewma , (ue .enqueued & ~UTIL_AVG_UNCHANGED ));
4784
+ return READ_ONCE (p -> se .avg .util_est ) & ~UTIL_AVG_UNCHANGED ;
4787
4785
}
4788
4786
4789
4787
static inline unsigned long task_util_est (struct task_struct * p )
@@ -4800,9 +4798,9 @@ static inline void util_est_enqueue(struct cfs_rq *cfs_rq,
4800
4798
return ;
4801
4799
4802
4800
/* Update root cfs_rq's estimated utilization */
4803
- enqueued = cfs_rq -> avg .util_est . enqueued ;
4801
+ enqueued = cfs_rq -> avg .util_est ;
4804
4802
enqueued += _task_util_est (p );
4805
- WRITE_ONCE (cfs_rq -> avg .util_est . enqueued , enqueued );
4803
+ WRITE_ONCE (cfs_rq -> avg .util_est , enqueued );
4806
4804
4807
4805
trace_sched_util_est_cfs_tp (cfs_rq );
4808
4806
}
@@ -4816,34 +4814,20 @@ static inline void util_est_dequeue(struct cfs_rq *cfs_rq,
4816
4814
return ;
4817
4815
4818
4816
/* Update root cfs_rq's estimated utilization */
4819
- enqueued = cfs_rq -> avg .util_est . enqueued ;
4817
+ enqueued = cfs_rq -> avg .util_est ;
4820
4818
enqueued -= min_t (unsigned int , enqueued , _task_util_est (p ));
4821
- WRITE_ONCE (cfs_rq -> avg .util_est . enqueued , enqueued );
4819
+ WRITE_ONCE (cfs_rq -> avg .util_est , enqueued );
4822
4820
4823
4821
trace_sched_util_est_cfs_tp (cfs_rq );
4824
4822
}
4825
4823
4826
4824
#define UTIL_EST_MARGIN (SCHED_CAPACITY_SCALE / 100)
4827
4825
4828
- /*
4829
- * Check if a (signed) value is within a specified (unsigned) margin,
4830
- * based on the observation that:
4831
- *
4832
- * abs(x) < y := (unsigned)(x + y - 1) < (2 * y - 1)
4833
- *
4834
- * NOTE: this only works when value + margin < INT_MAX.
4835
- */
4836
- static inline bool within_margin (int value , int margin )
4837
- {
4838
- return ((unsigned int )(value + margin - 1 ) < (2 * margin - 1 ));
4839
- }
4840
-
4841
4826
static inline void util_est_update (struct cfs_rq * cfs_rq ,
4842
4827
struct task_struct * p ,
4843
4828
bool task_sleep )
4844
4829
{
4845
- long last_ewma_diff , last_enqueued_diff ;
4846
- struct util_est ue ;
4830
+ unsigned int ewma , dequeued , last_ewma_diff ;
4847
4831
4848
4832
if (!sched_feat (UTIL_EST ))
4849
4833
return ;
@@ -4855,77 +4839,73 @@ static inline void util_est_update(struct cfs_rq *cfs_rq,
4855
4839
if (!task_sleep )
4856
4840
return ;
4857
4841
4842
+ /* Get current estimate of utilization */
4843
+ ewma = READ_ONCE (p -> se .avg .util_est );
4844
+
4858
4845
/*
4859
4846
* If the PELT values haven't changed since enqueue time,
4860
4847
* skip the util_est update.
4861
4848
*/
4862
- ue = p -> se .avg .util_est ;
4863
- if (ue .enqueued & UTIL_AVG_UNCHANGED )
4849
+ if (ewma & UTIL_AVG_UNCHANGED )
4864
4850
return ;
4865
4851
4866
- last_enqueued_diff = ue .enqueued ;
4852
+ /* Get utilization at dequeue */
4853
+ dequeued = task_util (p );
4867
4854
4868
4855
/*
4869
4856
* Reset EWMA on utilization increases, the moving average is used only
4870
4857
* to smooth utilization decreases.
4871
4858
*/
4872
- ue .enqueued = task_util (p );
4873
- if (ue .ewma < ue .enqueued ) {
4874
- ue .ewma = ue .enqueued ;
4859
+ if (ewma <= dequeued ) {
4860
+ ewma = dequeued ;
4875
4861
goto done ;
4876
4862
}
4877
4863
4878
4864
/*
4879
4865
* Skip update of task's estimated utilization when its members are
4880
4866
* already ~1% close to its last activation value.
4881
4867
*/
4882
- last_ewma_diff = ue .enqueued - ue .ewma ;
4883
- last_enqueued_diff -= ue .enqueued ;
4884
- if (within_margin (last_ewma_diff , UTIL_EST_MARGIN )) {
4885
- if (!within_margin (last_enqueued_diff , UTIL_EST_MARGIN ))
4886
- goto done ;
4887
-
4888
- return ;
4889
- }
4868
+ last_ewma_diff = ewma - dequeued ;
4869
+ if (last_ewma_diff < UTIL_EST_MARGIN )
4870
+ goto done ;
4890
4871
4891
4872
/*
4892
4873
* To avoid overestimation of actual task utilization, skip updates if
4893
4874
* we cannot grant there is idle time in this CPU.
4894
4875
*/
4895
- if (task_util ( p ) > arch_scale_cpu_capacity (cpu_of (rq_of (cfs_rq ))))
4876
+ if (dequeued > arch_scale_cpu_capacity (cpu_of (rq_of (cfs_rq ))))
4896
4877
return ;
4897
4878
4898
4879
/*
4899
4880
* To avoid underestimate of task utilization, skip updates of EWMA if
4900
4881
* we cannot grant that thread got all CPU time it wanted.
4901
4882
*/
4902
- if ((ue . enqueued + UTIL_EST_MARGIN ) < task_runnable (p ))
4883
+ if ((dequeued + UTIL_EST_MARGIN ) < task_runnable (p ))
4903
4884
goto done ;
4904
4885
4905
4886
4906
4887
/*
4907
4888
* Update Task's estimated utilization
4908
4889
*
4909
4890
* When *p completes an activation we can consolidate another sample
4910
- * of the task size. This is done by storing the current PELT value
4911
- * as ue.enqueued and by using this value to update the Exponential
4912
- * Weighted Moving Average (EWMA):
4891
+ * of the task size. This is done by using this value to update the
4892
+ * Exponential Weighted Moving Average (EWMA):
4913
4893
*
4914
4894
* ewma(t) = w * task_util(p) + (1-w) * ewma(t-1)
4915
4895
* = w * task_util(p) + ewma(t-1) - w * ewma(t-1)
4916
4896
* = w * (task_util(p) - ewma(t-1)) + ewma(t-1)
4917
- * = w * ( last_ewma_diff ) + ewma(t-1)
4918
- * = w * (last_ewma_diff + ewma(t-1) / w)
4897
+ * = w * ( - last_ewma_diff ) + ewma(t-1)
4898
+ * = w * (- last_ewma_diff + ewma(t-1) / w)
4919
4899
*
4920
4900
* Where 'w' is the weight of new samples, which is configured to be
4921
4901
* 0.25, thus making w=1/4 ( >>= UTIL_EST_WEIGHT_SHIFT)
4922
4902
*/
4923
- ue . ewma <<= UTIL_EST_WEIGHT_SHIFT ;
4924
- ue . ewma + = last_ewma_diff ;
4925
- ue . ewma >>= UTIL_EST_WEIGHT_SHIFT ;
4903
+ ewma <<= UTIL_EST_WEIGHT_SHIFT ;
4904
+ ewma - = last_ewma_diff ;
4905
+ ewma >>= UTIL_EST_WEIGHT_SHIFT ;
4926
4906
done :
4927
- ue . enqueued |= UTIL_AVG_UNCHANGED ;
4928
- WRITE_ONCE (p -> se .avg .util_est , ue );
4907
+ ewma |= UTIL_AVG_UNCHANGED ;
4908
+ WRITE_ONCE (p -> se .avg .util_est , ewma );
4929
4909
4930
4910
trace_sched_util_est_se_tp (& p -> se );
4931
4911
}
@@ -7653,16 +7633,16 @@ cpu_util(int cpu, struct task_struct *p, int dst_cpu, int boost)
7653
7633
if (sched_feat (UTIL_EST )) {
7654
7634
unsigned long util_est ;
7655
7635
7656
- util_est = READ_ONCE (cfs_rq -> avg .util_est . enqueued );
7636
+ util_est = READ_ONCE (cfs_rq -> avg .util_est );
7657
7637
7658
7638
/*
7659
7639
* During wake-up @p isn't enqueued yet and doesn't contribute
7660
- * to any cpu_rq(cpu)->cfs.avg.util_est.enqueued.
7640
+ * to any cpu_rq(cpu)->cfs.avg.util_est.
7661
7641
* If @dst_cpu == @cpu add it to "simulate" cpu_util after @p
7662
7642
* has been enqueued.
7663
7643
*
7664
7644
* During exec (@dst_cpu = -1) @p is enqueued and does
7665
- * contribute to cpu_rq(cpu)->cfs.util_est.enqueued.
7645
+ * contribute to cpu_rq(cpu)->cfs.util_est.
7666
7646
* Remove it to "simulate" cpu_util without @p's contribution.
7667
7647
*
7668
7648
* Despite the task_on_rq_queued(@p) check there is still a
0 commit comments