41 #include <sys/ioctl.h>
43 #include <sys/syscall.h>
44 #include <sys/types.h>
60 attr.size = PERF_ATTR_SIZE_VER0;
71 :
fd(-1), ringBuffer(NULL), pageSize(-1)
78 :
fd(-1), ringBuffer(NULL), pageSize(-1)
80 attach(config, tid, parent);
84 :
fd(-1), ringBuffer(NULL), pageSize(-1)
100 warn(
"PerfKvmCounter: Failed to unmap ring buffer (%i)\n",
111 if (
ioctl(PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP) == -1)
112 panic(
"KVM: Failed to enable performance counters (%i)\n", errno);
118 if (
ioctl(PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP) == -1)
119 panic(
"KVM: Failed to disable performance counters (%i)\n", errno);
125 if (
ioctl(PERF_EVENT_IOC_PERIOD, &period) == -1)
126 panic(
"KVM: Failed to set period of performance counter (%i)\n", errno);
132 if (
ioctl(PERF_EVENT_IOC_REFRESH, refresh) == -1)
133 panic(
"KVM: Failed to refresh performance counter (%i)\n", errno);
141 read(&value,
sizeof(uint64_t));
148 struct f_owner_ex sigowner;
150 sigowner.type = F_OWNER_TID;
153 if (
fcntl(F_SETOWN_EX, &sigowner) == -1 ||
154 fcntl(F_SETSIG, signal) == -1 ||
155 fcntl(F_SETFL, O_ASYNC) == -1)
156 panic(
"PerfKvmCounter: Failed to enable signals for counter (%i)\n",
162 pid_t tid,
int group_fd)
166 fd = syscall(__NR_perf_event_open,
172 panic(
"PerfKvmCounter::open failed (%i)\n", errno);
180 return syscall(__NR_gettid);
192 panic(
"PerfKvmCounter: Failed to determine page size (%i)\n",
197 ringBuffer = (
struct perf_event_mmap_page *)mmap(
199 PROT_READ | PROT_WRITE, MAP_SHARED,
202 panic(
"PerfKvmCounter: MMAP failed (%i)\n",
210 return ::fcntl(
fd, cmd, p1);
217 return ::ioctl(
fd, request, p1);
223 char *_buf = (
char *)buf;
234 panic(
"PerfKvmCounter::read failed (%i)\n", errno);
238 panic(
"PerfKvmCounter::read unexpected EOF.\n");
void detach()
Detach a counter from PerfEvent.
long pageSize
Cached host page size.
struct perf_event_attr attr
Underlying perf_event_attr structure describing the counter.
uint64_t read() const
Read the current value of a counter.
PerfKvmCounter()
Create a new counter, but don't attach it.
struct perf_event_mmap_page * ringBuffer
Memory mapped PerfEvent sample ring buffer.
void enableSignals(pid_t tid, int signal)
Enable signal delivery to a thread on counter overflow.
int fd
PerfEvent file descriptor associated with counter.
pid_t gettid()
Get the TID of the current thread.
void refresh(int refresh)
Enable a counter for a fixed number of events.
PerfKvmCounterConfig(uint32_t type, uint64_t config)
Initialize PerfEvent counter configuration structure.
void mmapPerf(int pages)
MMAP the PerfEvent file descriptor.
void period(uint64_t period)
Update the period of an overflow counter.
int ringNumPages
Total number of pages in ring buffer.
An instance of a performance counter.
void attach(PerfKvmCounterConfig &config, pid_t tid)
Attach a counter.
PerfEvent counter configuration.
int ioctl(int request, long p1)
PerfEvent ioctl interface.
void stop()
Stop counting.
void start()
Start counting.
bool attached() const
Check if a counter is attached.
int fcntl(int cmd, long p1)
PerfEvent fnctl interface.