linux/tools/testing/selftests/powerpc/pmu/ebb/ebb_on_willing_child_test.c
<<
>>
Prefs
   1/*
   2 * Copyright 2014, Michael Ellerman, IBM Corp.
   3 * Licensed under GPLv2.
   4 */
   5
   6#include <signal.h>
   7#include <stdio.h>
   8#include <stdlib.h>
   9#include <stdbool.h>
  10#include <sys/types.h>
  11#include <sys/wait.h>
  12#include <unistd.h>
  13
  14#include "ebb.h"
  15
  16
  17/*
  18 * Tests we can setup an EBB on our child. The child expects this and enables
  19 * EBBs, which are then delivered to the child, even though the event is
  20 * created by the parent.
  21 */
  22
  23static int victim_child(union pipe read_pipe, union pipe write_pipe)
  24{
  25        FAIL_IF(wait_for_parent(read_pipe));
  26
  27        /* Setup our EBB handler, before the EBB event is created */
  28        ebb_enable_pmc_counting(1);
  29        setup_ebb_handler(standard_ebb_callee);
  30        ebb_global_enable();
  31
  32        FAIL_IF(notify_parent(write_pipe));
  33
  34        while (ebb_state.stats.ebb_count < 20) {
  35                FAIL_IF(core_busy_loop());
  36        }
  37
  38        ebb_global_disable();
  39        ebb_freeze_pmcs();
  40
  41        count_pmc(1, sample_period);
  42
  43        dump_ebb_state();
  44
  45        FAIL_IF(ebb_state.stats.ebb_count == 0);
  46
  47        return 0;
  48}
  49
  50/* Tests we can setup an EBB on our child - if it's expecting it */
  51int ebb_on_willing_child(void)
  52{
  53        union pipe read_pipe, write_pipe;
  54        struct event event;
  55        pid_t pid;
  56
  57        SKIP_IF(!ebb_is_supported());
  58
  59        FAIL_IF(pipe(read_pipe.fds) == -1);
  60        FAIL_IF(pipe(write_pipe.fds) == -1);
  61
  62        pid = fork();
  63        if (pid == 0) {
  64                /* NB order of pipes looks reversed */
  65                exit(victim_child(write_pipe, read_pipe));
  66        }
  67
  68        /* Signal the child to setup its EBB handler */
  69        FAIL_IF(sync_with_child(read_pipe, write_pipe));
  70
  71        /* Child is running now */
  72
  73        event_init_named(&event, 0x1001e, "cycles");
  74        event_leader_ebb_init(&event);
  75
  76        event.attr.exclude_kernel = 1;
  77        event.attr.exclude_hv = 1;
  78        event.attr.exclude_idle = 1;
  79
  80        FAIL_IF(event_open_with_pid(&event, pid));
  81        FAIL_IF(ebb_event_enable(&event));
  82
  83        /* Child show now take EBBs and then exit */
  84        FAIL_IF(wait_for_child(pid));
  85
  86        event_close(&event);
  87
  88        return 0;
  89}
  90
  91int main(void)
  92{
  93        return test_harness(ebb_on_willing_child, "ebb_on_willing_child");
  94}
  95