]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
PM: EM: Add dump to get-perf-domains in the EM YNL spec
authorChangwoo Min <changwoo@igalia.com>
Thu, 8 Jan 2026 05:32:12 +0000 (14:32 +0900)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 9 Jan 2026 20:44:46 +0000 (21:44 +0100)
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. Share the reply format of do and dump using
perf-domain-attrs, so remove perf-domains. The YNL spec, autogenerated
files, and the do implementation are updated, and the dump implementation
is added.

Suggested-by: Donald Hunter <donald.hunter@gmail.com>
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
Signed-off-by: Changwoo Min <changwoo@igalia.com>
Link: https://patch.msgid.link/20260108053212.642478-5-changwoo@igalia.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Documentation/netlink/specs/dev-energymodel.yaml
include/uapi/linux/dev_energymodel.h
kernel/power/em_netlink.c
kernel/power/em_netlink_autogen.c
kernel/power/em_netlink_autogen.h

index af8b8f72f722ce80a7b912ad66f730cc8504ad38..11faabfdfbe8fa6e26e4ee769cda10ab10a2e253 100644 (file)
@@ -42,16 +42,6 @@ definitions:
           missing real power information.
 
 attribute-sets:
-  -
-    name: perf-domains
-    doc: >-
-      Information on all the performance domains.
-    attributes:
-      -
-        name: perf-domain
-        type: nest
-        nested-attributes: perf-domain
-        multi-attr: true
   -
     name: perf-domain
     doc: >-
@@ -133,12 +123,21 @@ operations:
   list:
     -
       name: get-perf-domains
-      attribute-set: perf-domains
+      attribute-set: perf-domain
       doc: Get the list of information for all performance domains.
       do:
-        reply:
+        request:
           attributes:
-            - perf-domain
+            - perf-domain-id
+        reply:
+          attributes: &perf-domain-attrs
+            - pad
+            - perf-domain-id
+            - flags
+            - cpus
+      dump:
+        reply:
+          attributes: *perf-domain-attrs
     -
       name: get-perf-table
       attribute-set: perf-table
index 3399967e1f930994d9b63848be06a86ff9161dbd..355d8885c9a071671e346689b723bb4ecace171e 100644 (file)
@@ -36,13 +36,6 @@ enum dev_energymodel_perf_domain_flags {
        DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_ARTIFICIAL = 4,
 };
 
-enum {
-       DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN = 1,
-
-       __DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX,
-       DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX = (__DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX - 1)
-};
-
 enum {
        DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD = 1,
        DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID,
index b6edb018c65a6a7d4803714e7b38e1a8803cc590..5a611d3950fd51a01834e3b0a3b1ebfa807142a5 100644 (file)
 #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;
@@ -43,14 +50,8 @@ static int __em_nl_get_pd(struct em_perf_domain *pd, void *data)
 {
        struct sk_buff *msg = data;
        struct cpumask *cpumask;
-       struct nlattr *entry;
        int cpu;
 
-       entry = nla_nest_start(msg,
-                              DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN);
-       if (!entry)
-               goto out_cancel_nest;
-
        if (nla_put_u32(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID,
                        pd->id))
                goto out_cancel_nest;
@@ -66,26 +67,50 @@ static int __em_nl_get_pd(struct em_perf_domain *pd, void *data)
                        goto out_cancel_nest;
        }
 
-       nla_nest_end(msg, entry);
-
        return 0;
 
 out_cancel_nest:
-       nla_nest_cancel(msg, entry);
-
        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_DOMAIN_PERF_DOMAIN_ID])
+               return -EINVAL;
 
+       id = nla_get_u32(info->attrs[DEV_ENERGYMODEL_A_PERF_DOMAIN_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 +119,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 +130,22 @@ out_cancel_msg:
        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;
index 44acef0e7df2b087dc7c400727964da4646a9e0d..fedd473e4244e84eaf08e4c9e979842c2961dd9a 100644 (file)
 
 #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_DOMAIN_PERF_DOMAIN_ID + 1] = {
+       [DEV_ENERGYMODEL_A_PERF_DOMAIN_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_DOMAIN_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,
index f7e4bddcbd53af86e7329dbc045d87f4310f5ba4..5caf2f7e18a51cfc1a27c690552938baf4faf87b 100644 (file)
@@ -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);