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/[email protected]/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
> 

Reply via email to