Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

authored by

Changwoo Min and committed by
Rafael J. Wysocki
380ff27a d29b900c

+80 -38
+12 -13
Documentation/netlink/specs/dev-energymodel.yaml
··· 43 43 44 44 attribute-sets: 45 45 - 46 - name: perf-domains 47 - doc: >- 48 - Information on all the performance domains. 49 - attributes: 50 - - 51 - name: perf-domain 52 - type: nest 53 - nested-attributes: perf-domain 54 - multi-attr: true 55 - - 56 46 name: perf-domain 57 47 doc: >- 58 48 Information on a single performance domains. ··· 123 133 list: 124 134 - 125 135 name: get-perf-domains 126 - attribute-set: perf-domains 136 + attribute-set: perf-domain 127 137 doc: Get the list of information for all performance domains. 128 138 do: 129 - reply: 139 + request: 130 140 attributes: 131 - - perf-domain 141 + - perf-domain-id 142 + reply: 143 + attributes: &perf-domain-attrs 144 + - pad 145 + - perf-domain-id 146 + - flags 147 + - cpus 148 + dump: 149 + reply: 150 + attributes: *perf-domain-attrs 132 151 - 133 152 name: get-perf-table 134 153 attribute-set: perf-table
-7
include/uapi/linux/dev_energymodel.h
··· 37 37 }; 38 38 39 39 enum { 40 - DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN = 1, 41 - 42 - __DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX, 43 - DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX = (__DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX - 1) 44 - }; 45 - 46 - enum { 47 40 DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD = 1, 48 41 DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID, 49 42 DEV_ENERGYMODEL_A_PERF_DOMAIN_FLAGS,
+52 -16
kernel/power/em_netlink.c
··· 18 18 #include "em_netlink_autogen.h" 19 19 20 20 /*************************** Command encoding ********************************/ 21 + struct dump_ctx { 22 + int idx; 23 + int start; 24 + struct sk_buff *skb; 25 + struct netlink_callback *cb; 26 + }; 27 + 21 28 static int __em_nl_get_pd_size(struct em_perf_domain *pd, void *data) 22 29 { 23 30 int nr_cpus, msg_sz, cpus_sz; ··· 50 43 { 51 44 struct sk_buff *msg = data; 52 45 struct cpumask *cpumask; 53 - struct nlattr *entry; 54 46 int cpu; 55 - 56 - entry = nla_nest_start(msg, 57 - DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN); 58 - if (!entry) 59 - goto out_cancel_nest; 60 47 61 48 if (nla_put_u32(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID, 62 49 pd->id)) ··· 67 66 goto out_cancel_nest; 68 67 } 69 68 70 - nla_nest_end(msg, entry); 71 - 72 69 return 0; 73 70 74 71 out_cancel_nest: 75 - nla_nest_cancel(msg, entry); 76 - 77 72 return -EMSGSIZE; 73 + } 74 + 75 + static int __em_nl_get_pd_for_dump(struct em_perf_domain *pd, void *data) 76 + { 77 + const struct genl_info *info; 78 + struct dump_ctx *ctx = data; 79 + void *hdr; 80 + int ret; 81 + 82 + if (ctx->idx++ < ctx->start) 83 + return 0; 84 + 85 + info = genl_info_dump(ctx->cb); 86 + hdr = genlmsg_iput(ctx->skb, info); 87 + if (!hdr) { 88 + genlmsg_cancel(ctx->skb, hdr); 89 + return -EMSGSIZE; 90 + } 91 + 92 + ret = __em_nl_get_pd(pd, ctx->skb); 93 + genlmsg_end(ctx->skb, hdr); 94 + return ret; 78 95 } 79 96 80 97 int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb, 81 98 struct genl_info *info) 82 99 { 100 + int id, ret = -EMSGSIZE, msg_sz = 0; 101 + int cmd = info->genlhdr->cmd; 102 + struct em_perf_domain *pd; 83 103 struct sk_buff *msg; 84 104 void *hdr; 85 - int cmd = info->genlhdr->cmd; 86 - int ret = -EMSGSIZE, msg_sz = 0; 87 105 88 - for_each_em_perf_domain(__em_nl_get_pd_size, &msg_sz); 106 + if (!info->attrs[DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID]) 107 + return -EINVAL; 89 108 109 + id = nla_get_u32(info->attrs[DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID]); 110 + pd = em_perf_domain_get_by_id(id); 111 + 112 + __em_nl_get_pd_size(pd, &msg_sz); 90 113 msg = genlmsg_new(msg_sz, GFP_KERNEL); 91 114 if (!msg) 92 115 return -ENOMEM; ··· 119 94 if (!hdr) 120 95 goto out_free_msg; 121 96 122 - ret = for_each_em_perf_domain(__em_nl_get_pd, msg); 97 + ret = __em_nl_get_pd(pd, msg); 123 98 if (ret) 124 99 goto out_cancel_msg; 125 - 126 100 genlmsg_end(msg, hdr); 127 101 128 102 return genlmsg_reply(msg, info); ··· 130 106 genlmsg_cancel(msg, hdr); 131 107 out_free_msg: 132 108 nlmsg_free(msg); 133 - 134 109 return ret; 110 + } 111 + 112 + int dev_energymodel_nl_get_perf_domains_dumpit(struct sk_buff *skb, 113 + struct netlink_callback *cb) 114 + { 115 + struct dump_ctx ctx = { 116 + .idx = 0, 117 + .start = cb->args[0], 118 + .skb = skb, 119 + .cb = cb, 120 + }; 121 + 122 + return for_each_em_perf_domain(__em_nl_get_pd_for_dump, &ctx); 135 123 } 136 124 137 125 static struct em_perf_domain *__em_nl_get_pd_table_id(struct nlattr **attrs)