* [PATCH v4 00/11] Add support for SCMIv4.0 Powercap Extensions
From: Philip Radford @ 2026-04-01 9:53 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi, linux-pm
Cc: sudeep.holla, james.quinlan, f.fainelli, vincent.guittot,
etienne.carriere, peng.fan, michal.simek, quic_sibis,
dan.carpenter, d-gole, souvik.chakravarty, Philip Radford
Hi all,
I will be taking over this series from Cristian and in doing so I have
addressed a couple of issues raised by the first version and added four
additional patches since Cristian's original series:
[6/11] exposes the measurement averaging interval (MAI) value when the
agent has registered to receive power measurement change notifications
for the power capping domain.
[9/11] adds MAI get and set support for the powercap protocol.
[10/11] introduces a synthetic root zone to act as a common parent for all
top-level domains.
[11/11] adds get_power_uw to synthetic root zone, summing the per-zone
power of immediate child zones.
TODO:
- Add enable/disable functionality to synthetic root zone to enable/disable
immediate children.
The original series was based on v6.17-rc1 whereas this version has been
based on v7.0-rc4.
The rest of Cristian's series is explained below;
SCMIv4.0 [1] introduces some new features and commands into the Powercap
protocol. In a nutshell, such protocol changes add support for:
- setting multiple powercap limit/interval constraints for each SCMI
powercap domain which supports multiple Concurrent Power Limit
- enabling more Powercap commands to use Fastchannels mechanism
- adding multiple constraints support to the existing notifications
After a bit of needed updates in the SCMI core this series adds:
- support for the idea of optional multiple Concurrent Power Limit (CPLs)
- support for the new FCs
- support for extended notifications
- enable usage of such multiple constraint in the ARM SCMI Powercap driver
Note that the public SCMIv4.0 spec at [1] is currently still BETA0, so
this series could anyway need some minor rework along the way and
definitely will need to wait for a final public release before being
possibly merged.
Tested on a single and multi-instance scenario on an emulated setup
implementing the new protocol extensions.
Based on v7.0-rc4.
Thanks,
Phil
---
V3->V4
- Rebased on v7.0-rc4
- Added sythentic parent node and functionality
- Moved fastchannel inits outside of loop
- Renamed arguments for consistency
V2->V3
- Added powercap MAI get/set support
V1->V2
- Rebased on sudeep/for-next/scmi/updates
- Amended Copyright to include 2026
- Added patch to extend powercap report to include MAI
- Removed creation of pi powercap_info struct due to legacy code change
- Amended references to pi->version and similar, which were based on
legacy code
- Wrapped two variables in le32_to_cpu() to appease Sparse warnings
- Amended comparing operator value in response to feedback
Cristian Marussi (7):
firmware: arm_scmi: Add an optional custom parameter to fastchannel
helpers
firmware: arm_scmi: Refactor powercap domain layout
firmware: arm_scmi: Add SCMIv4.0 Powercap basic support
firmware: arm_scmi: Add SCMIv4.0 Powercap FCs support
firmware: arm_scmi: Add SCMIV4.0 Powercap notifications support
include: trace: Add new parameter to trace_scmi_fc_call
powercap: arm_scmi: Enable multiple constraints support
Philip Radford (4):
firmware: arm_scmi: Extend powercap report to include MAI
firmware: arm_scmi: add Powercap MAI get/set support
powercap: arm_scmi: Create synthetic parent node for multi-instance
powercap: arm_scmi: Add get_power_uw to synthetic node
drivers/firmware/arm_scmi/driver.c | 12 +-
drivers/firmware/arm_scmi/perf.c | 16 +-
drivers/firmware/arm_scmi/powercap.c | 984 ++++++++++++++++++++------
drivers/firmware/arm_scmi/protocols.h | 2 +-
drivers/powercap/arm_scmi_powercap.c | 146 +++-
include/linux/scmi_protocol.h | 87 ++-
include/trace/events/scmi.h | 12 +-
7 files changed, 986 insertions(+), 273 deletions(-)
--
2.47.3
^ permalink raw reply
* Re: [PATCH 2/3] dt-bindings: power: qcom,rpmhpd: Add new power domains and new levels
From: Konrad Dybcio @ 2026-04-01 9:21 UTC (permalink / raw)
To: Fenglin Wu, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Ulf Hansson
Cc: Subbaraman Narayanamurthy, linux-arm-msm, devicetree,
linux-kernel, linux-pm, kernel
In-Reply-To: <20260401-haw-rpmhpd-v1-2-c830c79ed8f9@oss.qualcomm.com>
On 4/1/26 11:15 AM, Fenglin Wu wrote:
> Add definitions for the new power domains which present in Hawi SoC:
> - RPMHPD_DCX (Display Core X): supplies VDD_DISP for the display
> subsystem
> - RPMHPD_GBX (Graphics Box): supplies VDD_GFX_BX for the GPU/graphics
> subsystem
>
> Also, add constants for new power domain levels that supported in Hawi
> SoC, including: LOW_SVS_D3_0, LOW_SVS_D1_0, LOW_SVS_D0_0, SVS_L2_0,
> TURBO_L1_0/1/2, TURBO_L1_0/1/2.
>
> Signed-off-by: Fenglin Wu <fenglin.wu@oss.qualcomm.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
^ permalink raw reply
* Re: [PATCH 3/3] pmdomain: qcom: rpmhpd: Add power domains for Hawi SoC
From: Konrad Dybcio @ 2026-04-01 9:21 UTC (permalink / raw)
To: Fenglin Wu, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Ulf Hansson
Cc: Subbaraman Narayanamurthy, linux-arm-msm, devicetree,
linux-kernel, linux-pm, kernel
In-Reply-To: <20260401-haw-rpmhpd-v1-3-c830c79ed8f9@oss.qualcomm.com>
On 4/1/26 11:15 AM, Fenglin Wu wrote:
> Add the RPMh power domains required for the Hawi SoC. This includes
> new definitions for domains supplying specific hardware components:
> - DCX: supplies VDD_DISP
> - GBX: supplies VDD_GFX_BX
>
> Signed-off-by: Fenglin Wu <fenglin.wu@oss.qualcomm.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
^ permalink raw reply
* [PATCH] power: sequencing: pcie-m2: enforce PCI and OF dependencies
From: Arnd Bergmann @ 2026-04-01 9:16 UTC (permalink / raw)
To: Bartosz Golaszewski, Manivannan Sadhasivam
Cc: Arnd Bergmann, Ulf Hansson, Michal Wilczynski, linux-pm,
linux-kernel
From: Arnd Bergmann <arnd@arndb.de>
The driver fails to build when PCI is disabled:
drivers/power/sequencing/pwrseq-pcie-m2.c: In function 'pwrseq_pcie_m2_register_notifier':
drivers/power/sequencing/pwrseq-pcie-m2.c:368:54: error: 'pci_bus_type' undeclared (first use in this function); did you mean 'pci_pcie_type'?
368 | ret = bus_register_notifier(&pci_bus_type, &ctx->nb);
| ^~~~~~~~~~~~
| pci_pcie_type
Similarly, when CONFIG_OF is disabled:
drivers/power/sequencing/pwrseq-pcie-m2.c: In function 'pwrseq_m2_pcie_create_bt_node':
drivers/power/sequencing/pwrseq-pcie-m2.c:191:9: error: implicit declaration of function 'of_changeset_init' [-Wimplicit-function-declaration]
191 | of_changeset_init(ctx->ocs);
| ^~~~~~~~~~~~~~~~~
Make both dependencies unconditional to prevent compile-testing
in either configuration.
Fixes: 3f736aecbdc8 ("power: sequencing: pcie-m2: Create serdev device for WCN7850 bluetooth")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/power/sequencing/Kconfig | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/power/sequencing/Kconfig b/drivers/power/sequencing/Kconfig
index 1ec142525a4a..77c6d9227251 100644
--- a/drivers/power/sequencing/Kconfig
+++ b/drivers/power/sequencing/Kconfig
@@ -37,8 +37,9 @@ config POWER_SEQUENCING_TH1520_GPU
config POWER_SEQUENCING_PCIE_M2
tristate "PCIe M.2 connector power sequencing driver"
- depends on (PCI && OF) || COMPILE_TEST
- select OF_DYNAMIC if OF
+ depends on OF
+ depends on PCI
+ select OF_DYNAMIC
help
Say Y here to enable the power sequencing driver for PCIe M.2
connectors. This driver handles the power sequencing for the M.2
--
2.39.5
^ permalink raw reply related
* [PATCH 2/3] dt-bindings: power: qcom,rpmhpd: Add new power domains and new levels
From: Fenglin Wu @ 2026-04-01 9:15 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
Ulf Hansson, Konrad Dybcio
Cc: Subbaraman Narayanamurthy, linux-arm-msm, devicetree,
linux-kernel, linux-pm, kernel, Fenglin Wu
In-Reply-To: <20260401-haw-rpmhpd-v1-0-c830c79ed8f9@oss.qualcomm.com>
Add definitions for the new power domains which present in Hawi SoC:
- RPMHPD_DCX (Display Core X): supplies VDD_DISP for the display
subsystem
- RPMHPD_GBX (Graphics Box): supplies VDD_GFX_BX for the GPU/graphics
subsystem
Also, add constants for new power domain levels that supported in Hawi
SoC, including: LOW_SVS_D3_0, LOW_SVS_D1_0, LOW_SVS_D0_0, SVS_L2_0,
TURBO_L1_0/1/2, TURBO_L1_0/1/2.
Signed-off-by: Fenglin Wu <fenglin.wu@oss.qualcomm.com>
---
include/dt-bindings/power/qcom,rpmhpd.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/include/dt-bindings/power/qcom,rpmhpd.h b/include/dt-bindings/power/qcom,rpmhpd.h
index 06851363ae0e..67e2634fdc99 100644
--- a/include/dt-bindings/power/qcom,rpmhpd.h
+++ b/include/dt-bindings/power/qcom,rpmhpd.h
@@ -28,15 +28,20 @@
#define RPMHPD_XO 18
#define RPMHPD_NSP2 19
#define RPMHPD_GMXC 20
+#define RPMHPD_DCX 21
+#define RPMHPD_GBX 22
/* RPMh Power Domain performance levels */
#define RPMH_REGULATOR_LEVEL_RETENTION 16
#define RPMH_REGULATOR_LEVEL_MIN_SVS 48
+#define RPMH_REGULATOR_LEVEL_LOW_SVS_D3_0 49
#define RPMH_REGULATOR_LEVEL_LOW_SVS_D3 50
#define RPMH_REGULATOR_LEVEL_LOW_SVS_D2_1 51
#define RPMH_REGULATOR_LEVEL_LOW_SVS_D2 52
#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1_1 54
+#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1_0 55
#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56
+#define RPMH_REGULATOR_LEVEL_LOW_SVS_D0_0 59
#define RPMH_REGULATOR_LEVEL_LOW_SVS_D0 60
#define RPMH_REGULATOR_LEVEL_LOW_SVS 64
#define RPMH_REGULATOR_LEVEL_LOW_SVS_P1 72
@@ -47,6 +52,7 @@
#define RPMH_REGULATOR_LEVEL_SVS_L0 144
#define RPMH_REGULATOR_LEVEL_SVS_L1 192
#define RPMH_REGULATOR_LEVEL_SVS_L2 224
+#define RPMH_REGULATOR_LEVEL_SVS_L2_0 225
#define RPMH_REGULATOR_LEVEL_NOM 256
#define RPMH_REGULATOR_LEVEL_NOM_L0 288
#define RPMH_REGULATOR_LEVEL_NOM_L1 320
@@ -54,8 +60,14 @@
#define RPMH_REGULATOR_LEVEL_TURBO 384
#define RPMH_REGULATOR_LEVEL_TURBO_L0 400
#define RPMH_REGULATOR_LEVEL_TURBO_L1 416
+#define RPMH_REGULATOR_LEVEL_TURBO_L1_0 417
+#define RPMH_REGULATOR_LEVEL_TURBO_L1_1 418
+#define RPMH_REGULATOR_LEVEL_TURBO_L1_2 419
#define RPMH_REGULATOR_LEVEL_TURBO_L2 432
#define RPMH_REGULATOR_LEVEL_TURBO_L3 448
+#define RPMH_REGULATOR_LEVEL_TURBO_L3_0 449
+#define RPMH_REGULATOR_LEVEL_TURBO_L3_1 450
+#define RPMH_REGULATOR_LEVEL_TURBO_L3_2 451
#define RPMH_REGULATOR_LEVEL_TURBO_L4 452
#define RPMH_REGULATOR_LEVEL_TURBO_L5 456
#define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464
--
2.43.0
^ permalink raw reply related
* [PATCH 3/3] pmdomain: qcom: rpmhpd: Add power domains for Hawi SoC
From: Fenglin Wu @ 2026-04-01 9:15 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
Ulf Hansson, Konrad Dybcio
Cc: Subbaraman Narayanamurthy, linux-arm-msm, devicetree,
linux-kernel, linux-pm, kernel, Fenglin Wu
In-Reply-To: <20260401-haw-rpmhpd-v1-0-c830c79ed8f9@oss.qualcomm.com>
Add the RPMh power domains required for the Hawi SoC. This includes
new definitions for domains supplying specific hardware components:
- DCX: supplies VDD_DISP
- GBX: supplies VDD_GFX_BX
Signed-off-by: Fenglin Wu <fenglin.wu@oss.qualcomm.com>
---
drivers/pmdomain/qcom/rpmhpd.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/drivers/pmdomain/qcom/rpmhpd.c b/drivers/pmdomain/qcom/rpmhpd.c
index 19849703be4a..f5ae2a63765d 100644
--- a/drivers/pmdomain/qcom/rpmhpd.c
+++ b/drivers/pmdomain/qcom/rpmhpd.c
@@ -102,11 +102,21 @@ static struct rpmhpd cx_ao_w_mx_parent = {
.res_name = "cx.lvl",
};
+static struct rpmhpd dcx = {
+ .pd = { .name = "dcx", },
+ .res_name = "dcx.lvl",
+};
+
static struct rpmhpd ebi = {
.pd = { .name = "ebi", },
.res_name = "ebi.lvl",
};
+static struct rpmhpd gbx = {
+ .pd = { .name = "gbx", },
+ .res_name = "gbx.lvl",
+};
+
static struct rpmhpd gfx = {
.pd = { .name = "gfx", },
.res_name = "gfx.lvl",
@@ -622,6 +632,33 @@ static const struct rpmhpd_desc kaanapali_desc = {
.num_pds = ARRAY_SIZE(kaanapali_rpmhpds),
};
+/* Hawi RPMH powerdomains */
+static struct rpmhpd *hawi_rpmhpds[] = {
+ [RPMHPD_CX] = &cx,
+ [RPMHPD_CX_AO] = &cx_ao,
+ [RPMHPD_DCX] = &dcx,
+ [RPMHPD_EBI] = &ebi,
+ [RPMHPD_GBX] = &gbx,
+ [RPMHPD_GFX] = &gfx,
+ [RPMHPD_GMXC] = &gmxc,
+ [RPMHPD_LCX] = &lcx,
+ [RPMHPD_LMX] = &lmx,
+ [RPMHPD_MMCX] = &mmcx,
+ [RPMHPD_MMCX_AO] = &mmcx_ao,
+ [RPMHPD_MX] = &mx,
+ [RPMHPD_MX_AO] = &mx_ao,
+ [RPMHPD_MXC] = &mxc,
+ [RPMHPD_MXC_AO] = &mxc_ao,
+ [RPMHPD_MSS] = &mss,
+ [RPMHPD_NSP] = &nsp,
+ [RPMHPD_NSP2] = &nsp2,
+};
+
+static const struct rpmhpd_desc hawi_desc = {
+ .rpmhpds = hawi_rpmhpds,
+ .num_pds = ARRAY_SIZE(hawi_rpmhpds),
+};
+
/* QDU1000/QRU1000 RPMH powerdomains */
static struct rpmhpd *qdu1000_rpmhpds[] = {
[QDU1000_CX] = &cx,
@@ -796,6 +833,7 @@ static const struct rpmhpd_desc qcs615_desc = {
static const struct of_device_id rpmhpd_match_table[] = {
{ .compatible = "qcom,glymur-rpmhpd", .data = &glymur_desc },
+ { .compatible = "qcom,hawi-rpmhpd", .data = &hawi_desc },
{ .compatible = "qcom,kaanapali-rpmhpd", .data = &kaanapali_desc },
{ .compatible = "qcom,milos-rpmhpd", .data = &milos_desc },
{ .compatible = "qcom,qcs615-rpmhpd", .data = &qcs615_desc },
--
2.43.0
^ permalink raw reply related
* [PATCH 1/3] dt-bindings: power: qcom,rpmpd: Add Hawi RPMh power domain
From: Fenglin Wu @ 2026-04-01 9:15 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
Ulf Hansson, Konrad Dybcio
Cc: Subbaraman Narayanamurthy, linux-arm-msm, devicetree,
linux-kernel, linux-pm, kernel, Fenglin Wu
In-Reply-To: <20260401-haw-rpmhpd-v1-0-c830c79ed8f9@oss.qualcomm.com>
Document the RPMh power domain for Hawi SoC.
Signed-off-by: Fenglin Wu <fenglin.wu@oss.qualcomm.com>
---
Documentation/devicetree/bindings/power/qcom,rpmpd.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
index 27af5b8aa134..35a0e01c2015 100644
--- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
+++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
@@ -18,6 +18,7 @@ properties:
oneOf:
- enum:
- qcom,glymur-rpmhpd
+ - qcom,hawi-rpmhpd
- qcom,kaanapali-rpmhpd
- qcom,mdm9607-rpmpd
- qcom,milos-rpmhpd
--
2.43.0
^ permalink raw reply related
* [PATCH 0/3] power: qcom,rpmpd: add RPMh power doamins support for Hawi SoC
From: Fenglin Wu @ 2026-04-01 9:15 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
Ulf Hansson, Konrad Dybcio
Cc: Subbaraman Narayanamurthy, linux-arm-msm, devicetree,
linux-kernel, linux-pm, kernel, Fenglin Wu
Add constant definitions for the new power domains and new voltage
levels present in Hawi SoC. Also add RPMH power domain support for
Hawi SoC.
Signed-off-by: Fenglin Wu <fenglin.wu@oss.qualcomm.com>
---
Fenglin Wu (3):
dt-bindings: power: qcom,rpmpd: Add Hawi RPMh power domain
dt-bindings: power: qcom,rpmhpd: Add new power domains and new levels
pmdomain: qcom: rpmhpd: Add power domains for Hawi SoC
.../devicetree/bindings/power/qcom,rpmpd.yaml | 1 +
drivers/pmdomain/qcom/rpmhpd.c | 38 ++++++++++++++++++++++
include/dt-bindings/power/qcom,rpmhpd.h | 12 +++++++
3 files changed, 51 insertions(+)
---
base-commit: 33b1a2ee3a3df63e7a08e51e6de2b2d28ddf257f
change-id: 20260401-haw-rpmhpd-b40a68a3ce79
Best regards,
--
Fenglin Wu <fenglin.wu@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH v3 0/2] Support BPF traversal of wakeup sources
From: Greg Kroah-Hartman @ 2026-04-01 9:15 UTC (permalink / raw)
To: Samuel Wu
Cc: Rafael J. Wysocki, Pavel Machek, Len Brown, Danilo Krummrich,
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Song Liu, Yonghong Song, Jiri Olsa, Shuah Khan, kernel-team,
linux-kernel, linux-pm, driver-core, bpf, linux-kselftest
In-Reply-To: <20260331153413.2469218-1-wusamuel@google.com>
On Tue, Mar 31, 2026 at 08:34:09AM -0700, Samuel Wu wrote:
> This patchset adds requisite kfuncs for BPF programs to safely traverse
> wakeup_sources, and puts a config flag around the sysfs interface.
>
> Currently, a traversal of wakeup sources require going through
> /sys/class/wakeup/* or /d/wakeup_sources/*. The repeated syscalls to query
> sysfs is inefficient, as there can be hundreds of wakeup_sources, with each
> wakeup source also having multiple attributes. debugfs is unstable and
> insecure.
Describe "inefficient" please?
And if you really think that doing an open/read/close on a virtual
filesystem is inefficient, then I have the syscall for you!
I've been trying to get readfile() accepted every few years, looks like
I last tried in 2020:
https://lore.kernel.org/r/20200704140250.423345-1-gregkh@linuxfoundation.org
but I keep the patchset up to date in my local tree all the time.
Would that help you out here instead?
> Adding kfuncs to lock/unlock wakeup sources allows BPF program to safely
> traverse the wakeup sources list. The head address of wakeup_sources can
> safely be resolved through BPF helper functions or variable attributes.
Who is going to be calling this?
> On a quiescent Pixel 6 traversing 150 wakeup_sources, I am seeing ~34x
> speedup (sampled 75 times in table below). For a device under load, the
> speedup is greater.
> +-------+----+----------+----------+
> | | n | AVG (ms) | STD (ms) |
> +-------+----+----------+----------+
> | sysfs | 75 | 44.9 | 12.6 |
> +-------+----+----------+----------+
> | BPF | 75 | 1.3 | 0.7 |
> +-------+----+----------+----------+
150 sysfs calls in 44.9 ms feels very slow. but really, what are you
expecting here, sysfs should NEVER be on a "fast path" that you care
about performance. Why are you hammering on sysfs here? What HAS to
have this type of performance?
In other words, what problem are you trying to solve that having access
to 150+ sysfs files all at once in a faster way is going to fix?
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH v3 1/2] PM: wakeup: Add kfuncs to traverse over wakeup_sources
From: Greg Kroah-Hartman @ 2026-04-01 9:11 UTC (permalink / raw)
To: Samuel Wu
Cc: Rafael J. Wysocki, Len Brown, Pavel Machek, Danilo Krummrich,
Andrii Nakryiko, Eduard Zingerman, Alexei Starovoitov,
Daniel Borkmann, Martin KaFai Lau, Kumar Kartikeya Dwivedi,
Song Liu, Yonghong Song, Jiri Olsa, Shuah Khan, kernel-team,
linux-kernel, linux-pm, driver-core, bpf, linux-kselftest
In-Reply-To: <20260331153413.2469218-2-wusamuel@google.com>
On Tue, Mar 31, 2026 at 08:34:10AM -0700, Samuel Wu wrote:
> Iterating through wakeup sources via sysfs or debugfs can be inefficient
> or restricted. Introduce BPF kfuncs to allow high-performance and safe
> in-kernel traversal of the wakeup_sources list.
What exactly is "inefficient"? I think you might have some numbers in
your 0/2 patch, but putting it in here would be best.
And who is going to be calling these functions, just ebpf scripts?
> The new kfuncs include:
> - bpf_wakeup_sources_get_head() to obtain the list head.
> - bpf_wakeup_sources_read_lock/unlock() to manage the SRCU lock.
Does this mean we can stop exporting wakeup_sources_read_lock() now?
> For verifier safety, the underlying SRCU index is wrapped in an opaque
> 'struct bpf_ws_lock' pointer. This enables the use of KF_ACQUIRE and
> KF_RELEASE flags, allowing the BPF verifier to strictly enforce paired
> lock/unlock cycles and prevent resource leaks.
But it's an index, not a lock. Is this just a verifier thing?
>
> Signed-off-by: Samuel Wu <wusamuel@google.com>
> ---
> drivers/base/power/power.h | 7 ++++
> drivers/base/power/wakeup.c | 72 +++++++++++++++++++++++++++++++++++--
> 2 files changed, 77 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
> index 922ed457db19..8823aceeac8b 100644
> --- a/drivers/base/power/power.h
> +++ b/drivers/base/power/power.h
> @@ -168,3 +168,10 @@ static inline void device_pm_init(struct device *dev)
> device_pm_sleep_init(dev);
> pm_runtime_init(dev);
> }
> +
> +#ifdef CONFIG_BPF_SYSCALL
> +struct bpf_ws_lock { };
An empty structure? This is just an int, so you are casting an int to a
pointer? Can we make wakeup_sources_read_lock() actually use a
structure instead to make this simpler?
> +struct bpf_ws_lock *bpf_wakeup_sources_read_lock(void);
> +void bpf_wakeup_sources_read_unlock(struct bpf_ws_lock *lock);
> +void *bpf_wakeup_sources_get_head(void);
> +#endif
> diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
> index b8e48a023bf0..8eda7d35d9cc 100644
> --- a/drivers/base/power/wakeup.c
> +++ b/drivers/base/power/wakeup.c
> @@ -1168,11 +1168,79 @@ static const struct file_operations wakeup_sources_stats_fops = {
> .release = seq_release_private,
> };
>
> -static int __init wakeup_sources_debugfs_init(void)
> +#ifdef CONFIG_BPF_SYSCALL
> +#include <linux/btf.h>
> +
> +__bpf_kfunc_start_defs();
> +
> +/**
> + * bpf_wakeup_sources_read_lock - Acquire the SRCU lock for wakeup sources
> + *
> + * The underlying SRCU lock returns an integer index. However, the BPF verifier
> + * requires a pointer (PTR_TO_BTF_ID) to strictly track the state of acquired
> + * resources using KF_ACQUIRE and KF_RELEASE semantics. We use an opaque
> + * structure pointer (struct bpf_ws_lock *) to satisfy the verifier while
> + * safely encoding the integer index within the pointer address itself.
> + *
> + * Return: An opaque pointer encoding the SRCU lock index + 1 (to avoid NULL).
> + */
> +__bpf_kfunc struct bpf_ws_lock *bpf_wakeup_sources_read_lock(void)
> +{
> + return (struct bpf_ws_lock *)(long)(wakeup_sources_read_lock() + 1);
Why are you incrementing this by 1?
> +}
> +
> +/**
> + * bpf_wakeup_sources_read_unlock - Release the SRCU lock for wakeup sources
> + * @lock: The opaque pointer returned by bpf_wakeup_sources_read_lock()
> + *
> + * The BPF verifier guarantees that @lock is a valid, unreleased pointer from
> + * the acquire function. We decode the pointer back into the integer SRCU index
> + * by subtracting 1 and release the lock.
> + */
> +__bpf_kfunc void bpf_wakeup_sources_read_unlock(struct bpf_ws_lock *lock)
> +{
> + wakeup_sources_read_unlock((int)(long)lock - 1);
Why decrementing by one?
So it's really an int, but you are casting it to a pointer, incrementing
it by one to make it a "fake" pointer value (i.e. unaligned mess), and
then when unlocking casting the pointer back to an int, and then
decrementing the value?
This feels "odd" :(
> +}
> +
> +/**
> + * bpf_wakeup_sources_get_head - Get the head of the wakeup sources list
> + *
> + * Return: The head of the wakeup sources list.
> + */
> +__bpf_kfunc void *bpf_wakeup_sources_get_head(void)
> +{
> + return &wakeup_sources;
> +}
> +
> +__bpf_kfunc_end_defs();
> +
> +BTF_KFUNCS_START(wakeup_source_kfunc_ids)
> +BTF_ID_FLAGS(func, bpf_wakeup_sources_read_lock, KF_ACQUIRE)
> +BTF_ID_FLAGS(func, bpf_wakeup_sources_read_unlock, KF_RELEASE)
> +BTF_ID_FLAGS(func, bpf_wakeup_sources_get_head)
> +BTF_KFUNCS_END(wakeup_source_kfunc_ids)
> +
> +static const struct btf_kfunc_id_set wakeup_source_kfunc_set = {
> + .owner = THIS_MODULE,
This isn't a module.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH v5 1/2] thermal/qcom/lmh: support SDM670 and its CPU clusters
From: Konrad Dybcio @ 2026-04-01 8:30 UTC (permalink / raw)
To: Richard Acayan
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Amit Kucheria, Thara Gopinath, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, linux-arm-msm, devicetree,
linux-pm
In-Reply-To: <acwH6N56W_ULNe2q@rdacayan>
On 3/31/26 7:44 PM, Richard Acayan wrote:
> On Tue, Mar 31, 2026 at 10:30:29AM +0200, Konrad Dybcio wrote:
>> On 3/30/26 6:52 PM, Richard Acayan wrote:
>>> The LMh driver was made for Qualcomm SoCs with clusters of 4 CPUs, but
>>> some SoCs divide the CPUs into different sizes of clusters. In SDM670,
>>> the first 6 CPUs are in the little cluster and the next 2 are in the big
>>> cluster. Define the clusters in the match data and define the different
>>> cluster configuration for SDM670.
>>>
>>> Currently, this tolerates linking to any CPU in a given cluster.
>>>
>>> Signed-off-by: Richard Acayan <mailingradian@gmail.com>
>>> ---
>>
>> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>>
>> [...]
>>> + if (cpu_id < 0) {
>>> + dev_err(dev, "Wrong CPU id associated with LMh node\n");
>>> + return -EINVAL;
>>> + }
>>
>> nit: try to use 'return dev_err_probe(dev, ret, "....") in the future
>
> Does "in the future" apply to the inevitable next revision? This would
> be the first occurrence of dev_err_probe in this driver and the error
> path was just cut-and-paste.
Not necessarily, 'in the future' meaning 'in your future patches'
Konrad
^ permalink raw reply
* Re: [PATCH 1/2] pmdomain/rockchip: skip QoS operations for idle-only domains
From: Shawn Lin @ 2026-04-01 7:11 UTC (permalink / raw)
To: Daniel Bozeman, ulf.hansson, heiko, linux-pm, linux-arm-kernel,
linux-rockchip, linux-kernel
Cc: shawn.lin, finley.xiao
In-Reply-To: <acy3eP0dZBx6A950@claude-dev>
+ Finley
在 2026/04/01 星期三 14:13, Daniel Bozeman 写道:
> <fc6f00fa-10b0-44c8-d8b4-694f8ff3b9ea@rock-chips.com>
>
> I ran additional tests to gather evidence:
>
> Test 1: Patch 2 only (skip EPROBE_DEFER), no patch 1.
> Result: kernel panic. The idle-only domains register
> successfully, but genpd_power_off_work_fn attempts to power
> them off and crashes in rockchip_pmu_set_idle_request:
>
> Internal error: synchronous external abort: 0000000096000010
> CPU: 0 PID: 59 Comm: kworker/0:3
> Workqueue: pm genpd_power_off_work_fn
> pc : regmap_mmio_read32le+0x8/0x20
> Call trace:
> regmap_mmio_read32le+0x8/0x20
> _regmap_bus_reg_read+0x6c/0xac
> _regmap_read+0x60/0xd8
> regmap_read+0x4c/0x7c
> rockchip_pmu_set_idle_request.isra.0+0x94/0x1b4
> rockchip_pd_power+0x378/0x604
> rockchip_pd_power_off+0x14/0x34
> genpd_power_off.isra.0+0x1f0/0x2f0
> genpd_power_off_work_fn+0x34/0x54
>
> Test 2: No kernel patches, PD_GPU disabled via
> status = "disabled" in DTS to avoid EPROBE_DEFER entirely.
> Result: same kernel panic. The idle-only domains register
> but crash identically when genpd tries to power them off.
> Same call trace as above.
>
> So the crash is not caused by probe ordering or
> EPROBE_DEFER -- it happens whenever idle-only domains
> (pwr_mask == 0) are registered and genpd attempts to
> power them off. The QoS register access in
> rockchip_pmu_set_idle_request faults on these domains.
>
> Regarding S2R: you raise a valid concern about skipping
> QoS save/restore. However, these idle-only domains cannot
> actually be powered off (pwr_mask == 0), so
> rockchip_do_pmu_set_power_domain already returns early for
> them. The QoS save/idle/restore cycle in rockchip_pd_power
> has no effect on these domains since the power state never
> changes -- the save and restore are paired around a no-op.
> Skipping the entire sequence for pwr_mask == 0 should be
> safe for S2R as well.
>
Thanks for these details but I think it explains the phenomenon
and work around it but didn't explain the root cause.
RK3528 SoC can't power down these PDs but only support to idle them.
Right, idle these PDs could still make QoS registers inaccessable.
But from the code, rockchip_pmu_save_qos() and
rockchip_pmu_restore_qos() both are called under idle-free state.
One possible guess is it's clk related. Could you please help
test your environment with "clk_ignore_unused" set in cmdline?
Another test is to print out genpd->name in the entry of
rockchip_pd_power_on() and rockchip_pd_power_off() to see
which one is inaccessable.
> Both patches are needed:
> - Patch 1: prevents the QoS crash on idle-only domains
> - Patch 2: prevents probe teardown from making things worse
>
> Tested on NanoPi Zero2 (RK3528) with all four scenarios:
> both patches (boots), patch 2 only (panic), DTS workaround
> (panic), both patches + E20C regression test (no issues).
>
> The board DTS that triggers this (GPIO-controlled USB VBUS
> regulator on GPIO4/PD_RKVENC) can be seen at:
> https://github.com/dboze/openwrt/blob/add-nanopi-zero2-clean/target/linux/rockchip/patches-6.12/102-arm64-dts-rockchip-Add-FriendlyElec-NanoPi-Zero2.patch
>
^ permalink raw reply
* [PATCH 3/3] power: sequencing: pcie-m2: Guard the helper functions making use of PCI bus notifier
From: Manivannan Sadhasivam @ 2026-04-01 7:07 UTC (permalink / raw)
To: brgl, robh
Cc: linux-pci, linux-pm, linux-kernel, linux-serial, mani,
Manivannan Sadhasivam, kernel test robot
In-Reply-To: <20260401070735.107162-1-manivannan.sadhasivam@oss.qualcomm.com>
The PCI bus notifier is only visible if CONFIG_PCI symbol is selected in
Kconfig. But this driver can be built without CONFIG_PCI due to
CONFIG_COMPILE_TEST, leading to below build error:
drivers/power/sequencing/pwrseq-pcie-m2.c: In function 'pwrseq_pcie_m2_free_resources':
>> drivers/power/sequencing/pwrseq-pcie-m2.c:185:34: error: 'pci_bus_type' undeclared (first use in this function); did you mean 'pci_pcie_type'?
185 | bus_unregister_notifier(&pci_bus_type, &ctx->nb);
| ^~~~~~~~~~~~
| pci_pcie_type
drivers/power/sequencing/pwrseq-pcie-m2.c:185:34: note: each undeclared identifier is reported only once for each function it appears in
drivers/power/sequencing/pwrseq-pcie-m2.c: In function 'pwrseq_pcie_m2_register_notifier':
drivers/power/sequencing/pwrseq-pcie-m2.c:340:54: error: 'pci_bus_type' undeclared (first use in this function); did you mean 'pci_pcie_type'?
340 | ret = bus_register_notifier(&pci_bus_type, &ctx->nb);
| ^~~~~~~~~~~~
| pci_pcie_type
So add guards to make sure that all these helper functions making use of
the PCI bus notifier are only compiled if CONFIG_PCI is selected.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202603180609.ucspJefN-lkp@intel.com
Fixes: 3f736aecbdc8 ("power: sequencing: pcie-m2: Create serdev device for WCN7850 bluetooth")
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/power/sequencing/pwrseq-pcie-m2.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
index a75ca4fda2eb..d3102fea8d93 100644
--- a/drivers/power/sequencing/pwrseq-pcie-m2.c
+++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
@@ -177,6 +177,7 @@ static int pwrseq_pcie_m2_match(struct pwrseq_device *pwrseq,
return PWRSEQ_NO_MATCH;
}
+#if IS_ENABLED(CONFIG_PCI)
static int pwrseq_m2_pcie_create_bt_node(struct pwrseq_pcie_m2_ctx *ctx,
struct device_node *parent)
{
@@ -374,6 +375,12 @@ static int pwrseq_pcie_m2_register_notifier(struct pwrseq_pcie_m2_ctx *ctx, stru
return 0;
}
+#else
+static int pwrseq_pcie_m2_register_notifier(struct pwrseq_pcie_m2_ctx *ctx, struct device *dev)
+{
+ return 0;
+}
+#endif /* CONFIG_PCI */
static int pwrseq_pcie_m2_probe(struct platform_device *pdev)
{
@@ -452,8 +459,10 @@ static void pwrseq_pcie_m2_remove(struct platform_device *pdev)
{
struct pwrseq_pcie_m2_ctx *ctx = platform_get_drvdata(pdev);
+#if IS_ENABLED(CONFIG_PCI)
bus_unregister_notifier(&pci_bus_type, &ctx->nb);
pwrseq_pcie_m2_remove_serdev(ctx);
+#endif
regulator_bulk_free(ctx->num_vregs, ctx->regs);
}
--
2.51.0
^ permalink raw reply related
* [PATCH 2/3] serdev: Add CONFIG_SERIAL_DEV_BUS guard for of_find_serdev_controller_by_node() API
From: Manivannan Sadhasivam @ 2026-04-01 7:07 UTC (permalink / raw)
To: brgl, robh
Cc: linux-pci, linux-pm, linux-kernel, linux-serial, mani,
Manivannan Sadhasivam, kernel test robot
In-Reply-To: <20260401070735.107162-1-manivannan.sadhasivam@oss.qualcomm.com>
Currently, this API is only guarded by CONFIG_OF. But the function
definition is guarded by CONFIG_SERIAL_DEV_BUS symbol in the .c file. This
causes below build error if CONFIG_SERIAL_DEV_BUS is not selected but only
CONFIG_OF:
pwrseq-pcie-m2.c:(.text+0x924): undefined reference to `of_find_serdev_controller_by_node'
Fix this issue by adding the CONFIG_SERIAL_DEV_BUS guard to the function
prototype.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202604011226.KGNn5974-lkp@intel.com/
Fixes: a2b4814190af ("serdev: Add an API to find the serdev controller associated with the devicetree node")
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
include/linux/serdev.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index 0de261a26284..58f000534bdb 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -356,13 +356,13 @@ static inline bool serdev_acpi_get_uart_resource(struct acpi_resource *ares,
}
#endif /* CONFIG_ACPI */
-#ifdef CONFIG_OF
+#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_SERIAL_DEV_BUS)
struct serdev_controller *of_find_serdev_controller_by_node(struct device_node *node);
#else
static inline struct serdev_controller *of_find_serdev_controller_by_node(struct device_node *node)
{
return NULL;
}
-#endif /* CONFIG_OF */
+#endif /* CONFIG_OF && CONFIG_SERIAL_DEV_BUS */
#endif /*_LINUX_SERDEV_H */
--
2.51.0
^ permalink raw reply related
* [PATCH 1/3] serdev: Add missing stubs for serdev APIs when CONFIG_SERIAL_DEV_BUS is not selected
From: Manivannan Sadhasivam @ 2026-04-01 7:07 UTC (permalink / raw)
To: brgl, robh
Cc: linux-pci, linux-pm, linux-kernel, linux-serial, mani,
Manivannan Sadhasivam, kernel test robot
In-Reply-To: <20260401070735.107162-1-manivannan.sadhasivam@oss.qualcomm.com>
Some of the serdev APIs are not guarded by CONFIG_SERIAL_DEV_BUS and also
missing the stubs when the symbol is not selected. This leads to the below
build errors:
drivers/power/sequencing/pwrseq-pcie-m2.o: in function `pwrseq_pcie_m2_remove_serdev':
>> pwrseq-pcie-m2.c:(.text+0x260): undefined reference to `serdev_device_remove'
powerpc64-linux-ld: drivers/power/sequencing/pwrseq-pcie-m2.o: in function `pwrseq_m2_pcie_notify':
>> powerpc64-linux-ld: pwrseq-pcie-m2.c:(.text+0x9c8): undefined reference to `serdev_device_alloc'
>> powerpc64-linux-ld: pwrseq-pcie-m2.c:(.text+0xc00): undefined reference to `serdev_device_add'
Fix these issues by adding the CONFIG_SERIAL_DEV_BUS guard to function
prototypes and stubs when the symbol is not selected.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202604011226.KGNn5974-lkp@intel.com/
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
include/linux/serdev.h | 42 ++++++++++++++++++++++++++++++++----------
1 file changed, 32 insertions(+), 10 deletions(-)
diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index 188c0ba62d50..0de261a26284 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -156,16 +156,6 @@ static inline void serdev_controller_put(struct serdev_controller *ctrl)
put_device(&ctrl->dev);
}
-struct serdev_device *serdev_device_alloc(struct serdev_controller *);
-int serdev_device_add(struct serdev_device *);
-void serdev_device_remove(struct serdev_device *);
-
-struct serdev_controller *serdev_controller_alloc(struct device *host,
- struct device *parent,
- size_t size);
-int serdev_controller_add(struct serdev_controller *);
-void serdev_controller_remove(struct serdev_controller *);
-
static inline void serdev_controller_write_wakeup(struct serdev_controller *ctrl)
{
struct serdev_device *serdev = ctrl->serdev;
@@ -204,6 +194,16 @@ void serdev_device_write_wakeup(struct serdev_device *);
ssize_t serdev_device_write(struct serdev_device *, const u8 *, size_t, long);
void serdev_device_write_flush(struct serdev_device *);
+struct serdev_device *serdev_device_alloc(struct serdev_controller *);
+int serdev_device_add(struct serdev_device *);
+void serdev_device_remove(struct serdev_device *);
+
+struct serdev_controller *serdev_controller_alloc(struct device *host,
+ struct device *parent,
+ size_t size);
+int serdev_controller_add(struct serdev_controller *);
+void serdev_controller_remove(struct serdev_controller *);
+
/*
* serdev device driver functions
*/
@@ -264,6 +264,28 @@ static inline ssize_t serdev_device_write(struct serdev_device *sdev,
}
static inline void serdev_device_write_flush(struct serdev_device *sdev) {}
+static inline struct serdev_device *serdev_device_alloc(struct serdev_controller *)
+{
+ return NULL;
+}
+static inline int serdev_device_add(struct serdev_device *)
+{
+ return -ENODEV;
+}
+static inline void serdev_device_remove(struct serdev_device *) {}
+
+static inline struct serdev_controller *serdev_controller_alloc(struct device *host,
+ struct device *parent,
+ size_t size)
+{
+ return NULL;
+}
+static inline int serdev_controller_add(struct serdev_controller *)
+{
+ return -ENODEV;
+}
+static inline void serdev_controller_remove(struct serdev_controller *) {}
+
#define serdev_device_driver_register(x)
#define serdev_device_driver_unregister(x)
--
2.51.0
^ permalink raw reply related
* [PATCH 0/3] Pwrseq/serdev fixes
From: Manivannan Sadhasivam @ 2026-04-01 7:07 UTC (permalink / raw)
To: brgl, robh
Cc: linux-pci, linux-pm, linux-kernel, linux-serial, mani,
Manivannan Sadhasivam
Hi Bartosz,
This series fixes build issues reported by kernel test robot on the recently
merged M.2 Key E pwrseq series.
Patches 2 and 3 can be squashed with offending commits, while patch 1 should be
applied separately.
- Mani
Manivannan Sadhasivam (3):
serdev: Add missing stubs for serdev APIs when CONFIG_SERIAL_DEV_BUS
is not selected
serdev: Add CONFIG_SERIAL_DEV_BUS guard for
of_find_serdev_controller_by_node() API
power: sequencing: pcie-m2: Guard the helper functions making use of
PCI bus notifier
drivers/power/sequencing/pwrseq-pcie-m2.c | 9 +++++
include/linux/serdev.h | 46 +++++++++++++++++------
2 files changed, 43 insertions(+), 12 deletions(-)
--
2.51.0
^ permalink raw reply
* Re: [PATCH] cpufreq: governor: fix double free in cpufreq_dbs_governor_init() error path
From: Viresh Kumar @ 2026-04-01 6:23 UTC (permalink / raw)
To: Guangshuo Li
Cc: Rafael J. Wysocki, Tobin C. Harding, linux-pm, linux-kernel,
stable
In-Reply-To: <20260401024535.1395801-1-lgs201920130244@gmail.com>
On 01-04-26, 10:45, Guangshuo Li wrote:
> When kobject_init_and_add() fails, cpufreq_dbs_governor_init() calls
> kobject_put(&dbs_data->attr_set.kobj).
>
> The kobject release callback cpufreq_dbs_data_release() calls
> gov->exit(dbs_data) and kfree(dbs_data), but the current error path
> then calls gov->exit(dbs_data) and kfree(dbs_data) again, causing a
> double free.
>
> Keep the direct kfree(dbs_data) for the gov->init() failure path, but
> after kobject_init_and_add() has been called, let kobject_put() handle
> the cleanup through cpufreq_dbs_data_release().
>
> Fixes: 4ebe36c94aed ("cpufreq: Fix kobject memleak")
> Cc: stable@vger.kernel.org
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
> ---
> drivers/cpufreq/cpufreq_governor.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
--
viresh
^ permalink raw reply
* Re: [PATCH 1/2] pmdomain/rockchip: skip QoS operations for idle-only domains
From: Daniel Bozeman @ 2026-04-01 6:13 UTC (permalink / raw)
To: shawn.lin, ulf.hansson, heiko, linux-pm, linux-arm-kernel,
linux-rockchip, linux-kernel
In-Reply-To: <fc6f00fa-10b0-44c8-d8b4-694f8ff3b9ea@rock-chips.com>
<fc6f00fa-10b0-44c8-d8b4-694f8ff3b9ea@rock-chips.com>
I ran additional tests to gather evidence:
Test 1: Patch 2 only (skip EPROBE_DEFER), no patch 1.
Result: kernel panic. The idle-only domains register
successfully, but genpd_power_off_work_fn attempts to power
them off and crashes in rockchip_pmu_set_idle_request:
Internal error: synchronous external abort: 0000000096000010
CPU: 0 PID: 59 Comm: kworker/0:3
Workqueue: pm genpd_power_off_work_fn
pc : regmap_mmio_read32le+0x8/0x20
Call trace:
regmap_mmio_read32le+0x8/0x20
_regmap_bus_reg_read+0x6c/0xac
_regmap_read+0x60/0xd8
regmap_read+0x4c/0x7c
rockchip_pmu_set_idle_request.isra.0+0x94/0x1b4
rockchip_pd_power+0x378/0x604
rockchip_pd_power_off+0x14/0x34
genpd_power_off.isra.0+0x1f0/0x2f0
genpd_power_off_work_fn+0x34/0x54
Test 2: No kernel patches, PD_GPU disabled via
status = "disabled" in DTS to avoid EPROBE_DEFER entirely.
Result: same kernel panic. The idle-only domains register
but crash identically when genpd tries to power them off.
Same call trace as above.
So the crash is not caused by probe ordering or
EPROBE_DEFER -- it happens whenever idle-only domains
(pwr_mask == 0) are registered and genpd attempts to
power them off. The QoS register access in
rockchip_pmu_set_idle_request faults on these domains.
Regarding S2R: you raise a valid concern about skipping
QoS save/restore. However, these idle-only domains cannot
actually be powered off (pwr_mask == 0), so
rockchip_do_pmu_set_power_domain already returns early for
them. The QoS save/idle/restore cycle in rockchip_pd_power
has no effect on these domains since the power state never
changes -- the save and restore are paired around a no-op.
Skipping the entire sequence for pwr_mask == 0 should be
safe for S2R as well.
Both patches are needed:
- Patch 1: prevents the QoS crash on idle-only domains
- Patch 2: prevents probe teardown from making things worse
Tested on NanoPi Zero2 (RK3528) with all four scenarios:
both patches (boots), patch 2 only (panic), DTS workaround
(panic), both patches + E20C regression test (no issues).
The board DTS that triggers this (GPIO-controlled USB VBUS
regulator on GPIO4/PD_RKVENC) can be seen at:
https://github.com/dboze/openwrt/blob/add-nanopi-zero2-clean/target/linux/rockchip/patches-6.12/102-arm64-dts-rockchip-Add-FriendlyElec-NanoPi-Zero2.patch
^ permalink raw reply
* [rafael-pm:fixes] BUILD SUCCESS 6a7d7bac274585a9bb18b4d61cb59718334f4a39
From: kernel test robot @ 2026-04-01 5:53 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: linux-acpi, linux-pm
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git fixes
branch HEAD: 6a7d7bac274585a9bb18b4d61cb59718334f4a39 Merge branch 'thermal-core-fixes' into fixes
elapsed time: 1058m
configs tested: 197
configs skipped: 7
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-15.2.0
alpha allyesconfig gcc-15.2.0
alpha defconfig gcc-15.2.0
arc allmodconfig clang-16
arc allmodconfig gcc-15.2.0
arc allnoconfig gcc-15.2.0
arc allyesconfig clang-23
arc allyesconfig gcc-15.2.0
arc defconfig gcc-15.2.0
arc randconfig-001-20260401 clang-23
arc randconfig-002-20260401 clang-23
arm allnoconfig clang-23
arm allnoconfig gcc-15.2.0
arm allyesconfig clang-16
arm allyesconfig gcc-15.2.0
arm defconfig gcc-15.2.0
arm mmp2_defconfig gcc-15.2.0
arm randconfig-001-20260401 clang-23
arm randconfig-002-20260401 clang-23
arm randconfig-003-20260401 clang-23
arm randconfig-004-20260401 clang-23
arm64 allmodconfig clang-19
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-15.2.0
arm64 defconfig gcc-15.2.0
arm64 randconfig-001-20260401 gcc-15.2.0
arm64 randconfig-002-20260401 gcc-15.2.0
arm64 randconfig-003-20260401 gcc-15.2.0
arm64 randconfig-004-20260401 gcc-15.2.0
csky allmodconfig gcc-15.2.0
csky allnoconfig gcc-15.2.0
csky defconfig gcc-15.2.0
csky randconfig-001-20260401 gcc-15.2.0
csky randconfig-002-20260401 gcc-15.2.0
hexagon allmodconfig clang-17
hexagon allmodconfig gcc-15.2.0
hexagon allnoconfig clang-23
hexagon allnoconfig gcc-15.2.0
hexagon defconfig gcc-15.2.0
hexagon randconfig-001-20260401 gcc-15.2.0
hexagon randconfig-002-20260401 gcc-15.2.0
i386 allmodconfig clang-20
i386 allmodconfig gcc-14
i386 allnoconfig gcc-14
i386 allnoconfig gcc-15.2.0
i386 allyesconfig clang-20
i386 allyesconfig gcc-14
i386 buildonly-randconfig-001-20260401 gcc-14
i386 buildonly-randconfig-002-20260401 gcc-14
i386 buildonly-randconfig-003-20260401 gcc-14
i386 buildonly-randconfig-004-20260401 gcc-14
i386 buildonly-randconfig-005-20260401 gcc-14
i386 buildonly-randconfig-006-20260401 gcc-14
i386 defconfig gcc-15.2.0
i386 randconfig-001-20260401 gcc-14
i386 randconfig-002-20260401 gcc-14
i386 randconfig-003-20260401 gcc-14
i386 randconfig-004-20260401 gcc-14
i386 randconfig-005-20260401 gcc-14
i386 randconfig-006-20260401 gcc-14
i386 randconfig-007-20260401 gcc-14
i386 randconfig-011-20260401 clang-20
i386 randconfig-012-20260401 clang-20
i386 randconfig-013-20260401 clang-20
i386 randconfig-014-20260401 clang-20
i386 randconfig-015-20260401 clang-20
i386 randconfig-016-20260401 clang-20
i386 randconfig-017-20260401 clang-20
loongarch allmodconfig clang-23
loongarch allnoconfig clang-23
loongarch allnoconfig gcc-15.2.0
loongarch defconfig clang-19
loongarch loongson64_defconfig clang-23
loongarch randconfig-001-20260401 gcc-15.2.0
loongarch randconfig-002-20260401 gcc-15.2.0
m68k allmodconfig gcc-15.2.0
m68k allnoconfig gcc-15.2.0
m68k allyesconfig clang-16
m68k allyesconfig gcc-15.2.0
m68k defconfig clang-19
microblaze allnoconfig gcc-15.2.0
microblaze allyesconfig gcc-15.2.0
microblaze defconfig clang-19
mips allmodconfig gcc-15.2.0
mips allnoconfig gcc-15.2.0
mips allyesconfig gcc-15.2.0
nios2 allmodconfig clang-23
nios2 allmodconfig gcc-11.5.0
nios2 allnoconfig clang-23
nios2 allnoconfig gcc-11.5.0
nios2 defconfig clang-19
nios2 randconfig-001-20260401 gcc-15.2.0
nios2 randconfig-002-20260401 gcc-15.2.0
openrisc allmodconfig clang-23
openrisc allmodconfig gcc-15.2.0
openrisc allnoconfig clang-23
openrisc allnoconfig gcc-15.2.0
openrisc defconfig gcc-15.2.0
parisc allmodconfig gcc-15.2.0
parisc allnoconfig clang-23
parisc allnoconfig gcc-15.2.0
parisc allyesconfig clang-19
parisc allyesconfig gcc-15.2.0
parisc defconfig gcc-15.2.0
parisc randconfig-001-20260401 gcc-8.5.0
parisc randconfig-002-20260401 gcc-8.5.0
parisc64 defconfig clang-19
powerpc allmodconfig gcc-15.2.0
powerpc allnoconfig clang-23
powerpc allnoconfig gcc-15.2.0
powerpc holly_defconfig clang-23
powerpc randconfig-001-20260401 gcc-8.5.0
powerpc randconfig-002-20260401 gcc-8.5.0
powerpc64 randconfig-001-20260401 gcc-8.5.0
powerpc64 randconfig-002-20260401 gcc-8.5.0
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allnoconfig gcc-15.2.0
riscv allyesconfig clang-16
riscv defconfig gcc-15.2.0
riscv randconfig-001-20260401 gcc-9.5.0
riscv randconfig-002-20260401 gcc-9.5.0
s390 allmodconfig clang-18
s390 allmodconfig clang-19
s390 allnoconfig clang-23
s390 allyesconfig gcc-15.2.0
s390 defconfig gcc-15.2.0
s390 randconfig-001-20260401 gcc-9.5.0
s390 randconfig-002-20260401 gcc-9.5.0
sh allmodconfig gcc-15.2.0
sh allnoconfig clang-23
sh allnoconfig gcc-15.2.0
sh allyesconfig clang-19
sh allyesconfig gcc-15.2.0
sh defconfig gcc-14
sh randconfig-001-20260401 gcc-9.5.0
sh randconfig-002-20260401 gcc-9.5.0
sparc allnoconfig clang-23
sparc allnoconfig gcc-15.2.0
sparc defconfig gcc-15.2.0
sparc randconfig-001-20260401 clang-16
sparc randconfig-002-20260401 clang-16
sparc64 allmodconfig clang-23
sparc64 defconfig gcc-14
sparc64 randconfig-001-20260401 clang-16
sparc64 randconfig-002-20260401 clang-16
um allmodconfig clang-19
um allnoconfig clang-23
um allyesconfig gcc-14
um allyesconfig gcc-15.2.0
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001-20260401 clang-16
um randconfig-002-20260401 clang-16
um x86_64_defconfig gcc-14
x86_64 allmodconfig clang-20
x86_64 allnoconfig clang-20
x86_64 allnoconfig clang-23
x86_64 allyesconfig clang-20
x86_64 buildonly-randconfig-001-20260401 gcc-12
x86_64 buildonly-randconfig-002-20260401 gcc-12
x86_64 buildonly-randconfig-003-20260401 gcc-12
x86_64 buildonly-randconfig-004-20260401 gcc-12
x86_64 buildonly-randconfig-005-20260401 gcc-12
x86_64 buildonly-randconfig-006-20260401 gcc-12
x86_64 defconfig gcc-14
x86_64 kexec clang-20
x86_64 randconfig-001-20260401 clang-20
x86_64 randconfig-002-20260401 clang-20
x86_64 randconfig-003-20260401 clang-20
x86_64 randconfig-004-20260401 clang-20
x86_64 randconfig-005-20260401 clang-20
x86_64 randconfig-006-20260401 clang-20
x86_64 randconfig-011-20260401 gcc-14
x86_64 randconfig-012-20260401 gcc-14
x86_64 randconfig-013-20260401 gcc-14
x86_64 randconfig-014-20260401 gcc-14
x86_64 randconfig-015-20260401 gcc-14
x86_64 randconfig-016-20260401 gcc-14
x86_64 randconfig-071-20260401 gcc-14
x86_64 randconfig-072-20260401 gcc-14
x86_64 randconfig-073-20260401 gcc-14
x86_64 randconfig-074-20260401 gcc-14
x86_64 randconfig-075-20260401 gcc-14
x86_64 randconfig-076-20260401 gcc-14
x86_64 rhel-9.4 clang-20
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-20
x86_64 rhel-9.4-kselftests clang-20
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-20
xtensa allnoconfig clang-23
xtensa allnoconfig gcc-15.2.0
xtensa allyesconfig clang-23
xtensa randconfig-001-20260401 clang-16
xtensa randconfig-002-20260401 clang-16
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* [PATCH v2 4/4] PM / devfreq: Optimize error return value of governor_show()
From: Yaxiong Tian @ 2026-04-01 3:31 UTC (permalink / raw)
To: myungjoo.ham, kyungmin.park, cw00.choi, zhanjie9, nm
Cc: linux-pm, linux-kernel, Yaxiong Tian
In-Reply-To: <20260401032838.66168-1-tianyaxiong@kylinos.cn>
When df->governor is NULL, governor_show() returns -EINVAL, which
confuses users.
To fix this issue, return -ENOENT to indicate that no governor is
currently set for the device.
Signed-off-by: Yaxiong Tian <tianyaxiong@kylinos.cn>
---
drivers/devfreq/devfreq.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 975f82d7a9d1..c40568d2a4dc 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -1377,7 +1377,7 @@ static ssize_t governor_show(struct device *dev,
struct devfreq *df = to_devfreq(dev);
if (!df->governor)
- return -EINVAL;
+ return -ENOENT;
return sprintf(buf, "%s\n", df->governor->name);
}
--
2.25.1
^ permalink raw reply related
* [PATCH v2 3/4] PM / devfreq: Fix governor_store() failing when device has no current governor
From: Yaxiong Tian @ 2026-04-01 3:31 UTC (permalink / raw)
To: myungjoo.ham, kyungmin.park, cw00.choi, zhanjie9, nm
Cc: linux-pm, linux-kernel, Yaxiong Tian
In-Reply-To: <20260401032838.66168-1-tianyaxiong@kylinos.cn>
Since devfreq_remove_governor() may clear the device's current governor
in certain situations, while governors actually exist independently
of the device, directly returning EINVAL in this case is inaccurate.
To fix this issue, remove this check and add relevant logic for when
df->governor is NULL.
Fixes: 483d557ee9a3 ("PM / devfreq: Clean up the devfreq instance name in sysfs attr")
Signed-off-by: Yaxiong Tian <tianyaxiong@kylinos.cn>
---
drivers/devfreq/devfreq.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 2977b07be939..975f82d7a9d1 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -1390,9 +1390,6 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
char str_governor[DEVFREQ_NAME_LEN + 1];
const struct devfreq_governor *governor, *prev_governor;
- if (!df->governor)
- return -EINVAL;
-
ret = sscanf(buf, "%" __stringify(DEVFREQ_NAME_LEN) "s", str_governor);
if (ret != 1)
return -EINVAL;
@@ -1403,6 +1400,20 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
ret = PTR_ERR(governor);
goto out;
}
+
+ if (!df->governor) {
+ df->governor = governor;
+ ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
+ if (ret) {
+ dev_warn(dev, "%s: Governor %s not started(%d)\n",
+ __func__, df->governor->name, ret);
+ df->governor = NULL;
+ } else {
+ ret = sysfs_update_group(&df->dev.kobj, &gov_attr_group);
+ }
+ goto out;
+ }
+
if (df->governor == governor) {
ret = 0;
goto out;
--
2.25.1
^ permalink raw reply related
* [PATCH v2 2/4] PM / devfreq: Fix available_governors_show() when no governor is set
From: Yaxiong Tian @ 2026-04-01 3:30 UTC (permalink / raw)
To: myungjoo.ham, kyungmin.park, cw00.choi, zhanjie9, nm
Cc: linux-pm, linux-kernel, Yaxiong Tian
In-Reply-To: <20260401032838.66168-1-tianyaxiong@kylinos.cn>
Since devfreq_remove_governor() may clear the device's current governor
in certain situations, while governors actually exist independently of
the device, directly returning EINVAL in this case is inaccurate.
To fix this issue, remove this check and use df->governor for validity
verification in the following code.
Fixes: 483d557ee9a3 ("PM / devfreq: Clean up the devfreq instance name in sysfs attr")
Signed-off-by: Yaxiong Tian <tianyaxiong@kylinos.cn>
---
drivers/devfreq/devfreq.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 994984f7b6e1..2977b07be939 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -1468,16 +1468,13 @@ static ssize_t available_governors_show(struct device *d,
struct devfreq *df = to_devfreq(d);
ssize_t count = 0;
- if (!df->governor)
- return -EINVAL;
-
mutex_lock(&devfreq_list_lock);
/*
* The devfreq with immutable governor (e.g., passive) shows
* only own governor.
*/
- if (IS_SUPPORTED_FLAG(df->governor->flags, IMMUTABLE)) {
+ if (df->governor && IS_SUPPORTED_FLAG(df->governor->flags, IMMUTABLE)) {
count = scnprintf(&buf[count], DEVFREQ_NAME_LEN,
"%s ", df->governor->name);
/*
--
2.25.1
^ permalink raw reply related
* [PATCH v2 1/4] PM / devfreq: Fix possible null pointer issue in devfreq_add_governor()
From: Yaxiong Tian @ 2026-04-01 3:30 UTC (permalink / raw)
To: myungjoo.ham, kyungmin.park, cw00.choi, zhanjie9, nm
Cc: linux-pm, linux-kernel, Yaxiong Tian
In-Reply-To: <20260401032838.66168-1-tianyaxiong@kylinos.cn>
When a user removes a governor using devfreq_remove_governor(), if
the current device is using this governor, devfreq->governor will
be set to NULL. When the user registers any governor
using devfreq_add_governor(), since devfreq->governor is NULL, a
null pointer error occurs in strncmp().
For example: A user loads the userspace gov through a module, then
a device selects userspace. When unloading the userspace module and
then loading it again, the null pointer error occurs:
Unable to handle kernel NULL pointer dereference at virtual address
0000000000000010
Mem abort info:
ESR = 0x0000000096000004
EC = 0x25: DABT (current EL), IL = 32 bits
*******************skip *********************
Call trace:
__pi_strncmp+0x20/0x1b8
devfreq_userspace_init+0x1c/0xff8 [governor_userspace]
do_one_initcall+0x4c/0x278
do_init_module+0x5c/0x218
load_module+0x1f1c/0x1fc8
init_module_from_file+0x8c/0xd0
__arm64_sys_finit_module+0x220/0x3d8
invoke_syscall+0x48/0x110
el0_svc_common.constprop.0+0xbc/0xe8
do_el0_svc+0x20/0x30
el0_svc+0x24/0xb8
el0t_64_sync_handler+0xb8/0xc0
el0t_64_sync+0x14c/0x150
To fix this issue, remove the list_for_each_entry() logic, as
find_devfreq_governor() has already checked for the existence of
governor with the same name. This makes it impossible to find a
duplicate governor in the list, so the subsequent logic is
unreachable and can be removed.
Fixes: 1b5c1be2c88e ("PM / devfreq: map devfreq drivers to governor using name")
Signed-off-by: Yaxiong Tian <tianyaxiong@kylinos.cn>
---
drivers/devfreq/devfreq.c | 33 ---------------------------------
1 file changed, 33 deletions(-)
Hi Jie Zhan:
If you're willing, I'd like to add your Co-developed-by tag.
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 82dd9a43dc62..994984f7b6e1 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -1261,7 +1261,6 @@ void devfreq_resume(void)
int devfreq_add_governor(struct devfreq_governor *governor)
{
struct devfreq_governor *g;
- struct devfreq *devfreq;
int err = 0;
if (!governor) {
@@ -1280,38 +1279,6 @@ int devfreq_add_governor(struct devfreq_governor *governor)
list_add(&governor->node, &devfreq_governor_list);
- list_for_each_entry(devfreq, &devfreq_list, node) {
- int ret = 0;
- struct device *dev = devfreq->dev.parent;
-
- if (!strncmp(devfreq->governor->name, governor->name,
- DEVFREQ_NAME_LEN)) {
- /* The following should never occur */
- if (devfreq->governor) {
- dev_warn(dev,
- "%s: Governor %s already present\n",
- __func__, devfreq->governor->name);
- ret = devfreq->governor->event_handler(devfreq,
- DEVFREQ_GOV_STOP, NULL);
- if (ret) {
- dev_warn(dev,
- "%s: Governor %s stop = %d\n",
- __func__,
- devfreq->governor->name, ret);
- }
- /* Fall through */
- }
- devfreq->governor = governor;
- ret = devfreq->governor->event_handler(devfreq,
- DEVFREQ_GOV_START, NULL);
- if (ret) {
- dev_warn(dev, "%s: Governor %s start=%d\n",
- __func__, devfreq->governor->name,
- ret);
- }
- }
- }
-
err_out:
mutex_unlock(&devfreq_list_lock);
--
2.25.1
^ permalink raw reply related
* [PATCH v2 0/4] Fix some errors in the devfreq core layer when governor is NULL
From: Yaxiong Tian @ 2026-04-01 3:28 UTC (permalink / raw)
To: myungjoo.ham, kyungmin.park, cw00.choi, zhanjie9, nm
Cc: linux-pm, linux-kernel, Yaxiong Tian
While doing some development work with devfreq_add_governor()/
devfreq_remove_governor(), I discovered several bugs caused when
devfreq->governor is NULL. Specifically:
1) A possible null pointer issue in devfreq_add_governor(), caused
by devfreq_remove_governor() setting devfreq->governor to NULL in
certain situations, while devfreq_add_governor() lacks corresponding
checks for devfreq->governor.
2) When operating on governor and available_governors under /sys,
there are also some unexpected errors.
For issue 1, the solution is similar to Jie Zhan's PATCH.
https://lore.kernel.org/linux-pm/20260326123428.800407-6-zhanjie9@hisilicon.com/
The original v1 approach actually changed the original logic, which is incorrect.
See the following patches for details.
change in v2:
1) rebase to linux-next(20260326) /devfreq-next
2) remove some code to fix null pointer in patch1
3) add sysfs_update_group() in patch2
Yaxiong Tian (4):
PM / devfreq: Fix possible null pointer issue in
devfreq_add_governor()
PM / devfreq: Fix available_governors_show() when no governor is set
PM / devfreq: Fix governor_store() failing when device has no current
governor
PM / devfreq: Optimize error return value of governor_show()
drivers/devfreq/devfreq.c | 57 +++++++++++----------------------------
1 file changed, 16 insertions(+), 41 deletions(-)
--
2.25.1
^ permalink raw reply
* Re: [PATCH] cpufreq: governor: fix double free in cpufreq_dbs_governor_init() error path
From: Zhongqiu Han @ 2026-04-01 3:26 UTC (permalink / raw)
To: Guangshuo Li, Rafael J. Wysocki, Viresh Kumar, Tobin C. Harding,
linux-pm, linux-kernel
Cc: stable, zhongqiu.han
In-Reply-To: <20260401024535.1395801-1-lgs201920130244@gmail.com>
On 4/1/2026 10:45 AM, Guangshuo Li wrote:
> When kobject_init_and_add() fails, cpufreq_dbs_governor_init() calls
> kobject_put(&dbs_data->attr_set.kobj).
>
> The kobject release callback cpufreq_dbs_data_release() calls
> gov->exit(dbs_data) and kfree(dbs_data), but the current error path
> then calls gov->exit(dbs_data) and kfree(dbs_data) again, causing a
> double free.
>
> Keep the direct kfree(dbs_data) for the gov->init() failure path, but
> after kobject_init_and_add() has been called, let kobject_put() handle
> the cleanup through cpufreq_dbs_data_release().
>
> Fixes: 4ebe36c94aed ("cpufreq: Fix kobject memleak")
> Cc: stable@vger.kernel.org
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Thanks for the good catch and fix — this aligns with an issue I noticed
recently and looks reasonable to me.
Reviewed-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
> ---
> drivers/cpufreq/cpufreq_governor.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
> index 1a7fcaf39cc9..3ad51a986781 100644
> --- a/drivers/cpufreq/cpufreq_governor.c
> +++ b/drivers/cpufreq/cpufreq_governor.c
> @@ -468,13 +468,13 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy)
> /* Failure, so roll back. */
> pr_err("initialization failed (dbs_data kobject init error %d)\n", ret);
>
> - kobject_put(&dbs_data->attr_set.kobj);
> -
> policy->governor_data = NULL;
>
> if (!have_governor_per_policy())
> gov->gdbs_data = NULL;
> - gov->exit(dbs_data);
> +
> + kobject_put(&dbs_data->attr_set.kobj);
> + goto free_policy_dbs_info;
>
> free_dbs_data:
> kfree(dbs_data);
--
Thx and BRs,
Zhongqiu Han
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox