cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dlfilter-show-cycles.c (2936B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * dlfilter-show-cycles.c: Print the number of cycles at the start of each line
      4 * Copyright (c) 2021, Intel Corporation.
      5 */
      6#include <perf/perf_dlfilter.h>
      7#include <string.h>
      8#include <stdio.h>
      9
     10#define MAX_CPU 4096
     11
     12enum {
     13	INSTR_CYC,
     14	BRNCH_CYC,
     15	OTHER_CYC,
     16	MAX_ENTRY
     17};
     18
     19static __u64 cycles[MAX_CPU][MAX_ENTRY];
     20static __u64 cycles_rpt[MAX_CPU][MAX_ENTRY];
     21
     22#define BITS		16
     23#define TABLESZ		(1 << BITS)
     24#define TABLEMAX	(TABLESZ / 2)
     25#define MASK		(TABLESZ - 1)
     26
     27static struct entry {
     28	__u32 used;
     29	__s32 tid;
     30	__u64 cycles[MAX_ENTRY];
     31	__u64 cycles_rpt[MAX_ENTRY];
     32} table[TABLESZ];
     33
     34static int tid_cnt;
     35
     36static int event_entry(const char *event)
     37{
     38	if (!event)
     39		return OTHER_CYC;
     40	if (!strncmp(event, "instructions", 12))
     41		return INSTR_CYC;
     42	if (!strncmp(event, "branches", 8))
     43		return BRNCH_CYC;
     44	return OTHER_CYC;
     45}
     46
     47static struct entry *find_entry(__s32 tid)
     48{
     49	__u32 pos = tid & MASK;
     50	struct entry *e;
     51
     52	e = &table[pos];
     53	while (e->used) {
     54		if (e->tid == tid)
     55			return e;
     56		if (++pos == TABLESZ)
     57			pos = 0;
     58		e = &table[pos];
     59	}
     60
     61	if (tid_cnt >= TABLEMAX) {
     62		fprintf(stderr, "Too many threads\n");
     63		return NULL;
     64	}
     65
     66	tid_cnt += 1;
     67	e->used = 1;
     68	e->tid = tid;
     69	return e;
     70}
     71
     72static void add_entry(__s32 tid, int pos, __u64 cnt)
     73{
     74	struct entry *e = find_entry(tid);
     75
     76	if (e)
     77		e->cycles[pos] += cnt;
     78}
     79
     80int filter_event_early(void *data, const struct perf_dlfilter_sample *sample, void *ctx)
     81{
     82	__s32 cpu = sample->cpu;
     83	__s32 tid = sample->tid;
     84	int pos;
     85
     86	if (!sample->cyc_cnt)
     87		return 0;
     88
     89	pos = event_entry(sample->event);
     90
     91	if (cpu >= 0 && cpu < MAX_CPU)
     92		cycles[cpu][pos] += sample->cyc_cnt;
     93	else if (tid != -1)
     94		add_entry(tid, pos, sample->cyc_cnt);
     95	return 0;
     96}
     97
     98static void print_vals(__u64 cycles, __u64 delta)
     99{
    100	if (delta)
    101		printf("%10llu %10llu ", cycles, delta);
    102	else
    103		printf("%10llu %10s ", cycles, "");
    104}
    105
    106int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx)
    107{
    108	__s32 cpu = sample->cpu;
    109	__s32 tid = sample->tid;
    110	int pos;
    111
    112	pos = event_entry(sample->event);
    113
    114	if (cpu >= 0 && cpu < MAX_CPU) {
    115		print_vals(cycles[cpu][pos], cycles[cpu][pos] - cycles_rpt[cpu][pos]);
    116		cycles_rpt[cpu][pos] = cycles[cpu][pos];
    117		return 0;
    118	}
    119
    120	if (tid != -1) {
    121		struct entry *e = find_entry(tid);
    122
    123		if (e) {
    124			print_vals(e->cycles[pos], e->cycles[pos] - e->cycles_rpt[pos]);
    125			e->cycles_rpt[pos] = e->cycles[pos];
    126			return 0;
    127		}
    128	}
    129
    130	printf("%22s", "");
    131	return 0;
    132}
    133
    134const char *filter_description(const char **long_description)
    135{
    136	static char *long_desc = "Cycle counts are accumulated per CPU (or "
    137		"per thread if CPU is not recorded) from IPC information, and "
    138		"printed together with the change since the last print, at the "
    139		"start of each line. Separate counts are kept for branches, "
    140		"instructions or other events.";
    141
    142	*long_description = long_desc;
    143	return "Print the number of cycles at the start of each line";
    144}