lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20251225040104.982704-5-changwoo@igalia.com>
Date: Thu, 25 Dec 2025 13:01:04 +0900
From: Changwoo Min <changwoo@...lia.com>
To: lukasz.luba@....com,
	rafael@...nel.org,
	donald.hunter@...il.com,
	kuba@...nel.org,
	davem@...emloft.net,
	edumazet@...gle.com,
	pabeni@...hat.com,
	horms@...nel.org,
	lenb@...nel.org,
	pavel@...nel.org,
	changwoo@...lia.com
Cc: kernel-dev@...lia.com,
	linux-pm@...r.kernel.org,
	netdev@...r.kernel.org,
	sched-ext@...ts.linux.dev,
	linux-kernel@...r.kernel.org
Subject: [PATCH for 6.19 4/4] PM: EM: Add dump to get-perf-domains in the EM YNL spec

Add dump to get-perf-domains, so that a user can fetch either information
about a specific performance domain with do or information about all
performance domains with dump. The YNL spec, autogenerated files, and
the do implementation are updated, and the dump implementation is added.

Suggested-by: Donald Hunter <donald.hunter@...il.com>
Signed-off-by: Changwoo Min <changwoo@...lia.com>
---
 .../netlink/specs/dev-energymodel.yaml        | 12 ++++
 include/uapi/linux/dev_energymodel.h          |  3 +-
 kernel/power/em_netlink.c                     | 58 +++++++++++++++++--
 kernel/power/em_netlink_autogen.c             | 16 ++++-
 kernel/power/em_netlink_autogen.h             |  2 +
 5 files changed, 82 insertions(+), 9 deletions(-)

diff --git a/Documentation/netlink/specs/dev-energymodel.yaml b/Documentation/netlink/specs/dev-energymodel.yaml
index af8b8f72f722..1843e68faacf 100644
--- a/Documentation/netlink/specs/dev-energymodel.yaml
+++ b/Documentation/netlink/specs/dev-energymodel.yaml
@@ -47,6 +47,11 @@ attribute-sets:
     doc: >-
       Information on all the performance domains.
     attributes:
+      -
+        name: perf-domain-id
+        type: u32
+        doc: >-
+          A unique ID number for each performance domain.
       -
         name: perf-domain
         type: nest
@@ -136,6 +141,13 @@ operations:
       attribute-set: perf-domains
       doc: Get the list of information for all performance domains.
       do:
+        request:
+          attributes:
+            - perf-domain-id
+        reply:
+          attributes:
+            - perf-domain
+      dump:
         reply:
           attributes:
             - perf-domain
diff --git a/include/uapi/linux/dev_energymodel.h b/include/uapi/linux/dev_energymodel.h
index 3399967e1f93..e8e133b5a797 100644
--- a/include/uapi/linux/dev_energymodel.h
+++ b/include/uapi/linux/dev_energymodel.h
@@ -37,7 +37,8 @@ enum dev_energymodel_perf_domain_flags {
 };
 
 enum {
-	DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN = 1,
+	DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN_ID = 1,
+	DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN,
 
 	__DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX,
 	DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX = (__DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX - 1)
diff --git a/kernel/power/em_netlink.c b/kernel/power/em_netlink.c
index b6edb018c65a..9412f1666007 100644
--- a/kernel/power/em_netlink.c
+++ b/kernel/power/em_netlink.c
@@ -18,6 +18,13 @@
 #include "em_netlink_autogen.h"
 
 /*************************** Command encoding ********************************/
+struct dump_ctx {
+	int idx;
+	int start;
+	struct sk_buff *skb;
+	struct netlink_callback *cb;
+};
+
 static int __em_nl_get_pd_size(struct em_perf_domain *pd, void *data)
 {
 	int nr_cpus, msg_sz, cpus_sz;
@@ -76,16 +83,44 @@ static int __em_nl_get_pd(struct em_perf_domain *pd, void *data)
 	return -EMSGSIZE;
 }
 
+static int __em_nl_get_pd_for_dump(struct em_perf_domain *pd, void *data)
+{
+	const struct genl_info *info;
+	struct dump_ctx *ctx = data;
+	void *hdr;
+	int ret;
+
+	if (ctx->idx++ < ctx->start)
+		return 0;
+
+	info = genl_info_dump(ctx->cb);
+	hdr = genlmsg_iput(ctx->skb, info);
+	if (!hdr) {
+		genlmsg_cancel(ctx->skb, hdr);
+		return -EMSGSIZE;
+	}
+
+	ret = __em_nl_get_pd(pd, ctx->skb);
+	genlmsg_end(ctx->skb, hdr);
+	return ret;
+}
+
 int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb,
 					      struct genl_info *info)
 {
+	int id, ret = -EMSGSIZE, msg_sz = 0;
+	int cmd = info->genlhdr->cmd;
+	struct em_perf_domain *pd;
 	struct sk_buff *msg;
 	void *hdr;
-	int cmd = info->genlhdr->cmd;
-	int ret = -EMSGSIZE, msg_sz = 0;
 
-	for_each_em_perf_domain(__em_nl_get_pd_size, &msg_sz);
+	if (!info->attrs[DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN_ID])
+		return -EINVAL;
+
+	id = nla_get_u32(info->attrs[DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN_ID]);
+	pd = em_perf_domain_get_by_id(id);
 
+	__em_nl_get_pd_size(pd, &msg_sz);
 	msg = genlmsg_new(msg_sz, GFP_KERNEL);
 	if (!msg)
 		return -ENOMEM;
@@ -94,10 +129,9 @@ int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb,
 	if (!hdr)
 		goto out_free_msg;
 
-	ret = for_each_em_perf_domain(__em_nl_get_pd, msg);
+	ret = __em_nl_get_pd(pd, msg);
 	if (ret)
 		goto out_cancel_msg;
-
 	genlmsg_end(msg, hdr);
 
 	return genlmsg_reply(msg, info);
@@ -106,10 +140,22 @@ int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb,
 	genlmsg_cancel(msg, hdr);
 out_free_msg:
 	nlmsg_free(msg);
-
 	return ret;
 }
 
+int dev_energymodel_nl_get_perf_domains_dumpit(struct sk_buff *skb,
+						struct netlink_callback *cb)
+{
+	struct dump_ctx ctx = {
+		.idx = 0,
+		.start = cb->args[0],
+		.skb = skb,
+		.cb = cb,
+	};
+
+	return for_each_em_perf_domain(__em_nl_get_pd_for_dump, &ctx);
+}
+
 static struct em_perf_domain *__em_nl_get_pd_table_id(struct nlattr **attrs)
 {
 	struct em_perf_domain *pd;
diff --git a/kernel/power/em_netlink_autogen.c b/kernel/power/em_netlink_autogen.c
index 44acef0e7df2..16a59200c6a4 100644
--- a/kernel/power/em_netlink_autogen.c
+++ b/kernel/power/em_netlink_autogen.c
@@ -11,6 +11,11 @@
 
 #include <uapi/linux/dev_energymodel.h>
 
+/* DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS - do */
+static const struct nla_policy dev_energymodel_get_perf_domains_nl_policy[DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN_ID + 1] = {
+	[DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN_ID] = { .type = NLA_U32, },
+};
+
 /* DEV_ENERGYMODEL_CMD_GET_PERF_TABLE - do */
 static const struct nla_policy dev_energymodel_get_perf_table_nl_policy[DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID + 1] = {
 	[DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID] = { .type = NLA_U32, },
@@ -18,10 +23,17 @@ static const struct nla_policy dev_energymodel_get_perf_table_nl_policy[DEV_ENER
 
 /* Ops table for dev_energymodel */
 static const struct genl_split_ops dev_energymodel_nl_ops[] = {
+	{
+		.cmd		= DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS,
+		.doit		= dev_energymodel_nl_get_perf_domains_doit,
+		.policy		= dev_energymodel_get_perf_domains_nl_policy,
+		.maxattr	= DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN_ID,
+		.flags		= GENL_CMD_CAP_DO,
+	},
 	{
 		.cmd	= DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS,
-		.doit	= dev_energymodel_nl_get_perf_domains_doit,
-		.flags	= GENL_CMD_CAP_DO,
+		.dumpit	= dev_energymodel_nl_get_perf_domains_dumpit,
+		.flags	= GENL_CMD_CAP_DUMP,
 	},
 	{
 		.cmd		= DEV_ENERGYMODEL_CMD_GET_PERF_TABLE,
diff --git a/kernel/power/em_netlink_autogen.h b/kernel/power/em_netlink_autogen.h
index f7e4bddcbd53..5caf2f7e18a5 100644
--- a/kernel/power/em_netlink_autogen.h
+++ b/kernel/power/em_netlink_autogen.h
@@ -14,6 +14,8 @@
 
 int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb,
 					     struct genl_info *info);
+int dev_energymodel_nl_get_perf_domains_dumpit(struct sk_buff *skb,
+					       struct netlink_callback *cb);
 int dev_energymodel_nl_get_perf_table_doit(struct sk_buff *skb,
 					   struct genl_info *info);
 
-- 
2.52.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