Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd53d337 authored by Rohit Gupta's avatar Rohit Gupta
Browse files

PM / devfreq: Fix perf event initialization to avoid memory leaks



Currently stop_hwmon only releases the perf events for each CPU
in the memlat device group. This leaves out the perf_event_attrs
that are not needed anymore leading to memory leaks.
This patch frees perf_event_attrs right after the perf events are
created because they are copied into the perf_event structure
when it is created for a particular event and hence do not need
to exist beyond that point.

Change-Id: If0871739ef477dfbcbbfc6ab2a631ce25deaf71c
Signed-off-by: default avatarRohit Gupta <rohgup@codeaurora.org>
parent 386d4f46
Loading
Loading
Loading
Loading
+16 −9
Original line number Diff line number Diff line
@@ -169,53 +169,60 @@ static void stop_hwmon(struct memlat_hwmon *hw)

}

struct perf_event *create_event(int cpu, unsigned long event)
static struct perf_event_attr *alloc_attr(void)
{
	struct perf_event *pevent;
	struct perf_event_attr *attr;

	attr = kzalloc(sizeof(struct perf_event_attr), GFP_KERNEL);
	if (!attr)
		return ERR_PTR(-ENOMEM);

	attr->config = event;
	attr->type = PERF_TYPE_RAW;
	attr->size = sizeof(struct perf_event_attr);
	attr->pinned = 1;
	attr->exclude_idle = 1;

	pevent = perf_event_create_kernel_counter(attr, cpu, NULL, NULL, NULL);

	return pevent;
	return attr;
}

static int set_events(struct memlat_hwmon_data *hw_data, int cpu)
{
	struct perf_event *pevent;
	struct perf_event_attr *attr;
	int err;

	pevent = create_event(cpu, INST_EV);
	/* Allocate an attribute for event initialization */
	attr = alloc_attr();
	if (IS_ERR(attr))
		return PTR_ERR(attr);

	attr->config = INST_EV;
	pevent = perf_event_create_kernel_counter(attr, cpu, NULL, NULL, NULL);
	if (IS_ERR(pevent))
		goto err_out;
	hw_data->events[INST_IDX].pevent = pevent;
	perf_event_enable(hw_data->events[INST_IDX].pevent);

	pevent = create_event(cpu, L2DM_EV);
	attr->config = L2DM_EV;
	pevent = perf_event_create_kernel_counter(attr, cpu, NULL, NULL, NULL);
	if (IS_ERR(pevent))
		goto err_out;
	hw_data->events[L2DM_IDX].pevent = pevent;
	perf_event_enable(hw_data->events[L2DM_IDX].pevent);

	pevent = create_event(cpu, CYC_EV);
	attr->config = CYC_EV;
	pevent = perf_event_create_kernel_counter(attr, cpu, NULL, NULL, NULL);
	if (IS_ERR(pevent))
		goto err_out;
	hw_data->events[CYC_IDX].pevent = pevent;
	perf_event_enable(hw_data->events[CYC_IDX].pevent);

	kfree(attr);
	return 0;

err_out:
	err = PTR_ERR(pevent);
	kfree(attr);
	return err;
}