Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright 2014, Michael Ellerman, IBM Corp.
0004  */
0005 
0006 #include <stdbool.h>
0007 #include <stdio.h>
0008 #include <stdlib.h>
0009 
0010 #include "ebb.h"
0011 
0012 
0013 #define NUMBER_OF_EBBS  50
0014 
0015 /*
0016  * Test that if we overflow the counter while in the EBB handler, we take
0017  * another EBB on exiting from the handler.
0018  *
0019  * We do this by counting with a stupidly low sample period, causing us to
0020  * overflow the PMU while we're still in the EBB handler, leading to another
0021  * EBB.
0022  *
0023  * We get out of what would otherwise be an infinite loop by leaving the
0024  * counter frozen once we've taken enough EBBs.
0025  */
0026 
0027 static void ebb_callee(void)
0028 {
0029     uint64_t siar, val;
0030 
0031     val = mfspr(SPRN_BESCR);
0032     if (!(val & BESCR_PMEO)) {
0033         ebb_state.stats.spurious++;
0034         goto out;
0035     }
0036 
0037     ebb_state.stats.ebb_count++;
0038     trace_log_counter(ebb_state.trace, ebb_state.stats.ebb_count);
0039 
0040     /* Resets the PMC */
0041     count_pmc(1, sample_period);
0042 
0043 out:
0044     if (ebb_state.stats.ebb_count == NUMBER_OF_EBBS)
0045         /* Reset but leave counters frozen */
0046         reset_ebb_with_clear_mask(MMCR0_PMAO);
0047     else
0048         /* Unfreezes */
0049         reset_ebb();
0050 
0051     /* Do some stuff to chew some cycles and pop the counter */
0052     siar = mfspr(SPRN_SIAR);
0053     trace_log_reg(ebb_state.trace, SPRN_SIAR, siar);
0054 
0055     val = mfspr(SPRN_PMC1);
0056     trace_log_reg(ebb_state.trace, SPRN_PMC1, val);
0057 
0058     val = mfspr(SPRN_MMCR0);
0059     trace_log_reg(ebb_state.trace, SPRN_MMCR0, val);
0060 }
0061 
0062 int back_to_back_ebbs(void)
0063 {
0064     struct event event;
0065 
0066     SKIP_IF(!ebb_is_supported());
0067 
0068     event_init_named(&event, 0x1001e, "cycles");
0069     event_leader_ebb_init(&event);
0070 
0071     event.attr.exclude_kernel = 1;
0072     event.attr.exclude_hv = 1;
0073     event.attr.exclude_idle = 1;
0074 
0075     FAIL_IF(event_open(&event));
0076 
0077     setup_ebb_handler(ebb_callee);
0078 
0079     FAIL_IF(ebb_event_enable(&event));
0080 
0081     sample_period = 5;
0082 
0083     ebb_freeze_pmcs();
0084     mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
0085     ebb_global_enable();
0086     ebb_unfreeze_pmcs();
0087 
0088     while (ebb_state.stats.ebb_count < NUMBER_OF_EBBS)
0089         FAIL_IF(core_busy_loop());
0090 
0091     ebb_global_disable();
0092     ebb_freeze_pmcs();
0093 
0094     dump_ebb_state();
0095 
0096     event_close(&event);
0097 
0098     FAIL_IF(ebb_state.stats.ebb_count != NUMBER_OF_EBBS);
0099 
0100     return 0;
0101 }
0102 
0103 int main(void)
0104 {
0105     return test_harness(back_to_back_ebbs, "back_to_back_ebbs");
0106 }