LIBPAF-EBB(2)

NAME
libpaf-ebb - The Power Architecture Facilities Event-Based Branch Library

SYNOPSIS
#include <paf/ebb.h>

typedef void (*ebbhandler_t)(void*);

int paf_ebb_pmu_init(uint64_t raw_event, int group);

int paf_ebb_pmu_init_ex(uint64_t raw_event, int group, pid_t pid, unsigned int " flags");

void paf_ebb_pmu_set_period(uint32_t sample_period);

void paf_ebb_pmu_reset(void);

ebbhandler_t paf_ebb_register_handler(ebbhandler_t handler, void * context, paf_ebb_callback_type_t type, int flags);

ebbhandler_t paf_ebb_handler(void);

int paf_ebb_enable_branches(void);

int paf_ebb_disable_branches(void);

void paf_ebb_enable_branches_fast(void);

void paf_ebb_disable_branches_fast(void);

int paf_ebb_event_close (int fd);

Compile and link with -lpaf-ebb.

DESCRIPTION
The Power Architecture® Facilities Event-Based Branch Library (libpaf-ebb) is a part of the Power Architecture Facilities Library (PAFLib) The Event-Based Branch Library provides an easy-to-use framework for using the Power Architecture Event-Based Branch facility (EBB). If enabled, the EBB facility generates an event-based exception when a user-specified event occurs, which causes the hardware to branch directly to a user-space address (EBB handler). The facility does not require any kernel handling besides initialization. Only Performance Monitor Unit (PMU) events are supported. The Event-Based Branch Library framework registers a proxy-handler with the hardware, on behalf of a user program, so that the program doesn't need to directly control the Power Architecture EBB facility (which would require assembly language instructions and an understanding of the EBB ELF ABI). The EBB Library proxy-handler will properly stack an ELF ABI EBB exception frame on the user-stack, preserve the current register context in that stack frame, and then pass control to a user registered (thread specific) handler. When the user-space handler has completed its task and returned control to the EBB Library proxy-handler, the proxy-handler will perform the tasks necessary to restore the register context, pop the EBB exception frame, and return control to the code that was interrupted by the event-based exception. paf_ebb_pmu_init() initializes the PMU event generation configuring the hardware counter raw_event with the specified group. The first call should use -1 to start a new group. Subsequent calls may create new groups or use the returned file descriptor from paf_ebb_pmu_init to associate events in a group. The file descriptor returned should be closed when done to prevent resource leak. The event-based exception is triggered when the PMU counter overflows. To set the PMC to an initial value different from default (0) use paf_ebb_pmu_set_period To reset it to potentially trigger another event call paf_ebb_pmu_reset(). paf_ebb_pmu_init_ex() initializes the PMU event generation configuring the hardware counter raw_event with the specified group , pid , cpu and flags. The first call should use -1 to start a new group. Subsequent calls may create new groups or use the returned file descriptor from paf_ebb_pmu_init to associate events in a group. The pid and cpu arguments allow specifying which process and CPU to monitor:

pid == 0 and cpu == -1
    This measures the calling process/thread on any CPU.

pid == 0 and cpu >= 0
    This measures the calling process/thread only when running on the specified CPU.

pid > 0 and cpu == -1
    This measures the specified process/thread on any CPU.

pid > 0 and cpu >= 0
    This measures the specified process/thread only when running on the specified CPU.

pid == -1 and cpu >= 0
    This measures all processes/threads on the specified CPU. This requires CAP_SYS_ADMIN capability or a /proc/sys/kernel/perf_event_paranoid value of less than 1.

pid == -1 and cpu == -1
    This setting is invalid and will return an error.

The flags argument is passed directly to perf_event_open syscall. paf_ebb_register_handler() registers the user handler (ebbhandler_t) function to be called when the EBB is triggered with the argument context. Common state registers (LR, CR, CTR, XER) are always saved and type specifies which further set of registers will be saved and restored:

PPCEBB_CALLBACK_GPR_SAVE:
    save/restore all General Purpose Registers.

