From 4ab53fe612e21b0f509a3b468c56706364de98df Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 29 Nov 2017 11:12:27 +0000 Subject: [PATCH 1/9] PM: Provide a config snippet for disabling PM A frequent source of build problems is poor handling of optional PM support, almost all development is done with the PM options enabled but they can be turned off. Currently few if any of the build test services do this as standard as there is no standard config for it and the use of selects and def_bool means that simply setting CONFIG_PM=n doesn't do what is expected. To make this easier provide a fragement that can be used with KCONFIG_ALLCONFIG to force PM off. CONFIG_XEN is disabled as Xen uses hibernation callbacks which end up turning on power management on architectures with Xen. Some cpuidle implementations on ARM select PM so CONFIG_CPU_IDLE is disabled, and some ARM architectures unconditionally enable PM so they are also disabled. Signed-off-by: Mark Brown Signed-off-by: Rafael J. Wysocki --- MAINTAINERS | 1 + kernel/configs/nopm.config | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 kernel/configs/nopm.config diff --git a/MAINTAINERS b/MAINTAINERS index d4fdcb12616c..ae6e590c5125 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10890,6 +10890,7 @@ F: include/linux/pm.h F: include/linux/pm_* F: include/linux/powercap.h F: drivers/powercap/ +F: kernel/configs/nopm.config POWER STATE COORDINATION INTERFACE (PSCI) M: Mark Rutland diff --git a/kernel/configs/nopm.config b/kernel/configs/nopm.config new file mode 100644 index 000000000000..81ff07863576 --- /dev/null +++ b/kernel/configs/nopm.config @@ -0,0 +1,15 @@ +CONFIG_PM=n +CONFIG_SUSPEND=n +CONFIG_HIBERNATION=n + +# Triggers PM on OMAP +CONFIG_CPU_IDLE=n + +# Triggers enablement via hibernate callbacks +CONFIG_XEN=n + +# ARM/ARM64 architectures that select PM unconditionally +CONFIG_ARCH_OMAP2PLUS_TYPICAL=n +CONFIG_ARCH_RENESAS=n +CONFIG_ARCH_TEGRA=n +CONFIG_ARCH_VEXPRESS=n From 7f6344896d3e5be3ccfef1c5c98ef24940e5f229 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sat, 11 Nov 2017 23:17:26 +0530 Subject: [PATCH 2/9] powercap: Simplify powercap_init() Simplify powercap_init() by reducing the number of redundant assignments in it. Signed-off-by: Arvind Yadav [ rjw: Subject+changelog ] Signed-off-by: Rafael J. Wysocki --- drivers/powercap/powercap_sys.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c index 5b10b50f8686..64b2b2501a79 100644 --- a/drivers/powercap/powercap_sys.c +++ b/drivers/powercap/powercap_sys.c @@ -673,15 +673,13 @@ EXPORT_SYMBOL_GPL(powercap_unregister_control_type); static int __init powercap_init(void) { - int result = 0; + int result; result = seed_constraint_attributes(); if (result) return result; - result = class_register(&powercap_class); - - return result; + return class_register(&powercap_class); } device_initcall(powercap_init); From 001d50c9a14f1fab94b329161a1db9235b4e60da Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 30 Nov 2017 12:54:28 +0100 Subject: [PATCH 3/9] PM / Domains: Remove obsolete "samsung,power-domain" check Currently the generic PM Domain code code checks for the presence of both (generic) "power-domains" and (Samsung Exynos legacy) "samsung,power-domain" properties in all device tree nodes representing devices. There are two issues with this: 1. This imposes a small boot-time penalty on all platforms using DT, 2. Platform-specific checks do not really belong in core framework code. Remove the platform-specific check, as the last user of "samsung,power-domain" was removed in commit 46dcf0ff0de35da8 ("ARM: dts: exynos: Remove exynos4415.dtsi"). All other users were converted before in commit 0da6587041363033 ("ARM: dts: convert to generic power domain bindings for exynos DT"). Signed-off-by: Geert Uytterhoeven Acked-by: Ulf Hansson Acked-by: Krzysztof Kozlowski Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 0c80bea05bcb..f9dcc981b6b9 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -2199,20 +2199,8 @@ int genpd_dev_pm_attach(struct device *dev) ret = of_parse_phandle_with_args(dev->of_node, "power-domains", "#power-domain-cells", 0, &pd_args); - if (ret < 0) { - if (ret != -ENOENT) - return ret; - - /* - * Try legacy Samsung-specific bindings - * (for backwards compatibility of DT ABI) - */ - pd_args.args_count = 0; - pd_args.np = of_parse_phandle(dev->of_node, - "samsung,power-domain", 0); - if (!pd_args.np) - return -ENOENT; - } + if (ret < 0) + return ret; mutex_lock(&gpd_list_lock); pd = genpd_get_from_provider(&pd_args); From a248efb3d634854dfcf43a165003597542e90d11 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 30 Nov 2017 12:57:00 +0100 Subject: [PATCH 4/9] bus: simple-pm-bus: convert bool SIMPLE_PM_BUS to tristate The Kconfig currently controlling compilation of this code is: config SIMPLE_PM_BUS bool "Simple Power-Managed Bus Driver" ...meaning that it currently is not being built as a module by anyone. In removing the orphaned modular support in a previous patch set, Geert indicated he'd rather see this code converted to tristate. I normally don't do that because it extends functionality that I can't easily run time test or even know if the use case makes sense, but since in this case the author has nominated it as such, we do the conversion here. Note that doesn't change the lack of run time testing ; this change is only tested for sucessful compile and modpost. [geert: Ethernet is probed successfully on sh73a0/kzm9g after insmodding simple-pm-bus.ko] Signed-off-by: Paul Gortmaker Tested-by: Geert Uytterhoeven Signed-off-by: Geert Uytterhoeven Acked-by: Simon Horman Signed-off-by: Rafael J. Wysocki --- drivers/bus/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index dc7b3c7b7d42..57e011d36a79 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig @@ -120,7 +120,7 @@ config QCOM_EBI2 SRAM, ethernet adapters, FPGAs and LCD displays. config SIMPLE_PM_BUS - bool "Simple Power-Managed Bus Driver" + tristate "Simple Power-Managed Bus Driver" depends on OF && PM help Driver for transparent busses that don't need a real driver, but From 3cfd68b5ba8737d28bfcf9b6487ea4d9216b8504 Mon Sep 17 00:00:00 2001 From: gaurav jindal Date: Fri, 5 Jan 2018 14:01:30 +0100 Subject: [PATCH 5/9] cpuidle: Avoid NULL argument in cpuidle_switch_governor() Checks if the new governor is NULL before updating the cupidle_curr_governor. Signed-off-by: gaurav jindal [ rjw : Subject ] Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/governor.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c index 4e78263e34a4..5d359aff3cc5 100644 --- a/drivers/cpuidle/governor.c +++ b/drivers/cpuidle/governor.c @@ -36,14 +36,15 @@ static struct cpuidle_governor * __cpuidle_find_governor(const char *str) /** * cpuidle_switch_governor - changes the governor * @gov: the new target governor - * - * NOTE: "gov" can be NULL to specify disabled * Must be called with cpuidle_lock acquired. */ int cpuidle_switch_governor(struct cpuidle_governor *gov) { struct cpuidle_device *dev; + if (!gov) + return -EINVAL; + if (gov == cpuidle_curr_governor) return 0; From 52b3672c135416d8ccc3c92f475b983a201fc6f5 Mon Sep 17 00:00:00 2001 From: Zhen Han Date: Wed, 10 Jan 2018 08:38:23 +0800 Subject: [PATCH 6/9] powercap: add suspend and resume mechanism for SOC power limit PL1 and PL2 could be throlled or de-throttled by Thermal management to control SOC temperature. However, currently, their value will be reset to default value after once system suspend and resume. Add pm_notifier to save PL1, PL2 before system suspect and restore PL1, PL2 after system resume. Signed-off-by: Zhen Han Signed-off-by: Rafael J. Wysocki --- drivers/powercap/intel_rapl.c | 97 +++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index d1694f1def72..0188cff98cdd 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -155,6 +156,7 @@ struct rapl_power_limit { int prim_id; /* primitive ID used to enable */ struct rapl_domain *domain; const char *name; + u64 last_power_limit; }; static const char pl1_name[] = "long_term"; @@ -1533,6 +1535,92 @@ static int rapl_cpu_down_prep(unsigned int cpu) static enum cpuhp_state pcap_rapl_online; +static void power_limit_state_save(void) +{ + struct rapl_package *rp; + struct rapl_domain *rd; + int nr_pl, ret, i; + + get_online_cpus(); + list_for_each_entry(rp, &rapl_packages, plist) { + if (!rp->power_zone) + continue; + rd = power_zone_to_rapl_domain(rp->power_zone); + nr_pl = find_nr_power_limit(rd); + for (i = 0; i < nr_pl; i++) { + switch (rd->rpl[i].prim_id) { + case PL1_ENABLE: + ret = rapl_read_data_raw(rd, + POWER_LIMIT1, + true, + &rd->rpl[i].last_power_limit); + if (ret) + rd->rpl[i].last_power_limit = 0; + break; + case PL2_ENABLE: + ret = rapl_read_data_raw(rd, + POWER_LIMIT2, + true, + &rd->rpl[i].last_power_limit); + if (ret) + rd->rpl[i].last_power_limit = 0; + break; + } + } + } + put_online_cpus(); +} + +static void power_limit_state_restore(void) +{ + struct rapl_package *rp; + struct rapl_domain *rd; + int nr_pl, i; + + get_online_cpus(); + list_for_each_entry(rp, &rapl_packages, plist) { + if (!rp->power_zone) + continue; + rd = power_zone_to_rapl_domain(rp->power_zone); + nr_pl = find_nr_power_limit(rd); + for (i = 0; i < nr_pl; i++) { + switch (rd->rpl[i].prim_id) { + case PL1_ENABLE: + if (rd->rpl[i].last_power_limit) + rapl_write_data_raw(rd, + POWER_LIMIT1, + rd->rpl[i].last_power_limit); + break; + case PL2_ENABLE: + if (rd->rpl[i].last_power_limit) + rapl_write_data_raw(rd, + POWER_LIMIT2, + rd->rpl[i].last_power_limit); + break; + } + } + } + put_online_cpus(); +} + +static int rapl_pm_callback(struct notifier_block *nb, + unsigned long mode, void *_unused) +{ + switch (mode) { + case PM_SUSPEND_PREPARE: + power_limit_state_save(); + break; + case PM_POST_SUSPEND: + power_limit_state_restore(); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block rapl_pm_notifier = { + .notifier_call = rapl_pm_callback, +}; + static int __init rapl_init(void) { const struct x86_cpu_id *id; @@ -1560,8 +1648,16 @@ static int __init rapl_init(void) /* Don't bail out if PSys is not supported */ rapl_register_psys(); + + ret = register_pm_notifier(&rapl_pm_notifier); + if (ret) + goto err_unreg_all; + return 0; +err_unreg_all: + cpuhp_remove_state(pcap_rapl_online); + err_unreg: rapl_unregister_powercap(); return ret; @@ -1569,6 +1665,7 @@ static int __init rapl_init(void) static void __exit rapl_exit(void) { + unregister_pm_notifier(&rapl_pm_notifier); cpuhp_remove_state(pcap_rapl_online); rapl_unregister_powercap(); } From a935424bb658f9ca37eb5e94119b857998341356 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 10 Jan 2018 21:31:56 +0100 Subject: [PATCH 7/9] PM / domains: Don't skip driver's ->suspend|resume_noirq() callbacks Commit 10da65423fdb (PM / Domains: Call driver's noirq callbacks) started to respect driver's noirq callbacks, but while doing that it also introduced a few potential problems. More precisely, in genpd_finish_suspend() and genpd_resume_noirq() the noirq callbacks at the driver level should be invoked, no matter of whether dev->power.wakeup_path is set or not. Additionally, the commit in question also made genpd_resume_noirq() to ignore the return value from pm_runtime_force_resume(). Let's fix both these issues! Fixes: 10da65423fdb (PM / Domains: Call driver's noirq callbacks) Signed-off-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index f9dcc981b6b9..48255ce7c0ad 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1032,15 +1032,12 @@ static int genpd_prepare(struct device *dev) static int genpd_finish_suspend(struct device *dev, bool poweroff) { struct generic_pm_domain *genpd; - int ret; + int ret = 0; genpd = dev_to_genpd(dev); if (IS_ERR(genpd)) return -EINVAL; - if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd)) - return 0; - if (poweroff) ret = pm_generic_poweroff_noirq(dev); else @@ -1048,10 +1045,18 @@ static int genpd_finish_suspend(struct device *dev, bool poweroff) if (ret) return ret; + if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd)) + return 0; + if (genpd->dev_ops.stop && genpd->dev_ops.start) { ret = pm_runtime_force_suspend(dev); - if (ret) + if (ret) { + if (poweroff) + pm_generic_restore_noirq(dev); + else + pm_generic_resume_noirq(dev); return ret; + } } genpd_lock(genpd); @@ -1085,7 +1090,7 @@ static int genpd_suspend_noirq(struct device *dev) static int genpd_resume_noirq(struct device *dev) { struct generic_pm_domain *genpd; - int ret = 0; + int ret; dev_dbg(dev, "%s()\n", __func__); @@ -1094,21 +1099,20 @@ static int genpd_resume_noirq(struct device *dev) return -EINVAL; if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd)) - return 0; + return pm_generic_resume_noirq(dev); genpd_lock(genpd); genpd_sync_power_on(genpd, true, 0); genpd->suspended_count--; genpd_unlock(genpd); - if (genpd->dev_ops.stop && genpd->dev_ops.start) + if (genpd->dev_ops.stop && genpd->dev_ops.start) { ret = pm_runtime_force_resume(dev); + if (ret) + return ret; + } - ret = pm_generic_resume_noirq(dev); - if (ret) - return ret; - - return ret; + return pm_generic_resume_noirq(dev); } /** From 17218e0092f8c7b7edce7ff08c8b23212eac7271 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 12 Jan 2018 14:10:38 +0100 Subject: [PATCH 8/9] PM / genpd: Stop/start devices without pm_runtime_force_suspend/resume() There are problems with calling pm_runtime_force_suspend/resume() to "stop" and "start" devices in genpd_finish_suspend() and genpd_resume_noirq() (and in analogous hibernation-specific genpd callbacks) after commit 122a22377a3d (PM / Domains: Stop/start devices during system PM suspend/resume in genpd) as those routines do much more than just "stopping" and "starting" devices (which was the stated purpose of that commit) unnecessarily and may not play well with system-wide PM driver callbacks. First, consider the pm_runtime_force_suspend() in genpd_finish_suspend(). If the current runtime PM status of the device is "suspended", that function most likely does the right thing by ignoring the device, because it should have been "stopped" already and whatever needed to be done to deactivate it shoud have been done. In turn, if the runtime PM status of the device is "active", genpd_runtime_suspend() is called for it (indirectly) and (1) runs the ->runtime_suspend callback provided by the device's driver (assuming no bus type with ->runtime_suspend of its own), (2) "stops" the device and (3) checks if the domain can be powered down, and then (4) the device's runtime PM status is changed to "suspended". Out of the four actions above (1) is not necessary and it may be outright harmful, (3) is pointless and (4) is questionable. The only operation that needs to be carried out here is (2). The reason why (1) is not necessary is because the system-wide PM callbacks provided by the device driver for the transition in question have been run and they should have taken care of the driver's part of device suspend already. Moreover, it may be harmful, because the ->runtime_suspend callback may want to access the device which is partially suspended at that point and may not be responsive. Also, system-wide PM callbacks may have been run already (in the previous phases of the system transition under way) for the device's parent or for its supplier devices (if any) and the device may not be accessible because of that. There also is no reason to do (3), because genpd_finish_suspend() will repeat it anyway, and (4) potentially causes confusion to ensue during the subsequent system transition to the working state. Consider pm_runtime_force_resume() in genpd_resume_noirq() now. It runs genpd_runtime_resume() for all devices with runtime PM status set to "suspended", which includes all of the devices whose runtime PM status was changed by pm_runtime_force_suspend() before and may include some devices already suspended when the pm_runtime_force_suspend() was running, which may be confusing. The genpd_runtime_resume() first tries to power up the domain, which (again) is pointless, because genpd_resume_noirq() has done that already. Then, it "starts" the device and runs the ->runtime_resume callback (from the driver, say) for it. If all is well, the device is left with the runtime PM status set to "active". Unfortunately, running the driver's ->runtime_resume callback before its system-wide PM callbacks and possibly before some system-wide PM callbacks of the parent device's driver (let alone supplier drivers) is asking for trouble, especially if the device had been suspended before pm_runtime_force_suspend() ran previously or if the callbacks in question expect to be run back-to-back with their suspend-side counterparts. It also should not be necessary, because the system-wide PM driver callbacks that will be invoked for the device subsequently should take care of resuming it just fine. [Running the driver's ->runtime_resume callback in the "noirq" phase of the transition to the working state may be problematic even for devices whose drivers do use pm_runtime_force_resume() in (or as) their system-wide PM callbacks if they have suppliers other than their parents, because it may cause the supplier to be resumed after the consumer in some cases.] Because of the above, modify genpd as follows: 1. Change genpd_finish_suspend() to only "stop" devices with runtime PM status set to "active" (without invoking runtime PM callbacks for them, changing their runtime PM status and so on). That doesn't change the handling of devices whose drivers use pm_runtime_force_suspend/resume() in (or as) their system-wide PM callbacks and addresses the issues described above for the other devices. 2. Change genpd_resume_noirq() to only "start" devices with runtime PM status set to "active" (without invoking runtime PM callbacks for them, changing their runtime PM status and so on). Again, that doesn't change the handling of devices whose drivers use pm_runtime_force_suspend/resume() in (or as) their system-wide PM callbacks and addresses the described issues for the other devices. Devices with runtime PM status set to "suspended" are not started with the assumption that they will be resumed later, either by pm_runtime_force_resume() or via runtime PM. 3. Change genpd_restore_noirq() to follow genpd_resume_noirq(). That causes devices already suspended before hibernation to be left alone (which also is the case without the change) and avoids running the ->runtime_resume driver callback too early for the other devices. 4. Change genpd_freeze_noirq() and genpd_thaw_noirq() in accordance with the above modifications. Fixes: 122a22377a3d (PM / Domains: Stop/start devices during system PM suspend/resume in genpd) Signed-off-by: Rafael J. Wysocki Acked-by: Ulf Hansson --- drivers/base/power/domain.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 48255ce7c0ad..528b24149bc7 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1048,8 +1048,9 @@ static int genpd_finish_suspend(struct device *dev, bool poweroff) if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd)) return 0; - if (genpd->dev_ops.stop && genpd->dev_ops.start) { - ret = pm_runtime_force_suspend(dev); + if (genpd->dev_ops.stop && genpd->dev_ops.start && + !pm_runtime_status_suspended(dev)) { + ret = genpd_stop_dev(genpd, dev); if (ret) { if (poweroff) pm_generic_restore_noirq(dev); @@ -1106,8 +1107,9 @@ static int genpd_resume_noirq(struct device *dev) genpd->suspended_count--; genpd_unlock(genpd); - if (genpd->dev_ops.stop && genpd->dev_ops.start) { - ret = pm_runtime_force_resume(dev); + if (genpd->dev_ops.stop && genpd->dev_ops.start && + !pm_runtime_status_suspended(dev)) { + ret = genpd_start_dev(genpd, dev); if (ret) return ret; } @@ -1139,8 +1141,9 @@ static int genpd_freeze_noirq(struct device *dev) if (ret) return ret; - if (genpd->dev_ops.stop && genpd->dev_ops.start) - ret = pm_runtime_force_suspend(dev); + if (genpd->dev_ops.stop && genpd->dev_ops.start && + !pm_runtime_status_suspended(dev)) + ret = genpd_stop_dev(genpd, dev); return ret; } @@ -1163,8 +1166,9 @@ static int genpd_thaw_noirq(struct device *dev) if (IS_ERR(genpd)) return -EINVAL; - if (genpd->dev_ops.stop && genpd->dev_ops.start) { - ret = pm_runtime_force_resume(dev); + if (genpd->dev_ops.stop && genpd->dev_ops.start && + !pm_runtime_status_suspended(dev)) { + ret = genpd_start_dev(genpd, dev); if (ret) return ret; } @@ -1221,8 +1225,9 @@ static int genpd_restore_noirq(struct device *dev) genpd_sync_power_on(genpd, true, 0); genpd_unlock(genpd); - if (genpd->dev_ops.stop && genpd->dev_ops.start) { - ret = pm_runtime_force_resume(dev); + if (genpd->dev_ops.stop && genpd->dev_ops.start && + !pm_runtime_status_suspended(dev)) { + ret = genpd_start_dev(genpd, dev); if (ret) return ret; } From 01857cf7748aef41c20987526d4c12f12b2f04ff Mon Sep 17 00:00:00 2001 From: Luis de Bethencourt Date: Wed, 17 Jan 2018 10:30:34 +0000 Subject: [PATCH 9/9] powercap: intel_rapl: Fix trailing semicolon The trailing semicolon is an empty statement that does no operation. Removing it since it doesn't do anything. Signed-off-by: Luis de Bethencourt Signed-off-by: Rafael J. Wysocki --- drivers/powercap/intel_rapl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index 0188cff98cdd..35636e1d8a3d 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c @@ -1211,7 +1211,7 @@ static int rapl_package_register_powercap(struct rapl_package *rp) struct rapl_domain *rd; char dev_name[17]; /* max domain name = 7 + 1 + 8 for int + 1 for null*/ struct powercap_zone *power_zone = NULL; - int nr_pl, ret;; + int nr_pl, ret; /* Update the domain data of the new package */ rapl_update_domain_data(rp);