Commit 380ff27a authored by Changwoo Min's avatar Changwoo Min Committed by Rafael J. Wysocki
Browse files

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: default avatarDonald Hunter <donald.hunter@gmail.com>
Reviewed-by: default avatarLukasz Luba <lukasz.luba@arm.com>
Reviewed-by: default avatarDonald Hunter <donald.hunter@gmail.com>
Signed-off-by: default avatarChangwoo Min <changwoo@igalia.com>
Link: https://patch.msgid.link/20260108053212.642478-5-changwoo@igalia.com


Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent d29b900c
Loading
Loading
Loading
Loading
+12 −13
Original line number Diff line number Diff line
@@ -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
+0 −7
Original line number Diff line number Diff line
@@ -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,
+52 −16
Original line number Diff line number Diff line
@@ -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;
@@ -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 @@ 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;
+14 −2
Original line number Diff line number Diff line
@@ -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_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, },
@@ -21,8 +26,15 @@ 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,
		.dumpit	= dev_energymodel_nl_get_perf_domains_dumpit,
		.flags	= GENL_CMD_CAP_DUMP,
	},
	{
		.cmd		= DEV_ENERGYMODEL_CMD_GET_PERF_TABLE,
		.doit		= dev_energymodel_nl_get_perf_table_doit,
+2 −0
Original line number Diff line number Diff line
@@ -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);