kernel/power/em_netlink.c

Source file repositories/reference/linux-study-clean/kernel/power/em_netlink.c

File Facts

System
Linux kernel
Corpus path
kernel/power/em_netlink.c
Extension
.c
Size
8981 bytes
Lines
378
Domain
Core OS
Bucket
Scheduler, Processes, Timers, Sync, And Syscalls
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

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;
	int *tot_msg_sz = data;

	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 */
		 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;
}

static int __em_nl_get_pd(struct em_perf_domain *pd, void *data)
{
	struct sk_buff *msg = data;
	struct cpumask *cpumask;
	int cpu;

	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, DEV_ENERGYMODEL_A_PERF_DOMAIN_FLAGS,
			      pd->flags, DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD))
		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;
	}

	return 0;

out_cancel_nest:
	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;

	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]);

Annotation

Implementation Notes