PM: EM: Introduce em_compute_costs()
authorLukasz Luba <lukasz.luba@arm.com>
Thu, 8 Feb 2024 11:55:39 +0000 (11:55 +0000)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 8 Feb 2024 14:00:25 +0000 (15:00 +0100)
Move the EM costs computation code into a new dedicated function,
em_compute_costs(), that can be reused in other places in the future.

This change is not expected to alter the general functionality.

Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
kernel/power/energy_model.c

index 0c3220f..5c47caa 100644 (file)
@@ -103,14 +103,52 @@ static void em_debug_create_pd(struct device *dev) {}
 static void em_debug_remove_pd(struct device *dev) {}
 #endif
 
+static int em_compute_costs(struct device *dev, struct em_perf_state *table,
+                           struct em_data_callback *cb, int nr_states,
+                           unsigned long flags)
+{
+       unsigned long prev_cost = ULONG_MAX;
+       u64 fmax;
+       int i, ret;
+
+       /* Compute the cost of each performance state. */
+       fmax = (u64) table[nr_states - 1].frequency;
+       for (i = nr_states - 1; i >= 0; i--) {
+               unsigned long power_res, cost;
+
+               if (flags & EM_PERF_DOMAIN_ARTIFICIAL) {
+                       ret = cb->get_cost(dev, table[i].frequency, &cost);
+                       if (ret || !cost || cost > EM_MAX_POWER) {
+                               dev_err(dev, "EM: invalid cost %lu %d\n",
+                                       cost, ret);
+                               return -EINVAL;
+                       }
+               } else {
+                       power_res = table[i].power;
+                       cost = div64_u64(fmax * power_res, table[i].frequency);
+               }
+
+               table[i].cost = cost;
+
+               if (table[i].cost >= prev_cost) {
+                       table[i].flags = EM_PERF_STATE_INEFFICIENT;
+                       dev_dbg(dev, "EM: OPP:%lu is inefficient\n",
+                               table[i].frequency);
+               } else {
+                       prev_cost = table[i].cost;
+               }
+       }
+
+       return 0;
+}
+
 static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd,
                                int nr_states, struct em_data_callback *cb,
                                unsigned long flags)
 {
-       unsigned long power, freq, prev_freq = 0, prev_cost = ULONG_MAX;
+       unsigned long power, freq, prev_freq = 0;
        struct em_perf_state *table;
        int i, ret;
-       u64 fmax;
 
        table = kcalloc(nr_states, sizeof(*table), GFP_KERNEL);
        if (!table)
@@ -154,33 +192,9 @@ static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd,
                table[i].frequency = prev_freq = freq;
        }
 
-       /* Compute the cost of each performance state. */
-       fmax = (u64) table[nr_states - 1].frequency;
-       for (i = nr_states - 1; i >= 0; i--) {
-               unsigned long power_res, cost;
-
-               if (flags & EM_PERF_DOMAIN_ARTIFICIAL) {
-                       ret = cb->get_cost(dev, table[i].frequency, &cost);
-                       if (ret || !cost || cost > EM_MAX_POWER) {
-                               dev_err(dev, "EM: invalid cost %lu %d\n",
-                                       cost, ret);
-                               goto free_ps_table;
-                       }
-               } else {
-                       power_res = table[i].power;
-                       cost = div64_u64(fmax * power_res, table[i].frequency);
-               }
-
-               table[i].cost = cost;
-
-               if (table[i].cost >= prev_cost) {
-                       table[i].flags = EM_PERF_STATE_INEFFICIENT;
-                       dev_dbg(dev, "EM: OPP:%lu is inefficient\n",
-                               table[i].frequency);
-               } else {
-                       prev_cost = table[i].cost;
-               }
-       }
+       ret = em_compute_costs(dev, table, cb, nr_states, flags);
+       if (ret)
+               goto free_ps_table;
 
        pd->table = table;
        pd->nr_perf_states = nr_states;