From patchwork Wed Mar 31 11:00: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: 412870 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp386234jai; Wed, 31 Mar 2021 04:02:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyzy1p986OoY4BxiRHohjxoY5jgEI3li6zQZMqFwELDKLo2a86XmKc9Q4yJ6t5bbxHMQqfo X-Received: by 2002:a17:906:f6ce:: with SMTP id jo14mr2938013ejb.476.1617188534844; Wed, 31 Mar 2021 04:02:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617188534; cv=none; d=google.com; s=arc-20160816; b=kZ0/vZ2tnIZfB1N9U5bMjBynn/6nW+bxrpIgghAlmvxiZQeVvOjLxrCCezi3REJ4lr 236kVu+aQb8wGNKU3czIBMKpWnY+o0KkgwExtigKKqazt28bWl47ZhMUi9+o475c+TbB vzpYfwlJYA+s9Z00P8hsMYZKxrw1FkOKln+wOgbtGOlFTlqabASEDGGbhOrBtSYC/ZFX TNrdVIFcsAOo5cX3Mj1WG85EFUdbc6/5A1DZSaEFG3x4RY66euR2J15DGUn+RbdJAmo+ JR1e9E+/KjYqKQyzvhN1ZLRFFIiWKrjaqhPaqkhNoTt022uBTUN+WRKIfkaDzsJ0ryds LY7Q== 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=Sv35hqDzF6q3d0fFvqaS34YxJ0dsD6UI4ML9lDyS//s=; b=kgJz+X/5O0YBHBPIuhIZr+Bv6BmcG7AmxZEcepsscVW0pEJUw4AnSVJunuz2MFsyDZ ymopeCp5h1JxdnLYNXbc21PCtkZ7rqVkSzAxYA/Lo47sGGQsBjDrxZzf3Rj7ezNBlXC+ myWacPZft7DRPmBsSjetvpegjcvB1TFnKv3QpAzZbzxgyecEDZ3+HJpF2Ni47Jm9fxxC pJ+37HoSoR5dqgbmNHLe4l/u+Wlu5EDVpimvPNetUgJWypC5a8JhDrlhesm84XTtKhML PxuOkvWfdZo/9fyoVh5+FbjZw5WXRUbO8ob2BZsvtzq2IBWb1yLwnMhSdZW7sLVa2jNW G3+A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=xPf2PUAo; 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 r16si1445467edw.458.2021.03.31.04.02.14; Wed, 31 Mar 2021 04:02:14 -0700 (PDT) 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=xPf2PUAo; 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 S235182AbhCaLBm (ORCPT + 7 others); Wed, 31 Mar 2021 07:01:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57344 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235504AbhCaLBE (ORCPT ); Wed, 31 Mar 2021 07:01:04 -0400 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 27DFAC061763 for ; Wed, 31 Mar 2021 04:01:04 -0700 (PDT) Received: by mail-wr1-x430.google.com with SMTP id k8so19217850wrc.3 for ; Wed, 31 Mar 2021 04:01:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=Sv35hqDzF6q3d0fFvqaS34YxJ0dsD6UI4ML9lDyS//s=; b=xPf2PUAolqhID4ks4fj3HU1QmbatvDZlL+87QpS0Id15KXTIG6uZqAL2FXKSpb+rT+ kjyrDRF2c9VQkeOC0hKE+pz0w7NCuwv/jtdBSu0o8FtmhC5oKBXWkXnD40l1Xbi0x+LB 6wJc+hBG2k5koPZ6VabN+9oz24O9wbqWZZWD0X9xEvXsXPLXVSBsqx86QSuNmA22ddY4 cbowrH4XAGVTyP1/l8yWH1n+TD6/XAlWRDx93KfG2oHj7fi/SYP67BwNS9guGw2ogDWj 5JkvMTkM9sdscM4Qpg72J+Vu2Q+7WdaMLqchTKhRQ5T/gNtEpOOnJtzRy+ZM9KjvOm0l Ga/Q== 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=Sv35hqDzF6q3d0fFvqaS34YxJ0dsD6UI4ML9lDyS//s=; b=Ik85Wo3DmHPD7GVC+ioOkcY9nr7/+c4szaXxfl9XmthnHjqgXS4rH+EgTqyP7/O2lA KSOz+E50EKGSATpnbQCCJQwwPl6rnS9UmmemfpK/nB14k2ztk88THcnWzUWAQQpIVdaI Z5YsWQi2ZqE/k9PMb4zcvRAWpN178ZdFBjwmYMKR+bHGVaQL4kN2e7W82KPu5/i7hWsL 8I02/LRgMOZ1i1SaegC7xAuL/i1LKtFKjYCUmmcothhzLuGpaMnbiy/F/8/X0A2PMQ2Q K2OeqdTNBZRDSfdQ3ud7nmVz9x1/KQ34Mm2Ti0zp0Woejerq03e7Lu0kAYS4UrFpbd3q Z5vw== X-Gm-Message-State: AOAM533AUygNBmOQhbeIVyvP+pn0PYVlMnoUdPYztj88irwqM1Y8TLsn XOBirYWr0lbb61bmO82Bynd73A== X-Received: by 2002:a05:6000:221:: with SMTP id l1mr3008668wrz.370.1617188462593; Wed, 31 Mar 2021 04:01:02 -0700 (PDT) Received: from localhost.localdomain ([82.142.26.252]) by smtp.gmail.com with ESMTPSA id u23sm3376275wmn.26.2021.03.31.04.01.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 Mar 2021 04:01:02 -0700 (PDT) From: Daniel Lezcano To: daniel.lezcano@linaro.org Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, lukasz.luba@arm.com, rafael@kernel.org, gregkh@linuxfoundation.org Subject: [PATCH v5 1/5] powercap/drivers/dtpm: Encapsulate even more the code Date: Wed, 31 Mar 2021 13:00:44 +0200 Message-Id: <20210331110048.24956-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 Reviewed-by: Lukasz Luba --- V4: - Replaced s/sprintf/snprintf/ for the dtpm node name 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..f6076de39540 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); + snprintf(name, sizeof(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 f14adb882338..b9c50c1b5948 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, @@ -195,7 +196,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 Wed Mar 31 11:00:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 412871 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp386252jai; Wed, 31 Mar 2021 04:02:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw4T613IHnFotRne0Dop2+rD9NFLT0gklEgDrVIkZ26mMb6mIP5fpBJGp2TdruXeLQSZq3t X-Received: by 2002:a17:906:1182:: with SMTP id n2mr2905195eja.234.1617188535736; Wed, 31 Mar 2021 04:02:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617188535; cv=none; d=google.com; s=arc-20160816; b=arnva8bvugbNLBm1aVJAyY3BFgk+9sYceUIaNIDOmfQzN5HuX/IWOfVC3eYaQaOsmW yglOA1KYYqxl1KRnrShzr/cjNjbKUqQe0WGFM4UUwUQnKD4tRnQAaEkI8G5r9exg6Snd FgnpjNwrjct6xWD0d7yLE74pRUUuNVV5PYc49CjysOJukFdfCBTm5i5MpMiMOcD6Hhdc HyLLsIPpHHVyxvVwaMAPD133mVyFl0TtWXP+LAuUvt8I3HmE/pJ3s2IsPSjA9+FMqA7L ZRtilxPMKnp2EKQ7Ga0kolrVgPtU8O1b4mrbE4seimHUXY4ABZwFYh6mGDS77EIkffOa TBdw== 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=5VFoz+HDWhcwV0oty4wzq4agQ6coiwbE2SClXgBAX7g=; b=033gp5KBKTTn9qI9JUTFjpXcnIpIm2iUyRq7qJZ301Nx42888hUuYjEoqQX99RiQsH dIOI/3jw42BhY7tw2m+lCTpJ7ndgXifV6SIwjX4tKO2/WjuJYL8BGKuLr4v4gH4bD2QC uH/N2DIBp23cAItmSzdYuOXDJulF4IfPMs/0yr+gmmOZIXv9AkdQ9cPvJrp4KJUNjiBT y5hMXb8zbHcR6NOa4nk3O+mOia8uUCgiWES0vyxxuNE/5jl9KRkoJsQ5Pk6q5mVKCsfM 1XyW8dDjr/mdNqnmHwOi02NjD/E1aGH/7M1aBDbMPNOvhXh+SBncOrWBH0DguDdXaGI2 zSaA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=DLEOI7bs; 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 r16si1445467edw.458.2021.03.31.04.02.15; Wed, 31 Mar 2021 04:02:15 -0700 (PDT) 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=DLEOI7bs; 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 S235467AbhCaLBo (ORCPT + 7 others); Wed, 31 Mar 2021 07:01:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57348 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235508AbhCaLBG (ORCPT ); Wed, 31 Mar 2021 07:01:06 -0400 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3D98AC061574 for ; Wed, 31 Mar 2021 04:01:05 -0700 (PDT) Received: by mail-wr1-x430.google.com with SMTP id v4so19188496wrp.13 for ; Wed, 31 Mar 2021 04:01:05 -0700 (PDT) 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=5VFoz+HDWhcwV0oty4wzq4agQ6coiwbE2SClXgBAX7g=; b=DLEOI7bsMKH9HhiRnz4W7c14JJmrn2TLclkvtM52BFSOZt//71KNlPPgc+2hiDhmq7 wmVPExzd+7Q9ZYR5zZ+I4KUG1kCoeSkVdlFTfLXYmL8vbzkYvLR4oVOMyzKSXjMAgRuN 7V9B2p8rqOoSAlXvgLa0shKCKPpY+Yq13Hq/N3Nwga+0BvhJJzzmUYZvkHBCYZ6E2mSX TyF/3OWNhPXiaHpAnOzGPo5zKbOXILWsDr86LW4JdG+VeybAPnQYyynLKScMH0DfGCTQ icHpJHuZiFyffar9izCU0WLVI2/xMoQVsfLlFRxx3wRdLeN5cw6Oqu0AJE9CG+TjZt9C iwJA== 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=5VFoz+HDWhcwV0oty4wzq4agQ6coiwbE2SClXgBAX7g=; b=TcyBxzqCAfDaoX64ezkLBvbxf8+Lve4NxbTGDDE6W7gkz+GXfJx03fvEhnsuWF0k/t lM0mUxPMphAu9X9G9dpbnb62FTPoP4L/oj0l1z3J3hjkz2cCJdGP2zdsXYXld98QRCpr I3cwR0vk/Vo40Q8x9ETrMMM+cdksuWfEfI3oPlKqJCRKq9el9kJkhCWB6YQjUmhDw2hw ECIZ5cdOk+wnRli1cfhDoiPfm6VKv1EGdCdq91v4BeExRDm6X4A8hAPX+LwUPMkfnXOF Iqm9fF65PtGgUchFJ4VuthLCGWiOQ2vHYw+KhNx+THZ+fYExAGX0ANBA11mwqpPXNnyb cw0A== X-Gm-Message-State: AOAM531ucL4qS6DyWUbsVPoybJwcaQqarEnjyqI9eKFxIifOaVfn5btU yERswIx5gXov5jpcFeZkrn4p+Q== X-Received: by 2002:a5d:4710:: with SMTP id y16mr3042702wrq.344.1617188463815; Wed, 31 Mar 2021 04:01:03 -0700 (PDT) Received: from localhost.localdomain ([82.142.26.252]) by smtp.gmail.com with ESMTPSA id u23sm3376275wmn.26.2021.03.31.04.01.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 Mar 2021 04:01:03 -0700 (PDT) From: Daniel Lezcano To: daniel.lezcano@linaro.org Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, lukasz.luba@arm.com, rafael@kernel.org, gregkh@linuxfoundation.org Subject: [PATCH v5 2/5] powercap/drivers/dtpm: Create a registering system Date: Wed, 31 Mar 2021 13:00:45 +0200 Message-Id: <20210331110048.24956-2-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210331110048.24956-1-daniel.lezcano@linaro.org> References: <20210331110048.24956-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 hierarchically 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. Cc: Greg KH Signed-off-by: Daniel Lezcano Reviewed-by: Lukasz Luba --- V5: - Decrease log level from 'info' to 'debug' - Remove the refcount, it is pointless, lifetime cycle is already handled by the device refcounting. The dtpm node allocator is in charge of freeing it. - Rename the functions to 'dtpm_add, dtpm_del, dtpm_lookup' - Fix missing kfrees when deleting the node from the list V4: - Fixed typo in the commit log V2: - Fixed error code path by dropping lock --- drivers/powercap/dtpm.c | 121 ++++++++++++++++++++++++++++++++++-- drivers/powercap/dtpm_cpu.c | 8 +-- include/linux/dtpm.h | 6 ++ 3 files changed, 127 insertions(+), 8 deletions(-) -- 2.17.1 diff --git a/drivers/powercap/dtpm.c b/drivers/powercap/dtpm.c index 58433b8ef9a1..8df7adeed0cf 100644 --- a/drivers/powercap/dtpm.c +++ b/drivers/powercap/dtpm.c @@ -34,6 +34,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 +160,113 @@ 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_lookup - Lookup for a registered dtpm node given its name + * @name: the name of the dtpm device + * + * The function looks up in the list of the registered dtpm + * devices. This function must be called to create a dtpm node in the + * powercap hierarchy. + * + * Return: a pointer to a dtpm structure, NULL if not found. + */ +struct dtpm *dtpm_lookup(const char *name) +{ + struct dtpm *dtpm; + + mutex_lock(&dtpm_lock); + dtpm = __dtpm_lookup(name); + mutex_unlock(&dtpm_lock); + + return dtpm; +} + +/** + * dtpm_add - Add 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. The list contains all the devices + * which are power capable in terms of limitation and power + * consumption measurements. Even if conceptually, a power capable + * device won't register itself twice, the function will check if it + * was already registered in order to prevent a misuse of the API. + * + * Return: 0 on success, -EEXIST if the device name is already present + * in the list, -ENOMEM in case of memory allocation failure. + */ +int dtpm_add(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); + + ret = 0; +out_unlock: + mutex_unlock(&dtpm_lock); + + return ret; +} + +/** + * dtpm_del - 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_del(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); + + break; + } + + mutex_unlock(&dtpm_lock); +} + /** * dtpm_update_power - Update the power on the dtpm * @dtpm: a pointer to a dtpm structure to update @@ -208,8 +323,6 @@ int dtpm_release_zone(struct powercap_zone *pcz) if (root == dtpm) root = NULL; - kfree(dtpm); - return 0; } @@ -388,7 +501,7 @@ void dtpm_unregister(struct dtpm *dtpm) { powercap_unregister_zone(pct, &dtpm->zone); - pr_info("Unregistered dtpm node '%s'\n", dtpm->zone.name); + pr_debug("Unregistered dtpm node '%s'\n", dtpm->zone.name); } /** @@ -457,7 +570,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_debug("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 f6076de39540..9deafd16a197 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) snprintf(name, sizeof(name), "cpu%d-cpufreq", dtpm_cpu->cpu); - ret = dtpm_register(name, dtpm, NULL); + ret = dtpm_add(name, dtpm); if (ret) goto out_kfree_dtpm_cpu; @@ -185,12 +185,12 @@ static int cpuhp_dtpm_cpu_online(unsigned int cpu) &dtpm_cpu->qos_req, FREQ_QOS_MAX, pd->table[pd->nr_perf_states - 1].frequency); if (ret) - goto out_dtpm_unregister; + goto out_dtpm_del; return 0; -out_dtpm_unregister: - dtpm_unregister(dtpm); +out_dtpm_del: + dtpm_del(name); dtpm_cpu = NULL; dtpm = NULL; diff --git a/include/linux/dtpm.h b/include/linux/dtpm.h index acf8d3638988..577c71d4e098 100644 --- a/include/linux/dtpm.h +++ b/include/linux/dtpm.h @@ -75,4 +75,10 @@ int dtpm_register(const char *name, struct dtpm *dtpm, struct dtpm *parent); int dtpm_register_cpu(struct dtpm *parent); +struct dtpm *dtpm_lookup(const char *name); + +int dtpm_add(const char *name, struct dtpm *dtpm); + +void dtpm_del(const char *name); + #endif From patchwork Wed Mar 31 11:00:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 412869 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp386240jai; Wed, 31 Mar 2021 04:02:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJygbj39nurAejhxmEwG4Czk8FWTl0z1JiKte26hHWzUtQkvgGt6w77mjImp0zwjRxK6A0oS X-Received: by 2002:a17:906:22d4:: with SMTP id q20mr2982543eja.54.1617188535299; Wed, 31 Mar 2021 04:02:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617188535; cv=none; d=google.com; s=arc-20160816; b=gOlqHWSL9BFFuzcod0KYPBknAz7QypcALmItLk0m+ZhuRBhSR3T7no4XnKEnx1w3d+ SsVEuws2jLthpizVlhQEwtb5d5YUwD2dwXXOdeBsS8ZE2k/oMMM+61eZ1gYmOR6yIftB O1Ise+kn8QlqT1SsXbbKE/XOcsUqOmKesR5Ab7fZrWjUYHZa8Cr1G+WzaT6EXKFCcpR+ r5lA4NcM7QxmWCZS/9KiCrd4KQQ2RMtHs78DUuoXhLuRGfFiCjDNoyNfN0NZQGtUu/54 o0KARRleqn8PgAW+SQCCMT4odGOqnY46fNXy/OHgemKCyh0EwoPIU/FwmK7Xqa0wZ8Dr Negg== 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=vpasoPhVYw8KNa6DUjj7NxNL215nlw6wzCs7oS8Xu4Y=; b=OAkLEBD9yXUGCl2YGa7V3w3Xr4wDe4d8YN0j9zguxgC8tdZjnEREoRdLnUsSL00ENL oTp+KVAC9n2e4jcZx0eo2q1XQN+dtuv6p6Xfown+HfOQ5C9PqMcBSAArnpPL/vw2NFCp XEK57nWosWGPAYomo2fH5PUS7utf3poJI7pwadXkvZehbYRwoTpRatRKRZyGGsm4qEJ5 jwYjSbLlXdE84RTA9Um8LQXLNs8wI2DAgCAPiNFYclG49e/fuQylCzRIylufvcl/OpEr hJczj2x2NgSCNWfwNJxkC4MPpo8k77g3SsD+0LK3hGwJlmeit4dKPigRfHgn/GKMMGnT 9a2A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=uQyjeCo+; 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 r16si1445467edw.458.2021.03.31.04.02.15; Wed, 31 Mar 2021 04:02:15 -0700 (PDT) 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=uQyjeCo+; 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 S235476AbhCaLBn (ORCPT + 7 others); Wed, 31 Mar 2021 07:01:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57358 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235511AbhCaLBG (ORCPT ); Wed, 31 Mar 2021 07:01:06 -0400 Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [IPv6:2a00:1450:4864:20::42e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F807C06174A for ; Wed, 31 Mar 2021 04:01:06 -0700 (PDT) Received: by mail-wr1-x42e.google.com with SMTP id v11so19184327wro.7 for ; Wed, 31 Mar 2021 04:01:06 -0700 (PDT) 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=vpasoPhVYw8KNa6DUjj7NxNL215nlw6wzCs7oS8Xu4Y=; b=uQyjeCo+EVTso/xgGDo28DMqdCmJtay4jgqZ3FNfvHhVtu64Umhi/iNfGq2DlKALXO idzufOKV8nF0heW54D32ECXTjvO+HHAjQaaRfBuNJu7SW7ht4Z1WIQJv+i5b4bHMdiH9 4cYX5p2wZYvPVrN2ObTYay9nzrkIbGlObv1brow543d01FHy1WuhaL1mSjr3FqZ7LGS2 NjVRG/fS86qR2E6VgMmU5aSd99LWoI+8jbFfkBExxBXX2ihQ/NVn8WPGbkKBnIElIuvb 4w0B1t4Sjmv8iPevznorlPKyzJ7XaMPBmSgUQRoxbc70HBMyGMdkWIwEMFbQypXsvPBN 7acg== 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=vpasoPhVYw8KNa6DUjj7NxNL215nlw6wzCs7oS8Xu4Y=; b=KYepev2UNCEKZfL3X+c0iH205VrU6ZUgSV0QfD3DoG2TvOpsJZz/VcGr7DcBjN1ViK nlaCqzvUrIarMaaShagGil+g3QPFKUcoWZdud2FS4DLqGqnS85GEu+3f/BpPPclCuRAT 1RQ2i5IZXTDclWt2P1GyQ9sj+MmLEUfQwp5smHUnGE++Jk43kaTyHYb6RkQ6ZuCOyEmD psFfoLWzX5iMU0q3L5zKP1ylRQzR72S9uQZSCU3t3ochCEuSoXs1/990wUdaY4a+VjT4 YhJ+r1csLQj3dybTtnQxRWCdoIftizL+hf8GoFBOxRJQK2Ej+ifTdehdev/2VNXohbxN xJKg== X-Gm-Message-State: AOAM530a04NzqqlWKJ356U+X0rTSRfTCaAfeX7EWU80vXQZjqkkYig9b tslAJhnpTvognw5QuYF3HftsWg== X-Received: by 2002:adf:f9d0:: with SMTP id w16mr3090824wrr.336.1617188464931; Wed, 31 Mar 2021 04:01:04 -0700 (PDT) Received: from localhost.localdomain ([82.142.26.252]) by smtp.gmail.com with ESMTPSA id u23sm3376275wmn.26.2021.03.31.04.01.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 Mar 2021 04:01:04 -0700 (PDT) From: Daniel Lezcano To: daniel.lezcano@linaro.org Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, lukasz.luba@arm.com, rafael@kernel.org, gregkh@linuxfoundation.org Subject: [PATCH v5 3/5] powercap/drivers/dtpm: Simplify the dtpm table Date: Wed, 31 Mar 2021 13:00:46 +0200 Message-Id: <20210331110048.24956-3-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210331110048.24956-1-daniel.lezcano@linaro.org> References: <20210331110048.24956-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 | 20 +++++++++----------- 3 files changed, 14 insertions(+), 14 deletions(-) -- 2.17.1 diff --git a/drivers/powercap/dtpm.c b/drivers/powercap/dtpm.c index 8df7adeed0cf..3bcd8374baf8 100644 --- a/drivers/powercap/dtpm.c +++ b/drivers/powercap/dtpm.c @@ -580,7 +580,7 @@ int dtpm_register(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)) { @@ -589,7 +589,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 9deafd16a197..74b39a1082e5 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 577c71d4e098..2ec2821111d1 100644 --- a/include/linux/dtpm.h +++ b/include/linux/dtpm.h @@ -33,25 +33,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; \ From patchwork Wed Mar 31 11:00:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 412872 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp386271jai; Wed, 31 Mar 2021 04:02:16 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwydX4ZwK/v8Xp7GYni1BeMcu8xtL1Zhm5VQhhnkBRI1eswr/TihBUeXk6KWuxJZo5pwXrY X-Received: by 2002:a5d:49c7:: with SMTP id t7mr3014801wrs.306.1617188536577; Wed, 31 Mar 2021 04:02:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617188536; cv=none; d=google.com; s=arc-20160816; b=WzYhIt6YG+INKxCBjnl357jaMWWs9stw5qy1eZobpYYKjSlugzFQ8a2tisDwEU/1/P YelG4J8wpl03CcP/fWRnGf3+XTPsm1Pv7Y1Lqg6F8QaL3qFsN6DS4mkFw68IGYjgHnL2 GYO1M2wchgQd3RbKCMVbv+cfAKnEBqWRO1zb0GyJL0HUK7jYKFXwFnwV6ropEFki3Wcd NZ6y1CBiUh0R8MwYWQ/J8d0kaKMK3NGDLE7kmFX5kLEz1nPWQGeiTFrNPWYrOA5TpvGe ScfpU+GOkZSyPOsQzic5IRcruormGz+/StK82fI9uieBJqL8VNjee/OZ2SsQbDbwDVpk 1iig== 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=wS83U3PlCAQKDrzEYnjqkchqohrJ402wKL3+09F+PoY=; b=iBEg9gVZF5J/XtQEfT6lfyemPHsEQKzt80KwZP0H1tXp6Y+zXWWvK7slMmoLNAenxZ t4kah0ATuCI8T+PFDyOWuNF57qubbl8uXUvIp5Z1s5lFxJL2Ox7uLhH6Z9JCONirLlAF j++3bMf2jZomk5HhU7SjbIwC63akSuQYnU/LnlWixQ1lYyFCR5jz6hlYzH9dBzmnd6E+ z5etmMRYjwRobKtXglptZJrNr6EPb1uq041kxKBeJGxxCXyGcrQqZRLPvCzrCboJEByu B+C6f4jgogtz83qJEDRUUmhumfwzEPBHRsdCkt57Nf9EadLXbWGcXdthR3cxFvL702xE 9iUA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=D+7P2wLV; 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 r16si1445467edw.458.2021.03.31.04.02.16; Wed, 31 Mar 2021 04:02:16 -0700 (PDT) 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=D+7P2wLV; 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 S235420AbhCaLBp (ORCPT + 7 others); Wed, 31 Mar 2021 07:01:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57366 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235519AbhCaLBI (ORCPT ); Wed, 31 Mar 2021 07:01:08 -0400 Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A0547C061762 for ; Wed, 31 Mar 2021 04:01:07 -0700 (PDT) Received: by mail-wr1-x42a.google.com with SMTP id j18so19229919wra.2 for ; Wed, 31 Mar 2021 04:01:07 -0700 (PDT) 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=wS83U3PlCAQKDrzEYnjqkchqohrJ402wKL3+09F+PoY=; b=D+7P2wLVbI7e2JBtAwClLChJ6zsnQXns0riW4htlbQnpD+1y8qhVf1IkJKYiPxu1Dn aRwabjL+Rqe1QHsr/qXc3NGON//a1IxfX61wBoEgykwZFTIZ7CqAXayazQfe5BfgSsaX Nq7ijsGwJw/Uh6CR0MKnHVRYUleoFUK85d3yzoIw2+gI+XvS5Z0M9ewWgrsgTlQfPGn1 f6tYpWgL6PaLmguRYgq7mmGoxJpNQiNgVjrBT9amYzJB9gczzMBFyvnbHFfWgXQJ28Er LkclzIpFf7KgEZ99Y0cq5OYGUCCym6hvJGBOZzgBfUItvfpYhXJxpy3tLMv16jL6IUQG uYbg== 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=wS83U3PlCAQKDrzEYnjqkchqohrJ402wKL3+09F+PoY=; b=rzLU6LG+RhJHNz71S67q2qJFBmiSVyQFrFb0Nfrkha/fG/2xSix6ib1/orDWddqrVV vOeA/gEyMD54g63nAH+Tiu7SnGVW4eTMQwx2RCoqGrz6A9VWH8BWRfaOd4BM0d32y6Dz tOClNAIMXWvkKbni9uNhvKx1W3IujbnEbgTq8gQE4rS3pVOdcQRuUgkXWTe/+4m06kXW zj3gQ/rZoig+7TP/62Q/IxbX/OKjflh50jOsCApRGmWN53TqqqJTeb47/jWKsnpKBv3w ROVr2k4lTXRbc8/vLsMTkwBwqKccny/w5xiJsfiJ0bB3Ms1vCQTs+X+ah8PEQlbIEjJG Mocw== X-Gm-Message-State: AOAM5303n86WXWhaic1S8zmLkWUU/+kD4u9l1wn4f9Tx8ynBhU8ohd94 L8VuEQRs9CuCHTWk7SJdCeC1uw== X-Received: by 2002:adf:e54a:: with SMTP id z10mr2970586wrm.87.1617188466235; Wed, 31 Mar 2021 04:01:06 -0700 (PDT) Received: from localhost.localdomain ([82.142.26.252]) by smtp.gmail.com with ESMTPSA id u23sm3376275wmn.26.2021.03.31.04.01.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 Mar 2021 04:01:05 -0700 (PDT) From: Daniel Lezcano To: daniel.lezcano@linaro.org Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, lukasz.luba@arm.com, rafael@kernel.org, gregkh@linuxfoundation.org Subject: [PATCH v5 4/5] powercap/drivers/dtpm: Use container_of instead of a private data field Date: Wed, 31 Mar 2021 13:00:47 +0200 Message-Id: <20210331110048.24956-4-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210331110048.24956-1-daniel.lezcano@linaro.org> References: <20210331110048.24956-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 | 24 +++++++++---------- drivers/powercap/dtpm_cpu.c | 46 ++++++++++++++++++------------------- include/linux/dtpm.h | 3 +-- 3 files changed, 35 insertions(+), 38 deletions(-) -- 2.17.1 diff --git a/drivers/powercap/dtpm.c b/drivers/powercap/dtpm.c index 3bcd8374baf8..03dbabc1ffd0 100644 --- a/drivers/powercap/dtpm.c +++ b/drivers/powercap/dtpm.c @@ -190,6 +190,12 @@ struct dtpm *dtpm_lookup(const char *name) dtpm = __dtpm_lookup(name); mutex_unlock(&dtpm_lock); + if (!dtpm) { + dtpm = kzalloc(sizeof(*dtpm), GFP_KERNEL); + if (dtpm) + dtpm_init(dtpm, NULL); + } + return dtpm; } @@ -470,24 +476,18 @@ 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); dtpm->weight = 1024; dtpm->ops = ops; } - - return dtpm; } /** @@ -578,7 +578,7 @@ int dtpm_register(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; @@ -593,4 +593,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 74b39a1082e5..f4092d1b01d7 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; snprintf(name, sizeof(name), "cpu%d-cpufreq", dtpm_cpu->cpu); - ret = dtpm_add(name, dtpm); + ret = dtpm_add(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_del: dtpm_del(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 2ec2821111d1..e47bd5bbf56e 100644 --- a/include/linux/dtpm.h +++ b/include/linux/dtpm.h @@ -23,7 +23,6 @@ struct dtpm { u64 power_max; u64 power_min; int weight; - void *private; }; struct dtpm_ops { @@ -65,7 +64,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_unregister(struct dtpm *dtpm); From patchwork Wed Mar 31 11:00:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 412873 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp386285jai; Wed, 31 Mar 2021 04:02:17 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwnSKzpnbLdJckEJS3BNj3relmmrTQhtCRKsMl0hvYI+/aHBFU9cUuWZCoksaGdFzDhsAFi X-Received: by 2002:a05:6402:c1:: with SMTP id i1mr2880769edu.315.1617188537482; Wed, 31 Mar 2021 04:02:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617188537; cv=none; d=google.com; s=arc-20160816; b=k27sJOyV18Hk6Fh+epQC2Edem7dmA6luS5aV5XCXfwChfWu32TalUWHMQwXX0kYBHY uYc1K8y6aHcS3HsrlYwNnVSclTN6TScJERgyR4a2QWXC13Qjnvqbp21a6l8zTWI7ZCGM Gb7POWcKHnyUNT/F/inXPRpmQvdrArjH3j96Y78VSirm5LXm0kQC6Qivj7HBmnx4+tIA g77tlqJBLeJYPtOb8cEloA32jU8yKzGKLs6S/XnqjBMTzGaKh1fPZJz90KHbVFEkmudG g0UMjDxDxMkvNCe4QvA4MWFBuuQFhYGbJyLUfPKr8hl3bvwNJJD7SRrH53rJ5fDiV5DA +MQA== 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=IN1SjCUiJXttEzEwKJpOwO8v8lxJB5yWOIgxTzXkjf4=; b=k9d/Y8Y8TZBm+adt+ulA7RE4M3uL4L8yo3/yVFAyoXNVpE7QdOgbZp2gYmBhHBAIhW 4fWfr5BFxRStgiM5XlK4/WmFhnb/W0cg+pYhJeKbs61rT8N9rZL8lmCETP/n0kfJgIjT tdKQLfAUBCNDF148rV20xkE5vEK5MQcWKCth4rgL/XAX5LZK2JQPMtFNOv9SLMF0Np9H 4vXiaUqViBZ7d4pjn4T3CfKuaq0TdX2wUUqME7k5kVp8YtBq4SpeAzJqMEI5CMftkUPX MuvpUbOgcPVVgET8AkNRn/GJraZDWsmWLhChgsKgrWlcU/5j2h3NarUEiT3AZTsz7zE3 tYtA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="mES/btcE"; 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 r16si1445467edw.458.2021.03.31.04.02.17; Wed, 31 Mar 2021 04:02:17 -0700 (PDT) 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="mES/btcE"; 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 S235466AbhCaLBq (ORCPT + 7 others); Wed, 31 Mar 2021 07:01:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57376 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235524AbhCaLBJ (ORCPT ); Wed, 31 Mar 2021 07:01:09 -0400 Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AB59DC0613D7 for ; Wed, 31 Mar 2021 04:01:08 -0700 (PDT) Received: by mail-wr1-x433.google.com with SMTP id z2so19216019wrl.5 for ; Wed, 31 Mar 2021 04:01:08 -0700 (PDT) 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=IN1SjCUiJXttEzEwKJpOwO8v8lxJB5yWOIgxTzXkjf4=; b=mES/btcERywUzdWQs1lJxM93buJiHXH0MILQ1g6KKVjqG1sh10JFCAQI2AA2xTNX46 fYc9nHcE8G81eSRcDO9fesgjtZcNXyE+ZCZ07MYPvDxkig2XST3Sv1VBAkV4ZAAWHcMW P1E8dzFXRygT10p1+Z8dhDxqY/icRWDlEcKKCrRpW/GJPrIEVQQQwUoa9mphcogE9lwB Ye65w2zXC7BjafTuGEhrNfvG+5KIy3OVbmgePRstcMZTq9bZAoZccoa9Rzb/h16fW7Cf jzPH422YDX0/p8XLb/Vpt/n8VlCuaNRqgpESHWRMx4BiknJaRQkqylA3nORJ6GGoFIxL 2nTw== 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=IN1SjCUiJXttEzEwKJpOwO8v8lxJB5yWOIgxTzXkjf4=; b=FjGmMki8Z1ASxILvc09riPqq5yl6H2zmsMoS5mQR5nLE0bTKT4aWoyi55n3dcmnpvK /DOBP3ekuZqAwCSDHyIJBbaqLJI7tZ7bEFi1RqjSoB3eok8onXXieLP6CqboCnDLufSF 6IEe1lC+GJvDVshtlQKkdNymqOiekHOfU8btYQZXI3GoGZ0jChT29VHni5RlX9c3z5PK fpZEWPpR1O0uta1uxB7IjIU45ezSWUzMBwXW0qhuD6gPGM7BDlVXpOJGjc96EynWPPZO w6NUqR3pb6fPfnRML1g9uTke4EERKvuT1bQiBqqZ4xWIVVJByg6RI6171gXsqacySD48 IVBg== X-Gm-Message-State: AOAM533gL3LyioHlj7pJ12mxl3JL5A/HBJSVP1SLM5T/S2f3OHo2E4/2 ufwEfImLXn2Z7/OaQmHFntkYUQ== X-Received: by 2002:a5d:6684:: with SMTP id l4mr2973647wru.381.1617188467320; Wed, 31 Mar 2021 04:01:07 -0700 (PDT) Received: from localhost.localdomain ([82.142.26.252]) by smtp.gmail.com with ESMTPSA id u23sm3376275wmn.26.2021.03.31.04.01.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 Mar 2021 04:01:06 -0700 (PDT) From: Daniel Lezcano To: daniel.lezcano@linaro.org Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, lukasz.luba@arm.com, rafael@kernel.org, gregkh@linuxfoundation.org Subject: [PATCH v5 5/5] powercap/drivers/dtpm: Scale the power with the load Date: Wed, 31 Mar 2021 13:00:48 +0200 Message-Id: <20210331110048.24956-5-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210331110048.24956-1-daniel.lezcano@linaro.org> References: <20210331110048.24956-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 Reviewed-by: Lukasz Luba --- V3: - Fixed uninitialized 'cpu' in scaled_power_uw() 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 | 46 +++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 7 deletions(-) -- 2.17.1 diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c index f4092d1b01d7..eae35ae3c42e 100644 --- a/drivers/powercap/dtpm_cpu.c +++ b/drivers/powercap/dtpm_cpu.c @@ -68,27 +68,59 @@ 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 = 0, sum_util = 0; + int cpu; + + for_each_cpu_and(cpu, pd_mask, cpu_online_mask) { + + /* + * The capacity is the same for all CPUs belonging to + * the same perf domain, so a single call to + * arch_scale_cpu_capacity() is enough. However, we + * need the CPU parameter to be initialized by the + * loop, so the call ends up in this block. + * + * We can initialize 'max' with a cpumask_first() call + * before the loop but the bits computation is not + * worth given the arch_scale_cpu_capacity() just + * returns a value where the resulting assembly code + * will be optimized by the compiler. + */ + max = arch_scale_cpu_capacity(cpu); + sum_util += sched_cpu_util(cpu, max); + } + + /* + * In the improbable case where all the CPUs of the perf + * domain are offline, 'max' will be zero and will lead to an + * illegal operation with a zero division. + */ + return max ? (power * ((sum_util << 10) / max)) >> 10 : 0; +} + 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;