linux/tools/testing/selftests/powerpc/pmu/ebb/ebb_on_willing_child_test.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright 2014, Michael Ellerman, IBM Corp.
   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        dump_ebb_state();
  42
  43        FAIL_IF(ebb_state.stats.ebb_count == 0);
  44
  45        return 0;
  46}
  47
  48/* Tests we can setup an EBB on our child - if it's expecting it */
  49int ebb_on_willing_child(void)
  50{
  51        union pipe read_pipe, write_pipe;
  52        struct event event;
  53        pid_t pid;
  54
  55        SKIP_IF(!ebb_is_supported());
  56
  57        FAIL_IF(pipe(read_pipe.fds) == -1);
  58        FAIL_IF(pipe(write_pipe.fds) == -1);
  59
  60        pid = fork();
  61        if (pid == 0) {
  62                /* NB order of pipes looks reversed */
  63                exit(victim_child(write_pipe, read_pipe));
  64        }
  65
  66        /* Signal the child to setup its EBB handler */
  67        FAIL_IF(sync_with_child(read_pipe, write_pipe));
  68
  69        /* Child is running now */
  70
  71        event_init_named(&event, 0x1001e, "cycles");
  72        event_leader_ebb_init(&event);
  73
  74        event.attr.exclude_kernel = 1;
  75        event.attr.exclude_hv = 1;
  76        event.attr.exclude_idle = 1;
  77
  78        FAIL_IF(event_open_with_pid(&event, pid));
  79        FAIL_IF(ebb_event_enable(&event));
  80
  81        /* Child show now take EBBs and then exit */
  82        FAIL_IF(wait_for_child(pid));
  83
  84        event_close(&event);
  85
  86        return 0;
  87}
  88
  89int main(void)
  90{
  91        return test_harness(ebb_on_willing_child, "ebb_on_willing_child");
  92}
  93