linux/tools/testing/selftests/powerpc/pmu/ebb/ebb_on_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. Nothing interesting happens, because
  19 * even though the event is enabled and running the child hasn't enabled the
  20 * actual delivery of the EBBs.
  21 */
  22
  23static int victim_child(union pipe read_pipe, union pipe write_pipe)
  24{
  25        int i;
  26
  27        FAIL_IF(wait_for_parent(read_pipe));
  28        FAIL_IF(notify_parent(write_pipe));
  29
  30        /* Parent creates EBB event */
  31
  32        FAIL_IF(wait_for_parent(read_pipe));
  33        FAIL_IF(notify_parent(write_pipe));
  34
  35        /* Check the EBB is enabled by writing PMC1 */
  36        write_pmc1();
  37
  38        /* EBB event is enabled here */
  39        for (i = 0; i < 1000000; i++) ;
  40
  41        return 0;
  42}
  43
  44int ebb_on_child(void)
  45{
  46        union pipe read_pipe, write_pipe;
  47        struct event event;
  48        pid_t pid;
  49
  50        SKIP_IF(!ebb_is_supported());
  51
  52        FAIL_IF(pipe(read_pipe.fds) == -1);
  53        FAIL_IF(pipe(write_pipe.fds) == -1);
  54
  55        pid = fork();
  56        if (pid == 0) {
  57                /* NB order of pipes looks reversed */
  58                exit(victim_child(write_pipe, read_pipe));
  59        }
  60
  61        FAIL_IF(sync_with_child(read_pipe, write_pipe));
  62
  63        /* Child is running now */
  64
  65        event_init_named(&event, 0x1001e, "cycles");
  66        event_leader_ebb_init(&event);
  67
  68        event.attr.exclude_kernel = 1;
  69        event.attr.exclude_hv = 1;
  70        event.attr.exclude_idle = 1;
  71
  72        FAIL_IF(event_open_with_pid(&event, pid));
  73        FAIL_IF(ebb_event_enable(&event));
  74
  75        FAIL_IF(sync_with_child(read_pipe, write_pipe));
  76
  77        /* Child should just exit happily */
  78        FAIL_IF(wait_for_child(pid));
  79
  80        event_close(&event);
  81
  82        return 0;
  83}
  84
  85int main(void)
  86{
  87        return test_harness(ebb_on_child, "ebb_on_child");
  88}
  89