From 3a8be15639f48c787832004ed866be6fbc54111e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20G=C3=B3mez?= Date: Sun, 29 Sep 2024 15:08:47 -0300 Subject: [PATCH] [SQUASH] sched/energy: Bring back energy model This wasn't doing any harm in the end. Revert "Revert "arm64: dts: trinket: Enable freq-energy-model"" This reverts commit ce4e2d09c94b4d3caf77542c337835a467b8e8c9. Revert "Revert "sched/energy: Checkout to branch android-4.14 of https://android.googlesource.com/kernel/common"" This reverts commit 16a7f6504771a9379ed4c3383794724ecb7464f9. --- arch/arm64/boot/dts/qcom/trinket.dtsi | 8 +++ kernel/sched/energy.c | 97 +++++++++++---------------- 2 files changed, 48 insertions(+), 57 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/trinket.dtsi b/arch/arm64/boot/dts/qcom/trinket.dtsi index 36c3cacc4434..225ee55787c3 100644 --- a/arch/arm64/boot/dts/qcom/trinket.dtsi +++ b/arch/arm64/boot/dts/qcom/trinket.dtsi @@ -68,6 +68,7 @@ capacity-dmips-mhz = <1024>; sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>; next-level-cache = <&L2_0>; + freq-energy-model; qcom,lmh-dcvs = <&lmh_dcvs0>; #cooling-cells = <2>; L2_0: l2-cache { @@ -97,6 +98,7 @@ capacity-dmips-mhz = <1024>; sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>; next-level-cache = <&L2_0>; + freq-energy-model; qcom,lmh-dcvs = <&lmh_dcvs0>; #cooling-cells = <2>; @@ -123,6 +125,7 @@ capacity-dmips-mhz = <1024>; sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>; next-level-cache = <&L2_0>; + freq-energy-model; qcom,lmh-dcvs = <&lmh_dcvs0>; #cooling-cells = <2>; @@ -149,6 +152,7 @@ capacity-dmips-mhz = <1024>; sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>; next-level-cache = <&L2_0>; + freq-energy-model; qcom,lmh-dcvs = <&lmh_dcvs0>; #cooling-cells = <2>; @@ -175,6 +179,7 @@ capacity-dmips-mhz = <1638>; sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>; next-level-cache = <&L2_1>; + freq-energy-model; qcom,lmh-dcvs = <&lmh_dcvs1>; #cooling-cells = <2>; L2_1: l2-cache { @@ -205,6 +210,7 @@ capacity-dmips-mhz = <1638>; sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>; next-level-cache = <&L2_1>; + freq-energy-model; qcom,lmh-dcvs = <&lmh_dcvs1>; #cooling-cells = <2>; @@ -231,6 +237,7 @@ capacity-dmips-mhz = <1638>; sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>; next-level-cache = <&L2_1>; + freq-energy-model; qcom,lmh-dcvs = <&lmh_dcvs1>; #cooling-cells = <2>; @@ -257,6 +264,7 @@ capacity-dmips-mhz = <1638>; sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>; next-level-cache = <&L2_1>; + freq-energy-model; qcom,lmh-dcvs = <&lmh_dcvs1>; #cooling-cells = <2>; diff --git a/kernel/sched/energy.c b/kernel/sched/energy.c index 9efd07394bd7..8342de041e11 100644 --- a/kernel/sched/energy.c +++ b/kernel/sched/energy.c @@ -51,6 +51,7 @@ static void free_resources(void) } } static bool sge_ready; +static bool freq_energy_model; void check_max_cap_vs_cpu_scale(int cpu, struct sched_group_energy *sge) { @@ -62,7 +63,7 @@ void check_max_cap_vs_cpu_scale(int cpu, struct sched_group_energy *sge) if (max_cap == cpu_scale) return; - pr_debug("CPU%d max energy model capacity=%ld != cpu_scale=%ld\n", cpu, + pr_warn("CPU%d max energy model capacity=%ld != cpu_scale=%ld\n", cpu, max_cap, cpu_scale); } @@ -76,9 +77,6 @@ void init_sched_energy_costs(void) int sd_level, i, nstates, cpu; const __be32 *val; - if (!sched_is_energy_aware()) - return; - for_each_possible_cpu(cpu) { cn = of_get_cpu_node(cpu, NULL); if (!cn) { @@ -90,6 +88,9 @@ void init_sched_energy_costs(void) pr_warn("CPU device node has no sched-energy-costs\n"); return; } + /* Check if the energy model contains frequency/power values */ + if (of_find_property(cn, "freq-energy-model", NULL)) + freq_energy_model = true; for_each_possible_sd_level(sd_level) { cp = of_parse_phandle(cn, "sched-energy-costs", sd_level); @@ -104,21 +105,25 @@ void init_sched_energy_costs(void) sge = kcalloc(1, sizeof(struct sched_group_energy), GFP_NOWAIT); - if (!sge) - goto out; nstates = (prop->length / sizeof(u32)) / 2; cap_states = kcalloc(nstates, sizeof(struct capacity_state), GFP_NOWAIT); - if (!cap_states) { - kfree(sge); - goto out; - } for (i = 0, val = prop->value; i < nstates; i++) { - cap_states[i].cap = SCHED_CAPACITY_SCALE; - cap_states[i].frequency = be32_to_cpup(val++); + if (freq_energy_model) { + /* + * Capacity values will be calculated later using + * frequency reported by OPP driver and cpu_uarch_scale + * values. + */ + cap_states[i].frequency = be32_to_cpup(val++); + cap_states[i].cap = 0; + } else { + cap_states[i].frequency = 0; + cap_states[i].cap = be32_to_cpup(val++); + } cap_states[i].power = be32_to_cpup(val++); } @@ -128,8 +133,6 @@ void init_sched_energy_costs(void) prop = of_find_property(cp, "idle-cost-data", NULL); if (!prop || !prop->value) { pr_warn("No idle-cost data, skipping sched_energy init\n"); - kfree(sge); - kfree(cap_states); goto out; } @@ -137,11 +140,6 @@ void init_sched_energy_costs(void) idle_states = kcalloc(nstates, sizeof(struct idle_state), GFP_NOWAIT); - if (!idle_states) { - kfree(sge); - kfree(cap_states); - goto out; - } for (i = 0, val = prop->value; i < nstates; i++) idle_states[i].power = be32_to_cpup(val++); @@ -151,10 +149,9 @@ void init_sched_energy_costs(void) sge_array[cpu][sd_level] = sge; } - - check_max_cap_vs_cpu_scale(cpu, sge_array[cpu][SD_LEVEL0]); + if (!freq_energy_model) + check_max_cap_vs_cpu_scale(cpu, sge_array[cpu][SD_LEVEL0]); } - sge_ready = true; pr_info("Sched-energy-costs installed from DT\n"); return; @@ -165,17 +162,16 @@ void init_sched_energy_costs(void) static int sched_energy_probe(struct platform_device *pdev) { - unsigned long max_freq = 0; - int max_efficiency = INT_MIN; int cpu; unsigned long *max_frequencies = NULL; int ret; - if (!sched_is_energy_aware()) - return 0; if (!sge_ready) return -EPROBE_DEFER; + if (!energy_aware() || !freq_energy_model) + return 0; + max_frequencies = kmalloc_array(nr_cpu_ids, sizeof(unsigned long), GFP_KERNEL); if (!max_frequencies) { @@ -190,9 +186,6 @@ static int sched_energy_probe(struct platform_device *pdev) for_each_possible_cpu(cpu) { struct device *cpu_dev; struct dev_pm_opp *opp; - int efficiency = topology_get_cpu_efficiency(cpu); - - max_efficiency = max(efficiency, max_efficiency); cpu_dev = get_cpu_device(cpu); if (IS_ERR_OR_NULL(cpu_dev)) { @@ -217,19 +210,13 @@ static int sched_energy_probe(struct platform_device *pdev) /* Convert HZ to KHZ */ max_frequencies[cpu] /= 1000; - max_freq = max(max_freq, max_frequencies[cpu]); } /* update capacity in energy model */ for_each_possible_cpu(cpu) { unsigned long cpu_max_cap; struct sched_group_energy *sge_l0, *sge; - int efficiency = topology_get_cpu_efficiency(cpu); - - cpu_max_cap = DIV_ROUND_UP(SCHED_CAPACITY_SCALE * - max_frequencies[cpu], max_freq); - cpu_max_cap = DIV_ROUND_UP(cpu_max_cap * efficiency, - max_efficiency); + cpu_max_cap = topology_get_cpu_scale(NULL, cpu); /* * All the cap_states have same frequency table so use @@ -261,7 +248,6 @@ static int sched_energy_probe(struct platform_device *pdev) break; sge->cap_states[i].cap = cap; } - dev_dbg(&pdev->dev, "cpu=%d freq=%ld cap=%ld power_d0=%ld\n", cpu, freq, sge_l0->cap_states[i].cap, @@ -269,8 +255,8 @@ static int sched_energy_probe(struct platform_device *pdev) } dev_info(&pdev->dev, - "cpu=%d eff=%d [freq=%ld cap=%ld power_d0=%ld] -> [freq=%ld cap=%ld power_d0=%ld]\n", - cpu, efficiency, + "cpu=%d [freq=%ld cap=%ld power_d0=%ld] -> [freq=%ld cap=%ld power_d0=%ld]\n", + cpu, sge_l0->cap_states[0].frequency, sge_l0->cap_states[0].cap, sge_l0->cap_states[0].power, @@ -279,45 +265,42 @@ static int sched_energy_probe(struct platform_device *pdev) sge_l0->cap_states[ncapstates - 1].power ); } - - - dev_dbg(&pdev->dev, - "cpu=%d efficiency=%d max_frequency=%ld max_efficiency=%d cpu_max_capacity=%ld\n", - cpu, efficiency, max_frequencies[cpu], max_efficiency, - cpu_max_cap); - } kfree(max_frequencies); - dev_info(&pdev->dev, "Sched-energy-costs capacity updated\n"); return 0; exit: if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "error=%d\n", ret); - kfree(max_frequencies); return ret; } -static const struct of_device_id of_sched_energy_dt[] = { - { - .compatible = "sched-energy", - }, - { } -}; - static struct platform_driver energy_driver = { .driver = { .name = "sched-energy", - .of_match_table = of_sched_energy_dt, }, .probe = sched_energy_probe, }; +static struct platform_device energy_device = { + .name = "sched-energy", +}; + static int __init sched_energy_init(void) { - return platform_driver_register(&energy_driver); + int ret; + + ret = platform_device_register(&energy_device); + if (ret) + pr_err("%s device_register failed:%d\n", __func__, ret); + ret = platform_driver_register(&energy_driver); + if (ret) { + pr_err("%s driver_register failed:%d\n", __func__, ret); + platform_device_unregister(&energy_device); + } + return ret; } subsys_initcall(sched_energy_init);