Re: [PATCH 2/2] perf: Userspace software event and ioctl
From: Pawel Moll <hidden>
Date: 2014-09-25 17:20:59
Also in:
lkml
On Wed, 2014-09-24 at 08:49 +0100, Ingo Molnar wrote:
* Pawel Moll [off-list ref] wrote:quoted
On Thu, 2014-09-18 at 15:34 +0100, Pawel Moll wrote:quoted
This patch adds a PERF_COUNT_SW_USERSPACE_EVENT type, which can be generated by user with PERF_EVENT_IOC_ENTRY ioctl command, which injects an event of said type into the perf buffer.It occurred to me last night that currently perf doesn't handle "write" syscall at all, while this seems like the most natural way of "injecting" userspace events into perf buffer. An ioctl would still be needed to set a type of the following events, something like: ioctl(SET_TYPE, 0x42); write(perf_fd, binaryblob, size); ioctl(SET_TYPE, 0); dprintf(perf_fd, "String"); which is fine for use cases when the type doesn't change often, but would double the amount of syscalls when every single event is of a different type. Perhaps there still should be a "generating ioctl" taking both type and data/size in one go?Absolutely, there should be a single syscall.
Yeah, it's my gut feeling as well. I just wonder if we still want to keep write() handler for operations on perf fds? This seems natural - takes data buffer and its size. The only issue is the type.
I'd even argue it should be a new prctl(): that way we could both generate user events for specific perf fds, but also into any currently active context (that allows just generation/injection of user events). In the latter case we might have no fd to work off from.
When Arnaldo suggested that the "user events" could be used by perf trace, it was exactly my first thought. I just didn't have answer how to present it to the user (an extra syscall didn't seem like a good idea), but prctl seems interesting, something like this? prctl(PR_TRACE_UEVENT, type, size, data, 0); How would we select tasks that can write to a given buffer? Maybe an ioctl() on a perf fd? Something like this? ioctl(perf_fd, PERF_EVENT_IOC_ENABLE_UEVENT, pid); ioctl(perf_fd, PERF_EVENT_IOC_DISABLE_UEVENT, pid); It could set/clear a flag in pid's task_struct (but probably not in the "normal" flags, as they are only supposed to be set by owner and in ptrace/fork case) and a pointer to the task in perf_event(_context). Or maybe some variation on ptrace would be more in place? This would also solve issue of permission checking (if the profiling tool can ptrace the process, it can also enable/disable its uevent generation capability). Paweł Or maybe it should go through ptrace?