PPCEBB_CALLBACK_FPR_SAVE:
    save/restore all General Purpose Registers and all Floating-Point Register.

PPCEBB_CALLBACK_VR_SAVE:
    save/restore all General Purpose Registers, all Floating-Point Register, and all Vector Registers (VMX).

PPCEBB_CALLBACK_VSR_SAVE:
    save/restore all General Purpose Registers, all Floating-Point Register, all Vector Registers (VMX), and all Vector Scalar Registers (VSX).

The current support flags is either 0 or a multibyte mask of bits with one or more of the following options:

•   PAF_EBB_FLAGS_RESET_PMU after the callback activation the EBB machanism will be reset, similiar to a call to paf_ebb_pmu_reset

paf_ebb_handler() returns the registered handler previously issued by paf_ebb_register_handler(). The paf_ebb_enable_branches() and paf_ebb_disable_branches() enable/disable EBB triggering and add required memory synchonizations. They also check if EBB is available. The fast versions paf_ebb_enable_branches_fast() and paf_ebb_disable_branches_fast() aso enable/disable the EBB branches, however they do not check if EBB is available on the system, neither add memory synchonization after the mtspr call. paf_ebb_event_close() closes PMU event.

RETURN VALUE
paf_ebb_pmu_init() returns a file descriptor to be used in group association or -1 case of error. paf_ebb_pmu_init_ex() returns a file descriptor to be used in group association or -1 case of error. paf_ebb_register_handler() returns the registered handler or EBB_REG_ERR on error. On error errno is set appropriately. paf_ebb_handler() returns the previous registered handler or EBB_REG_ERR if no handler has been registered. On error errno is set appropriately. paf_ebb_enable_branches() and paf_ebb_disable_branches() return 0 in case of success or -1 otherwise. On error errno is set appropriately. paf_ebb_event_close() return 0 in case of success or -1 otherwise.

ERRORS

ENOSYS
    system does not support EBB facility.

VERSIONS
The EBB facility is part of Power ISA [category: Server] first appearing in Power ISA 2.07. Linux support for the EBB facility first appeared in Linux kernel version 3.10. Support for the ELF EBB ABI first appeared in glibc version 2.18 though the ABI is not runtime incompatible with backporting to earlier glibc versions.

EXAMPLE
The following example show how to setup a simple EBB handler to update a global counter.

#include <stdio.h>
#include <paf/ebb.h>
#include <unistd.h>
#define PM_RUN_INST_CMPL  0x400FA
/* Set it volatile to force memory read in loop below.  */
static volatile int ebb_handler_triggered = 0;
static void ebb_handler(void *context)
{
  int *trigger = (int*) (context);
  *trigger += 1;
}
void do_work (void)
{
  while (1)
    {
      if (ebb_handler_triggered == 1000)
        break;
    }
}
int do_ebb(void)
{
  ebbhandler_t handler;
  ebb_handler_triggered = 0;
  int ebb_fd;
  ebb_fd = paf_ebb_pmu_init (PM_RUN_INST_CMPL, -1);
  paf_ebb_pmu_set_period (500000);
  handler = paf_ebb_register_handler (ebb_handler,
                                      (void*)&ebb_handler_triggered,
                                      PAF_EBB_CALLBACK_GPR_SAVE,
                                      PAF_EBB_FLAGS_RESET_PMU);
  paf_ebb_pmu_reset ();
  paf_ebb_enable_branches ();
  do_work ();
  paf_ebb_disable_branches ();
  printf ("Done; %d EBB interrupts handled\n", ebb_handler_triggered);
  close (ebb_fd);
  return 0;
}
int main (int argc, char *argv[])
{
  return do_ebb ();
}

SEE ALSO
libpaf-dsc(3)

REFERENCES

Power ISA™ Version 2.07

REPORTING BUGS

Email bug reports to Adhemerval Zanella <azanella@linux.vnet.ibm.com>.

AUTHORS
This manual page was written by Adhemerval Zanella <azanella@linux.vnet.ibm.com> and Ryan S. Arnold.