@@ -8084,6 +8084,105 @@ static unsigned long cpu_util_without(int cpu, struct task_struct *p)
8084
8084
return cpu_util (cpu , p , -1 , 0 );
8085
8085
}
8086
8086
8087
+ /*
8088
+ * This function computes an effective utilization for the given CPU, to be
8089
+ * used for frequency selection given the linear relation: f = u * f_max.
8090
+ *
8091
+ * The scheduler tracks the following metrics:
8092
+ *
8093
+ * cpu_util_{cfs,rt,dl,irq}()
8094
+ * cpu_bw_dl()
8095
+ *
8096
+ * Where the cfs,rt and dl util numbers are tracked with the same metric and
8097
+ * synchronized windows and are thus directly comparable.
8098
+ *
8099
+ * The cfs,rt,dl utilization are the running times measured with rq->clock_task
8100
+ * which excludes things like IRQ and steal-time. These latter are then accrued
8101
+ * in the IRQ utilization.
8102
+ *
8103
+ * The DL bandwidth number OTOH is not a measured metric but a value computed
8104
+ * based on the task model parameters and gives the minimal utilization
8105
+ * required to meet deadlines.
8106
+ */
8107
+ unsigned long effective_cpu_util (int cpu , unsigned long util_cfs ,
8108
+ unsigned long * min ,
8109
+ unsigned long * max )
8110
+ {
8111
+ unsigned long util , irq , scale ;
8112
+ struct rq * rq = cpu_rq (cpu );
8113
+
8114
+ scale = arch_scale_cpu_capacity (cpu );
8115
+
8116
+ /*
8117
+ * Early check to see if IRQ/steal time saturates the CPU, can be
8118
+ * because of inaccuracies in how we track these -- see
8119
+ * update_irq_load_avg().
8120
+ */
8121
+ irq = cpu_util_irq (rq );
8122
+ if (unlikely (irq >= scale )) {
8123
+ if (min )
8124
+ * min = scale ;
8125
+ if (max )
8126
+ * max = scale ;
8127
+ return scale ;
8128
+ }
8129
+
8130
+ if (min ) {
8131
+ /*
8132
+ * The minimum utilization returns the highest level between:
8133
+ * - the computed DL bandwidth needed with the IRQ pressure which
8134
+ * steals time to the deadline task.
8135
+ * - The minimum performance requirement for CFS and/or RT.
8136
+ */
8137
+ * min = max (irq + cpu_bw_dl (rq ), uclamp_rq_get (rq , UCLAMP_MIN ));
8138
+
8139
+ /*
8140
+ * When an RT task is runnable and uclamp is not used, we must
8141
+ * ensure that the task will run at maximum compute capacity.
8142
+ */
8143
+ if (!uclamp_is_used () && rt_rq_is_runnable (& rq -> rt ))
8144
+ * min = max (* min , scale );
8145
+ }
8146
+
8147
+ /*
8148
+ * Because the time spend on RT/DL tasks is visible as 'lost' time to
8149
+ * CFS tasks and we use the same metric to track the effective
8150
+ * utilization (PELT windows are synchronized) we can directly add them
8151
+ * to obtain the CPU's actual utilization.
8152
+ */
8153
+ util = util_cfs + cpu_util_rt (rq );
8154
+ util += cpu_util_dl (rq );
8155
+
8156
+ /*
8157
+ * The maximum hint is a soft bandwidth requirement, which can be lower
8158
+ * than the actual utilization because of uclamp_max requirements.
8159
+ */
8160
+ if (max )
8161
+ * max = min (scale , uclamp_rq_get (rq , UCLAMP_MAX ));
8162
+
8163
+ if (util >= scale )
8164
+ return scale ;
8165
+
8166
+ /*
8167
+ * There is still idle time; further improve the number by using the
8168
+ * IRQ metric. Because IRQ/steal time is hidden from the task clock we
8169
+ * need to scale the task numbers:
8170
+ *
8171
+ * max - irq
8172
+ * U' = irq + --------- * U
8173
+ * max
8174
+ */
8175
+ util = scale_irq_capacity (util , irq , scale );
8176
+ util += irq ;
8177
+
8178
+ return min (scale , util );
8179
+ }
8180
+
8181
+ unsigned long sched_cpu_util (int cpu )
8182
+ {
8183
+ return effective_cpu_util (cpu , cpu_util_cfs (cpu ), NULL , NULL );
8184
+ }
8185
+
8087
8186
/*
8088
8187
* energy_env - Utilization landscape for energy estimation.
8089
8188
* @task_busy_time: Utilization contribution by the task for which we test the
0 commit comments