From patchwork Tue Mar 9 22:42:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 396096 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp2976828jai; Tue, 9 Mar 2021 14:43:34 -0800 (PST) X-Google-Smtp-Source: ABdhPJya2Oz4wOQsb58kQOlBZpbOtSbOr+dxz2+0oxQkWXoEWKudsEPGAE4fLN7DvjSWFMI6cmKc X-Received: by 2002:aa7:d98b:: with SMTP id u11mr1130219eds.352.1615329814130; Tue, 09 Mar 2021 14:43:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1615329814; cv=none; d=google.com; s=arc-20160816; b=mVpZWRA7Ln0HzbzwtN3KcTiV8u9c/kvPjrdAGC2wH6l+NK8MK9Ww1ERmiijUIFSc8I dCJZuYjJ/YNH1qv0oZdV8J3a9sugu1RW5Gie/XUmW89N+WHgPt3qa7/QvgIspGEz6HWa RqTqmq6udycAl818dy/gLpDfmxhXVrYGpv0O7RuAW++bpDpG3L6erPQcwent36kgmTvx sJlGZP5vl89UURyOcREQh9z+Chm6KY7wj4uu6EJb2lcTXqp6HtLyB65IiJ073uJmdPOn ikSp2V7/TxNg8glM7Q5k4YQip46xTn5xcqruXW0pf5RKn0e6hrcQTiIZZXrGWwUzkyng i5Pg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:message-id:date:subject:cc:to:from :dkim-signature; bh=GoTOdV/s4l3cqoypT5zUMlfkcoLLVwoOXrCw3mPvlog=; b=aQ1t6KaQ6P+2h5A8BZTxIAhM8ZeQPmKZClcQfY4iG2W4aVQaCPPw5AL9AxvX0wddre 4380lFGaV57eN28hZiMyog3hsv9VMT5IsBIMQ7DtjGCYVBnp6+NNk7BuMUH70/J8wnaf NJ8SUOesoVAz8E18cFLDfown0voEa7FYBFyUexOPBPD10ei5lNjhczTR6VCz1mE0g8i8 /5uWRgr6chuYyhasKU2CvrueDufAME++p7FiSWz3bNm2L2WBvNZ/HLhu0cREPHuJtsxw xQN3D3cokXzKBMd3ze0mTy9FfivlNhU3lFdNp4U9vsU7eO+9X2rDXC84Qx4ibzZ6rtGd 9Dcg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=A41AsGXF; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id c11si7915222edr.72.2021.03.09.14.43.33; Tue, 09 Mar 2021 14:43:34 -0800 (PST) Received-SPF: pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=A41AsGXF; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231904AbhCIWnB (ORCPT + 7 others); Tue, 9 Mar 2021 17:43:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53030 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232094AbhCIWmy (ORCPT ); Tue, 9 Mar 2021 17:42:54 -0500 Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 268E2C06175F for ; Tue, 9 Mar 2021 14:42:54 -0800 (PST) Received: by mail-wr1-x431.google.com with SMTP id a18so19056423wrc.13 for ; Tue, 09 Mar 2021 14:42:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=GoTOdV/s4l3cqoypT5zUMlfkcoLLVwoOXrCw3mPvlog=; b=A41AsGXFsRHJrRzA8lw9FLreB0ZjhH2MeFEigLEUrIsKyAEc8rjCZT+NWV8i+ws5id DHs6hwkBEELd02yschGbG3BnOsEVJyeCUVeHZfyafXCEklEFbKChHmLAWoL54XHELjxa dsCD0mufz8LP0DlyBkyEzRWK9h0WVWxAy4yndCyhl3ouPT03v7FdoNGRUmtV/OwM2uPv krhTvJkc/FdJnRDiGbBIzVutESmyhZ+0e3+rIKXiubnpEhumO2vlHvvYc/wEAIU+j/hh zNaWR0Mrt3eg46Fo2PCmuWBWvdsJlWK5/MDUpVOu7Mj7JiQbbsPi5pbeEH3Um75mwzte SEtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=GoTOdV/s4l3cqoypT5zUMlfkcoLLVwoOXrCw3mPvlog=; b=STByGP9gxDb0ZO6Ou8MLV5ywcONpoeQVs8F94+Gws4amhIhI+7edQpG4N621zT9hPk m9sQPS6NM9MIYW5Z6lZ5e72mhyPWY/yolbUlG0NiMeImkZlWl8VJEDTxQeTKcAiAdhBZ /E/fEkevw/tFpGwU1H9Du70LfBiV/WjbjkUSxHbxi5GeldNaY/laSp83/0blLHs9HZWR Qi86kP+ORT4QptgjCoa2QwVpara8MKiHJ/A0WbJRk6LlAwL/2xrJMTr27HRvYIr8GUV7 LyLHAabtXpD2WovWVTUN4+v9omYaEbgmiDHRqCsI24FB9TAZP8PmFg8mn/xvjoZWWrzu fhDw== X-Gm-Message-State: AOAM530PqAWRUGF1FKFt2EiJbitr9wppvE93S8gzkCtksT+u/ujhkfPg /wOT4XVbz2FXb9zry9OePMtY3g== X-Received: by 2002:a5d:538d:: with SMTP id d13mr169591wrv.92.1615329772784; Tue, 09 Mar 2021 14:42:52 -0800 (PST) Received: from localhost.localdomain ([82.142.0.212]) by smtp.gmail.com with ESMTPSA id p16sm30352179wrt.54.2021.03.09.14.42.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Mar 2021 14:42:52 -0800 (PST) From: Daniel Lezcano To: daniel.lezcano@linaro.org, rafael@kernel.org Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, lukasz.luba@arm.com Subject: [PATCH v2 1/5] powercap/drivers/dtpm: Encapsulate even more the code Date: Tue, 9 Mar 2021 23:42:40 +0100 Message-Id: <20210309224244.27225-1-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.17.1 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org In order to increase the self-encapsulation of the dtpm generic code, the following changes are adding a power update ops to the dtpm ops. That allows the generic code to call directly the dtpm backend function to update the power values. The power update function does compute the power characteristics when the function is invoked. In the case of the CPUs, the power consumption depends on the number of online CPUs. The online CPUs mask is not up to date at CPUHP_AP_ONLINE_DYN state in the tear down callback. That is the reason why the online / offline are at separate state. As there is already an existing state for DTPM, this one is only moved to the DEAD state, so there is no addition of new state with these changes. The dtpm node is not removed when the cpu is unplugged. That simplifies the code for the next changes and results in a more self-encapsulated code. Signed-off-by: Daniel Lezcano --- V2: - Updated the changelog with the CPU node not being removed - Commented the cpu hotplug callbacks to explain why there are two callbacks - Changed 'upt_power_uw' to 'update_power_uw' - Removed unused cpumask variable --- drivers/powercap/dtpm.c | 54 ++++++------- drivers/powercap/dtpm_cpu.c | 148 ++++++++++++++++-------------------- include/linux/cpuhotplug.h | 2 +- include/linux/dtpm.h | 3 +- 4 files changed, 97 insertions(+), 110 deletions(-) -- 2.17.1 diff --git a/drivers/powercap/dtpm.c b/drivers/powercap/dtpm.c index c2185ec5f887..58433b8ef9a1 100644 --- a/drivers/powercap/dtpm.c +++ b/drivers/powercap/dtpm.c @@ -116,8 +116,6 @@ static void __dtpm_sub_power(struct dtpm *dtpm) parent->power_limit -= dtpm->power_limit; parent = parent->parent; } - - __dtpm_rebalance_weight(root); } static void __dtpm_add_power(struct dtpm *dtpm) @@ -130,45 +128,45 @@ static void __dtpm_add_power(struct dtpm *dtpm) parent->power_limit += dtpm->power_limit; parent = parent->parent; } +} + +static int __dtpm_update_power(struct dtpm *dtpm) +{ + int ret; + + __dtpm_sub_power(dtpm); - __dtpm_rebalance_weight(root); + ret = dtpm->ops->update_power_uw(dtpm); + if (ret) + pr_err("Failed to update power for '%s': %d\n", + dtpm->zone.name, ret); + + if (!test_bit(DTPM_POWER_LIMIT_FLAG, &dtpm->flags)) + dtpm->power_limit = dtpm->power_max; + + __dtpm_add_power(dtpm); + + if (root) + __dtpm_rebalance_weight(root); + + return ret; } /** * dtpm_update_power - Update the power on the dtpm * @dtpm: a pointer to a dtpm structure to update - * @power_min: a u64 representing the new power_min value - * @power_max: a u64 representing the new power_max value * * Function to update the power values of the dtpm node specified in * parameter. These new values will be propagated to the tree. * * Return: zero on success, -EINVAL if the values are inconsistent */ -int dtpm_update_power(struct dtpm *dtpm, u64 power_min, u64 power_max) +int dtpm_update_power(struct dtpm *dtpm) { - int ret = 0; + int ret; mutex_lock(&dtpm_lock); - - if (power_min == dtpm->power_min && power_max == dtpm->power_max) - goto unlock; - - if (power_max < power_min) { - ret = -EINVAL; - goto unlock; - } - - __dtpm_sub_power(dtpm); - - dtpm->power_min = power_min; - dtpm->power_max = power_max; - if (!test_bit(DTPM_POWER_LIMIT_FLAG, &dtpm->flags)) - dtpm->power_limit = power_max; - - __dtpm_add_power(dtpm); - -unlock: + ret = __dtpm_update_power(dtpm); mutex_unlock(&dtpm_lock); return ret; @@ -436,6 +434,7 @@ int dtpm_register(const char *name, struct dtpm *dtpm, struct dtpm *parent) if (dtpm->ops && !(dtpm->ops->set_power_uw && dtpm->ops->get_power_uw && + dtpm->ops->update_power_uw && dtpm->ops->release)) return -EINVAL; @@ -455,7 +454,8 @@ int dtpm_register(const char *name, struct dtpm *dtpm, struct dtpm *parent) root = dtpm; } - __dtpm_add_power(dtpm); + if (dtpm->ops && !dtpm->ops->update_power_uw(dtpm)) + __dtpm_add_power(dtpm); pr_info("Registered dtpm node '%s' / %llu-%llu uW, \n", dtpm->zone.name, dtpm->power_min, dtpm->power_max); diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c index 51c366938acd..cfb120280887 100644 --- a/drivers/powercap/dtpm_cpu.c +++ b/drivers/powercap/dtpm_cpu.c @@ -14,6 +14,8 @@ * The CPU hotplug is supported and the power numbers will be updated * if a CPU is hot plugged / unplugged. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -23,8 +25,6 @@ #include #include -static struct dtpm *__parent; - static DEFINE_PER_CPU(struct dtpm *, dtpm_per_cpu); struct dtpm_cpu { @@ -32,57 +32,16 @@ struct dtpm_cpu { int cpu; }; -/* - * When a new CPU is inserted at hotplug or boot time, add the power - * contribution and update the dtpm tree. - */ -static int power_add(struct dtpm *dtpm, struct em_perf_domain *em) -{ - u64 power_min, power_max; - - power_min = em->table[0].power; - power_min *= MICROWATT_PER_MILLIWATT; - power_min += dtpm->power_min; - - power_max = em->table[em->nr_perf_states - 1].power; - power_max *= MICROWATT_PER_MILLIWATT; - power_max += dtpm->power_max; - - return dtpm_update_power(dtpm, power_min, power_max); -} - -/* - * When a CPU is unplugged, remove its power contribution from the - * dtpm tree. - */ -static int power_sub(struct dtpm *dtpm, struct em_perf_domain *em) -{ - u64 power_min, power_max; - - power_min = em->table[0].power; - power_min *= MICROWATT_PER_MILLIWATT; - power_min = dtpm->power_min - power_min; - - power_max = em->table[em->nr_perf_states - 1].power; - power_max *= MICROWATT_PER_MILLIWATT; - power_max = dtpm->power_max - power_max; - - return dtpm_update_power(dtpm, power_min, power_max); -} - static u64 set_pd_power_limit(struct dtpm *dtpm, u64 power_limit) { struct dtpm_cpu *dtpm_cpu = dtpm->private; - struct em_perf_domain *pd; + struct em_perf_domain *pd = em_cpu_get(dtpm_cpu->cpu); struct cpumask cpus; unsigned long freq; u64 power; int i, nr_cpus; - pd = em_cpu_get(dtpm_cpu->cpu); - cpumask_and(&cpus, cpu_online_mask, to_cpumask(pd->cpus)); - nr_cpus = cpumask_weight(&cpus); for (i = 0; i < pd->nr_perf_states; i++) { @@ -113,6 +72,7 @@ static u64 get_pd_power_uw(struct dtpm *dtpm) pd = em_cpu_get(dtpm_cpu->cpu); freq = cpufreq_quick_get(dtpm_cpu->cpu); + cpumask_and(&cpus, cpu_online_mask, to_cpumask(pd->cpus)); nr_cpus = cpumask_weight(&cpus); @@ -128,6 +88,27 @@ static u64 get_pd_power_uw(struct dtpm *dtpm) return 0; } +static int update_pd_power_uw(struct dtpm *dtpm) +{ + struct dtpm_cpu *dtpm_cpu = dtpm->private; + struct em_perf_domain *em = em_cpu_get(dtpm_cpu->cpu); + struct cpumask cpus; + int nr_cpus; + + cpumask_and(&cpus, cpu_online_mask, to_cpumask(em->cpus)); + nr_cpus = cpumask_weight(&cpus); + + dtpm->power_min = em->table[0].power; + dtpm->power_min *= MICROWATT_PER_MILLIWATT; + dtpm->power_min *= nr_cpus; + + dtpm->power_max = em->table[em->nr_perf_states - 1].power; + dtpm->power_max *= MICROWATT_PER_MILLIWATT; + dtpm->power_max *= nr_cpus; + + return 0; +} + static void pd_release(struct dtpm *dtpm) { struct dtpm_cpu *dtpm_cpu = dtpm->private; @@ -139,39 +120,24 @@ static void pd_release(struct dtpm *dtpm) } static struct dtpm_ops dtpm_ops = { - .set_power_uw = set_pd_power_limit, - .get_power_uw = get_pd_power_uw, - .release = pd_release, + .set_power_uw = set_pd_power_limit, + .get_power_uw = get_pd_power_uw, + .update_power_uw = update_pd_power_uw, + .release = pd_release, }; static int cpuhp_dtpm_cpu_offline(unsigned int cpu) { - struct cpufreq_policy *policy; struct em_perf_domain *pd; struct dtpm *dtpm; - policy = cpufreq_cpu_get(cpu); - - if (!policy) - return 0; - pd = em_cpu_get(cpu); if (!pd) return -EINVAL; dtpm = per_cpu(dtpm_per_cpu, cpu); - power_sub(dtpm, pd); - - if (cpumask_weight(policy->cpus) != 1) - return 0; - - for_each_cpu(cpu, policy->related_cpus) - per_cpu(dtpm_per_cpu, cpu) = NULL; - - dtpm_unregister(dtpm); - - return 0; + return dtpm_update_power(dtpm); } static int cpuhp_dtpm_cpu_online(unsigned int cpu) @@ -184,7 +150,6 @@ static int cpuhp_dtpm_cpu_online(unsigned int cpu) int ret = -ENOMEM; policy = cpufreq_cpu_get(cpu); - if (!policy) return 0; @@ -194,7 +159,7 @@ static int cpuhp_dtpm_cpu_online(unsigned int cpu) dtpm = per_cpu(dtpm_per_cpu, cpu); if (dtpm) - return power_add(dtpm, pd); + return dtpm_update_power(dtpm); dtpm = dtpm_alloc(&dtpm_ops); if (!dtpm) @@ -210,27 +175,20 @@ static int cpuhp_dtpm_cpu_online(unsigned int cpu) for_each_cpu(cpu, policy->related_cpus) per_cpu(dtpm_per_cpu, cpu) = dtpm; - sprintf(name, "cpu%d", dtpm_cpu->cpu); + sprintf(name, "cpu%d-cpufreq", dtpm_cpu->cpu); - ret = dtpm_register(name, dtpm, __parent); + ret = dtpm_register(name, dtpm, NULL); if (ret) goto out_kfree_dtpm_cpu; - ret = power_add(dtpm, pd); - if (ret) - goto out_dtpm_unregister; - ret = freq_qos_add_request(&policy->constraints, &dtpm_cpu->qos_req, FREQ_QOS_MAX, pd->table[pd->nr_perf_states - 1].frequency); if (ret) - goto out_power_sub; + goto out_dtpm_unregister; return 0; -out_power_sub: - power_sub(dtpm, pd); - out_dtpm_unregister: dtpm_unregister(dtpm); dtpm_cpu = NULL; @@ -248,10 +206,38 @@ static int cpuhp_dtpm_cpu_online(unsigned int cpu) int dtpm_register_cpu(struct dtpm *parent) { - __parent = parent; + int ret; + + /* + * The callbacks at CPU hotplug time are calling + * dtpm_update_power() which in turns calls update_pd_power(). + * + * The function update_pd_power() uses the online mask to + * figure out the power consumption limits. + * + * At CPUHP_AP_ONLINE_DYN, the CPU is present in the CPU + * online mask when the cpuhp_dtpm_cpu_online function is + * called, but the CPU is still in the online mask for the + * tear down callback. So the power can not be updated when + * the CPU is unplugged. + * + * At CPUHP_AP_DTPM_CPU_DEAD, the situation is the opposite as + * above. The CPU online mask is not up to date when the CPU + * is plugged in. + * + * For this reason, we need to call the online and offline + * callbacks at different moments when the CPU online mask is + * consistent with the power numbers we want to update. + */ + ret = cpuhp_setup_state(CPUHP_AP_DTPM_CPU_DEAD, "dtpm_cpu:offline", + NULL, cpuhp_dtpm_cpu_offline); + if (ret < 0) + return ret; + + ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "dtpm_cpu:online", + cpuhp_dtpm_cpu_online, NULL); + if (ret < 0) + return ret; - return cpuhp_setup_state(CPUHP_AP_DTPM_CPU_ONLINE, - "dtpm_cpu:online", - cpuhp_dtpm_cpu_online, - cpuhp_dtpm_cpu_offline); + return 0; } diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index ee09a39627d6..fcb2967fb5ba 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -61,6 +61,7 @@ enum cpuhp_state { CPUHP_LUSTRE_CFS_DEAD, CPUHP_AP_ARM_CACHE_B15_RAC_DEAD, CPUHP_PADATA_DEAD, + CPUHP_AP_DTPM_CPU_DEAD, CPUHP_WORKQUEUE_PREP, CPUHP_POWER_NUMA_PREPARE, CPUHP_HRTIMERS_PREPARE, @@ -193,7 +194,6 @@ enum cpuhp_state { CPUHP_AP_ONLINE_DYN_END = CPUHP_AP_ONLINE_DYN + 30, CPUHP_AP_X86_HPET_ONLINE, CPUHP_AP_X86_KVM_CLK_ONLINE, - CPUHP_AP_DTPM_CPU_ONLINE, CPUHP_AP_ACTIVE, CPUHP_ONLINE, }; diff --git a/include/linux/dtpm.h b/include/linux/dtpm.h index e80a332e3d8a..acf8d3638988 100644 --- a/include/linux/dtpm.h +++ b/include/linux/dtpm.h @@ -29,6 +29,7 @@ struct dtpm { struct dtpm_ops { u64 (*set_power_uw)(struct dtpm *, u64); u64 (*get_power_uw)(struct dtpm *); + int (*update_power_uw)(struct dtpm *); void (*release)(struct dtpm *); }; @@ -62,7 +63,7 @@ static inline struct dtpm *to_dtpm(struct powercap_zone *zone) return container_of(zone, struct dtpm, zone); } -int dtpm_update_power(struct dtpm *dtpm, u64 power_min, u64 power_max); +int dtpm_update_power(struct dtpm *dtpm); int dtpm_release_zone(struct powercap_zone *pcz); From patchwork Tue Mar 9 22:42:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 396095 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp2976811jai; Tue, 9 Mar 2021 14:43:33 -0800 (PST) X-Google-Smtp-Source: ABdhPJxLr8jfdZ3gY9K86ONqrNGqiiYHTjEGtqEb8B3JpfXQEZmgaVgqTdJ+2UKDqGWpIpvqZD1N X-Received: by 2002:a17:906:a099:: with SMTP id q25mr295073ejy.549.1615329813318; Tue, 09 Mar 2021 14:43:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1615329813; cv=none; d=google.com; s=arc-20160816; b=WWF/N2pg70bzWOcy8cc3Q7ElUDWa9OZu6m33AjpgZ7ZcpcMOFZPYeUnBJBUEhAXxc8 JKFR+nYC6FWBJAyuYIkEp0snMQuGMJU19/3WuQh91TLvhK29JVQZr6D6993Gw8fGs8wv t5Myxz+QcNq2wFj4W8mAU2DKPIIVW7qX9T1wVZwWlFvwWYBdwR6AYo0JQE0vX0ACkqC/ E22eRY666XwBiL5vvsC22Juqr7Qp4EiVqVPxPT0LfI1sMKvEGE5Ca+Ymm3PS/KoaMJ2e LrcyK9GDwlzPmNwATlPtSmn9PPIFyq5uYWXCKP2Z7VBVukv7Xh68QyepFIit4hp+SgW9 rSMA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature; bh=84rQ3NvsOhm26IexTySRGDCIz117SxZ//6BzkM58sV8=; b=zd+7s1xHw4aCUa0pWQ1Hm2i5R/STznkSF2rG5boj3R5GEabAS5YQhbBn2A5+bwo/MQ 5jeKZCRK+nv7lX2FPpRv/CvSbkpvjqIwlQE2ji/vaAobdX1CM2JvBH3jRBNFTqvCAvsh 6ufpVXdfqR259tLoNVOERF0tqDRiIJe/u17NnWVRxp9rNBKEjH6GB4GBj5yj0BmIsQU/ ZfwPgOOI05gbkkKmpcpBZDTsmYgZCDbn8tzwhpahh38qMcybWcocnZ4QMDcGZ/8kCEiL 5rRwA8ryMK2MxYobL9kQUcMJ4zzuqc58LXMJ6P3tgevubTJnrSIFFisXs+2nnQDu2pH+ oUTg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=gMh7U27m; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id c11si7915222edr.72.2021.03.09.14.43.33; Tue, 09 Mar 2021 14:43:33 -0800 (PST) Received-SPF: pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=gMh7U27m; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232131AbhCIWnB (ORCPT + 7 others); Tue, 9 Mar 2021 17:43:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53042 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232176AbhCIWmz (ORCPT ); Tue, 9 Mar 2021 17:42:55 -0500 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C813C06175F for ; Tue, 9 Mar 2021 14:42:55 -0800 (PST) Received: by mail-wr1-x435.google.com with SMTP id w11so19098186wrr.10 for ; Tue, 09 Mar 2021 14:42:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=84rQ3NvsOhm26IexTySRGDCIz117SxZ//6BzkM58sV8=; b=gMh7U27m742GajfbBTcKF3cghgI5zQOkaYrdSmQpmxb1DaN/msJae1ytHLi5wcuF30 7KD/kqkI/lu8DsxU5YW/SXn87MeHBIvqZ0xH7s3sRZ4Fzfe3HAfehoK9zK2dspmijQdQ sX58szXDngr5enfUG8Oj2T2hL69iKT4QJBf0iMBl2chBfpU++5IprhuCdjPjegcnrs0U vQg8hsrwG4AsBa/M/v30kz/U4xHW21q/iFDuGFn8kGr6m/vnuya0ywiO3Pi0i/uamsrE v1pmgpnTA0+bTFD81U+s9n4OYXlmYX8UCoBdmEiH/e0T1oWNrgPSEjoJshu7f935wGp3 QB6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=84rQ3NvsOhm26IexTySRGDCIz117SxZ//6BzkM58sV8=; b=jjaVQH6gfiz347ku0lrhvIbOQtXNxGrieXUL/6kdbBtKHLKqSu9IUJ4Cag1cNXBBfW FhjV9CoQdF5K3LIWAPAHoJAxxK6+fuEvcpNd5BLj33ZVDC09U8hkMip2x0Yv9FgsFsgJ kpgIRpkqkSesRtpK75yJTFO/DE9wbAz8Uds97P2Q2z5Cqek5r79aU7HQ2TUxpthf+506 pLJOhKJMJDk81xb5q2yhIx6H2z80iLKv7sOY4AWTf44hPpoDtecfwLSvLusexdeOnzoK LxFlXArmureyGrd71ebKR2DG5wuD+Nh75VTsAMMgUwd4LLdHs2JnlKJMAlItGIwqGLeE deug== X-Gm-Message-State: AOAM531bnka0zcZB311TttdKEAKFRGQwmSmmOpXQQ3DF3a/Ger9dCao5 rsJB0pw9jLYq8rLNZdBDPIokEztsruUUmo5p X-Received: by 2002:a05:6000:192:: with SMTP id p18mr107109wrx.403.1615329773814; Tue, 09 Mar 2021 14:42:53 -0800 (PST) Received: from localhost.localdomain ([82.142.0.212]) by smtp.gmail.com with ESMTPSA id p16sm30352179wrt.54.2021.03.09.14.42.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Mar 2021 14:42:53 -0800 (PST) From: Daniel Lezcano To: daniel.lezcano@linaro.org, rafael@kernel.org Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, lukasz.luba@arm.com Subject: [PATCH v2 2/5] powercap/drivers/dtpm: Create a registering system Date: Tue, 9 Mar 2021 23:42:41 +0100 Message-Id: <20210309224244.27225-2-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210309224244.27225-1-daniel.lezcano@linaro.org> References: <20210309224244.27225-1-daniel.lezcano@linaro.org> Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org A SoC can be differently structured depending on the platform and the kernel can not be aware of all the combinations, as well as the specific tweaks for a particular board. The creation of the hierarchy must be delegated to userspace. These changes provide a registering mechanism where the different subsystems will initialize their dtpm backends and register with a name the dtpm node in a list. The next changes will provide an userspace interface to create hierachically the different nodes. Those will be created by name and found via the list filled by the different subsystem. If a specified name is not found in the list, it is assumed to be a virtual node which will have children and the default is to allocate such node. When the node register in the list, the function will be dtpm_register where the previous semantic was to create the node. Thus, the functions are renamed to reflect their purpose. Signed-off-by: Daniel Lezcano --- V2: - Fixed error code path by dropping lock --- drivers/powercap/dtpm.c | 161 ++++++++++++++++++++++++++++++++++-- drivers/powercap/dtpm_cpu.c | 4 +- include/linux/dtpm.h | 12 ++- 3 files changed, 164 insertions(+), 13 deletions(-) -- 2.17.1 diff --git a/drivers/powercap/dtpm.c b/drivers/powercap/dtpm.c index 58433b8ef9a1..d00f55f0ee30 100644 --- a/drivers/powercap/dtpm.c +++ b/drivers/powercap/dtpm.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,14 @@ static DEFINE_MUTEX(dtpm_lock); static struct powercap_control_type *pct; static struct dtpm *root; +struct dtpm_node { + const char *name; + struct dtpm *dtpm; + struct list_head node; +}; + +static LIST_HEAD(dtpm_list); + static int get_time_window_us(struct powercap_zone *pcz, int cid, u64 *window) { return -ENOSYS; @@ -152,6 +161,138 @@ static int __dtpm_update_power(struct dtpm *dtpm) return ret; } +static struct dtpm *__dtpm_lookup(const char *name) +{ + struct dtpm_node *node; + + list_for_each_entry(node, &dtpm_list, node) { + if (!strcmp(name, node->name)) + return node->dtpm; + } + + return NULL; +} + +/** + * dtpm_get - Get a reference to a dtpm structure + * @name: the name of the dtpm device + * + * The function looks up in the list of the registered dtpm + * devices. If the dtpm device is not found, a virtual one is + * allocated. This function must be called to create a dtpm node in + * the powercap hierarchy. + * + * Return: a pointer to a dtpm structure, NULL if there is not enough + * memory + */ +struct dtpm *dtpm_get(const char *name) +{ + struct dtpm *dtpm; + + mutex_lock(&dtpm_lock); + dtpm = __dtpm_lookup(name); + if (!dtpm) + dtpm = dtpm_alloc(NULL); + else + kref_get(&dtpm->kref); + mutex_unlock(&dtpm_lock); + + return dtpm; +} + +static void dtpm_release(struct kref *kref) +{ + struct dtpm *dtpm = container_of(kref, struct dtpm, kref); + + kfree(dtpm); +} + +/** + * dtpm_put - Release a reference on a dtpm device + * @dtpm: a pointer to a dtpm structure + * + * Release the reference on the specified dtpm device. The last + * reference leads to a memory release. + */ +void dtpm_put(struct dtpm *dtpm) +{ + kref_put(&dtpm->kref, dtpm_release); +} + +/** + * dtpm_register - Register the dtpm in the dtpm list + * @name: a name used as an identifier + * @dtpm: the dtpm node to be registered + * + * Stores the dtpm device in a list. + * + * Return: 0 on success, -EEXIST if the device name is already present + * in the list, -ENOMEM in case of memory allocation failure. + */ +int dtpm_register(const char *name, struct dtpm *dtpm) +{ + struct dtpm_node *node; + int ret; + + mutex_lock(&dtpm_lock); + + ret = -EEXIST; + if (__dtpm_lookup(name)) + goto out_unlock; + + ret = -ENOMEM; + node = kzalloc(sizeof(*node), GFP_KERNEL); + if (!node) + goto out_unlock; + + node->name = kstrdup(name, GFP_KERNEL); + if (!node->name) { + kfree(node); + goto out_unlock; + } + + node->dtpm = dtpm; + + list_add(&node->node, &dtpm_list); + + pr_info("Registered %s\n", name); + + ret = 0; +out_unlock: + mutex_unlock(&dtpm_lock); + + return ret; +} + +/** + * dtpm_unregister - Remove the dtpm device from the list + * @name: the dtpm device name to be removed + * + * Remove the dtpm device from the list of the registered devices. + */ +void dtpm_unregister(const char *name) +{ + struct dtpm_node *node; + + mutex_lock(&dtpm_lock); + + list_for_each_entry(node, &dtpm_list, node) { + + if (strcmp(name, node->name)) + continue; + + list_del(&node->node); + kfree(node->name); + kfree(node); + + pr_info("Unregistered %s\n", name); + + break; + } + + mutex_unlock(&dtpm_lock); +} + /** * dtpm_update_power - Update the power on the dtpm * @dtpm: a pointer to a dtpm structure to update @@ -208,7 +349,7 @@ int dtpm_release_zone(struct powercap_zone *pcz) if (root == dtpm) root = NULL; - kfree(dtpm); + dtpm_put(dtpm); return 0; } @@ -370,6 +511,7 @@ struct dtpm *dtpm_alloc(struct dtpm_ops *ops) if (dtpm) { INIT_LIST_HEAD(&dtpm->children); INIT_LIST_HEAD(&dtpm->sibling); + kref_init(&dtpm->kref); dtpm->weight = 1024; dtpm->ops = ops; } @@ -378,28 +520,29 @@ struct dtpm *dtpm_alloc(struct dtpm_ops *ops) } /** - * dtpm_unregister - Unregister a dtpm node from the hierarchy tree - * @dtpm: a pointer to a dtpm structure corresponding to the node to be removed + * dtpm_destroy - Destroy a dtpm node from the hierarchy tree + * @dtpm: a pointer to a dtpm structure corresponding to the node to be + * removed and destroyed * * Call the underlying powercap unregister function. That will call * the release callback of the powercap zone. */ -void dtpm_unregister(struct dtpm *dtpm) +void dtpm_destroy(struct dtpm *dtpm) { powercap_unregister_zone(pct, &dtpm->zone); - pr_info("Unregistered dtpm node '%s'\n", dtpm->zone.name); + pr_info("Destroyed dtpm node '%s'\n", dtpm->zone.name); } /** - * dtpm_register - Register a dtpm node in the hierarchy tree + * dtpm_create - Create a dtpm node in the hierarchy tree * @name: a string specifying the name of the node * @dtpm: a pointer to a dtpm structure corresponding to the new node * @parent: a pointer to a dtpm structure corresponding to the parent node * * Create a dtpm node in the tree. If no parent is specified, the node * is the root node of the hierarchy. If the root node already exists, - * then the registration will fail. The powercap controller must be + * then the creation will fail. The powercap controller must be * initialized before calling this function. * * The dtpm structure must be initialized with the power numbers @@ -413,7 +556,7 @@ void dtpm_unregister(struct dtpm *dtpm) * * parent have ops which are reserved for leaves * Other negative values are reported back from the powercap framework */ -int dtpm_register(const char *name, struct dtpm *dtpm, struct dtpm *parent) +int dtpm_create(const char *name, struct dtpm *dtpm, struct dtpm *parent) { struct powercap_zone *pcz; @@ -457,7 +600,7 @@ int dtpm_register(const char *name, struct dtpm *dtpm, struct dtpm *parent) if (dtpm->ops && !dtpm->ops->update_power_uw(dtpm)) __dtpm_add_power(dtpm); - pr_info("Registered dtpm node '%s' / %llu-%llu uW, \n", + pr_info("Created dtpm node '%s' / %llu-%llu uW, \n", dtpm->zone.name, dtpm->power_min, dtpm->power_max); mutex_unlock(&dtpm_lock); diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c index cfb120280887..628d4d6d83a6 100644 --- a/drivers/powercap/dtpm_cpu.c +++ b/drivers/powercap/dtpm_cpu.c @@ -177,7 +177,7 @@ static int cpuhp_dtpm_cpu_online(unsigned int cpu) sprintf(name, "cpu%d-cpufreq", dtpm_cpu->cpu); - ret = dtpm_register(name, dtpm, NULL); + ret = dtpm_register(name, dtpm); if (ret) goto out_kfree_dtpm_cpu; @@ -190,7 +190,7 @@ static int cpuhp_dtpm_cpu_online(unsigned int cpu) return 0; out_dtpm_unregister: - dtpm_unregister(dtpm); + dtpm_unregister(name); dtpm_cpu = NULL; dtpm = NULL; diff --git a/include/linux/dtpm.h b/include/linux/dtpm.h index acf8d3638988..d724c5a7b2f4 100644 --- a/include/linux/dtpm.h +++ b/include/linux/dtpm.h @@ -14,6 +14,7 @@ struct dtpm { struct powercap_zone zone; + struct kref kref; struct dtpm *parent; struct list_head sibling; struct list_head children; @@ -69,10 +70,17 @@ int dtpm_release_zone(struct powercap_zone *pcz); struct dtpm *dtpm_alloc(struct dtpm_ops *ops); -void dtpm_unregister(struct dtpm *dtpm); +void dtpm_destroy(struct dtpm *dtpm); -int dtpm_register(const char *name, struct dtpm *dtpm, struct dtpm *parent); +int dtpm_create(const char *name, struct dtpm *dtpm, struct dtpm *parent); int dtpm_register_cpu(struct dtpm *parent); +int dtpm_register(const char *name, struct dtpm *dtpm); + +void dtpm_unregister(const char *name); + +struct dtpm *dtpm_get(const char *name); + +void dtpm_put(struct dtpm *dtpm); #endif From patchwork Tue Mar 9 22:42:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 396094 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp2976797jai; Tue, 9 Mar 2021 14:43:32 -0800 (PST) X-Google-Smtp-Source: ABdhPJwIYBIqBz3ylhhGqqU2SkOoPG6GDM0uBLGOV87764ETFzIAVyZNXquY7pIlRdmEQuR6jFR4 X-Received: by 2002:a17:906:2612:: with SMTP id h18mr310352ejc.309.1615329812531; Tue, 09 Mar 2021 14:43:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1615329812; cv=none; d=google.com; s=arc-20160816; b=DrzLbOHzseW302uhw+9wy/6WRrNqRVsE/f1bBI1O+/vFOYKKBj1JsRQIlyEyQI1Y9v itB90T0XhnXtdWkUh/gUxkLShpMxeWe2/Mm4aPnbX9tlOhNKRPnrgRtWIMgwRzaDShV9 S6Rkysq6CAD+VVP2jRd1fPSB4U3g4Ntizbj676pe7eV3bnNGeB6ALFXGeRLYDsf56HCg cDP0Wl4h6KCxuz/eUF8sT7EpYzKSNv7zIWw8UodtpAoWchuM1eXp2a1M16948JRT4mkX oNkw4jvb8BNoknGEeEGf7yt0ahtXVNEiKnhX7WL5I3cZbTZVdz5xc8DYtn69DwMY5KIE 2auQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature; bh=MUZ+0f1MMpnUEJ4a2J6EdFMV+wQUIe9TSPtGUldR/hk=; b=bES682RNwGDfHx2wlLtL27iamp/zaXWKlBhN+tQFnguH/vzfNjQaDxvCNicv30ko7K 35Dm09bOqNVxAdfaw5/J8XBaY6WL18SvHogDTVS+3BNeX7gGsXnY1i70utyDtNaDRUjR lbnB2bijVUnG7EMkklU3Zkm8fTTuQiMbEkImtWtBjrHcX/mSospPkDafRc2tmOfeR5Dc shr3cgfLpn1/V4WSw3U6Ng1kLdsBSKAXG+y8DrfiiLerbXXodQyx/0gLSQwevnI2n97I W1HN7qOWmojDvTJbo8T96iYMiuS0/zAcChb49ZviZVflJSLqHnhiu8jfh5a9gh1uybv4 QwQQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=s822vc9+; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id c11si7915222edr.72.2021.03.09.14.43.32; Tue, 09 Mar 2021 14:43:32 -0800 (PST) Received-SPF: pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=s822vc9+; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232187AbhCIWnC (ORCPT + 7 others); Tue, 9 Mar 2021 17:43:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53044 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230215AbhCIWm4 (ORCPT ); Tue, 9 Mar 2021 17:42:56 -0500 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 13807C06174A for ; Tue, 9 Mar 2021 14:42:56 -0800 (PST) Received: by mail-wr1-x432.google.com with SMTP id d15so19103647wrv.5 for ; Tue, 09 Mar 2021 14:42:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=MUZ+0f1MMpnUEJ4a2J6EdFMV+wQUIe9TSPtGUldR/hk=; b=s822vc9+x/Dq+3b8vhn5JB+q6n/TaZFZTgy5tpUU+Ly/AMYvK9PjZDZ+UOucjXSTxG gahynK+1hhzvPDnPurnEUaU4lqdVWA+TpooeaFJptOOvxGHEPs3UqG1hELM/WkndTM3K AlqG9RhLBSUp06dp1/FOYM4b5d8v7IJ9I9tm1fReqgcjofWK3jJq9S9SliQLwtSJAys/ m59+G8HYrdD5XFmbpnpQ8ByJV41BNhChGbi/R6nBLP/h/L4QDKf5USrnPjR0UAo8rapD jdYM4Wss+MSFYs4Wbbr87mRQXXzt6aE40AHv8kXxdBCxeeqMqCATuK/fjo2NrPpuQsjt 5hjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=MUZ+0f1MMpnUEJ4a2J6EdFMV+wQUIe9TSPtGUldR/hk=; b=Tkdnkq/OVSiTm+bvAt82335RQnPGEZedBF9zhLrT67Mjm6AjvHkqFw+SciueIeGpNJ 3o2fREKjhP7aIDNJ39tdd5IGJQit4VKApQ+1DYFiEx9iXyE5fAZFx0Mk1w+1Ah2E6J2s 7aubM1uA/hqqEx8hVQFKgdXJ2RLuOs1R7p+Hp/quc6Ol+VZH5tRmE1x010KusMAFC5Q1 NXkY2s7QOksnZn2O6TcKkX+ahukXZ1hxqNd3Rtq8dYC7r3fAc6NQFK0V8rY9T0s8kO0k 6jInYgGpQ8aVTLFh0S+xmvsvakQppZmH3m8TB7ewN/j4yvF8p8Z6Z0pi/7pK23VekXfu nOZA== X-Gm-Message-State: AOAM530NPfkSq3u/OefyIjAjvBeJXJhzWpP82oUmlVYQ+YJ9TqxguHbp kdN0EYcGwUU1LFfyZLK5s1GmRg== X-Received: by 2002:adf:f148:: with SMTP id y8mr128607wro.107.1615329774764; Tue, 09 Mar 2021 14:42:54 -0800 (PST) Received: from localhost.localdomain ([82.142.0.212]) by smtp.gmail.com with ESMTPSA id p16sm30352179wrt.54.2021.03.09.14.42.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Mar 2021 14:42:54 -0800 (PST) From: Daniel Lezcano To: daniel.lezcano@linaro.org, rafael@kernel.org Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, lukasz.luba@arm.com Subject: [PATCH v2 3/5] powercap/drivers/dtpm: Simplify the dtpm table Date: Tue, 9 Mar 2021 23:42:42 +0100 Message-Id: <20210309224244.27225-3-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210309224244.27225-1-daniel.lezcano@linaro.org> References: <20210309224244.27225-1-daniel.lezcano@linaro.org> Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The dtpm table is an array of pointers, that forces the user of the table to define initdata along with the declaration of the table entry. It is more efficient to create an array of dtpm structure, so the declaration of the table entry can be done by initializing the different fields. Signed-off-by: Daniel Lezcano Reviewed-by: Lukasz Luba --- drivers/powercap/dtpm.c | 4 ++-- drivers/powercap/dtpm_cpu.c | 4 +++- include/linux/dtpm.h | 22 +++++++++------------- 3 files changed, 14 insertions(+), 16 deletions(-) -- 2.17.1 diff --git a/drivers/powercap/dtpm.c b/drivers/powercap/dtpm.c index d00f55f0ee30..74d9603bd42a 100644 --- a/drivers/powercap/dtpm.c +++ b/drivers/powercap/dtpm.c @@ -610,7 +610,7 @@ int dtpm_create(const char *name, struct dtpm *dtpm, struct dtpm *parent) static int __init dtpm_init(void) { - struct dtpm_descr **dtpm_descr; + struct dtpm_descr *dtpm_descr; pct = powercap_register_control_type(NULL, "dtpm", NULL); if (IS_ERR(pct)) { @@ -619,7 +619,7 @@ static int __init dtpm_init(void) } for_each_dtpm_table(dtpm_descr) - (*dtpm_descr)->init(*dtpm_descr); + dtpm_descr->init(); return 0; } diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c index 628d4d6d83a6..983f1ca27dc3 100644 --- a/drivers/powercap/dtpm_cpu.c +++ b/drivers/powercap/dtpm_cpu.c @@ -204,7 +204,7 @@ static int cpuhp_dtpm_cpu_online(unsigned int cpu) return ret; } -int dtpm_register_cpu(struct dtpm *parent) +static int __init dtpm_cpu_init(void) { int ret; @@ -241,3 +241,5 @@ int dtpm_register_cpu(struct dtpm *parent) return 0; } + +DTPM_DECLARE(dtpm_cpu, dtpm_cpu_init); diff --git a/include/linux/dtpm.h b/include/linux/dtpm.h index d724c5a7b2f4..5f71ddc18ee9 100644 --- a/include/linux/dtpm.h +++ b/include/linux/dtpm.h @@ -34,25 +34,23 @@ struct dtpm_ops { void (*release)(struct dtpm *); }; -struct dtpm_descr; - -typedef int (*dtpm_init_t)(struct dtpm_descr *); +typedef int (*dtpm_init_t)(void); struct dtpm_descr { - struct dtpm *parent; - const char *name; dtpm_init_t init; }; /* Init section thermal table */ -extern struct dtpm_descr *__dtpm_table[]; -extern struct dtpm_descr *__dtpm_table_end[]; +extern struct dtpm_descr __dtpm_table[]; +extern struct dtpm_descr __dtpm_table_end[]; -#define DTPM_TABLE_ENTRY(name) \ - static typeof(name) *__dtpm_table_entry_##name \ - __used __section("__dtpm_table") = &name +#define DTPM_TABLE_ENTRY(name, __init) \ + static struct dtpm_descr __dtpm_table_entry_##name \ + __used __section("__dtpm_table") = { \ + .init = __init, \ + } -#define DTPM_DECLARE(name) DTPM_TABLE_ENTRY(name) +#define DTPM_DECLARE(name, init) DTPM_TABLE_ENTRY(name, init) #define for_each_dtpm_table(__dtpm) \ for (__dtpm = __dtpm_table; \ @@ -74,8 +72,6 @@ void dtpm_destroy(struct dtpm *dtpm); int dtpm_create(const char *name, struct dtpm *dtpm, struct dtpm *parent); -int dtpm_register_cpu(struct dtpm *parent); - int dtpm_register(const char *name, struct dtpm *dtpm); void dtpm_unregister(const char *name); From patchwork Tue Mar 9 22:42:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 396097 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp2976842jai; Tue, 9 Mar 2021 14:43:35 -0800 (PST) X-Google-Smtp-Source: ABdhPJx2IEKnOyyW1jt9snamhFIeoPcDaL/iNaJD6kAOmPZaCD3c9GPehBz22rLIZK5qXDLhd4t8 X-Received: by 2002:a17:906:1a4b:: with SMTP id j11mr330727ejf.55.1615329814976; Tue, 09 Mar 2021 14:43:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1615329814; cv=none; d=google.com; s=arc-20160816; b=ox5ZpKHY0wZig+B7bFlxW7xJf9XEVLbLm+9OHxfuqjHh0kEc7b15hS/vXVHD6Q8JGR kr0qadAm3gxgz8IXc9KW3wDYIfx5HxafgEaWjEVaQWn5kGOmHtSte+b+v6MFT//lMPr4 Bqgn7k6Es+Bz4QYeXLSTQAz3dys+DfUCDMvY8m0UVVGSrEpMdTeg9eUo+QDEHuXymKuU Y8XNYoU2wVeV754zLTaWkh09h54hTk3/n7uT9PuOab+cCjDq9jq9qDhyQp53D6xSB14o HIOM3WlBejcuS7dw55nz0e9z3x7Y0zRRFugEEdXytZv2Q6wc3s8LXYgUvYPQddGFzQms PyEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature; bh=tGAdxc5Fb2RB7pZV+JmXUvhQNnyRCNFzDkDAeSmuI2Q=; b=awXs2q8TvaDVIIRlxcQeS3HvEX430MmarsP6Fqa4FMAabKXQ0WsyI46OOU7/WrYdXm zhjKXekaJvXc2WVkKVLRI4VF1nQomYRDn53CSds9vg5BZlfV1v+04iC5JuiXQfLMVZcO mP7P5U6/1rKEsh6DSFRU7b4qq7Kn95QpaUX5JYK81goyt8dRmg4iKGWzWl0CG4hpWMv/ vdemg6zabVMLY5lIBDRjGv1hJKMuM/GILbKkCTyEBKZEMqrVBeXZOytdZmXth7fnzTHg XulWbjLpe63ONQ4ClbXFbC2yNLxI4P1k45xsSaptKbQX7HdylfylM/sOfc72ddmK7u0F 25sA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Yc6adA4N; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id c11si7915222edr.72.2021.03.09.14.43.34; Tue, 09 Mar 2021 14:43:34 -0800 (PST) Received-SPF: pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Yc6adA4N; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232193AbhCIWnD (ORCPT + 7 others); Tue, 9 Mar 2021 17:43:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53056 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232182AbhCIWm5 (ORCPT ); Tue, 9 Mar 2021 17:42:57 -0500 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 218E5C06175F for ; Tue, 9 Mar 2021 14:42:57 -0800 (PST) Received: by mail-wr1-x435.google.com with SMTP id f12so19091893wrx.8 for ; Tue, 09 Mar 2021 14:42:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=tGAdxc5Fb2RB7pZV+JmXUvhQNnyRCNFzDkDAeSmuI2Q=; b=Yc6adA4N+tb+x2vpiGhn1J782snwlw5R67Gk+c9o1wox5wrhTXSv5EskUu8VbG73n/ DS/9hlp3vyY7cMDV29tK0JPv5/PvYKPW1tLW2Lb9ZiPNAcFtyPSyOwvli0/jpF1Itfre ddys+RDsYS6w0hyeugfBUeB+9xNkobojrs9Dp2simq+1PqGy35w3SxdnRY38ZYjQBEKj Z0YhgURp5EHO0it48kKLV36JojS0BSAt6C27kG/YjTW/uOtZkFbp+Zb1kLr4br64+ZFy yfsc+Da+Z9pI1fOB3pvgQPY9ioKHN8ElqAPjxxd/sHxOMW/rYBs190GY4E9uhh0+TaVX dKLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=tGAdxc5Fb2RB7pZV+JmXUvhQNnyRCNFzDkDAeSmuI2Q=; b=kKPyp2pMtCh6rgEQF/s/hGUxh83kGDC1NrFAFRlBlE3DIzmYthF8Wf/6Q9k5sfkiGA zE1M5wyREy+hd0o1fa3t1MBMeKyjNcNO7G/96sKLLRk2oSWt7QOpymSu/cgHcigY3ZKf yVcndoxvRBG+d1M8wzALkmsscg19Ej2ZsDpDhcgAWs9FBVkHrt+dRCHj53E2dMfrGen6 tos3J336tEomdp12JJSLfoPx67Pw8bdP0XiGCicPqqpn51B3W5Am6TGsT41HiYMDNbJZ xoP36G6glX74iUIlAMlh3BFKWUmDAvuktkIGku8VMih5MjhtqL5MFqJCAKTZfl2mW+j1 pJ/w== X-Gm-Message-State: AOAM533VK+XexwMsrb8e0bDRlzSNzF+y1qe5ZQ15fmfkjfPWX+yJ6U81 ozBzoLzxIP9KaiKBUuVO1BTMnA== X-Received: by 2002:a5d:4523:: with SMTP id j3mr156110wra.288.1615329775748; Tue, 09 Mar 2021 14:42:55 -0800 (PST) Received: from localhost.localdomain ([82.142.0.212]) by smtp.gmail.com with ESMTPSA id p16sm30352179wrt.54.2021.03.09.14.42.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Mar 2021 14:42:55 -0800 (PST) From: Daniel Lezcano To: daniel.lezcano@linaro.org, rafael@kernel.org Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, lukasz.luba@arm.com Subject: [PATCH v2 4/5] powercap/drivers/dtpm: Use container_of instead of a private data field Date: Tue, 9 Mar 2021 23:42:43 +0100 Message-Id: <20210309224244.27225-4-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210309224244.27225-1-daniel.lezcano@linaro.org> References: <20210309224244.27225-1-daniel.lezcano@linaro.org> Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The dtpm framework provides an API to allocate a dtpm node. However when a backend dtpm driver needs to allocate a dtpm node it must define its own structure and store the pointer of this structure in the private field of the dtpm structure. It is more elegant to use the container_of macro and add the dtpm structure inside the dtpm backend specific structure. The code will be able to deal properly with the dtpm structure as a generic entity, making all this even more self-encapsulated. The dtpm_alloc() function does no longer make sense as the dtpm structure will be allocated when allocating the device specific dtpm structure. The dtpm_init() is provided instead. Signed-off-by: Daniel Lezcano Reviewed-by: Lukasz Luba --- drivers/powercap/dtpm.c | 27 ++++++++++------------ drivers/powercap/dtpm_cpu.c | 46 ++++++++++++++++++------------------- include/linux/dtpm.h | 3 +-- 3 files changed, 35 insertions(+), 41 deletions(-) -- 2.17.1 diff --git a/drivers/powercap/dtpm.c b/drivers/powercap/dtpm.c index 74d9603bd42a..a4784ac2f79b 100644 --- a/drivers/powercap/dtpm.c +++ b/drivers/powercap/dtpm.c @@ -191,10 +191,13 @@ struct dtpm *dtpm_get(const char *name) mutex_lock(&dtpm_lock); dtpm = __dtpm_lookup(name); - if (!dtpm) - dtpm = dtpm_alloc(NULL); - else + if (!dtpm) { + dtpm = kzalloc(sizeof(*dtpm), GFP_KERNEL); + if (dtpm) + dtpm_init(dtpm, NULL); + } else { kref_get(&dtpm->kref); + } mutex_unlock(&dtpm_lock); return dtpm; @@ -498,16 +501,12 @@ static struct powercap_zone_ops zone_ops = { }; /** - * dtpm_alloc - Allocate and initialize a dtpm struct - * @name: a string specifying the name of the node - * - * Return: a struct dtpm pointer, NULL in case of error + * dtpm_init - Allocate and initialize a dtpm struct + * @dtpm: The dtpm struct pointer to be initialized + * @ops: The dtpm device specific ops, NULL for a virtual node */ -struct dtpm *dtpm_alloc(struct dtpm_ops *ops) +void dtpm_init(struct dtpm *dtpm, struct dtpm_ops *ops) { - struct dtpm *dtpm; - - dtpm = kzalloc(sizeof(*dtpm), GFP_KERNEL); if (dtpm) { INIT_LIST_HEAD(&dtpm->children); INIT_LIST_HEAD(&dtpm->sibling); @@ -515,8 +514,6 @@ struct dtpm *dtpm_alloc(struct dtpm_ops *ops) dtpm->weight = 1024; dtpm->ops = ops; } - - return dtpm; } /** @@ -608,7 +605,7 @@ int dtpm_create(const char *name, struct dtpm *dtpm, struct dtpm *parent) return 0; } -static int __init dtpm_init(void) +static int __init init_dtpm(void) { struct dtpm_descr *dtpm_descr; @@ -623,4 +620,4 @@ static int __init dtpm_init(void) return 0; } -late_initcall(dtpm_init); +late_initcall(init_dtpm); diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c index 983f1ca27dc3..ac7f2e7e262f 100644 --- a/drivers/powercap/dtpm_cpu.c +++ b/drivers/powercap/dtpm_cpu.c @@ -25,16 +25,22 @@ #include #include -static DEFINE_PER_CPU(struct dtpm *, dtpm_per_cpu); - struct dtpm_cpu { + struct dtpm dtpm; struct freq_qos_request qos_req; int cpu; }; +static DEFINE_PER_CPU(struct dtpm_cpu *, dtpm_per_cpu); + +static struct dtpm_cpu *to_dtpm_cpu(struct dtpm *dtpm) +{ + return container_of(dtpm, struct dtpm_cpu, dtpm); +} + static u64 set_pd_power_limit(struct dtpm *dtpm, u64 power_limit) { - struct dtpm_cpu *dtpm_cpu = dtpm->private; + struct dtpm_cpu *dtpm_cpu = to_dtpm_cpu(dtpm); struct em_perf_domain *pd = em_cpu_get(dtpm_cpu->cpu); struct cpumask cpus; unsigned long freq; @@ -64,7 +70,7 @@ static u64 set_pd_power_limit(struct dtpm *dtpm, u64 power_limit) static u64 get_pd_power_uw(struct dtpm *dtpm) { - struct dtpm_cpu *dtpm_cpu = dtpm->private; + struct dtpm_cpu *dtpm_cpu = to_dtpm_cpu(dtpm); struct em_perf_domain *pd; struct cpumask cpus; unsigned long freq; @@ -90,7 +96,7 @@ static u64 get_pd_power_uw(struct dtpm *dtpm) static int update_pd_power_uw(struct dtpm *dtpm) { - struct dtpm_cpu *dtpm_cpu = dtpm->private; + struct dtpm_cpu *dtpm_cpu = to_dtpm_cpu(dtpm); struct em_perf_domain *em = em_cpu_get(dtpm_cpu->cpu); struct cpumask cpus; int nr_cpus; @@ -111,7 +117,7 @@ static int update_pd_power_uw(struct dtpm *dtpm) static void pd_release(struct dtpm *dtpm) { - struct dtpm_cpu *dtpm_cpu = dtpm->private; + struct dtpm_cpu *dtpm_cpu = to_dtpm_cpu(dtpm); if (freq_qos_request_active(&dtpm_cpu->qos_req)) freq_qos_remove_request(&dtpm_cpu->qos_req); @@ -129,20 +135,19 @@ static struct dtpm_ops dtpm_ops = { static int cpuhp_dtpm_cpu_offline(unsigned int cpu) { struct em_perf_domain *pd; - struct dtpm *dtpm; + struct dtpm_cpu *dtpm_cpu; pd = em_cpu_get(cpu); if (!pd) return -EINVAL; - dtpm = per_cpu(dtpm_per_cpu, cpu); + dtpm_cpu = per_cpu(dtpm_per_cpu, cpu); - return dtpm_update_power(dtpm); + return dtpm_update_power(&dtpm_cpu->dtpm); } static int cpuhp_dtpm_cpu_online(unsigned int cpu) { - struct dtpm *dtpm; struct dtpm_cpu *dtpm_cpu; struct cpufreq_policy *policy; struct em_perf_domain *pd; @@ -157,27 +162,23 @@ static int cpuhp_dtpm_cpu_online(unsigned int cpu) if (!pd) return -EINVAL; - dtpm = per_cpu(dtpm_per_cpu, cpu); - if (dtpm) - return dtpm_update_power(dtpm); - - dtpm = dtpm_alloc(&dtpm_ops); - if (!dtpm) - return -EINVAL; + dtpm_cpu = per_cpu(dtpm_per_cpu, cpu); + if (dtpm_cpu) + return dtpm_update_power(&dtpm_cpu->dtpm); dtpm_cpu = kzalloc(sizeof(*dtpm_cpu), GFP_KERNEL); if (!dtpm_cpu) - goto out_kfree_dtpm; + return -ENOMEM; - dtpm->private = dtpm_cpu; + dtpm_init(&dtpm_cpu->dtpm, &dtpm_ops); dtpm_cpu->cpu = cpu; for_each_cpu(cpu, policy->related_cpus) - per_cpu(dtpm_per_cpu, cpu) = dtpm; + per_cpu(dtpm_per_cpu, cpu) = dtpm_cpu; sprintf(name, "cpu%d-cpufreq", dtpm_cpu->cpu); - ret = dtpm_register(name, dtpm); + ret = dtpm_register(name, &dtpm_cpu->dtpm); if (ret) goto out_kfree_dtpm_cpu; @@ -192,15 +193,12 @@ static int cpuhp_dtpm_cpu_online(unsigned int cpu) out_dtpm_unregister: dtpm_unregister(name); dtpm_cpu = NULL; - dtpm = NULL; out_kfree_dtpm_cpu: for_each_cpu(cpu, policy->related_cpus) per_cpu(dtpm_per_cpu, cpu) = NULL; kfree(dtpm_cpu); -out_kfree_dtpm: - kfree(dtpm); return ret; } diff --git a/include/linux/dtpm.h b/include/linux/dtpm.h index 5f71ddc18ee9..4f7ad21291e6 100644 --- a/include/linux/dtpm.h +++ b/include/linux/dtpm.h @@ -24,7 +24,6 @@ struct dtpm { u64 power_max; u64 power_min; int weight; - void *private; }; struct dtpm_ops { @@ -66,7 +65,7 @@ int dtpm_update_power(struct dtpm *dtpm); int dtpm_release_zone(struct powercap_zone *pcz); -struct dtpm *dtpm_alloc(struct dtpm_ops *ops); +void dtpm_init(struct dtpm *dtpm, struct dtpm_ops *ops); void dtpm_destroy(struct dtpm *dtpm); From patchwork Tue Mar 9 22:42:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 396098 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp2976835jai; Tue, 9 Mar 2021 14:43:34 -0800 (PST) X-Google-Smtp-Source: ABdhPJy5APjKL0J2htjgpXA+m0OXSzdTuaRng9XSlGiVxW1I1dtXlef3W9/jLlj+trKgI5YcR/kd X-Received: by 2002:a17:906:3685:: with SMTP id a5mr363677ejc.352.1615329814583; Tue, 09 Mar 2021 14:43:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1615329814; cv=none; d=google.com; s=arc-20160816; b=TV4zMMPU7d+0uii32aylYP3jiN8HDgewnn5WsbikeUyaL4GWzHMD09sNQBurYdezle o+AnLG9S2cxN7xmLEHQATOAWFBVSInEfV3fRnz4AexqM/ANT+HGO+cmO3Pn649p8e7pb 0yhW+5AJZ9UkEO0RAY4KrGNSnB4Tv4tCiCmWr66IGSbFhjkJEvGcCDxTjlK55AfH4AKX BjllxFZh7QXCO7b/C65PEugc+K8Ccx0Pssu6taF3F8dgmKBT3bdhDcIbzrUGQuZb9JSY Kl+K8/9rn9jbvLP1H3CSNF4NgoSiBZGaoYMG9GQcZkHBfQhCB+vnAusmt080Uh/8x7i+ BUkA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature; bh=0x5NnmCRCiyNY9UYzDiRv/bqTSntYaFcl6ygf/f/TM4=; b=XWr05C5DNWS/dNCZ8dYzI9YrBQ23JmL9zZqHoBRCrtNZu/h74Xqr92UEVLWGaLDRr1 U4kaInpNRgJxpBtuinEo5p0Q7f+FGNxQgO8hLBTdzIDmYSOi4NEd03s61bFKw9tVnU2s 9LNWB+oV7c4xhaGJyT6tN4eWAaN5mMiczFMIdNOQKKqLHBUveiICoD4Bzt3ypOg601jm YStgH0ctd+LOk+QNFavwPH6vjpjwoFDgauY3+F0qUivpMxVtqdiQToQyjAd8u1h2nNAY 8aBESmquETHygMjqPrEPXQsMUVUWcwsfZrqEo5ipbx7aQyO/QzWc920OdWL8Sxt74jFz eeyg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="TVJ/xwG9"; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id c11si7915222edr.72.2021.03.09.14.43.34; Tue, 09 Mar 2021 14:43:34 -0800 (PST) Received-SPF: pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="TVJ/xwG9"; spf=pass (google.com: domain of linux-pm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232173AbhCIWnD (ORCPT + 7 others); Tue, 9 Mar 2021 17:43:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53064 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232184AbhCIWm6 (ORCPT ); Tue, 9 Mar 2021 17:42:58 -0500 Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4BD89C06174A for ; Tue, 9 Mar 2021 14:42:58 -0800 (PST) Received: by mail-wm1-x334.google.com with SMTP id m20-20020a7bcb940000b029010cab7e5a9fso8481919wmi.3 for ; Tue, 09 Mar 2021 14:42:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=0x5NnmCRCiyNY9UYzDiRv/bqTSntYaFcl6ygf/f/TM4=; b=TVJ/xwG9NZy1JuEErmWA2lk3anjcw77r9ar/9MXO85bVVZClKnUpfOLrecGYrfDv5l /YesT30aCQGc3x6m0mgHmAFewX1DVs0esR0lb43JB1C5JyCwrbgjsX10ptt9bpNDD3m2 Z76mEtgNOuF1jxy36AgcwKWjVD03+6caSv14BGA8Tt9x+LM8So5yaKsjgi2iHVPpcGSZ v8kElDJs8gTKD2JzYwe1vSAmH5tK/ET5TLGWVd8oBLArB5Us8WgK3c4ld3k3KLRZC0PF 3rLLxBW3qAh5iMM9+/GUw/cb7pkP/ceOlriZLbDsn8sZufhAhiw6guu+tHBvLbeLOfk8 4w/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=0x5NnmCRCiyNY9UYzDiRv/bqTSntYaFcl6ygf/f/TM4=; b=cacwja8ehof2vxsjhFnBiJqk3P+q+9UF+xsU3b+Lk222vvz/qMltwS/8nMQq+zposn G+t+oHADpmJrMuRElJ++6FEblZw5AMKjzQVbdtJeCZDASjm5dCr1TXg7XzlvA+BH5Ocq HC5r26orv0vRMtOoaaX84edhW9WJJQRIyN3GS+JNw9t4j311G0X+ahEe9YaS5BuzD+8+ ciFsOQDre50cgXiVVb/gAkplDPSQ3BZucT2oU1cT/sGwF+9b6g7TefLYPELWa97RTpqP 7yN8lbucWJ/0voD8iC1GAkgFqeBtQOjuaNsoiBmHvuVTZJKOx2UqtP4x2LgFP95lxDz2 NXqw== X-Gm-Message-State: AOAM533dPfW45BtZsWrtFZrw+fi7qn1G97gyz99/9G8fUoejc0etfZZx o+8fqdb8pLgVzr/x5XwxjakMpA== X-Received: by 2002:a1c:cc14:: with SMTP id h20mr172799wmb.14.1615329776988; Tue, 09 Mar 2021 14:42:56 -0800 (PST) Received: from localhost.localdomain ([82.142.0.212]) by smtp.gmail.com with ESMTPSA id p16sm30352179wrt.54.2021.03.09.14.42.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Mar 2021 14:42:56 -0800 (PST) From: Daniel Lezcano To: daniel.lezcano@linaro.org, rafael@kernel.org Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, lukasz.luba@arm.com Subject: [PATCH v2 5/5] powercap/drivers/dtpm: Scale the power with the load Date: Tue, 9 Mar 2021 23:42:44 +0100 Message-Id: <20210309224244.27225-5-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210309224244.27225-1-daniel.lezcano@linaro.org> References: <20210309224244.27225-1-daniel.lezcano@linaro.org> Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Currently the power consumption is based on the current OPP power assuming the entire performance domain is fully loaded. That gives very gross power estimation and we can do much better by using the load to scale the power consumption. Use the utilization to normalize and scale the power usage over the max possible power. Tested on a rock960 with 2 big CPUS, the power consumption estimation conforms with the expected one. Before this change: ~$ ~/dhrystone -t 1 -l 10000& ~$ cat /sys/devices/virtual/powercap/dtpm/dtpm:0/dtpm:0:1/constraint_0_max_power_uw 2260000 After this change: ~$ ~/dhrystone -t 1 -l 10000& ~$ cat /sys/devices/virtual/powercap/dtpm/dtpm:0/dtpm:0:1/constraint_0_max_power_uw 1130000 ~$ ~/dhrystone -t 2 -l 10000& ~$ cat /sys/devices/virtual/powercap/dtpm/dtpm:0/dtpm:0:1/constraint_0_max_power_uw 2260000 Signed-off-by: Daniel Lezcano --- V2: - Replaced cpumask by em_span_cpus - Changed 'util' metrics variable types - Optimized utilization scaling power computation - Renamed parameter name for scale_pd_power_uw() --- drivers/powercap/dtpm_cpu.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) -- 2.17.1 Reported-by: kernel test robot diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c index ac7f2e7e262f..6a1537e6da0d 100644 --- a/drivers/powercap/dtpm_cpu.c +++ b/drivers/powercap/dtpm_cpu.c @@ -68,27 +68,40 @@ static u64 set_pd_power_limit(struct dtpm *dtpm, u64 power_limit) return power_limit; } +static u64 scale_pd_power_uw(struct cpumask *pd_mask, u64 power) +{ + unsigned long max, sum_util = 0; + int cpu; + + max = arch_scale_cpu_capacity(cpu); + + for_each_cpu_and(cpu, pd_mask, cpu_online_mask) + sum_util += sched_cpu_util(cpu, max); + + return (power * ((sum_util << 10) / max)) >> 10; +} + static u64 get_pd_power_uw(struct dtpm *dtpm) { struct dtpm_cpu *dtpm_cpu = to_dtpm_cpu(dtpm); struct em_perf_domain *pd; - struct cpumask cpus; + struct cpumask *pd_mask; unsigned long freq; - int i, nr_cpus; + int i; pd = em_cpu_get(dtpm_cpu->cpu); - freq = cpufreq_quick_get(dtpm_cpu->cpu); - cpumask_and(&cpus, cpu_online_mask, to_cpumask(pd->cpus)); - nr_cpus = cpumask_weight(&cpus); + pd_mask = em_span_cpus(pd); + + freq = cpufreq_quick_get(dtpm_cpu->cpu); for (i = 0; i < pd->nr_perf_states; i++) { if (pd->table[i].frequency < freq) continue; - return pd->table[i].power * - MICROWATT_PER_MILLIWATT * nr_cpus; + return scale_pd_power_uw(pd_mask, pd->table[i].power * + MICROWATT_PER_MILLIWATT); } return 0;