root/tools/testing/selftests/powerpc/pmu/ebb/pmae_handling_test.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. syscall_ebb_callee
  2. test_body
  3. pmae_handling
  4. main

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright 2014, Michael Ellerman, IBM Corp.
   4  */
   5 
   6 #include <sched.h>
   7 #include <signal.h>
   8 #include <stdbool.h>
   9 #include <stdio.h>
  10 #include <stdlib.h>
  11 
  12 #include "ebb.h"
  13 
  14 
  15 /*
  16  * Test that the kernel properly handles PMAE across context switches.
  17  *
  18  * We test this by calling into the kernel inside our EBB handler, where PMAE
  19  * is clear. A cpu eater companion thread is running on the same CPU as us to
  20  * encourage the scheduler to switch us.
  21  *
  22  * The kernel must make sure that when it context switches us back in, it
  23  * honours the fact that we had PMAE clear.
  24  *
  25  * Observed to hit the failing case on the first EBB with a broken kernel.
  26  */
  27 
  28 static bool mmcr0_mismatch;
  29 static uint64_t before, after;
  30 
  31 static void syscall_ebb_callee(void)
  32 {
  33         uint64_t val;
  34 
  35         val = mfspr(SPRN_BESCR);
  36         if (!(val & BESCR_PMEO)) {
  37                 ebb_state.stats.spurious++;
  38                 goto out;
  39         }
  40 
  41         ebb_state.stats.ebb_count++;
  42         count_pmc(1, sample_period);
  43 
  44         before = mfspr(SPRN_MMCR0);
  45 
  46         /* Try and get ourselves scheduled, to force a PMU context switch */
  47         sched_yield();
  48 
  49         after = mfspr(SPRN_MMCR0);
  50         if (before != after)
  51                 mmcr0_mismatch = true;
  52 
  53 out:
  54         reset_ebb();
  55 }
  56 
  57 static int test_body(void)
  58 {
  59         struct event event;
  60 
  61         SKIP_IF(!ebb_is_supported());
  62 
  63         event_init_named(&event, 0x1001e, "cycles");
  64         event_leader_ebb_init(&event);
  65 
  66         event.attr.exclude_kernel = 1;
  67         event.attr.exclude_hv = 1;
  68         event.attr.exclude_idle = 1;
  69 
  70         FAIL_IF(event_open(&event));
  71 
  72         setup_ebb_handler(syscall_ebb_callee);
  73         ebb_global_enable();
  74 
  75         FAIL_IF(ebb_event_enable(&event));
  76 
  77         mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
  78 
  79         while (ebb_state.stats.ebb_count < 20 && !mmcr0_mismatch)
  80                 FAIL_IF(core_busy_loop());
  81 
  82         ebb_global_disable();
  83         ebb_freeze_pmcs();
  84 
  85         count_pmc(1, sample_period);
  86 
  87         dump_ebb_state();
  88 
  89         if (mmcr0_mismatch)
  90                 printf("Saw MMCR0 before 0x%lx after 0x%lx\n", before, after);
  91 
  92         event_close(&event);
  93 
  94         FAIL_IF(ebb_state.stats.ebb_count == 0);
  95         FAIL_IF(mmcr0_mismatch);
  96 
  97         return 0;
  98 }
  99 
 100 int pmae_handling(void)
 101 {
 102         return eat_cpu(test_body);
 103 }
 104 
 105 int main(void)
 106 {
 107         return test_harness(pmae_handling, "pmae_handling");
 108 }

/* [<][>][^][v][top][bottom][index][help] */