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

Merge tag 'pm-6.19-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management fixes from Rafael Wysocki:
"These fix an error path memory leak in the energy model management
code, fix a kerneldoc comment in it, and fix and revamp the energy
model YNL specification added recently along with the new energy model
management netlink interface (that received feedback after being
added):

- Fix a memory leak in em_create_pd() error path (Malaya Kumar Rout)

- Fix stale description of the cost field in struct em_perf_state to
reflect the current code (Yaxiong Tian)

- Fix and revamp the energy model YNL specification added recently
along with the energy model netlink interface (Changwoo Min)"

* tag 'pm-6.19-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
PM: EM: Add dump to get-perf-domains in the EM YNL spec
PM: EM: Change cpus' type from string to u64 array in the EM YNL spec
PM: EM: Rename em.yaml to dev-energymodel.yaml
PM: EM: Fix yamllint warnings in the EM YNL spec
PM: EM: Fix memory leak in em_create_pd() error path
PM: EM: Fix incorrect description of the cost field in struct em_perf_state

+454 -288
+175
Documentation/netlink/specs/dev-energymodel.yaml
··· 1 + # SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 2 + # 3 + # Copyright (c) 2025 Valve Corporation. 4 + # 5 + --- 6 + name: dev-energymodel 7 + 8 + doc: | 9 + Energy model netlink interface to notify its changes. 10 + 11 + protocol: genetlink 12 + 13 + uapi-header: linux/dev_energymodel.h 14 + 15 + definitions: 16 + - 17 + type: flags 18 + name: perf-state-flags 19 + entries: 20 + - 21 + name: perf-state-inefficient 22 + doc: >- 23 + The performance state is inefficient. There is in this perf-domain, 24 + another performance state with a higher frequency but a lower or 25 + equal power cost. 26 + - 27 + type: flags 28 + name: perf-domain-flags 29 + entries: 30 + - 31 + name: perf-domain-microwatts 32 + doc: >- 33 + The power values are in micro-Watts or some other scale. 34 + - 35 + name: perf-domain-skip-inefficiencies 36 + doc: >- 37 + Skip inefficient states when estimating energy consumption. 38 + - 39 + name: perf-domain-artificial 40 + doc: >- 41 + The power values are artificial and might be created by platform 42 + missing real power information. 43 + 44 + attribute-sets: 45 + - 46 + name: perf-domain 47 + doc: >- 48 + Information on a single performance domains. 49 + attributes: 50 + - 51 + name: pad 52 + type: pad 53 + - 54 + name: perf-domain-id 55 + type: u32 56 + doc: >- 57 + A unique ID number for each performance domain. 58 + - 59 + name: flags 60 + type: u64 61 + doc: >- 62 + Bitmask of performance domain flags. 63 + enum: perf-domain-flags 64 + - 65 + name: cpus 66 + type: u64 67 + multi-attr: true 68 + doc: >- 69 + CPUs that belong to this performance domain. 70 + - 71 + name: perf-table 72 + doc: >- 73 + Performance states table. 74 + attributes: 75 + - 76 + name: perf-domain-id 77 + type: u32 78 + doc: >- 79 + A unique ID number for each performance domain. 80 + - 81 + name: perf-state 82 + type: nest 83 + nested-attributes: perf-state 84 + multi-attr: true 85 + - 86 + name: perf-state 87 + doc: >- 88 + Performance state of a performance domain. 89 + attributes: 90 + - 91 + name: pad 92 + type: pad 93 + - 94 + name: performance 95 + type: u64 96 + doc: >- 97 + CPU performance (capacity) at a given frequency. 98 + - 99 + name: frequency 100 + type: u64 101 + doc: >- 102 + The frequency in KHz, for consistency with CPUFreq. 103 + - 104 + name: power 105 + type: u64 106 + doc: >- 107 + The power consumed at this level (by 1 CPU or by a registered 108 + device). It can be a total power: static and dynamic. 109 + - 110 + name: cost 111 + type: u64 112 + doc: >- 113 + The cost coefficient associated with this level, used during energy 114 + calculation. Equal to: power * max_frequency / frequency. 115 + - 116 + name: flags 117 + type: u64 118 + doc: >- 119 + Bitmask of performance state flags. 120 + enum: perf-state-flags 121 + 122 + operations: 123 + list: 124 + - 125 + name: get-perf-domains 126 + attribute-set: perf-domain 127 + doc: Get the list of information for all performance domains. 128 + do: 129 + request: 130 + attributes: 131 + - perf-domain-id 132 + reply: 133 + attributes: &perf-domain-attrs 134 + - pad 135 + - perf-domain-id 136 + - flags 137 + - cpus 138 + dump: 139 + reply: 140 + attributes: *perf-domain-attrs 141 + - 142 + name: get-perf-table 143 + attribute-set: perf-table 144 + doc: Get the energy model table of a performance domain. 145 + do: 146 + request: 147 + attributes: 148 + - perf-domain-id 149 + reply: 150 + attributes: 151 + - perf-domain-id 152 + - perf-state 153 + - 154 + name: perf-domain-created 155 + doc: A performance domain is created. 156 + notify: get-perf-table 157 + mcgrp: event 158 + - 159 + name: perf-domain-updated 160 + doc: A performance domain is updated. 161 + notify: get-perf-table 162 + mcgrp: event 163 + - 164 + name: perf-domain-deleted 165 + doc: A performance domain is deleted. 166 + attribute-set: perf-table 167 + event: 168 + attributes: 169 + - perf-domain-id 170 + mcgrp: event 171 + 172 + mcast-groups: 173 + list: 174 + - 175 + name: event
-113
Documentation/netlink/specs/em.yaml
··· 1 - # SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 2 - 3 - name: em 4 - 5 - doc: | 6 - Energy model netlink interface to notify its changes. 7 - 8 - protocol: genetlink 9 - 10 - uapi-header: linux/energy_model.h 11 - 12 - attribute-sets: 13 - - 14 - name: pds 15 - attributes: 16 - - 17 - name: pd 18 - type: nest 19 - nested-attributes: pd 20 - multi-attr: true 21 - - 22 - name: pd 23 - attributes: 24 - - 25 - name: pad 26 - type: pad 27 - - 28 - name: pd-id 29 - type: u32 30 - - 31 - name: flags 32 - type: u64 33 - - 34 - name: cpus 35 - type: string 36 - - 37 - name: pd-table 38 - attributes: 39 - - 40 - name: pd-id 41 - type: u32 42 - - 43 - name: ps 44 - type: nest 45 - nested-attributes: ps 46 - multi-attr: true 47 - - 48 - name: ps 49 - attributes: 50 - - 51 - name: pad 52 - type: pad 53 - - 54 - name: performance 55 - type: u64 56 - - 57 - name: frequency 58 - type: u64 59 - - 60 - name: power 61 - type: u64 62 - - 63 - name: cost 64 - type: u64 65 - - 66 - name: flags 67 - type: u64 68 - 69 - operations: 70 - list: 71 - - 72 - name: get-pds 73 - attribute-set: pds 74 - doc: Get the list of information for all performance domains. 75 - do: 76 - reply: 77 - attributes: 78 - - pd 79 - - 80 - name: get-pd-table 81 - attribute-set: pd-table 82 - doc: Get the energy model table of a performance domain. 83 - do: 84 - request: 85 - attributes: 86 - - pd-id 87 - reply: 88 - attributes: 89 - - pd-id 90 - - ps 91 - - 92 - name: pd-created 93 - doc: A performance domain is created. 94 - notify: get-pd-table 95 - mcgrp: event 96 - - 97 - name: pd-updated 98 - doc: A performance domain is updated. 99 - notify: get-pd-table 100 - mcgrp: event 101 - - 102 - name: pd-deleted 103 - doc: A performance domain is deleted. 104 - attribute-set: pd-table 105 - event: 106 - attributes: 107 - - pd-id 108 - mcgrp: event 109 - 110 - mcast-groups: 111 - list: 112 - - 113 - name: event
+4 -4
MAINTAINERS
··· 9304 9304 M: "Rafael J. Wysocki" <rafael@kernel.org> 9305 9305 L: linux-pm@vger.kernel.org 9306 9306 S: Maintained 9307 - F: kernel/power/energy_model.c 9308 - F: include/linux/energy_model.h 9307 + F: Documentation/netlink/specs/dev-energymodel.yaml 9309 9308 F: Documentation/power/energy-model.rst 9310 - F: Documentation/netlink/specs/em.yaml 9311 - F: include/uapi/linux/energy_model.h 9309 + F: include/linux/energy_model.h 9310 + F: include/uapi/linux/dev_energymodel.h 9312 9311 F: kernel/power/em_netlink*.* 9312 + F: kernel/power/energy_model.c 9313 9313 9314 9314 EPAPR HYPERVISOR BYTE CHANNEL DEVICE DRIVER 9315 9315 M: Laurentiu Tudor <laurentiu.tudor@nxp.com>
+1 -1
include/linux/energy_model.h
··· 18 18 * @power: The power consumed at this level (by 1 CPU or by a registered 19 19 * device). It can be a total power: static and dynamic. 20 20 * @cost: The cost coefficient associated with this level, used during 21 - * energy calculation. Equal to: power * max_frequency / frequency 21 + * energy calculation. Equal to: 10 * power * max_frequency / frequency 22 22 * @flags: see "em_perf_state flags" description below. 23 23 */ 24 24 struct em_perf_state {
+82
include/uapi/linux/dev_energymodel.h
··· 1 + /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ 2 + /* Do not edit directly, auto-generated from: */ 3 + /* Documentation/netlink/specs/dev-energymodel.yaml */ 4 + /* YNL-GEN uapi header */ 5 + /* To regenerate run: tools/net/ynl/ynl-regen.sh */ 6 + 7 + #ifndef _UAPI_LINUX_DEV_ENERGYMODEL_H 8 + #define _UAPI_LINUX_DEV_ENERGYMODEL_H 9 + 10 + #define DEV_ENERGYMODEL_FAMILY_NAME "dev-energymodel" 11 + #define DEV_ENERGYMODEL_FAMILY_VERSION 1 12 + 13 + /** 14 + * enum dev_energymodel_perf_state_flags 15 + * @DEV_ENERGYMODEL_PERF_STATE_FLAGS_PERF_STATE_INEFFICIENT: The performance 16 + * state is inefficient. There is in this perf-domain, another performance 17 + * state with a higher frequency but a lower or equal power cost. 18 + */ 19 + enum dev_energymodel_perf_state_flags { 20 + DEV_ENERGYMODEL_PERF_STATE_FLAGS_PERF_STATE_INEFFICIENT = 1, 21 + }; 22 + 23 + /** 24 + * enum dev_energymodel_perf_domain_flags 25 + * @DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_MICROWATTS: The power values 26 + * are in micro-Watts or some other scale. 27 + * @DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_SKIP_INEFFICIENCIES: Skip 28 + * inefficient states when estimating energy consumption. 29 + * @DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_ARTIFICIAL: The power values 30 + * are artificial and might be created by platform missing real power 31 + * information. 32 + */ 33 + enum dev_energymodel_perf_domain_flags { 34 + DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_MICROWATTS = 1, 35 + DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_SKIP_INEFFICIENCIES = 2, 36 + DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_ARTIFICIAL = 4, 37 + }; 38 + 39 + enum { 40 + DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD = 1, 41 + DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID, 42 + DEV_ENERGYMODEL_A_PERF_DOMAIN_FLAGS, 43 + DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS, 44 + 45 + __DEV_ENERGYMODEL_A_PERF_DOMAIN_MAX, 46 + DEV_ENERGYMODEL_A_PERF_DOMAIN_MAX = (__DEV_ENERGYMODEL_A_PERF_DOMAIN_MAX - 1) 47 + }; 48 + 49 + enum { 50 + DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID = 1, 51 + DEV_ENERGYMODEL_A_PERF_TABLE_PERF_STATE, 52 + 53 + __DEV_ENERGYMODEL_A_PERF_TABLE_MAX, 54 + DEV_ENERGYMODEL_A_PERF_TABLE_MAX = (__DEV_ENERGYMODEL_A_PERF_TABLE_MAX - 1) 55 + }; 56 + 57 + enum { 58 + DEV_ENERGYMODEL_A_PERF_STATE_PAD = 1, 59 + DEV_ENERGYMODEL_A_PERF_STATE_PERFORMANCE, 60 + DEV_ENERGYMODEL_A_PERF_STATE_FREQUENCY, 61 + DEV_ENERGYMODEL_A_PERF_STATE_POWER, 62 + DEV_ENERGYMODEL_A_PERF_STATE_COST, 63 + DEV_ENERGYMODEL_A_PERF_STATE_FLAGS, 64 + 65 + __DEV_ENERGYMODEL_A_PERF_STATE_MAX, 66 + DEV_ENERGYMODEL_A_PERF_STATE_MAX = (__DEV_ENERGYMODEL_A_PERF_STATE_MAX - 1) 67 + }; 68 + 69 + enum { 70 + DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS = 1, 71 + DEV_ENERGYMODEL_CMD_GET_PERF_TABLE, 72 + DEV_ENERGYMODEL_CMD_PERF_DOMAIN_CREATED, 73 + DEV_ENERGYMODEL_CMD_PERF_DOMAIN_UPDATED, 74 + DEV_ENERGYMODEL_CMD_PERF_DOMAIN_DELETED, 75 + 76 + __DEV_ENERGYMODEL_CMD_MAX, 77 + DEV_ENERGYMODEL_CMD_MAX = (__DEV_ENERGYMODEL_CMD_MAX - 1) 78 + }; 79 + 80 + #define DEV_ENERGYMODEL_MCGRP_EVENT "event" 81 + 82 + #endif /* _UAPI_LINUX_DEV_ENERGYMODEL_H */
-63
include/uapi/linux/energy_model.h
··· 1 - /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ 2 - /* Do not edit directly, auto-generated from: */ 3 - /* Documentation/netlink/specs/em.yaml */ 4 - /* YNL-GEN uapi header */ 5 - /* To regenerate run: tools/net/ynl/ynl-regen.sh */ 6 - 7 - #ifndef _UAPI_LINUX_ENERGY_MODEL_H 8 - #define _UAPI_LINUX_ENERGY_MODEL_H 9 - 10 - #define EM_FAMILY_NAME "em" 11 - #define EM_FAMILY_VERSION 1 12 - 13 - enum { 14 - EM_A_PDS_PD = 1, 15 - 16 - __EM_A_PDS_MAX, 17 - EM_A_PDS_MAX = (__EM_A_PDS_MAX - 1) 18 - }; 19 - 20 - enum { 21 - EM_A_PD_PAD = 1, 22 - EM_A_PD_PD_ID, 23 - EM_A_PD_FLAGS, 24 - EM_A_PD_CPUS, 25 - 26 - __EM_A_PD_MAX, 27 - EM_A_PD_MAX = (__EM_A_PD_MAX - 1) 28 - }; 29 - 30 - enum { 31 - EM_A_PD_TABLE_PD_ID = 1, 32 - EM_A_PD_TABLE_PS, 33 - 34 - __EM_A_PD_TABLE_MAX, 35 - EM_A_PD_TABLE_MAX = (__EM_A_PD_TABLE_MAX - 1) 36 - }; 37 - 38 - enum { 39 - EM_A_PS_PAD = 1, 40 - EM_A_PS_PERFORMANCE, 41 - EM_A_PS_FREQUENCY, 42 - EM_A_PS_POWER, 43 - EM_A_PS_COST, 44 - EM_A_PS_FLAGS, 45 - 46 - __EM_A_PS_MAX, 47 - EM_A_PS_MAX = (__EM_A_PS_MAX - 1) 48 - }; 49 - 50 - enum { 51 - EM_CMD_GET_PDS = 1, 52 - EM_CMD_GET_PD_TABLE, 53 - EM_CMD_PD_CREATED, 54 - EM_CMD_PD_UPDATED, 55 - EM_CMD_PD_DELETED, 56 - 57 - __EM_CMD_MAX, 58 - EM_CMD_MAX = (__EM_CMD_MAX - 1) 59 - }; 60 - 61 - #define EM_MCGRP_EVENT "event" 62 - 63 - #endif /* _UAPI_LINUX_ENERGY_MODEL_H */
+140 -73
kernel/power/em_netlink.c
··· 12 12 #include <linux/energy_model.h> 13 13 #include <net/sock.h> 14 14 #include <net/genetlink.h> 15 - #include <uapi/linux/energy_model.h> 15 + #include <uapi/linux/dev_energymodel.h> 16 16 17 17 #include "em_netlink.h" 18 18 #include "em_netlink_autogen.h" 19 19 20 - #define EM_A_PD_CPUS_LEN 256 21 - 22 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 + 23 28 static int __em_nl_get_pd_size(struct em_perf_domain *pd, void *data) 24 29 { 25 - char cpus_buf[EM_A_PD_CPUS_LEN]; 30 + int nr_cpus, msg_sz, cpus_sz; 26 31 int *tot_msg_sz = data; 27 - int msg_sz, cpus_sz; 28 32 29 - cpus_sz = snprintf(cpus_buf, sizeof(cpus_buf), "%*pb", 30 - cpumask_pr_args(to_cpumask(pd->cpus))); 33 + nr_cpus = cpumask_weight(to_cpumask(pd->cpus)); 34 + cpus_sz = nla_total_size_64bit(sizeof(u64)) * nr_cpus; 31 35 32 - msg_sz = nla_total_size(0) + /* EM_A_PDS_PD */ 33 - nla_total_size(sizeof(u32)) + /* EM_A_PD_PD_ID */ 34 - nla_total_size_64bit(sizeof(u64)) + /* EM_A_PD_FLAGS */ 35 - nla_total_size(cpus_sz); /* EM_A_PD_CPUS */ 36 + msg_sz = nla_total_size(0) + 37 + /* DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN */ 38 + nla_total_size(sizeof(u32)) + 39 + /* DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID */ 40 + nla_total_size_64bit(sizeof(u64)) + 41 + /* DEV_ENERGYMODEL_A_PERF_DOMAIN_FLAGS */ 42 + nla_total_size(cpus_sz); 43 + /* DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS */ 36 44 37 45 *tot_msg_sz += nlmsg_total_size(genlmsg_msg_size(msg_sz)); 38 46 return 0; ··· 48 40 49 41 static int __em_nl_get_pd(struct em_perf_domain *pd, void *data) 50 42 { 51 - char cpus_buf[EM_A_PD_CPUS_LEN]; 52 43 struct sk_buff *msg = data; 53 - struct nlattr *entry; 44 + struct cpumask *cpumask; 45 + int cpu; 54 46 55 - entry = nla_nest_start(msg, EM_A_PDS_PD); 56 - if (!entry) 47 + if (nla_put_u32(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID, 48 + pd->id)) 57 49 goto out_cancel_nest; 58 50 59 - if (nla_put_u32(msg, EM_A_PD_PD_ID, pd->id)) 51 + if (nla_put_u64_64bit(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_FLAGS, 52 + pd->flags, DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD)) 60 53 goto out_cancel_nest; 61 54 62 - if (nla_put_u64_64bit(msg, EM_A_PD_FLAGS, pd->flags, EM_A_PD_PAD)) 63 - goto out_cancel_nest; 64 - 65 - snprintf(cpus_buf, sizeof(cpus_buf), "%*pb", 66 - cpumask_pr_args(to_cpumask(pd->cpus))); 67 - if (nla_put_string(msg, EM_A_PD_CPUS, cpus_buf)) 68 - goto out_cancel_nest; 69 - 70 - nla_nest_end(msg, entry); 55 + cpumask = to_cpumask(pd->cpus); 56 + for_each_cpu(cpu, cpumask) { 57 + if (nla_put_u64_64bit(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS, 58 + cpu, DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD)) 59 + goto out_cancel_nest; 60 + } 71 61 72 62 return 0; 73 63 74 64 out_cancel_nest: 75 - nla_nest_cancel(msg, entry); 76 - 77 65 return -EMSGSIZE; 78 66 } 79 67 80 - int em_nl_get_pds_doit(struct sk_buff *skb, struct genl_info *info) 68 + static int __em_nl_get_pd_for_dump(struct em_perf_domain *pd, void *data) 81 69 { 70 + const struct genl_info *info; 71 + struct dump_ctx *ctx = data; 72 + void *hdr; 73 + int ret; 74 + 75 + if (ctx->idx++ < ctx->start) 76 + return 0; 77 + 78 + info = genl_info_dump(ctx->cb); 79 + hdr = genlmsg_iput(ctx->skb, info); 80 + if (!hdr) { 81 + genlmsg_cancel(ctx->skb, hdr); 82 + return -EMSGSIZE; 83 + } 84 + 85 + ret = __em_nl_get_pd(pd, ctx->skb); 86 + genlmsg_end(ctx->skb, hdr); 87 + return ret; 88 + } 89 + 90 + int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb, 91 + struct genl_info *info) 92 + { 93 + int id, ret = -EMSGSIZE, msg_sz = 0; 94 + int cmd = info->genlhdr->cmd; 95 + struct em_perf_domain *pd; 82 96 struct sk_buff *msg; 83 97 void *hdr; 84 - int cmd = info->genlhdr->cmd; 85 - int ret = -EMSGSIZE, msg_sz = 0; 86 98 87 - for_each_em_perf_domain(__em_nl_get_pd_size, &msg_sz); 99 + if (!info->attrs[DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID]) 100 + return -EINVAL; 88 101 102 + id = nla_get_u32(info->attrs[DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID]); 103 + pd = em_perf_domain_get_by_id(id); 104 + 105 + __em_nl_get_pd_size(pd, &msg_sz); 89 106 msg = genlmsg_new(msg_sz, GFP_KERNEL); 90 107 if (!msg) 91 108 return -ENOMEM; 92 109 93 - hdr = genlmsg_put_reply(msg, info, &em_nl_family, 0, cmd); 110 + hdr = genlmsg_put_reply(msg, info, &dev_energymodel_nl_family, 0, cmd); 94 111 if (!hdr) 95 112 goto out_free_msg; 96 113 97 - ret = for_each_em_perf_domain(__em_nl_get_pd, msg); 114 + ret = __em_nl_get_pd(pd, msg); 98 115 if (ret) 99 116 goto out_cancel_msg; 100 - 101 117 genlmsg_end(msg, hdr); 102 118 103 119 return genlmsg_reply(msg, info); ··· 130 98 genlmsg_cancel(msg, hdr); 131 99 out_free_msg: 132 100 nlmsg_free(msg); 133 - 134 101 return ret; 102 + } 103 + 104 + int dev_energymodel_nl_get_perf_domains_dumpit(struct sk_buff *skb, 105 + struct netlink_callback *cb) 106 + { 107 + struct dump_ctx ctx = { 108 + .idx = 0, 109 + .start = cb->args[0], 110 + .skb = skb, 111 + .cb = cb, 112 + }; 113 + 114 + return for_each_em_perf_domain(__em_nl_get_pd_for_dump, &ctx); 135 115 } 136 116 137 117 static struct em_perf_domain *__em_nl_get_pd_table_id(struct nlattr **attrs) ··· 151 107 struct em_perf_domain *pd; 152 108 int id; 153 109 154 - if (!attrs[EM_A_PD_TABLE_PD_ID]) 110 + if (!attrs[DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID]) 155 111 return NULL; 156 112 157 - id = nla_get_u32(attrs[EM_A_PD_TABLE_PD_ID]); 113 + id = nla_get_u32(attrs[DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID]); 158 114 pd = em_perf_domain_get_by_id(id); 159 115 return pd; 160 116 } ··· 163 119 { 164 120 int id_sz, ps_sz; 165 121 166 - id_sz = nla_total_size(sizeof(u32)); /* EM_A_PD_TABLE_PD_ID */ 167 - ps_sz = nla_total_size(0) + /* EM_A_PD_TABLE_PS */ 168 - nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_PERFORMANCE */ 169 - nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_FREQUENCY */ 170 - nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_POWER */ 171 - nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_COST */ 172 - nla_total_size_64bit(sizeof(u64)); /* EM_A_PS_FLAGS */ 122 + id_sz = nla_total_size(sizeof(u32)); 123 + /* DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID */ 124 + ps_sz = nla_total_size(0) + 125 + /* DEV_ENERGYMODEL_A_PERF_TABLE_PERF_STATE */ 126 + nla_total_size_64bit(sizeof(u64)) + 127 + /* DEV_ENERGYMODEL_A_PERF_STATE_PERFORMANCE */ 128 + nla_total_size_64bit(sizeof(u64)) + 129 + /* DEV_ENERGYMODEL_A_PERF_STATE_FREQUENCY */ 130 + nla_total_size_64bit(sizeof(u64)) + 131 + /* DEV_ENERGYMODEL_A_PERF_STATE_POWER */ 132 + nla_total_size_64bit(sizeof(u64)) + 133 + /* DEV_ENERGYMODEL_A_PERF_STATE_COST */ 134 + nla_total_size_64bit(sizeof(u64)); 135 + /* DEV_ENERGYMODEL_A_PERF_STATE_FLAGS */ 173 136 ps_sz *= pd->nr_perf_states; 174 137 175 138 return nlmsg_total_size(genlmsg_msg_size(id_sz + ps_sz)); 176 139 } 177 140 178 - static int __em_nl_get_pd_table(struct sk_buff *msg, const struct em_perf_domain *pd) 141 + static 142 + int __em_nl_get_pd_table(struct sk_buff *msg, const struct em_perf_domain *pd) 179 143 { 180 144 struct em_perf_state *table, *ps; 181 145 struct nlattr *entry; 182 146 int i; 183 147 184 - if (nla_put_u32(msg, EM_A_PD_TABLE_PD_ID, pd->id)) 148 + if (nla_put_u32(msg, DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID, 149 + pd->id)) 185 150 goto out_err; 186 151 187 152 rcu_read_lock(); ··· 199 146 for (i = 0; i < pd->nr_perf_states; i++) { 200 147 ps = &table[i]; 201 148 202 - entry = nla_nest_start(msg, EM_A_PD_TABLE_PS); 149 + entry = nla_nest_start(msg, 150 + DEV_ENERGYMODEL_A_PERF_TABLE_PERF_STATE); 203 151 if (!entry) 204 152 goto out_unlock_ps; 205 153 206 - if (nla_put_u64_64bit(msg, EM_A_PS_PERFORMANCE, 207 - ps->performance, EM_A_PS_PAD)) 154 + if (nla_put_u64_64bit(msg, 155 + DEV_ENERGYMODEL_A_PERF_STATE_PERFORMANCE, 156 + ps->performance, 157 + DEV_ENERGYMODEL_A_PERF_STATE_PAD)) 208 158 goto out_cancel_ps_nest; 209 - if (nla_put_u64_64bit(msg, EM_A_PS_FREQUENCY, 210 - ps->frequency, EM_A_PS_PAD)) 159 + if (nla_put_u64_64bit(msg, 160 + DEV_ENERGYMODEL_A_PERF_STATE_FREQUENCY, 161 + ps->frequency, 162 + DEV_ENERGYMODEL_A_PERF_STATE_PAD)) 211 163 goto out_cancel_ps_nest; 212 - if (nla_put_u64_64bit(msg, EM_A_PS_POWER, 213 - ps->power, EM_A_PS_PAD)) 164 + if (nla_put_u64_64bit(msg, 165 + DEV_ENERGYMODEL_A_PERF_STATE_POWER, 166 + ps->power, 167 + DEV_ENERGYMODEL_A_PERF_STATE_PAD)) 214 168 goto out_cancel_ps_nest; 215 - if (nla_put_u64_64bit(msg, EM_A_PS_COST, 216 - ps->cost, EM_A_PS_PAD)) 169 + if (nla_put_u64_64bit(msg, 170 + DEV_ENERGYMODEL_A_PERF_STATE_COST, 171 + ps->cost, 172 + DEV_ENERGYMODEL_A_PERF_STATE_PAD)) 217 173 goto out_cancel_ps_nest; 218 - if (nla_put_u64_64bit(msg, EM_A_PS_FLAGS, 219 - ps->flags, EM_A_PS_PAD)) 174 + if (nla_put_u64_64bit(msg, 175 + DEV_ENERGYMODEL_A_PERF_STATE_FLAGS, 176 + ps->flags, 177 + DEV_ENERGYMODEL_A_PERF_STATE_PAD)) 220 178 goto out_cancel_ps_nest; 221 179 222 180 nla_nest_end(msg, entry); ··· 243 179 return -EMSGSIZE; 244 180 } 245 181 246 - int em_nl_get_pd_table_doit(struct sk_buff *skb, struct genl_info *info) 182 + int dev_energymodel_nl_get_perf_table_doit(struct sk_buff *skb, 183 + struct genl_info *info) 247 184 { 248 185 int cmd = info->genlhdr->cmd; 249 186 int msg_sz, ret = -EMSGSIZE; ··· 262 197 if (!msg) 263 198 return -ENOMEM; 264 199 265 - hdr = genlmsg_put_reply(msg, info, &em_nl_family, 0, cmd); 200 + hdr = genlmsg_put_reply(msg, info, &dev_energymodel_nl_family, 0, cmd); 266 201 if (!hdr) 267 202 goto out_free_msg; 268 203 ··· 286 221 int msg_sz, ret = -EMSGSIZE; 287 222 void *hdr; 288 223 289 - if (!genl_has_listeners(&em_nl_family, &init_net, EM_NLGRP_EVENT)) 224 + if (!genl_has_listeners(&dev_energymodel_nl_family, &init_net, DEV_ENERGYMODEL_NLGRP_EVENT)) 290 225 return; 291 226 292 227 msg_sz = __em_nl_get_pd_table_size(pd); ··· 295 230 if (!msg) 296 231 return; 297 232 298 - hdr = genlmsg_put(msg, 0, 0, &em_nl_family, 0, ntf_type); 233 + hdr = genlmsg_put(msg, 0, 0, &dev_energymodel_nl_family, 0, ntf_type); 299 234 if (!hdr) 300 235 goto out_free_msg; 301 236 ··· 305 240 306 241 genlmsg_end(msg, hdr); 307 242 308 - genlmsg_multicast(&em_nl_family, msg, 0, EM_NLGRP_EVENT, GFP_KERNEL); 243 + genlmsg_multicast(&dev_energymodel_nl_family, msg, 0, 244 + DEV_ENERGYMODEL_NLGRP_EVENT, GFP_KERNEL); 309 245 310 246 return; 311 247 312 248 out_free_msg: 313 249 nlmsg_free(msg); 314 - return; 315 250 } 316 251 317 252 void em_notify_pd_created(const struct em_perf_domain *pd) 318 253 { 319 - __em_notify_pd_table(pd, EM_CMD_PD_CREATED); 254 + __em_notify_pd_table(pd, DEV_ENERGYMODEL_CMD_PERF_DOMAIN_CREATED); 320 255 } 321 256 322 257 void em_notify_pd_updated(const struct em_perf_domain *pd) 323 258 { 324 - __em_notify_pd_table(pd, EM_CMD_PD_UPDATED); 259 + __em_notify_pd_table(pd, DEV_ENERGYMODEL_CMD_PERF_DOMAIN_UPDATED); 325 260 } 326 261 327 262 static int __em_notify_pd_deleted_size(const struct em_perf_domain *pd) 328 263 { 329 - int id_sz = nla_total_size(sizeof(u32)); /* EM_A_PD_TABLE_PD_ID */ 264 + int id_sz = nla_total_size(sizeof(u32)); /* DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID */ 330 265 331 266 return nlmsg_total_size(genlmsg_msg_size(id_sz)); 332 267 } ··· 337 272 void *hdr; 338 273 int msg_sz; 339 274 340 - if (!genl_has_listeners(&em_nl_family, &init_net, EM_NLGRP_EVENT)) 275 + if (!genl_has_listeners(&dev_energymodel_nl_family, &init_net, 276 + DEV_ENERGYMODEL_NLGRP_EVENT)) 341 277 return; 342 278 343 279 msg_sz = __em_notify_pd_deleted_size(pd); ··· 347 281 if (!msg) 348 282 return; 349 283 350 - hdr = genlmsg_put(msg, 0, 0, &em_nl_family, 0, EM_CMD_PD_DELETED); 284 + hdr = genlmsg_put(msg, 0, 0, &dev_energymodel_nl_family, 0, 285 + DEV_ENERGYMODEL_CMD_PERF_DOMAIN_DELETED); 351 286 if (!hdr) 352 287 goto out_free_msg; 353 288 354 - if (nla_put_u32(msg, EM_A_PD_TABLE_PD_ID, pd->id)) { 289 + if (nla_put_u32(msg, DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID, 290 + pd->id)) 355 291 goto out_free_msg; 356 - } 357 292 358 293 genlmsg_end(msg, hdr); 359 294 360 - genlmsg_multicast(&em_nl_family, msg, 0, EM_NLGRP_EVENT, GFP_KERNEL); 295 + genlmsg_multicast(&dev_energymodel_nl_family, msg, 0, 296 + DEV_ENERGYMODEL_NLGRP_EVENT, GFP_KERNEL); 361 297 362 298 return; 363 299 364 300 out_free_msg: 365 301 nlmsg_free(msg); 366 - return; 367 302 } 368 303 369 304 /**************************** Initialization *********************************/ 370 305 static int __init em_netlink_init(void) 371 306 { 372 - return genl_register_family(&em_nl_family); 307 + return genl_register_family(&dev_energymodel_nl_family); 373 308 } 374 309 postcore_initcall(em_netlink_init);
+4 -2
kernel/power/energy_model.c
··· 449 449 INIT_LIST_HEAD(&pd->node); 450 450 451 451 id = ida_alloc(&em_pd_ida, GFP_KERNEL); 452 - if (id < 0) 453 - return -ENOMEM; 452 + if (id < 0) { 453 + kfree(pd); 454 + return id; 455 + } 454 456 pd->id = id; 455 457 456 458 em_table = em_table_alloc(pd);