All of lore.kernel.org
 help / color / mirror / Atom feed
From: Robert Richter <rric@kernel.org>
To: Borislav Petkov <bp@alien8.de>
Cc: LKML <linux-kernel@vger.kernel.org>,
	Peter Zijlstra <a.p.zijlstra@chello.nl>,
	Ingo Molnar <mingo@kernel.org>,
	Frederic Weisbecker <fweisbec@gmail.com>,
	Borislav Petkov <bp@suse.de>
Subject: Re: [RFC PATCH 2/3] perf: Add persistent event facilities
Date: Thu, 28 Mar 2013 19:15:16 +0100	[thread overview]
Message-ID: <20130328181516.GR11449@rric.localhost> (raw)
In-Reply-To: <1363352789-17991-3-git-send-email-bp@alien8.de>

Boris,

in general your approach looks good. Just a question and some comments
below.

On 15.03.13 14:06:28, Borislav Petkov wrote:
> Add a barebones implementation for registering persistent events with
> perf. For that, we don't destroy the buffers when they're unmapped;
> also, we map them read-only so that multiple agents can access them.
> 
> Also, we allocate the event buffers at event init time and not at mmap
> time so that we can log samples into them regardless of whether there
> are readers in userspace or not.

The mmap'ed region is already allocated by the kernel. How does a user
know the buffer size of the mmap'ed region?

Comments below of what I found so far.

Also, I wouldn't make too much use of -EINVAL, this should only be
used if the syscall contains *wrong* data.

-Robert

> +static struct perf_event *
> +add_persistent_event_on_cpu(unsigned int cpu, struct perf_event_attr *attr,
> +			    unsigned nr_pages)
> +{
> +	struct perf_event *event = ERR_PTR(-EINVAL);
> +	struct pers_event_desc *desc;
> +	struct ring_buffer *buf;
> +
> +	desc = kzalloc(sizeof(*desc), GFP_KERNEL);
> +	if (!desc)
> +		goto out;
> +
> +	event = perf_event_create_kernel_counter(attr, cpu, NULL, NULL, NULL);
> +	if (IS_ERR(event))
> +		goto err_event;
> +
> +	buf = rb_alloc(nr_pages, 0, cpu, 0);
> +	if (!buf)
> +		goto err_event_file;
> +
> +	rcu_assign_pointer(event->rb, buf);
> +
> +	desc->event = event;
> +	desc->attr  = attr;
> +
> +	INIT_LIST_HEAD(&desc->plist);
> +	list_add_tail(&desc->plist, &per_cpu(pers_events, cpu));
> +
> +	perf_event_enable(event);
> +
> +	goto out;
> +
> + err_event_file:
> +	perf_event_release_kernel(event);

event must be set to an error code here.

Better swap order of rb_alloc() and perf_event_create_kernel_
counter(). Makes things easier.

> +
> + err_event:
> +	kfree(desc);
> +
> + out:
> +	return event;
> +}
> +
> +static void rm_persistent_event(int cpu, struct perf_event_attr *attr)

Would rather prefer del_... as this is actually used for deleting
events in perf.

[...]

> +int perf_get_persistent_event_fd(unsigned cpu, struct perf_event_attr *attr)
> +{
> +	struct pers_event_desc *desc;
> +	struct file *event_file = NULL;
> +	int event_fd = -1;
> +
> +	list_for_each_entry(desc, &per_cpu(pers_events, cpu), plist) {
> +
> +		if (desc->attr->config != attr->config)
> +			continue;

Umm, the attr->config is not sufficient as a selector since it must be
unique which is not granted (of course it works for one event only).

> +
> +		event_fd = get_unused_fd();
> +		if (event_fd < 0)
> +			goto out;
> +
> +		event_file = anon_inode_getfile("[pers_event]", &perf_fops,
> +						desc->event, O_RDONLY);
> +		if (IS_ERR(event_file))
> +			goto err_event_file;
> +
> +		desc->fd = event_fd;
> +		fd_install(event_fd, event_file);
> +
> +		return event_fd;
> +	}
> +
> + err_event_file:
> +	put_unused_fd(event_fd);
> +
> +out:
> +	return event_fd;
> +}
> +
> +/*
> + * Create and enable the persistent version of the perf event described by
> + * @attr.
> + *
> + * @attr: perf event descriptor
> + * @nr_pages: size in pages
> + */
> +int perf_add_persistent_event(struct perf_event_attr *attr, unsigned nr_pages)
> +{
> +	struct perf_event *event;
> +	int i;
> +
> +	for_each_possible_cpu(i) {
> +		event = add_persistent_event_on_cpu(i, attr, nr_pages);
> +		if (IS_ERR(event)) {
> +			pr_err("%s: Error adding persistent event on cpu %d\n",
> +				__func__, i);
> +			goto unwind;
> +		}
> +	}
> +	return 0;
> +
> +unwind:
> +	while (--i >= 0)
> +		rm_persistent_event(i, attr);
> +
> +	return -EINVAL;

Should return the actual error.

> +}

  parent reply	other threads:[~2013-03-28 18:15 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-15 13:06 [RFC PATCH 0/3] Perf persistent events Borislav Petkov
2013-03-15 13:06 ` [RFC PATCH 1/3] perf: Add " Borislav Petkov
2013-04-06 15:53   ` Robert Richter
2013-04-07 10:31     ` Borislav Petkov
2013-03-15 13:06 ` [RFC PATCH 2/3] perf: Add persistent event facilities Borislav Petkov
2013-03-18  9:13   ` Namhyung Kim
2013-03-18 12:11     ` Borislav Petkov
2013-03-28 18:15   ` Robert Richter [this message]
2013-04-03 17:27     ` Borislav Petkov
2013-04-06 16:29       ` Robert Richter
2013-03-15 13:06 ` [RFC PATCH 3/3] MCE: Enable persistent event Borislav Petkov
2013-03-18  8:38 ` [RFC PATCH 0/3] Perf persistent events Namhyung Kim
2013-03-18  8:46   ` Ingo Molnar
2013-03-28 15:52     ` Robert Richter
2013-03-29 14:25       ` Borislav Petkov
2013-03-18  8:40 ` Ingo Molnar
2013-03-18 15:16   ` Borislav Petkov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130328181516.GR11449@rric.localhost \
    --to=rric@kernel.org \
    --cc=a.p.zijlstra@chello.nl \
    --cc=bp@alien8.de \
    --cc=bp@suse.de \
    --cc=fweisbec@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.