File Index
Files and directories
Sign in
FILE

back_to_back_ebbs_test.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/powerpc/pmu/ebb/back_to_back_ebbs_test.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright 2014, Michael Ellerman, IBM Corp.
  4 */
  5
  6#include <stdbool.h>
  7#include <stdio.h>
  8#include <stdlib.h>
  9
 10#include "ebb.h"
 11
 12
 13#define NUMBER_OF_EBBS	50
 14
 15/*
 16 * Test that if we overflow the counter while in the EBB handler, we take
 17 * another EBB on exiting from the handler.
 18 *
 19 * We do this by counting with a stupidly low sample period, causing us to
 20 * overflow the PMU while we're still in the EBB handler, leading to another
 21 * EBB.
 22 *
 23 * We get out of what would otherwise be an infinite loop by leaving the
 24 * counter frozen once we've taken enough EBBs.
 25 */
 26
 27static void ebb_callee(void)
 28{
 29	uint64_t siar, val;
 30
 31	val = mfspr(SPRN_BESCR);
 32	if (!(val & BESCR_PMEO)) {
 33		ebb_state.stats.spurious++;
 34		goto out;
 35	}
 36
 37	ebb_state.stats.ebb_count++;
 38	trace_log_counter(ebb_state.trace, ebb_state.stats.ebb_count);
 39
 40	/* Resets the PMC */
 41	count_pmc(1, sample_period);
 42
 43out:
 44	if (ebb_state.stats.ebb_count == NUMBER_OF_EBBS)
 45		/* Reset but leave counters frozen */
 46		reset_ebb_with_clear_mask(MMCR0_PMAO);
 47	else
 48		/* Unfreezes */
 49		reset_ebb();
 50
 51	/* Do some stuff to chew some cycles and pop the counter */
 52	siar = mfspr(SPRN_SIAR);
 53	trace_log_reg(ebb_state.trace, SPRN_SIAR, siar);
 54
 55	val = mfspr(SPRN_PMC1);
 56	trace_log_reg(ebb_state.trace, SPRN_PMC1, val);
 57
 58	val = mfspr(SPRN_MMCR0);
 59	trace_log_reg(ebb_state.trace, SPRN_MMCR0, val);
 60}
 61
 62int back_to_back_ebbs(void)
 63{
 64	struct event event;
 65
 66	SKIP_IF(!ebb_is_supported());
 67
 68	event_init_named(&event, 0x1001e, "cycles");
 69	event_leader_ebb_init(&event);
 70
 71	event.attr.exclude_kernel = 1;
 72	event.attr.exclude_hv = 1;
 73	event.attr.exclude_idle = 1;
 74
 75	FAIL_IF(event_open(&event));
 76
 77	setup_ebb_handler(ebb_callee);
 78
 79	FAIL_IF(ebb_event_enable(&event));
 80
 81	sample_period = 5;
 82
 83	ebb_freeze_pmcs();
 84	mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
 85	ebb_global_enable();
 86	ebb_unfreeze_pmcs();
 87
 88	while (ebb_state.stats.ebb_count < NUMBER_OF_EBBS)
 89		FAIL_IF(core_busy_loop());
 90
 91	ebb_global_disable();
 92	ebb_freeze_pmcs();
 93
 94	dump_ebb_state();
 95
 96	event_close(&event);
 97
 98	FAIL_IF(ebb_state.stats.ebb_count != NUMBER_OF_EBBS);
 99
100	return 0;
101}
102
103int main(void)
104{
105	return test_harness(back_to_back_ebbs, "back_to_back_ebbs");
106}
~/ Read-only file preview.