Messages in this thread | | | Date | Tue, 27 Jun 2017 14:34:04 +0530 | From | "Naveen N. Rao" <> | Subject | Re: [PATCH 0/2] Notifications for perf sideband events |
| |
On 2017/06/19 08:01PM, Naveen N. Rao wrote: > Currently, there is no way to ask for signals to be delivered when a > certain number of sideband events have been logged into the ring buffer. > This is problematic if we are only interested in, say, context switch > events. Furthermore, signals are more useful (rather than polling) for > self-profiling. This series provides for a way to achieve this. > > We ride on top of the existing support for ring buffer wakeup to > generate signals as desired. Counting sideband events still requires > some changes in the output path, but in normal cases, it ends up being > just a comparison. > > for > context switch events and how it can control notification through > signals. The key changes include the below perf_event_attr settings as > well as use of IOC_ENABLE: > pe.signal_on_wakeup = 1; > pe.count_sb_events = 1; > pe.wakeup_events = 2; > > To keep things simple, PERF_EVENT_IOC_REFRESH cannot be used if any of > the new attributes are set. > > RFC v2: > https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1420363.html > Changes: > - Send HUP on perf_event_exit_event() (suggested by Jiri) > - Disable use of IOC_REFRESH if signal_on_wakeup/count_sb_events is > set.
Peter, Arnaldo, Jiri, Can you please take a look at this patchset?
Thanks, Naveen
> > > - Naveen > > --- > Here is a sample program demonstrating the same: > > #define _GNU_SOURCE > > #include <stdlib.h> > #include <stdio.h> > #include <unistd.h> > #include <fcntl.h> > #include <string.h> > #include <signal.h> > #include <sys/ioctl.h> > #include <sys/mman.h> > #include <linux/perf_event.h> > #include <asm/unistd.h> > > static long > perf_event_open(struct perf_event_attr *hw_event, pid_t pid, > int cpu, int group_fd, unsigned long flags) > { > return syscall(__NR_perf_event_open, hw_event, pid, cpu, > group_fd, flags); > } > > static void sigio_handler(int n, siginfo_t *info, void *uc) > { > fprintf (stderr, "Caught %s\n", info->si_code == POLL_HUP ? "POLL_HUP" : > (info->si_code == POLL_IN ? "POLL_IN" : "other signal")); > } > > int main(int argc, char **argv) > { > struct perf_event_attr pe; > struct sigaction act; > int fd; > void *buf; > > memset(&act, 0, sizeof(act)); > act.sa_sigaction = sigio_handler; > act.sa_flags = SA_SIGINFO; > sigaction(SIGIO, &act, 0); > > memset(&pe, 0, sizeof(struct perf_event_attr)); > pe.size = sizeof(struct perf_event_attr); > pe.type = PERF_TYPE_SOFTWARE; > pe.config = PERF_COUNT_SW_DUMMY; > pe.disabled = 1; > pe.sample_period = 1; > pe.context_switch = 1; > pe.signal_on_wakeup = 1; > pe.count_sb_events = 1; > pe.wakeup_events = 2; > > fd = perf_event_open(&pe, 0, -1, -1, 0); > if (fd == -1) { > fprintf(stderr, "Error opening leader %lx\n", (unsigned long)pe.config); > exit(EXIT_FAILURE); > } > > buf = mmap(NULL, sysconf(_SC_PAGESIZE) * 2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); > if (buf == MAP_FAILED) { > fprintf(stderr, "Can't mmap buffer\n"); > return -1; > } > > if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_ASYNC) == -1) > return -2; > > if (fcntl(fd, F_SETSIG, SIGIO) == -1) > return -3; > > if (fcntl(fd, F_SETOWN, getpid()) == -1) > return -4; > > if (ioctl(fd, PERF_EVENT_IOC_ENABLE, 0) == -1) > return -5; > > fprintf (stderr, "Sleep 1\n"); > sleep(1); > fprintf (stderr, "Sleep 2\n"); > sleep(1); > fprintf (stderr, "Sleep 3\n"); > sleep(1); > > /* Disable the event counter */ > ioctl(fd, PERF_EVENT_IOC_DISABLE, 1); > > close(fd); > > return 0; > } > > > A sample output: > $ time ./cs > Sleep 1 > Caught POLL_IN > Sleep 2 > Caught POLL_IN > Sleep 3 > Caught POLL_IN > > real 0m3.040s > user 0m0.001s > sys 0m0.003s > > > Naveen N. Rao (2): > kernel/events: Add option to notify through signals on wakeup > kernel/events: Add option to enable counting sideband events in > wakeup_events > > include/uapi/linux/perf_event.h | 4 +++- > kernel/events/core.c | 20 ++++++++++++-------- > kernel/events/ring_buffer.c | 16 ++++++++++++++++ > 3 files changed, 31 insertions(+), 9 deletions(-) > > -- > 2.13.1 >
| |