// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/* Copyright (C) 2020 Facebook */
#include <errno.h>
#include <linux/err.h>
#include <linux/netfilter.h>
#include <linux/netfilter_arp.h>
#include <linux/perf_event.h>
#include <net/if.h>
#include <stdio.h>
#include <unistd.h>
#include <bpf/bpf.h>
#include <bpf/hashmap.h>
#include "json_writer.h"
#include "main.h"
#include "xlated_dumper.h"
#define PERF_HW_CACHE_LEN 128
static struct hashmap *link_table;
static struct dump_data dd;
static const char *perf_type_name[PERF_TYPE_MAX] = {
[PERF_TYPE_HARDWARE] = "hardware",
[PERF_TYPE_SOFTWARE] = "software",
[PERF_TYPE_TRACEPOINT] = "tracepoint",
[PERF_TYPE_HW_CACHE] = "hw-cache",
[PERF_TYPE_RAW] = "raw",
[PERF_TYPE_BREAKPOINT] = "breakpoint",
};
const char *event_symbols_hw[PERF_COUNT_HW_MAX] = {
[PERF_COUNT_HW_CPU_CYCLES] = "cpu-cycles",
[PERF_COUNT_HW_INSTRUCTIONS] = "instructions",
[PERF_COUNT_HW_CACHE_REFERENCES] = "cache-references",
[PERF_COUNT_HW_CACHE_MISSES] = "cache-misses",
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "branch-instructions",
[PERF_COUNT_HW_BRANCH_MISSES] = "branch-misses",
[PERF_COUNT_HW_BUS_CYCLES] = "bus-cycles",
[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = "stalled-cycles-frontend",
[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = "stalled-cycles-backend",
[PERF_COUNT_HW_REF_CPU_CYCLES] = "ref-cycles",
};
const char *event_symbols_sw[PERF_COUNT_SW_MAX] = {
[PERF_COUNT_SW_CPU_CLOCK] = "cpu-clock",
[PERF_COUNT_SW_TASK_CLOCK] = "task-clock",
[PERF_COUNT_SW_PAGE_FAULTS] = "page-faults",
[PERF_COUNT_SW_CONTEXT_SWITCHES] = "context-switches",
[PERF_COUNT_SW_CPU_MIGRATIONS] = "cpu-migrations",
[PERF_COUNT_SW_PAGE_FAULTS_MIN] = "minor-faults",
[PERF_COUNT_SW_PAGE_FAULTS_MAJ] = "major-faults",
[PERF_COUNT_SW_ALIGNMENT_FAULTS] = "alignment-faults",
[PERF_COUNT_SW_EMULATION_FAULTS] = "emulation-faults",
[PERF_COUNT_SW_DUMMY] = "dummy",
[PERF_COUNT_SW_BPF_OUTPUT] = "bpf-output",
[PERF_COUNT_SW_CGROUP_SWITCHES] = "cgroup-switches",
};
const char *evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX] = {
[PERF_COUNT_HW_CACHE_L1D] = "L1-dcache",
[PERF_COUNT_HW_CACHE_L1I] = "L1-icache",
[PERF_COUNT_HW_CACHE_LL] = "LLC",
[PERF_COUNT_HW_CACHE_DTLB] = "dTLB",
[PERF_COUNT_HW_CACHE_ITLB] = "iTLB",
[PERF_COUNT_HW_CACHE_BPU] = "branch",
[PERF_COUNT_HW_CACHE_NODE] = "node",
};
const char *evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX] = {
[PERF_COUNT_HW_CACHE_OP_READ] = "load",
[PERF_COUNT_HW_CACHE_OP_WRITE] = "store",
[PERF_COUNT_HW_CACHE_OP_PREFETCH] = "prefetch",
};
const char *evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
[PERF_COUNT_HW_CACHE_RESULT_ACCESS] = "refs",
[PERF_COUNT_HW_CACHE_RESULT_MISS] = "misses",
};
#define perf_event_name(array, id) ({ \
const char *event_str = NULL; \
\
if ((id) < ARRAY_SIZE(array)) \
event_str = array[id]; \
event_str; \
})
static int link_parse_fd(int *argc, char ***argv)
{
int fd;
if (is_prefix(**argv, "id")) {
unsigned int id;
char *endptr;
NEXT_ARGP();
id = strtoul(**argv, &endptr, 0);
if (*endptr) {
p_err("can't parse %s as ID", **argv);
return -1;
}
NEXT_ARGP();
fd = bpf_link_get_fd_by_id(id);
if (fd < 0)
p_err("failed to get link with ID %d: %s", id, strerror(errno));
return fd;