* [PATCH v2 for 6.19 0/4] Revise the EM YNL spec to be clearer
@ 2026-01-08 5:32 Changwoo Min
2026-01-08 5:32 ` [PATCH v2 for 6.19 1/4] PM: EM: Fix yamllint warnings in the EM YNL spec Changwoo Min
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Changwoo Min @ 2026-01-08 5:32 UTC (permalink / raw)
To: lukasz.luba, rafael, donald.hunter, kuba, davem, edumazet, pabeni,
horms, lenb, pavel, changwoo
Cc: kernel-dev, linux-pm, netdev, sched-ext, linux-kernel
This patch set addresses all the concerns raised at [1] to make the EM YNL spec
clearer. It includes the following changes:
- Fix the lint errors (1/4).
- Rename em.yaml to dev-energymodel.yaml (2/4). “dev-energymodel” was used
instead of “device-energy-model”, which was originally proposed [2], because
the netlink protocol name cannot exceed GENL_NAMSIZ(16). In addition, docs
strings and flags attributes were added.
- Change cpus' type from string to u64 array of CPU ids (3/4).
- Add dump to get-perf-domains in the EM YNL spec (4/4). A user can fetch
either information about a specific performance domain with do or information
about all performance domains with dump.
ChangeLog v1 -> v2:
- Remove perf-domains in the YNL spec, as do and dump of get-perf-domains
share the reply format using perf-domain-attrs (4/4).
- Add example outputs of get-perf-domains and get-perf-table for ease of
understanding (cover letter).
This can be tested using the tool, tools/net/ynl/pyynl/cli.py, for example,
with the following commands:
$> tools/net/ynl/pyynl/cli.py \
--spec Documentation/netlink/specs/dev-energymodel.yaml \
--dump get-perf-domains
> [{'cpus': [0, 1],
> 'flags': {'perf-domain-skip-inefficiencies', 'perf-domain-microwatts'},
> 'perf-domain-id': 0},
> {'cpus': [2, 3, 4], 'flags': {'perf-domain-microwatts'}, 'perf-domain-id': 1},
> {'cpus': [5, 6], 'flags': {'perf-domain-microwatts'}, 'perf-domain-id': 2},
> {'cpus': [7], 'flags': {'perf-domain-microwatts'}, 'perf-domain-id': 3}]
$> tools/net/ynl/pyynl/cli.py \
--spec Documentation/netlink/specs/dev-energymodel.yaml \
--do get-perf-domains --json '{"perf-domain-id": 0}'
> {'cpus': [0, 1],
> 'flags': {'perf-domain-skip-inefficiencies', 'perf-domain-microwatts'},
> 'perf-domain-id': 0}
$> tools/net/ynl/pyynl/cli.py \
--spec Documentation/netlink/specs/dev-energymodel.yaml \
--do get-perf-table --json '{"perf-domain-id": 0}'
> {'perf-domain-id': 0,
> 'perf-state': [{'cost': 2984,
> 'flags': {'perf-state-inefficient'},
> 'frequency': 364800,
> 'performance': 34,
> 'power': 10147},
>
> ...
>
> {'cost': 6982,
> 'flags': set(),
> 'frequency': 2265600,
> 'performance': 216,
> 'power': 150816}]}
$> tools/net/ynl/pyynl/cli.py \
--spec Documentation/netlink/specs/dev-energymodel.yaml \
--subscribe event --sleep 10
[1] https://lore.kernel.org/lkml/CAD4GDZy-aeWsiY=-ATr+Y4PzhMX71DFd_mmdMk4rxn3YG8U5GA@mail.gmail.com/
[2] https://lore.kernel.org/lkml/CAJZ5v0gpYQwC=1piaX-PNoyeoYJ7uw=DtAGdTVEXAsi4bnSdbA@mail.gmail.com/
Changwoo Min (4):
PM: EM: Fix yamllint warnings in the EM YNL spec
PM: EM: Rename em.yaml to dev-energymodel.yaml
PM: EM: Change cpus' type from string to u64 array in the EM YNL spec
PM: EM: Add dump to get-perf-domains in the EM YNL spec
.../netlink/specs/dev-energymodel.yaml | 175 ++++++++++++++
Documentation/netlink/specs/em.yaml | 113 ----------
MAINTAINERS | 8 +-
include/uapi/linux/dev_energymodel.h | 82 +++++++
include/uapi/linux/energy_model.h | 63 ------
kernel/power/em_netlink.c | 213 ++++++++++++------
kernel/power/em_netlink_autogen.c | 58 +++--
kernel/power/em_netlink_autogen.h | 22 +-
8 files changed, 449 insertions(+), 285 deletions(-)
create mode 100644 Documentation/netlink/specs/dev-energymodel.yaml
delete mode 100644 Documentation/netlink/specs/em.yaml
create mode 100644 include/uapi/linux/dev_energymodel.h
delete mode 100644 include/uapi/linux/energy_model.h
--
2.52.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 for 6.19 1/4] PM: EM: Fix yamllint warnings in the EM YNL spec
2026-01-08 5:32 [PATCH v2 for 6.19 0/4] Revise the EM YNL spec to be clearer Changwoo Min
@ 2026-01-08 5:32 ` Changwoo Min
2026-01-08 5:32 ` [PATCH v2 for 6.19 2/4] PM: EM: Rename em.yaml to dev-energymodel.yaml Changwoo Min
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Changwoo Min @ 2026-01-08 5:32 UTC (permalink / raw)
To: lukasz.luba, rafael, donald.hunter, kuba, davem, edumazet, pabeni,
horms, lenb, pavel, changwoo
Cc: kernel-dev, linux-pm, netdev, sched-ext, linux-kernel
The energy model YNL spec has the following two warnings
when checking with yamlint:
3:1 warning missing document start "---" (document-start)
107:13 error wrong indentation: expected 10 but found 12 (indentation)
So let’s fix whose lint warnings.
Fixes: bd26631ccdfd ("PM: EM: Add em.yaml and autogen files")
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>
---
Documentation/netlink/specs/em.yaml | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/Documentation/netlink/specs/em.yaml b/Documentation/netlink/specs/em.yaml
index 9905ca482325..0c595a874f08 100644
--- a/Documentation/netlink/specs/em.yaml
+++ b/Documentation/netlink/specs/em.yaml
@@ -1,5 +1,8 @@
# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
-
+#
+# Copyright (c) 2025 Valve Corporation.
+#
+---
name: em
doc: |
@@ -104,7 +107,7 @@ operations:
attribute-set: pd-table
event:
attributes:
- - pd-id
+ - pd-id
mcgrp: event
mcast-groups:
--
2.52.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 for 6.19 2/4] PM: EM: Rename em.yaml to dev-energymodel.yaml
2026-01-08 5:32 [PATCH v2 for 6.19 0/4] Revise the EM YNL spec to be clearer Changwoo Min
2026-01-08 5:32 ` [PATCH v2 for 6.19 1/4] PM: EM: Fix yamllint warnings in the EM YNL spec Changwoo Min
@ 2026-01-08 5:32 ` Changwoo Min
2026-01-08 5:32 ` [PATCH v2 for 6.19 3/4] PM: EM: Change cpus' type from string to u64 array in the EM YNL spec Changwoo Min
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Changwoo Min @ 2026-01-08 5:32 UTC (permalink / raw)
To: lukasz.luba, rafael, donald.hunter, kuba, davem, edumazet, pabeni,
horms, lenb, pavel, changwoo
Cc: kernel-dev, linux-pm, netdev, sched-ext, linux-kernel
The EM YNL specification used many acronyms, including ‘em’, ‘pd’,
‘ps’, etc. While the acronyms are short and convenient, they could be
confusing. So, let’s spell them out to be more specific. The following
changes were made in the spec. Note that the protocol name cannot exceed
GENL_NAMSIZ (16).
em -> dev-energymodel
pds -> perf-domains
pd -> perf-domain
pd-id -> perf-domain-id
pd-table -> perf-table
ps -> perf-state
get-pds -> get-perf-domains
get-pd-table -> get-perf-table
pd-created -> perf-domain-created
pd-updated -> perf-domain-updated
pd-deleted -> perf-domain-deleted
In addition. doc strings were added to the spec. based on the comments in
energy_model.h. Two flag attributes (perf-state-flags and
perf-domain-flags) were added for easily interpreting the bit flags.
Finally, the autogenerated files and em_netlink.c were updated accordingly
to reflect the name changes.
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>
---
.../netlink/specs/dev-energymodel.yaml | 175 ++++++++++++++++++
Documentation/netlink/specs/em.yaml | 116 ------------
MAINTAINERS | 8 +-
include/uapi/linux/dev_energymodel.h | 89 +++++++++
include/uapi/linux/energy_model.h | 63 -------
kernel/power/em_netlink.c | 135 ++++++++------
kernel/power/em_netlink_autogen.c | 44 ++---
kernel/power/em_netlink_autogen.h | 20 +-
8 files changed, 384 insertions(+), 266 deletions(-)
create mode 100644 Documentation/netlink/specs/dev-energymodel.yaml
delete mode 100644 Documentation/netlink/specs/em.yaml
create mode 100644 include/uapi/linux/dev_energymodel.h
delete mode 100644 include/uapi/linux/energy_model.h
diff --git a/Documentation/netlink/specs/dev-energymodel.yaml b/Documentation/netlink/specs/dev-energymodel.yaml
new file mode 100644
index 000000000000..cbc4bc38f23c
--- /dev/null
+++ b/Documentation/netlink/specs/dev-energymodel.yaml
@@ -0,0 +1,175 @@
+# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
+#
+# Copyright (c) 2025 Valve Corporation.
+#
+---
+name: dev-energymodel
+
+doc: |
+ Energy model netlink interface to notify its changes.
+
+protocol: genetlink
+
+uapi-header: linux/dev_energymodel.h
+
+definitions:
+ -
+ type: flags
+ name: perf-state-flags
+ entries:
+ -
+ name: perf-state-inefficient
+ doc: >-
+ The performance state is inefficient. There is in this perf-domain,
+ another performance state with a higher frequency but a lower or
+ equal power cost.
+ -
+ type: flags
+ name: perf-domain-flags
+ entries:
+ -
+ name: perf-domain-microwatts
+ doc: >-
+ The power values are in micro-Watts or some other scale.
+ -
+ name: perf-domain-skip-inefficiencies
+ doc: >-
+ Skip inefficient states when estimating energy consumption.
+ -
+ name: perf-domain-artificial
+ doc: >-
+ The power values are artificial and might be created by platform
+ 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: >-
+ Information on a single performance domains.
+ attributes:
+ -
+ name: pad
+ type: pad
+ -
+ name: perf-domain-id
+ type: u32
+ doc: >-
+ A unique ID number for each performance domain.
+ -
+ name: flags
+ type: u64
+ doc: >-
+ Bitmask of performance domain flags.
+ enum: perf-domain-flags
+ -
+ name: cpus
+ type: string
+ doc: >-
+ CPUs that belong to this performance domain.
+ -
+ name: perf-table
+ doc: >-
+ Performance states table.
+ attributes:
+ -
+ name: perf-domain-id
+ type: u32
+ doc: >-
+ A unique ID number for each performance domain.
+ -
+ name: perf-state
+ type: nest
+ nested-attributes: perf-state
+ multi-attr: true
+ -
+ name: perf-state
+ doc: >-
+ Performance state of a performance domain.
+ attributes:
+ -
+ name: pad
+ type: pad
+ -
+ name: performance
+ type: u64
+ doc: >-
+ CPU performance (capacity) at a given frequency.
+ -
+ name: frequency
+ type: u64
+ doc: >-
+ The frequency in KHz, for consistency with CPUFreq.
+ -
+ name: power
+ type: u64
+ doc: >-
+ The power consumed at this level (by 1 CPU or by a registered
+ device). It can be a total power: static and dynamic.
+ -
+ name: cost
+ type: u64
+ doc: >-
+ The cost coefficient associated with this level, used during energy
+ calculation. Equal to: power * max_frequency / frequency.
+ -
+ name: flags
+ type: u64
+ doc: >-
+ Bitmask of performance state flags.
+ enum: perf-state-flags
+
+operations:
+ list:
+ -
+ name: get-perf-domains
+ attribute-set: perf-domains
+ doc: Get the list of information for all performance domains.
+ do:
+ reply:
+ attributes:
+ - perf-domain
+ -
+ name: get-perf-table
+ attribute-set: perf-table
+ doc: Get the energy model table of a performance domain.
+ do:
+ request:
+ attributes:
+ - perf-domain-id
+ reply:
+ attributes:
+ - perf-domain-id
+ - perf-state
+ -
+ name: perf-domain-created
+ doc: A performance domain is created.
+ notify: get-perf-table
+ mcgrp: event
+ -
+ name: perf-domain-updated
+ doc: A performance domain is updated.
+ notify: get-perf-table
+ mcgrp: event
+ -
+ name: perf-domain-deleted
+ doc: A performance domain is deleted.
+ attribute-set: perf-table
+ event:
+ attributes:
+ - perf-domain-id
+ mcgrp: event
+
+mcast-groups:
+ list:
+ -
+ name: event
diff --git a/Documentation/netlink/specs/em.yaml b/Documentation/netlink/specs/em.yaml
deleted file mode 100644
index 0c595a874f08..000000000000
--- a/Documentation/netlink/specs/em.yaml
+++ /dev/null
@@ -1,116 +0,0 @@
-# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
-#
-# Copyright (c) 2025 Valve Corporation.
-#
----
-name: em
-
-doc: |
- Energy model netlink interface to notify its changes.
-
-protocol: genetlink
-
-uapi-header: linux/energy_model.h
-
-attribute-sets:
- -
- name: pds
- attributes:
- -
- name: pd
- type: nest
- nested-attributes: pd
- multi-attr: true
- -
- name: pd
- attributes:
- -
- name: pad
- type: pad
- -
- name: pd-id
- type: u32
- -
- name: flags
- type: u64
- -
- name: cpus
- type: string
- -
- name: pd-table
- attributes:
- -
- name: pd-id
- type: u32
- -
- name: ps
- type: nest
- nested-attributes: ps
- multi-attr: true
- -
- name: ps
- attributes:
- -
- name: pad
- type: pad
- -
- name: performance
- type: u64
- -
- name: frequency
- type: u64
- -
- name: power
- type: u64
- -
- name: cost
- type: u64
- -
- name: flags
- type: u64
-
-operations:
- list:
- -
- name: get-pds
- attribute-set: pds
- doc: Get the list of information for all performance domains.
- do:
- reply:
- attributes:
- - pd
- -
- name: get-pd-table
- attribute-set: pd-table
- doc: Get the energy model table of a performance domain.
- do:
- request:
- attributes:
- - pd-id
- reply:
- attributes:
- - pd-id
- - ps
- -
- name: pd-created
- doc: A performance domain is created.
- notify: get-pd-table
- mcgrp: event
- -
- name: pd-updated
- doc: A performance domain is updated.
- notify: get-pd-table
- mcgrp: event
- -
- name: pd-deleted
- doc: A performance domain is deleted.
- attribute-set: pd-table
- event:
- attributes:
- - pd-id
- mcgrp: event
-
-mcast-groups:
- list:
- -
- name: event
diff --git a/MAINTAINERS b/MAINTAINERS
index a0dd762f5648..6f9eada53887 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9298,12 +9298,12 @@ M: Lukasz Luba <lukasz.luba@arm.com>
M: "Rafael J. Wysocki" <rafael@kernel.org>
L: linux-pm@vger.kernel.org
S: Maintained
-F: kernel/power/energy_model.c
-F: include/linux/energy_model.h
+F: Documentation/netlink/specs/dev-energymodel.yaml
F: Documentation/power/energy-model.rst
-F: Documentation/netlink/specs/em.yaml
-F: include/uapi/linux/energy_model.h
+F: include/linux/energy_model.h
+F: include/uapi/linux/dev_energymodel.h
F: kernel/power/em_netlink*.*
+F: kernel/power/energy_model.c
EPAPR HYPERVISOR BYTE CHANNEL DEVICE DRIVER
M: Laurentiu Tudor <laurentiu.tudor@nxp.com>
diff --git a/include/uapi/linux/dev_energymodel.h b/include/uapi/linux/dev_energymodel.h
new file mode 100644
index 000000000000..3399967e1f93
--- /dev/null
+++ b/include/uapi/linux/dev_energymodel.h
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
+/* Do not edit directly, auto-generated from: */
+/* Documentation/netlink/specs/dev-energymodel.yaml */
+/* YNL-GEN uapi header */
+/* To regenerate run: tools/net/ynl/ynl-regen.sh */
+
+#ifndef _UAPI_LINUX_DEV_ENERGYMODEL_H
+#define _UAPI_LINUX_DEV_ENERGYMODEL_H
+
+#define DEV_ENERGYMODEL_FAMILY_NAME "dev-energymodel"
+#define DEV_ENERGYMODEL_FAMILY_VERSION 1
+
+/**
+ * enum dev_energymodel_perf_state_flags
+ * @DEV_ENERGYMODEL_PERF_STATE_FLAGS_PERF_STATE_INEFFICIENT: The performance
+ * state is inefficient. There is in this perf-domain, another performance
+ * state with a higher frequency but a lower or equal power cost.
+ */
+enum dev_energymodel_perf_state_flags {
+ DEV_ENERGYMODEL_PERF_STATE_FLAGS_PERF_STATE_INEFFICIENT = 1,
+};
+
+/**
+ * enum dev_energymodel_perf_domain_flags
+ * @DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_MICROWATTS: The power values
+ * are in micro-Watts or some other scale.
+ * @DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_SKIP_INEFFICIENCIES: Skip
+ * inefficient states when estimating energy consumption.
+ * @DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_ARTIFICIAL: The power values
+ * are artificial and might be created by platform missing real power
+ * information.
+ */
+enum dev_energymodel_perf_domain_flags {
+ DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_MICROWATTS = 1,
+ DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_SKIP_INEFFICIENCIES = 2,
+ 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,
+ DEV_ENERGYMODEL_A_PERF_DOMAIN_FLAGS,
+ DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS,
+
+ __DEV_ENERGYMODEL_A_PERF_DOMAIN_MAX,
+ DEV_ENERGYMODEL_A_PERF_DOMAIN_MAX = (__DEV_ENERGYMODEL_A_PERF_DOMAIN_MAX - 1)
+};
+
+enum {
+ DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID = 1,
+ DEV_ENERGYMODEL_A_PERF_TABLE_PERF_STATE,
+
+ __DEV_ENERGYMODEL_A_PERF_TABLE_MAX,
+ DEV_ENERGYMODEL_A_PERF_TABLE_MAX = (__DEV_ENERGYMODEL_A_PERF_TABLE_MAX - 1)
+};
+
+enum {
+ DEV_ENERGYMODEL_A_PERF_STATE_PAD = 1,
+ DEV_ENERGYMODEL_A_PERF_STATE_PERFORMANCE,
+ DEV_ENERGYMODEL_A_PERF_STATE_FREQUENCY,
+ DEV_ENERGYMODEL_A_PERF_STATE_POWER,
+ DEV_ENERGYMODEL_A_PERF_STATE_COST,
+ DEV_ENERGYMODEL_A_PERF_STATE_FLAGS,
+
+ __DEV_ENERGYMODEL_A_PERF_STATE_MAX,
+ DEV_ENERGYMODEL_A_PERF_STATE_MAX = (__DEV_ENERGYMODEL_A_PERF_STATE_MAX - 1)
+};
+
+enum {
+ DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS = 1,
+ DEV_ENERGYMODEL_CMD_GET_PERF_TABLE,
+ DEV_ENERGYMODEL_CMD_PERF_DOMAIN_CREATED,
+ DEV_ENERGYMODEL_CMD_PERF_DOMAIN_UPDATED,
+ DEV_ENERGYMODEL_CMD_PERF_DOMAIN_DELETED,
+
+ __DEV_ENERGYMODEL_CMD_MAX,
+ DEV_ENERGYMODEL_CMD_MAX = (__DEV_ENERGYMODEL_CMD_MAX - 1)
+};
+
+#define DEV_ENERGYMODEL_MCGRP_EVENT "event"
+
+#endif /* _UAPI_LINUX_DEV_ENERGYMODEL_H */
diff --git a/include/uapi/linux/energy_model.h b/include/uapi/linux/energy_model.h
deleted file mode 100644
index 0bcad967854f..000000000000
--- a/include/uapi/linux/energy_model.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
-/* Do not edit directly, auto-generated from: */
-/* Documentation/netlink/specs/em.yaml */
-/* YNL-GEN uapi header */
-/* To regenerate run: tools/net/ynl/ynl-regen.sh */
-
-#ifndef _UAPI_LINUX_ENERGY_MODEL_H
-#define _UAPI_LINUX_ENERGY_MODEL_H
-
-#define EM_FAMILY_NAME "em"
-#define EM_FAMILY_VERSION 1
-
-enum {
- EM_A_PDS_PD = 1,
-
- __EM_A_PDS_MAX,
- EM_A_PDS_MAX = (__EM_A_PDS_MAX - 1)
-};
-
-enum {
- EM_A_PD_PAD = 1,
- EM_A_PD_PD_ID,
- EM_A_PD_FLAGS,
- EM_A_PD_CPUS,
-
- __EM_A_PD_MAX,
- EM_A_PD_MAX = (__EM_A_PD_MAX - 1)
-};
-
-enum {
- EM_A_PD_TABLE_PD_ID = 1,
- EM_A_PD_TABLE_PS,
-
- __EM_A_PD_TABLE_MAX,
- EM_A_PD_TABLE_MAX = (__EM_A_PD_TABLE_MAX - 1)
-};
-
-enum {
- EM_A_PS_PAD = 1,
- EM_A_PS_PERFORMANCE,
- EM_A_PS_FREQUENCY,
- EM_A_PS_POWER,
- EM_A_PS_COST,
- EM_A_PS_FLAGS,
-
- __EM_A_PS_MAX,
- EM_A_PS_MAX = (__EM_A_PS_MAX - 1)
-};
-
-enum {
- EM_CMD_GET_PDS = 1,
- EM_CMD_GET_PD_TABLE,
- EM_CMD_PD_CREATED,
- EM_CMD_PD_UPDATED,
- EM_CMD_PD_DELETED,
-
- __EM_CMD_MAX,
- EM_CMD_MAX = (__EM_CMD_MAX - 1)
-};
-
-#define EM_MCGRP_EVENT "event"
-
-#endif /* _UAPI_LINUX_ENERGY_MODEL_H */
diff --git a/kernel/power/em_netlink.c b/kernel/power/em_netlink.c
index 4b85da138a06..6f6238c465bb 100644
--- a/kernel/power/em_netlink.c
+++ b/kernel/power/em_netlink.c
@@ -12,27 +12,31 @@
#include <linux/energy_model.h>
#include <net/sock.h>
#include <net/genetlink.h>
-#include <uapi/linux/energy_model.h>
+#include <uapi/linux/dev_energymodel.h>
#include "em_netlink.h"
#include "em_netlink_autogen.h"
-#define EM_A_PD_CPUS_LEN 256
+#define DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS_LEN 256
/*************************** Command encoding ********************************/
static int __em_nl_get_pd_size(struct em_perf_domain *pd, void *data)
{
- char cpus_buf[EM_A_PD_CPUS_LEN];
+ char cpus_buf[DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS_LEN];
int *tot_msg_sz = data;
int msg_sz, cpus_sz;
cpus_sz = snprintf(cpus_buf, sizeof(cpus_buf), "%*pb",
cpumask_pr_args(to_cpumask(pd->cpus)));
- msg_sz = nla_total_size(0) + /* EM_A_PDS_PD */
- nla_total_size(sizeof(u32)) + /* EM_A_PD_PD_ID */
- nla_total_size_64bit(sizeof(u64)) + /* EM_A_PD_FLAGS */
- nla_total_size(cpus_sz); /* EM_A_PD_CPUS */
+ msg_sz = nla_total_size(0) +
+ /* DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN */
+ nla_total_size(sizeof(u32)) +
+ /* DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID */
+ nla_total_size_64bit(sizeof(u64)) +
+ /* DEV_ENERGYMODEL_A_PERF_DOMAIN_FLAGS */
+ nla_total_size(cpus_sz);
+ /* DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS */
*tot_msg_sz += nlmsg_total_size(genlmsg_msg_size(msg_sz));
return 0;
@@ -40,23 +44,26 @@ static int __em_nl_get_pd_size(struct em_perf_domain *pd, void *data)
static int __em_nl_get_pd(struct em_perf_domain *pd, void *data)
{
- char cpus_buf[EM_A_PD_CPUS_LEN];
+ char cpus_buf[DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS_LEN];
struct sk_buff *msg = data;
struct nlattr *entry;
- entry = nla_nest_start(msg, EM_A_PDS_PD);
+ entry = nla_nest_start(msg,
+ DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN);
if (!entry)
goto out_cancel_nest;
- if (nla_put_u32(msg, EM_A_PD_PD_ID, pd->id))
+ if (nla_put_u32(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID,
+ pd->id))
goto out_cancel_nest;
- if (nla_put_u64_64bit(msg, EM_A_PD_FLAGS, pd->flags, EM_A_PD_PAD))
+ if (nla_put_u64_64bit(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_FLAGS,
+ pd->flags, DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD))
goto out_cancel_nest;
snprintf(cpus_buf, sizeof(cpus_buf), "%*pb",
cpumask_pr_args(to_cpumask(pd->cpus)));
- if (nla_put_string(msg, EM_A_PD_CPUS, cpus_buf))
+ if (nla_put_string(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS, cpus_buf))
goto out_cancel_nest;
nla_nest_end(msg, entry);
@@ -69,7 +76,8 @@ static int __em_nl_get_pd(struct em_perf_domain *pd, void *data)
return -EMSGSIZE;
}
-int em_nl_get_pds_doit(struct sk_buff *skb, struct genl_info *info)
+int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb,
+ struct genl_info *info)
{
struct sk_buff *msg;
void *hdr;
@@ -82,7 +90,7 @@ int em_nl_get_pds_doit(struct sk_buff *skb, struct genl_info *info)
if (!msg)
return -ENOMEM;
- hdr = genlmsg_put_reply(msg, info, &em_nl_family, 0, cmd);
+ hdr = genlmsg_put_reply(msg, info, &dev_energymodel_nl_family, 0, cmd);
if (!hdr)
goto out_free_msg;
@@ -107,10 +115,10 @@ static struct em_perf_domain *__em_nl_get_pd_table_id(struct nlattr **attrs)
struct em_perf_domain *pd;
int id;
- if (!attrs[EM_A_PD_TABLE_PD_ID])
+ if (!attrs[DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID])
return NULL;
- id = nla_get_u32(attrs[EM_A_PD_TABLE_PD_ID]);
+ id = nla_get_u32(attrs[DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID]);
pd = em_perf_domain_get_by_id(id);
return pd;
}
@@ -119,25 +127,34 @@ static int __em_nl_get_pd_table_size(const struct em_perf_domain *pd)
{
int id_sz, ps_sz;
- id_sz = nla_total_size(sizeof(u32)); /* EM_A_PD_TABLE_PD_ID */
- ps_sz = nla_total_size(0) + /* EM_A_PD_TABLE_PS */
- nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_PERFORMANCE */
- nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_FREQUENCY */
- nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_POWER */
- nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_COST */
- nla_total_size_64bit(sizeof(u64)); /* EM_A_PS_FLAGS */
+ id_sz = nla_total_size(sizeof(u32));
+ /* DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID */
+ ps_sz = nla_total_size(0) +
+ /* DEV_ENERGYMODEL_A_PERF_TABLE_PERF_STATE */
+ nla_total_size_64bit(sizeof(u64)) +
+ /* DEV_ENERGYMODEL_A_PERF_STATE_PERFORMANCE */
+ nla_total_size_64bit(sizeof(u64)) +
+ /* DEV_ENERGYMODEL_A_PERF_STATE_FREQUENCY */
+ nla_total_size_64bit(sizeof(u64)) +
+ /* DEV_ENERGYMODEL_A_PERF_STATE_POWER */
+ nla_total_size_64bit(sizeof(u64)) +
+ /* DEV_ENERGYMODEL_A_PERF_STATE_COST */
+ nla_total_size_64bit(sizeof(u64));
+ /* DEV_ENERGYMODEL_A_PERF_STATE_FLAGS */
ps_sz *= pd->nr_perf_states;
return nlmsg_total_size(genlmsg_msg_size(id_sz + ps_sz));
}
-static int __em_nl_get_pd_table(struct sk_buff *msg, const struct em_perf_domain *pd)
+static
+int __em_nl_get_pd_table(struct sk_buff *msg, const struct em_perf_domain *pd)
{
struct em_perf_state *table, *ps;
struct nlattr *entry;
int i;
- if (nla_put_u32(msg, EM_A_PD_TABLE_PD_ID, pd->id))
+ if (nla_put_u32(msg, DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID,
+ pd->id))
goto out_err;
rcu_read_lock();
@@ -146,24 +163,35 @@ static int __em_nl_get_pd_table(struct sk_buff *msg, const struct em_perf_domain
for (i = 0; i < pd->nr_perf_states; i++) {
ps = &table[i];
- entry = nla_nest_start(msg, EM_A_PD_TABLE_PS);
+ entry = nla_nest_start(msg,
+ DEV_ENERGYMODEL_A_PERF_TABLE_PERF_STATE);
if (!entry)
goto out_unlock_ps;
- if (nla_put_u64_64bit(msg, EM_A_PS_PERFORMANCE,
- ps->performance, EM_A_PS_PAD))
+ if (nla_put_u64_64bit(msg,
+ DEV_ENERGYMODEL_A_PERF_STATE_PERFORMANCE,
+ ps->performance,
+ DEV_ENERGYMODEL_A_PERF_STATE_PAD))
goto out_cancel_ps_nest;
- if (nla_put_u64_64bit(msg, EM_A_PS_FREQUENCY,
- ps->frequency, EM_A_PS_PAD))
+ if (nla_put_u64_64bit(msg,
+ DEV_ENERGYMODEL_A_PERF_STATE_FREQUENCY,
+ ps->frequency,
+ DEV_ENERGYMODEL_A_PERF_STATE_PAD))
goto out_cancel_ps_nest;
- if (nla_put_u64_64bit(msg, EM_A_PS_POWER,
- ps->power, EM_A_PS_PAD))
+ if (nla_put_u64_64bit(msg,
+ DEV_ENERGYMODEL_A_PERF_STATE_POWER,
+ ps->power,
+ DEV_ENERGYMODEL_A_PERF_STATE_PAD))
goto out_cancel_ps_nest;
- if (nla_put_u64_64bit(msg, EM_A_PS_COST,
- ps->cost, EM_A_PS_PAD))
+ if (nla_put_u64_64bit(msg,
+ DEV_ENERGYMODEL_A_PERF_STATE_COST,
+ ps->cost,
+ DEV_ENERGYMODEL_A_PERF_STATE_PAD))
goto out_cancel_ps_nest;
- if (nla_put_u64_64bit(msg, EM_A_PS_FLAGS,
- ps->flags, EM_A_PS_PAD))
+ if (nla_put_u64_64bit(msg,
+ DEV_ENERGYMODEL_A_PERF_STATE_FLAGS,
+ ps->flags,
+ DEV_ENERGYMODEL_A_PERF_STATE_PAD))
goto out_cancel_ps_nest;
nla_nest_end(msg, entry);
@@ -179,7 +207,8 @@ static int __em_nl_get_pd_table(struct sk_buff *msg, const struct em_perf_domain
return -EMSGSIZE;
}
-int em_nl_get_pd_table_doit(struct sk_buff *skb, struct genl_info *info)
+int dev_energymodel_nl_get_perf_table_doit(struct sk_buff *skb,
+ struct genl_info *info)
{
int cmd = info->genlhdr->cmd;
int msg_sz, ret = -EMSGSIZE;
@@ -197,7 +226,7 @@ int em_nl_get_pd_table_doit(struct sk_buff *skb, struct genl_info *info)
if (!msg)
return -ENOMEM;
- hdr = genlmsg_put_reply(msg, info, &em_nl_family, 0, cmd);
+ hdr = genlmsg_put_reply(msg, info, &dev_energymodel_nl_family, 0, cmd);
if (!hdr)
goto out_free_msg;
@@ -221,7 +250,7 @@ static void __em_notify_pd_table(const struct em_perf_domain *pd, int ntf_type)
int msg_sz, ret = -EMSGSIZE;
void *hdr;
- if (!genl_has_listeners(&em_nl_family, &init_net, EM_NLGRP_EVENT))
+ if (!genl_has_listeners(&dev_energymodel_nl_family, &init_net, DEV_ENERGYMODEL_NLGRP_EVENT))
return;
msg_sz = __em_nl_get_pd_table_size(pd);
@@ -230,7 +259,7 @@ static void __em_notify_pd_table(const struct em_perf_domain *pd, int ntf_type)
if (!msg)
return;
- hdr = genlmsg_put(msg, 0, 0, &em_nl_family, 0, ntf_type);
+ hdr = genlmsg_put(msg, 0, 0, &dev_energymodel_nl_family, 0, ntf_type);
if (!hdr)
goto out_free_msg;
@@ -240,28 +269,28 @@ static void __em_notify_pd_table(const struct em_perf_domain *pd, int ntf_type)
genlmsg_end(msg, hdr);
- genlmsg_multicast(&em_nl_family, msg, 0, EM_NLGRP_EVENT, GFP_KERNEL);
+ genlmsg_multicast(&dev_energymodel_nl_family, msg, 0,
+ DEV_ENERGYMODEL_NLGRP_EVENT, GFP_KERNEL);
return;
out_free_msg:
nlmsg_free(msg);
- return;
}
void em_notify_pd_created(const struct em_perf_domain *pd)
{
- __em_notify_pd_table(pd, EM_CMD_PD_CREATED);
+ __em_notify_pd_table(pd, DEV_ENERGYMODEL_CMD_PERF_DOMAIN_CREATED);
}
void em_notify_pd_updated(const struct em_perf_domain *pd)
{
- __em_notify_pd_table(pd, EM_CMD_PD_UPDATED);
+ __em_notify_pd_table(pd, DEV_ENERGYMODEL_CMD_PERF_DOMAIN_UPDATED);
}
static int __em_notify_pd_deleted_size(const struct em_perf_domain *pd)
{
- int id_sz = nla_total_size(sizeof(u32)); /* EM_A_PD_TABLE_PD_ID */
+ int id_sz = nla_total_size(sizeof(u32)); /* DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID */
return nlmsg_total_size(genlmsg_msg_size(id_sz));
}
@@ -272,7 +301,8 @@ void em_notify_pd_deleted(const struct em_perf_domain *pd)
void *hdr;
int msg_sz;
- if (!genl_has_listeners(&em_nl_family, &init_net, EM_NLGRP_EVENT))
+ if (!genl_has_listeners(&dev_energymodel_nl_family, &init_net,
+ DEV_ENERGYMODEL_NLGRP_EVENT))
return;
msg_sz = __em_notify_pd_deleted_size(pd);
@@ -281,28 +311,29 @@ void em_notify_pd_deleted(const struct em_perf_domain *pd)
if (!msg)
return;
- hdr = genlmsg_put(msg, 0, 0, &em_nl_family, 0, EM_CMD_PD_DELETED);
+ hdr = genlmsg_put(msg, 0, 0, &dev_energymodel_nl_family, 0,
+ DEV_ENERGYMODEL_CMD_PERF_DOMAIN_DELETED);
if (!hdr)
goto out_free_msg;
- if (nla_put_u32(msg, EM_A_PD_TABLE_PD_ID, pd->id)) {
+ if (nla_put_u32(msg, DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID,
+ pd->id))
goto out_free_msg;
- }
genlmsg_end(msg, hdr);
- genlmsg_multicast(&em_nl_family, msg, 0, EM_NLGRP_EVENT, GFP_KERNEL);
+ genlmsg_multicast(&dev_energymodel_nl_family, msg, 0,
+ DEV_ENERGYMODEL_NLGRP_EVENT, GFP_KERNEL);
return;
out_free_msg:
nlmsg_free(msg);
- return;
}
/**************************** Initialization *********************************/
static int __init em_netlink_init(void)
{
- return genl_register_family(&em_nl_family);
+ return genl_register_family(&dev_energymodel_nl_family);
}
postcore_initcall(em_netlink_init);
diff --git a/kernel/power/em_netlink_autogen.c b/kernel/power/em_netlink_autogen.c
index ceb3b2bb6ebe..44acef0e7df2 100644
--- a/kernel/power/em_netlink_autogen.c
+++ b/kernel/power/em_netlink_autogen.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
/* Do not edit directly, auto-generated from: */
-/* Documentation/netlink/specs/em.yaml */
+/* Documentation/netlink/specs/dev-energymodel.yaml */
/* YNL-GEN kernel source */
/* To regenerate run: tools/net/ynl/ynl-regen.sh */
@@ -9,41 +9,41 @@
#include "em_netlink_autogen.h"
-#include <uapi/linux/energy_model.h>
+#include <uapi/linux/dev_energymodel.h>
-/* EM_CMD_GET_PD_TABLE - do */
-static const struct nla_policy em_get_pd_table_nl_policy[EM_A_PD_TABLE_PD_ID + 1] = {
- [EM_A_PD_TABLE_PD_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, },
};
-/* Ops table for em */
-static const struct genl_split_ops em_nl_ops[] = {
+/* Ops table for dev_energymodel */
+static const struct genl_split_ops dev_energymodel_nl_ops[] = {
{
- .cmd = EM_CMD_GET_PDS,
- .doit = em_nl_get_pds_doit,
+ .cmd = DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS,
+ .doit = dev_energymodel_nl_get_perf_domains_doit,
.flags = GENL_CMD_CAP_DO,
},
{
- .cmd = EM_CMD_GET_PD_TABLE,
- .doit = em_nl_get_pd_table_doit,
- .policy = em_get_pd_table_nl_policy,
- .maxattr = EM_A_PD_TABLE_PD_ID,
+ .cmd = DEV_ENERGYMODEL_CMD_GET_PERF_TABLE,
+ .doit = dev_energymodel_nl_get_perf_table_doit,
+ .policy = dev_energymodel_get_perf_table_nl_policy,
+ .maxattr = DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID,
.flags = GENL_CMD_CAP_DO,
},
};
-static const struct genl_multicast_group em_nl_mcgrps[] = {
- [EM_NLGRP_EVENT] = { "event", },
+static const struct genl_multicast_group dev_energymodel_nl_mcgrps[] = {
+ [DEV_ENERGYMODEL_NLGRP_EVENT] = { "event", },
};
-struct genl_family em_nl_family __ro_after_init = {
- .name = EM_FAMILY_NAME,
- .version = EM_FAMILY_VERSION,
+struct genl_family dev_energymodel_nl_family __ro_after_init = {
+ .name = DEV_ENERGYMODEL_FAMILY_NAME,
+ .version = DEV_ENERGYMODEL_FAMILY_VERSION,
.netnsok = true,
.parallel_ops = true,
.module = THIS_MODULE,
- .split_ops = em_nl_ops,
- .n_split_ops = ARRAY_SIZE(em_nl_ops),
- .mcgrps = em_nl_mcgrps,
- .n_mcgrps = ARRAY_SIZE(em_nl_mcgrps),
+ .split_ops = dev_energymodel_nl_ops,
+ .n_split_ops = ARRAY_SIZE(dev_energymodel_nl_ops),
+ .mcgrps = dev_energymodel_nl_mcgrps,
+ .n_mcgrps = ARRAY_SIZE(dev_energymodel_nl_mcgrps),
};
diff --git a/kernel/power/em_netlink_autogen.h b/kernel/power/em_netlink_autogen.h
index 140ab548103c..f7e4bddcbd53 100644
--- a/kernel/power/em_netlink_autogen.h
+++ b/kernel/power/em_netlink_autogen.h
@@ -1,24 +1,26 @@
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
/* Do not edit directly, auto-generated from: */
-/* Documentation/netlink/specs/em.yaml */
+/* Documentation/netlink/specs/dev-energymodel.yaml */
/* YNL-GEN kernel header */
/* To regenerate run: tools/net/ynl/ynl-regen.sh */
-#ifndef _LINUX_EM_GEN_H
-#define _LINUX_EM_GEN_H
+#ifndef _LINUX_DEV_ENERGYMODEL_GEN_H
+#define _LINUX_DEV_ENERGYMODEL_GEN_H
#include <net/netlink.h>
#include <net/genetlink.h>
-#include <uapi/linux/energy_model.h>
+#include <uapi/linux/dev_energymodel.h>
-int em_nl_get_pds_doit(struct sk_buff *skb, struct genl_info *info);
-int em_nl_get_pd_table_doit(struct sk_buff *skb, struct genl_info *info);
+int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb,
+ struct genl_info *info);
+int dev_energymodel_nl_get_perf_table_doit(struct sk_buff *skb,
+ struct genl_info *info);
enum {
- EM_NLGRP_EVENT,
+ DEV_ENERGYMODEL_NLGRP_EVENT,
};
-extern struct genl_family em_nl_family;
+extern struct genl_family dev_energymodel_nl_family;
-#endif /* _LINUX_EM_GEN_H */
+#endif /* _LINUX_DEV_ENERGYMODEL_GEN_H */
--
2.52.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 for 6.19 3/4] PM: EM: Change cpus' type from string to u64 array in the EM YNL spec
2026-01-08 5:32 [PATCH v2 for 6.19 0/4] Revise the EM YNL spec to be clearer Changwoo Min
2026-01-08 5:32 ` [PATCH v2 for 6.19 1/4] PM: EM: Fix yamllint warnings in the EM YNL spec Changwoo Min
2026-01-08 5:32 ` [PATCH v2 for 6.19 2/4] PM: EM: Rename em.yaml to dev-energymodel.yaml Changwoo Min
@ 2026-01-08 5:32 ` Changwoo Min
2026-01-08 5:32 ` [PATCH v2 for 6.19 4/4] PM: EM: Add dump to get-perf-domains " Changwoo Min
2026-01-08 9:38 ` [PATCH v2 for 6.19 0/4] Revise the EM YNL spec to be clearer Donald Hunter
4 siblings, 0 replies; 8+ messages in thread
From: Changwoo Min @ 2026-01-08 5:32 UTC (permalink / raw)
To: lukasz.luba, rafael, donald.hunter, kuba, davem, edumazet, pabeni,
horms, lenb, pavel, changwoo
Cc: kernel-dev, linux-pm, netdev, sched-ext, linux-kernel
Previously, the cpus attribute was a string format which was a "%*pb"
stringification of a bitmap. That is not very consumable for a UAPI,
so let’s change it to an u64 array of CPU ids.
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>
---
.../netlink/specs/dev-energymodel.yaml | 3 ++-
kernel/power/em_netlink.c | 22 +++++++++----------
2 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/Documentation/netlink/specs/dev-energymodel.yaml b/Documentation/netlink/specs/dev-energymodel.yaml
index cbc4bc38f23c..af8b8f72f722 100644
--- a/Documentation/netlink/specs/dev-energymodel.yaml
+++ b/Documentation/netlink/specs/dev-energymodel.yaml
@@ -73,7 +73,8 @@ attribute-sets:
enum: perf-domain-flags
-
name: cpus
- type: string
+ type: u64
+ multi-attr: true
doc: >-
CPUs that belong to this performance domain.
-
diff --git a/kernel/power/em_netlink.c b/kernel/power/em_netlink.c
index 6f6238c465bb..b6edb018c65a 100644
--- a/kernel/power/em_netlink.c
+++ b/kernel/power/em_netlink.c
@@ -17,17 +17,14 @@
#include "em_netlink.h"
#include "em_netlink_autogen.h"
-#define DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS_LEN 256
-
/*************************** Command encoding ********************************/
static int __em_nl_get_pd_size(struct em_perf_domain *pd, void *data)
{
- char cpus_buf[DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS_LEN];
+ int nr_cpus, msg_sz, cpus_sz;
int *tot_msg_sz = data;
- int msg_sz, cpus_sz;
- cpus_sz = snprintf(cpus_buf, sizeof(cpus_buf), "%*pb",
- cpumask_pr_args(to_cpumask(pd->cpus)));
+ nr_cpus = cpumask_weight(to_cpumask(pd->cpus));
+ cpus_sz = nla_total_size_64bit(sizeof(u64)) * nr_cpus;
msg_sz = nla_total_size(0) +
/* DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN */
@@ -44,9 +41,10 @@ static int __em_nl_get_pd_size(struct em_perf_domain *pd, void *data)
static int __em_nl_get_pd(struct em_perf_domain *pd, void *data)
{
- char cpus_buf[DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS_LEN];
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);
@@ -61,10 +59,12 @@ static int __em_nl_get_pd(struct em_perf_domain *pd, void *data)
pd->flags, DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD))
goto out_cancel_nest;
- snprintf(cpus_buf, sizeof(cpus_buf), "%*pb",
- cpumask_pr_args(to_cpumask(pd->cpus)));
- if (nla_put_string(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS, cpus_buf))
- goto out_cancel_nest;
+ cpumask = to_cpumask(pd->cpus);
+ for_each_cpu(cpu, cpumask) {
+ if (nla_put_u64_64bit(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS,
+ cpu, DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD))
+ goto out_cancel_nest;
+ }
nla_nest_end(msg, entry);
--
2.52.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 for 6.19 4/4] PM: EM: Add dump to get-perf-domains in the EM YNL spec
2026-01-08 5:32 [PATCH v2 for 6.19 0/4] Revise the EM YNL spec to be clearer Changwoo Min
` (2 preceding siblings ...)
2026-01-08 5:32 ` [PATCH v2 for 6.19 3/4] PM: EM: Change cpus' type from string to u64 array in the EM YNL spec Changwoo Min
@ 2026-01-08 5:32 ` Changwoo Min
2026-01-27 12:40 ` Lai, Yi
2026-01-08 9:38 ` [PATCH v2 for 6.19 0/4] Revise the EM YNL spec to be clearer Donald Hunter
4 siblings, 1 reply; 8+ messages in thread
From: Changwoo Min @ 2026-01-08 5:32 UTC (permalink / raw)
To: lukasz.luba, rafael, donald.hunter, kuba, davem, edumazet, pabeni,
horms, lenb, pavel, changwoo
Cc: kernel-dev, linux-pm, netdev, sched-ext, linux-kernel
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>
---
.../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/Documentation/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.
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 = 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,
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"
/*************************** 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;
diff --git a/kernel/power/em_netlink_autogen.c b/kernel/power/em_netlink_autogen.c
index 44acef0e7df2..fedd473e4244 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_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,
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
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 for 6.19 0/4] Revise the EM YNL spec to be clearer
2026-01-08 5:32 [PATCH v2 for 6.19 0/4] Revise the EM YNL spec to be clearer Changwoo Min
` (3 preceding siblings ...)
2026-01-08 5:32 ` [PATCH v2 for 6.19 4/4] PM: EM: Add dump to get-perf-domains " Changwoo Min
@ 2026-01-08 9:38 ` Donald Hunter
2026-01-09 20:49 ` Rafael J. Wysocki
4 siblings, 1 reply; 8+ messages in thread
From: Donald Hunter @ 2026-01-08 9:38 UTC (permalink / raw)
To: Changwoo Min
Cc: lukasz.luba, rafael, kuba, davem, edumazet, pabeni, horms, lenb,
pavel, kernel-dev, linux-pm, netdev, sched-ext, linux-kernel
Changwoo Min <changwoo@igalia.com> writes:
> This patch set addresses all the concerns raised at [1] to make the EM YNL spec
> clearer. It includes the following changes:
>
> - Fix the lint errors (1/4).
> - Rename em.yaml to dev-energymodel.yaml (2/4). “dev-energymodel” was used
> instead of “device-energy-model”, which was originally proposed [2], because
> the netlink protocol name cannot exceed GENL_NAMSIZ(16). In addition, docs
> strings and flags attributes were added.
> - Change cpus' type from string to u64 array of CPU ids (3/4).
> - Add dump to get-perf-domains in the EM YNL spec (4/4). A user can fetch
> either information about a specific performance domain with do or information
> about all performance domains with dump.
>
> ChangeLog v1 -> v2:
> - Remove perf-domains in the YNL spec, as do and dump of get-perf-domains
> share the reply format using perf-domain-attrs (4/4).
> - Add example outputs of get-perf-domains and get-perf-table for ease of
> understanding (cover letter).
v2 looks good, thanks!
Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 for 6.19 0/4] Revise the EM YNL spec to be clearer
2026-01-08 9:38 ` [PATCH v2 for 6.19 0/4] Revise the EM YNL spec to be clearer Donald Hunter
@ 2026-01-09 20:49 ` Rafael J. Wysocki
0 siblings, 0 replies; 8+ messages in thread
From: Rafael J. Wysocki @ 2026-01-09 20:49 UTC (permalink / raw)
To: Donald Hunter, Changwoo Min
Cc: lukasz.luba, kuba, davem, edumazet, pabeni, horms, kernel-dev,
linux-pm, netdev, sched-ext, linux-kernel
On Thu, Jan 8, 2026 at 10:39 AM Donald Hunter <donald.hunter@gmail.com> wrote:
>
> Changwoo Min <changwoo@igalia.com> writes:
>
> > This patch set addresses all the concerns raised at [1] to make the EM YNL spec
> > clearer. It includes the following changes:
> >
> > - Fix the lint errors (1/4).
> > - Rename em.yaml to dev-energymodel.yaml (2/4). “dev-energymodel” was used
> > instead of “device-energy-model”, which was originally proposed [2], because
> > the netlink protocol name cannot exceed GENL_NAMSIZ(16). In addition, docs
> > strings and flags attributes were added.
> > - Change cpus' type from string to u64 array of CPU ids (3/4).
> > - Add dump to get-perf-domains in the EM YNL spec (4/4). A user can fetch
> > either information about a specific performance domain with do or information
> > about all performance domains with dump.
> >
> > ChangeLog v1 -> v2:
> > - Remove perf-domains in the YNL spec, as do and dump of get-perf-domains
> > share the reply format using perf-domain-attrs (4/4).
> > - Add example outputs of get-perf-domains and get-perf-table for ease of
> > understanding (cover letter).
>
> v2 looks good, thanks!
>
> Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
Applied as 6.19-rc material, thanks!
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 for 6.19 4/4] PM: EM: Add dump to get-perf-domains in the EM YNL spec
2026-01-08 5:32 ` [PATCH v2 for 6.19 4/4] PM: EM: Add dump to get-perf-domains " Changwoo Min
@ 2026-01-27 12:40 ` Lai, Yi
0 siblings, 0 replies; 8+ messages in thread
From: Lai, Yi @ 2026-01-27 12:40 UTC (permalink / raw)
To: Changwoo Min
Cc: lukasz.luba, rafael, donald.hunter, kuba, davem, edumazet, pabeni,
horms, lenb, pavel, kernel-dev, linux-pm, netdev, sched-ext,
linux-kernel
Hi Changwoo Min,
Greetings!
I used Syzkaller and found that there is general protection fault in __bitmap_weight in linux-next next-20260126.
After bisection and the first bad commit is:
"
380ff27af25e PM: EM: Add dump to get-perf-domains in the EM YNL spec
"
All detailed into can be found at:
https://github.com/laifryiee/syzkaller_logs/tree/main/260127_162751___bitmap_weight
Syzkaller repro code:
https://github.com/laifryiee/syzkaller_logs/tree/main/260127_162751___bitmap_weight/repro.c
Syzkaller repro syscall steps:
https://github.com/laifryiee/syzkaller_logs/tree/main/260127_162751___bitmap_weight/repro.prog
Syzkaller report:
https://github.com/laifryiee/syzkaller_logs/tree/main/260127_162751___bitmap_weight/repro.report
Kconfig(make olddefconfig):
https://github.com/laifryiee/syzkaller_logs/tree/main/260127_162751___bitmap_weight/kconfig_origin
Bisect info:
https://github.com/laifryiee/syzkaller_logs/tree/main/260127_162751___bitmap_weight/bisect_info.log
bzImage:
https://github.com/laifryiee/syzkaller_logs/raw/refs/heads/main/260127_162751___bitmap_weight/bzImage_v6.19-rc7
Issue dmesg:
https://github.com/laifryiee/syzkaller_logs/blob/main/260127_162751___bitmap_weight/v6.19-rc7_dmesg.log
"
[ 19.746792] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 I
[ 19.747509] KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037]
[ 19.747982] CPU: 0 UID: 0 PID: 710 Comm: repro Not tainted 6.19.0-rc7-v6.19-rc7 #1 PREEMPT(voluntary)
[ 19.748561] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org4
[ 19.749261] RIP: 0010:__bitmap_weight+0xb9/0x110
[ 19.749574] Code: 89 ee e8 3a cb 64 fe 45 85 ed 74 3e e8 30 d1 64 fe 48 8b 45 c8 48 8d 1c d8 48 b8 00 00 00 00 00 fc8
[ 19.750681] RSP: 0018:ff110000151ef488 EFLAGS: 00010206
[ 19.750982] RAX: dffffc0000000000 RBX: 0000000000000030 RCX: ffffffff8324fe06
[ 19.751388] RDX: 0000000000000006 RSI: ffffffff8324fe10 RDI: 0000000000000005
[ 19.751779] RBP: ff110000151ef4c0 R08: 0000000000000001 R09: ffe21c0002a3de7b
[ 19.752188] R10: 0000000000000002 R11: 0000000000000000 R12: 0000000000000000
[ 19.752585] R13: 0000000000000002 R14: 0000000000000030 R15: ff1100001e531a00
[ 19.752984] FS: 00007f0bbbba3740(0000) GS:ff110000e34b5000(0000) knlGS:0000000000000000
[ 19.753441] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 19.753779] CR2: 0000000020000b00 CR3: 000000001e6bd006 CR4: 0000000000771ef0
[ 19.754194] PKRU: 55555554
[ 19.754357] Call Trace:
[ 19.754505] <TASK>
[ 19.754639] dev_energymodel_nl_get_perf_domains_doit+0x140/0x4b0
[ 19.754997] genl_family_rcv_msg_doit+0x23d/0x330
[ 19.755285] ? __pfx_genl_family_rcv_msg_doit+0x10/0x10
[ 19.755594] ? genl_get_cmd+0x1c9/0x630
[ 19.755832] genl_rcv_msg+0x580/0x840
[ 19.756058] ? __pfx_genl_rcv_msg+0x10/0x10
[ 19.756315] ? __pfx_dev_energymodel_nl_get_perf_domains_doit+0x10/0x10
[ 19.756698] netlink_rcv_skb+0x174/0x450
[ 19.756934] ? __pfx_genl_rcv_msg+0x10/0x10
[ 19.757192] ? __pfx_netlink_rcv_skb+0x10/0x10
[ 19.757460] ? netlink_deliver_tap+0x1b9/0xca0
[ 19.757734] genl_rcv+0x32/0x50
[ 19.757928] netlink_unicast+0x7e2/0xc80
[ 19.758179] ? __pfx_netlink_unicast+0x10/0x10
[ 19.758446] ? __virt_addr_valid+0x10a/0x5f0
[ 19.758707] ? __check_object_size+0x3c/0x9b0
[ 19.758973] netlink_sendmsg+0x957/0xe80
[ 19.759219] ? __pfx_netlink_sendmsg+0x10/0x10
[ 19.759481] ? __import_iovec+0x1df/0x660
[ 19.759729] ? __might_fault+0xe0/0x1b0
[ 19.759963] ? __pfx_netlink_sendmsg+0x10/0x10
[ 19.760236] ____sys_sendmsg+0xaa3/0xc70
[ 19.760479] ? __pfx_____sys_sendmsg+0x10/0x10
[ 19.760754] ? __this_cpu_preempt_check+0x21/0x30
[ 19.761032] ? lock_release+0x14f/0x2a0
[ 19.761283] ___sys_sendmsg+0x121/0x1c0
[ 19.761516] ? do_anonymous_page+0x4c0/0x1a30
[ 19.761784] ? __pfx____sys_sendmsg+0x10/0x10
[ 19.762051] ? __handle_mm_fault+0x656/0x2d60
[ 19.762334] ? __lock_acquire+0x412/0x2210
[ 19.762590] __sys_sendmsg+0x177/0x220
[ 19.762813] ? __pfx___sys_sendmsg+0x10/0x10
[ 19.763074] ? lockdep_hardirqs_on+0x85/0x110
[ 19.763346] ? seqcount_lockdep_reader_access.constprop.0+0xb4/0xd0
[ 19.763729] ? __audit_syscall_entry+0x393/0x4f0
[ 19.764023] __x64_sys_sendmsg+0x80/0xc0
[ 19.764274] ? syscall_trace_enter+0x14d/0x240
[ 19.764551] x64_sys_call+0x1d98/0x21b0
[ 19.764787] do_syscall_64+0x6d/0x1180
[ 19.765020] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 19.765324] RIP: 0033:0x7f0bbb83ee5d
[ 19.765546] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d8
[ 19.766615] RSP: 002b:00007ffdd5009908 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
[ 19.767059] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f0bbb83ee5d
[ 19.767485] RDX: 0000000000000004 RSI: 0000000020000b00 RDI: 0000000000000003
[ 19.767897] RBP: 00007ffdd5009920 R08: 00007ffdd5009920 R09: 00007ffdd5009920
[ 19.768322] R10: 00007ffdd5009390 R11: 0000000000000246 R12: 00007ffdd5009a78
[ 19.768746] R13: 0000000000401829 R14: 0000000000403e08 R15: 00007f0bbbbf0000
[ 19.769176] </TASK>
[ 19.769316] Modules linked in:
[ 19.769547] ---[ end trace 0000000000000000 ]---
"
Hope this cound be insightful to you.
Regards,
Yi Lai
---
If you don't need the following environment to reproduce the problem or if you
already have one reproduced environment, please ignore the following information.
How to reproduce:
git clone https://gitlab.com/xupengfe/repro_vm_env.git
cd repro_vm_env
tar -xvf repro_vm_env.tar.gz
cd repro_vm_env; ./start3.sh // it needs qemu-system-x86_64 and I used v7.1.0
// start3.sh will load bzImage_2241ab53cbb5cdb08a6b2d4688feb13971058f65 v6.2-rc5 kernel
// You could change the bzImage_xxx as you want
// Maybe you need to remove line "-drive if=pflash,format=raw,readonly=on,file=./OVMF_CODE.fd \" for different qemu version
You could use below command to log in, there is no password for root.
ssh -p 10023 root@localhost
After login vm(virtual machine) successfully, you could transfer reproduced
binary to the vm by below way, and reproduce the problem in vm:
gcc -pthread -o repro repro.c
scp -P 10023 repro root@localhost:/root/
Get the bzImage for target kernel:
Please use target kconfig and copy it to kernel_src/.config
make olddefconfig
make -jx bzImage //x should equal or less than cpu num your pc has
Fill the bzImage file into above start3.sh to load the target kernel in vm.
Tips:
If you already have qemu-system-x86_64, please ignore below info.
If you want to install qemu v7.1.0 version:
git clone https://github.com/qemu/qemu.git
cd qemu
git checkout -f v7.1.0
mkdir build
cd build
yum install -y ninja-build.x86_64
yum -y install libslirp-devel.x86_64
../configure --target-list=x86_64-softmmu --enable-kvm --enable-vnc --enable-gtk --enable-sdl --enable-usb-redir --enable-slirp
make
make install
On Thu, Jan 08, 2026 at 02:32:12PM +0900, Changwoo Min wrote:
> 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>
> ---
> .../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/Documentation/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.
>
> 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 = 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,
> 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"
>
> /*************************** 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;
> diff --git a/kernel/power/em_netlink_autogen.c b/kernel/power/em_netlink_autogen.c
> index 44acef0e7df2..fedd473e4244 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_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,
> 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
>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-01-27 12:40 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-08 5:32 [PATCH v2 for 6.19 0/4] Revise the EM YNL spec to be clearer Changwoo Min
2026-01-08 5:32 ` [PATCH v2 for 6.19 1/4] PM: EM: Fix yamllint warnings in the EM YNL spec Changwoo Min
2026-01-08 5:32 ` [PATCH v2 for 6.19 2/4] PM: EM: Rename em.yaml to dev-energymodel.yaml Changwoo Min
2026-01-08 5:32 ` [PATCH v2 for 6.19 3/4] PM: EM: Change cpus' type from string to u64 array in the EM YNL spec Changwoo Min
2026-01-08 5:32 ` [PATCH v2 for 6.19 4/4] PM: EM: Add dump to get-perf-domains " Changwoo Min
2026-01-27 12:40 ` Lai, Yi
2026-01-08 9:38 ` [PATCH v2 for 6.19 0/4] Revise the EM YNL spec to be clearer Donald Hunter
2026-01-09 20:49 ` Rafael J. Wysocki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox