Linux Power Management development
 help / color / mirror / Atom feed
* 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

* [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

* [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 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 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 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

* [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

* 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

* 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

* [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

* [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 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 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

* 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

* 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 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 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

* [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

* [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 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 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] 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

* 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

* 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

* [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


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox