#include "llc.h" #include #include #include #include #include #include #include long perf_event_open(struct perf_event_attr* hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags) { return (syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags)); } void config_event(struct perf_event_attr* pe) { pe->type = PERF_TYPE_HW_CACHE; pe->size = sizeof(struct perf_event_attr); pe->config = PERF_COUNT_HW_CACHE_LL | PERF_COUNT_HW_CACHE_OP_READ << 8 | PERF_COUNT_HW_CACHE_RESULT_MISS << 16; pe->disabled = 1; pe->exclude_kernel = 1; pe->exclude_hv = 1; } int init_event(struct perf_event_attr* pe) { int fd = perf_event_open(pe, ALL_PIDS, CPU_0, LEADER, NO_FLAGS); if (fd == -1) { printk(KERN_INFO "Error with the LLC counter: %d", pe->config); exit(EXIT_FAILURE); } return fd; } void activate_event(int fd) { ioctl(fd, PERF_EVENT_IOC_RESET, 0); ioctl(fd, PERF_EVENT_IOC_ENABLE, 0); } void close_event(int fd) { ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); close(fd); } int setup_BE_monitor() { struct perf_event_attr pe_BE_monitor; memset(&pe_BE_monitor, 0, sizeof(struct perf_event_attr)); config_event(&pe_BE_monitor); int fd = init_event(&pe_BE_monitor); activate_event(fd); return fd; } long long query_BE_monitor(int fd) { long long count = 0; read(fd, &count, sizeof(count)); return count; } bool do_block_BE(int fd, long long max_misses) { return (query_BE_monitor(fd) > max_misses); } void close_BE_monitor(int fd) { close_event(fd); }