From nobody Tue Feb 10 01:15:18 2026 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DE4AA1F5842; Thu, 8 Jan 2026 05:33:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767850383; cv=none; b=B6n/SHX4BaYO9kI7Ydvrrrrl8m+uWQA4aq6o92q0TprNfAsFtVSiQv39MXYifbM68cNTwybn8BinYlaPVsp4Az9vRIwOmxux5h21OzGXq9izQ2ol5pP4h9G1BuorYGPL5uZUgfOhFMORN448iqaXV6Upzy7OA1UFMMs51cg00vQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767850383; c=relaxed/simple; bh=HLqK0G2kjQAAQqzcyJmfxHdNXJUOr7hSbfv1ALPn8Ig=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=r7auEJRDiLtedW3qRKKlAAQhYrZ8pCT+sBtGCklCNYoyLKKeUAZYawlRVheUA1oVsBF2ipCFBuDsDKQbbWw45JWz5FL1iUrSgHAD/2JUquqv1PbufLTc2NsVK+RKAnM6rMlU+Xzj+YLWGRTf9fO1kvwhOCPnsv39Lak4gG/4bEM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=h4khqfbg; arc=none smtp.client-ip=213.97.179.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="h4khqfbg" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=vlRYVuvsQhR4bUPoA6JYXawXi1xPfstRgxtLKj35HrI=; b=h4khqfbgPHJeo6GzglBP/Z6lrb L+0qdusy7qykYoy4Yy5mNz7RVhSoitWKX0vtwpx/jaywxOYAPOQm2MIW4BgHqWlc3OevzeHWUib0K N1yanR6ntpTLctB2e10Yk4W5B3Z+4F52VGWPLVku6GK5y8IjOXO+JVPd3L1v080QzaovIDpIF9SKX jZNba8jX9MWINsx7V37c37Ho0JVXZM2vpskoh/vmPAKeUDtT5ZLKeE9do/IxRnE9sGCs5dTuhSFXH OQk8kmCyqw4ygGvPlK6Hd5zstU8UwfkI775hndNmEsBXeTXYGYVeLoioAZBRrnHFkOjvZ/1Gy1Lnn e+Ly71Tw==; Received: from [58.29.143.236] (helo=localhost) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1vdidf-002qE6-Ls; Thu, 08 Jan 2026 06:32:52 +0100 From: Changwoo Min To: lukasz.luba@arm.com, rafael@kernel.org, donald.hunter@gmail.com, kuba@kernel.org, davem@davemloft.net, edumazet@google.com, pabeni@redhat.com, horms@kernel.org, lenb@kernel.org, pavel@kernel.org, changwoo@igalia.com Cc: kernel-dev@igalia.com, linux-pm@vger.kernel.org, netdev@vger.kernel.org, sched-ext@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v2 for 6.19 4/4] PM: EM: Add dump to get-perf-domains in the EM YNL spec Date: Thu, 8 Jan 2026 14:32:12 +0900 Message-ID: <20260108053212.642478-5-changwoo@igalia.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260108053212.642478-1-changwoo@igalia.com> References: <20260108053212.642478-1-changwoo@igalia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Lukasz Luba Reviewed-by: Donald Hunter Signed-off-by: Changwoo Min --- .../netlink/specs/dev-energymodel.yaml | 25 ++++--- include/uapi/linux/dev_energymodel.h | 7 -- kernel/power/em_netlink.c | 68 ++++++++++++++----- kernel/power/em_netlink_autogen.c | 16 ++++- kernel/power/em_netlink_autogen.h | 2 + 5 files changed, 80 insertions(+), 38 deletions(-) diff --git a/Documentation/netlink/specs/dev-energymodel.yaml b/Documentati= on/netlink/specs/dev-energymodel.yaml index af8b8f72f722..11faabfdfbe8 100644 --- a/Documentation/netlink/specs/dev-energymodel.yaml +++ b/Documentation/netlink/specs/dev-energymodel.yaml @@ -42,16 +42,6 @@ definitions: missing real power information. =20 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 diff --git a/include/uapi/linux/dev_energymodel.h b/include/uapi/linux/dev_= energymodel.h index 3399967e1f93..355d8885c9a0 100644 --- a/include/uapi/linux/dev_energymodel.h +++ b/include/uapi/linux/dev_energymodel.h @@ -36,13 +36,6 @@ enum dev_energymodel_perf_domain_flags { DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_ARTIFICIAL =3D 4, }; =20 -enum { - DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN =3D 1, - - __DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX, - DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX =3D (__DEV_ENERGYMODEL_A_PERF_DOMAINS_= MAX - 1) -}; - enum { DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD =3D 1, DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID, diff --git a/kernel/power/em_netlink.c b/kernel/power/em_netlink.c index b6edb018c65a..5a611d3950fd 100644 --- a/kernel/power/em_netlink.c +++ b/kernel/power/em_netlink.c @@ -18,6 +18,13 @@ #include "em_netlink_autogen.h" =20 /*************************** 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, voi= d *data) { struct sk_buff *msg =3D data; struct cpumask *cpumask; - struct nlattr *entry; int cpu; =20 - entry =3D 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, vo= id *data) goto out_cancel_nest; } =20 - nla_nest_end(msg, entry); - return 0; =20 out_cancel_nest: - nla_nest_cancel(msg, entry); - return -EMSGSIZE; } =20 +static int __em_nl_get_pd_for_dump(struct em_perf_domain *pd, void *data) +{ + const struct genl_info *info; + struct dump_ctx *ctx =3D data; + void *hdr; + int ret; + + if (ctx->idx++ < ctx->start) + return 0; + + info =3D genl_info_dump(ctx->cb); + hdr =3D genlmsg_iput(ctx->skb, info); + if (!hdr) { + genlmsg_cancel(ctx->skb, hdr); + return -EMSGSIZE; + } + + ret =3D __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 =3D -EMSGSIZE, msg_sz =3D 0; + int cmd =3D info->genlhdr->cmd; + struct em_perf_domain *pd; struct sk_buff *msg; void *hdr; - int cmd =3D info->genlhdr->cmd; - int ret =3D -EMSGSIZE, msg_sz =3D 0; =20 - 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; =20 + id =3D nla_get_u32(info->attrs[DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_= ID]); + pd =3D em_perf_domain_get_by_id(id); + + __em_nl_get_pd_size(pd, &msg_sz); msg =3D 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; =20 - ret =3D for_each_em_perf_domain(__em_nl_get_pd, msg); + ret =3D __em_nl_get_pd(pd, msg); if (ret) goto out_cancel_msg; - genlmsg_end(msg, hdr); =20 return genlmsg_reply(msg, info); @@ -106,10 +130,22 @@ int dev_energymodel_nl_get_perf_domains_doit(struct s= k_buff *skb, genlmsg_cancel(msg, hdr); out_free_msg: nlmsg_free(msg); - return ret; } =20 +int dev_energymodel_nl_get_perf_domains_dumpit(struct sk_buff *skb, + struct netlink_callback *cb) +{ + struct dump_ctx ctx =3D { + .idx =3D 0, + .start =3D cb->args[0], + .skb =3D skb, + .cb =3D 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 **attr= s) { struct em_perf_domain *pd; diff --git a/kernel/power/em_netlink_autogen.c b/kernel/power/em_netlink_au= togen.c index 44acef0e7df2..fedd473e4244 100644 --- a/kernel/power/em_netlink_autogen.c +++ b/kernel/power/em_netlink_autogen.c @@ -11,6 +11,11 @@ =20 #include =20 +/* 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] =3D { + [DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID] =3D { .type =3D NLA_U32, }, +}; + /* DEV_ENERGYMODEL_CMD_GET_PERF_TABLE - do */ static const struct nla_policy dev_energymodel_get_perf_table_nl_policy[DE= V_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID + 1] =3D { [DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID] =3D { .type =3D NLA_U32, }, @@ -18,10 +23,17 @@ static const struct nla_policy dev_energymodel_get_perf= _table_nl_policy[DEV_ENER =20 /* Ops table for dev_energymodel */ static const struct genl_split_ops dev_energymodel_nl_ops[] =3D { + { + .cmd =3D DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS, + .doit =3D dev_energymodel_nl_get_perf_domains_doit, + .policy =3D dev_energymodel_get_perf_domains_nl_policy, + .maxattr =3D DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID, + .flags =3D GENL_CMD_CAP_DO, + }, { .cmd =3D DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS, - .doit =3D dev_energymodel_nl_get_perf_domains_doit, - .flags =3D GENL_CMD_CAP_DO, + .dumpit =3D dev_energymodel_nl_get_perf_domains_dumpit, + .flags =3D GENL_CMD_CAP_DUMP, }, { .cmd =3D DEV_ENERGYMODEL_CMD_GET_PERF_TABLE, diff --git a/kernel/power/em_netlink_autogen.h b/kernel/power/em_netlink_au= togen.h index f7e4bddcbd53..5caf2f7e18a5 100644 --- a/kernel/power/em_netlink_autogen.h +++ b/kernel/power/em_netlink_autogen.h @@ -14,6 +14,8 @@ =20 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); =20 --=20 2.52.0