mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-18 03:23:53 -04:00
PM: EM: Implement em_nl_get_pds_doit()
When a userspace requests EM_CMD_GET_PDS, the kernel responds with
information on all performance domains. The message format of the
response is as follows:
EM_A_PDS_PD (NLA_NESTED)*
EM_A_PD_PD_ID (NLA_U32)
EM_A_PD_FLAGS (NLA_U64)
EM_A_PD_CPUS (NLA_STRING)
where EM_A_PDS_PD can be repeated as many times as there are performance
domains, and EM_A_PD_CPUS is a hexadecimal string representing a CPU
bitmask.
Signed-off-by: Changwoo Min <changwoo@igalia.com>
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
Link: https://patch.msgid.link/20251020220914.320832-7-changwoo@igalia.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
committed by
Rafael J. Wysocki
parent
7928339cfe
commit
d8eef04531
@@ -17,9 +17,89 @@
|
||||
#include "em_netlink.h"
|
||||
#include "em_netlink_autogen.h"
|
||||
|
||||
#define EM_A_PD_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];
|
||||
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 */
|
||||
|
||||
*tot_msg_sz += nlmsg_total_size(genlmsg_msg_size(msg_sz));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __em_nl_get_pd(struct em_perf_domain *pd, void *data)
|
||||
{
|
||||
char cpus_buf[EM_A_PD_CPUS_LEN];
|
||||
struct sk_buff *msg = data;
|
||||
struct nlattr *entry;
|
||||
|
||||
entry = nla_nest_start(msg, EM_A_PDS_PD);
|
||||
if (!entry)
|
||||
goto out_cancel_nest;
|
||||
|
||||
if (nla_put_u32(msg, EM_A_PD_PD_ID, pd->id))
|
||||
goto out_cancel_nest;
|
||||
|
||||
if (nla_put_u64_64bit(msg, EM_A_PD_FLAGS, pd->flags, EM_A_PD_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))
|
||||
goto out_cancel_nest;
|
||||
|
||||
nla_nest_end(msg, entry);
|
||||
|
||||
return 0;
|
||||
|
||||
out_cancel_nest:
|
||||
nla_nest_cancel(msg, entry);
|
||||
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
int em_nl_get_pds_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
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);
|
||||
|
||||
msg = genlmsg_new(msg_sz, GFP_KERNEL);
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
hdr = genlmsg_put_reply(msg, info, &em_nl_family, 0, cmd);
|
||||
if (!hdr)
|
||||
goto out_free_msg;
|
||||
|
||||
ret = for_each_em_perf_domain(__em_nl_get_pd, msg);
|
||||
if (ret)
|
||||
goto out_cancel_msg;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
||||
return genlmsg_reply(msg, info);
|
||||
|
||||
out_cancel_msg:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
out_free_msg:
|
||||
nlmsg_free(msg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int em_nl_get_pd_table_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
|
||||
Reference in New Issue
Block a user