Commit d6827331 authored by Teng Qin's avatar Teng Qin

Add bpf_close_perf_event_fd

Add bpf_close_perf_event_fd helper that first disables, then closes a
perf event fd. Use it in Python and C++ API for detach perf event
parent 5b40420a
......@@ -561,8 +561,8 @@ StatusTuple BPF::detach_perf_event_all_cpu(open_probe_t& attr) {
bool has_error = false;
std::string err_msg;
for (const auto& it : *attr.per_cpu_fd) {
int res = close(it.second);
if (res < 0) {
int res = bpf_close_perf_event_fd(it.second);
if (res != 0) {
has_error = true;
err_msg += "Failed to close perf event FD " + std::to_string(it.second) +
" For CPU " + std::to_string(it.first) + ": ";
......
......@@ -808,10 +808,21 @@ int bpf_attach_perf_event(int progfd, uint32_t ev_type, uint32_t ev_config,
return fd;
}
int bpf_detach_perf_event(uint32_t ev_type, uint32_t ev_config) {
// Right now, there is nothing to do, but it's a good idea to encourage
// callers to detach anything they attach.
return 0;
int bpf_close_perf_event_fd(int fd) {
int res, error = 0;
if (fd >= 0) {
res = ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
if (res != 0) {
perror("ioctl(PERF_EVENT_IOC_DISABLE) failed");
error = res;
}
res = close(fd);
if (res != 0) {
perror("close perf event FD failed");
error = (res && !error) ? res : error;
}
}
return error;
}
int bpf_obj_pin(int fd, const char *pathname)
......
......@@ -82,7 +82,8 @@ int bpf_attach_xdp(const char *dev_name, int progfd, uint32_t flags);
int bpf_attach_perf_event(int progfd, uint32_t ev_type, uint32_t ev_config,
uint64_t sample_period, uint64_t sample_freq,
pid_t pid, int cpu, int group_fd);
int bpf_detach_perf_event(uint32_t ev_type, uint32_t ev_config);
int bpf_close_perf_event_fd(int fd);
int bpf_obj_pin(int fd, const char *pathname);
int bpf_obj_get(const char *pathname);
......
......@@ -730,13 +730,13 @@ class BPF(object):
except KeyError:
raise Exception("Perf event type {} config {} not attached".format(
ev_type, ev_config))
res = 0
for fd in fds.values():
os.close(fd)
res = lib.bpf_detach_perf_event(ev_type, ev_config)
if res < 0:
res = lib.bpf_close_perf_event_fd(fd) or res
if res != 0:
raise Exception("Failed to detach BPF from perf event")
del self.open_perf_events[(ev_type, ev_config)]
return res
def _add_uprobe(self, name, probe):
global _num_open_probes
......
......@@ -115,14 +115,15 @@ lib.perf_reader_free.argtypes = [ct.c_void_p]
lib.perf_reader_fd.restype = int
lib.perf_reader_fd.argtypes = [ct.c_void_p]
lib.bpf_attach_xdp.restype = ct.c_int;
lib.bpf_attach_xdp.restype = ct.c_int
lib.bpf_attach_xdp.argtypes = [ct.c_char_p, ct.c_int, ct.c_uint]
lib.bpf_attach_perf_event.restype = ct.c_int;
lib.bpf_attach_perf_event.restype = ct.c_int
lib.bpf_attach_perf_event.argtype = [ct.c_int, ct.c_uint, ct.c_uint, ct.c_ulonglong, ct.c_ulonglong,
ct.c_int, ct.c_int, ct.c_int]
lib.bpf_detach_perf_event.restype = ct.c_int;
lib.bpf_detach_perf_event.argtype = [ct.c_uint, ct.c_uint]
lib.bpf_close_perf_event_fd.restype = ct.c_int
lib.bpf_close_perf_event_fd.argtype = [ct.c_int]
# bcc symbol helpers
class bcc_symbol(ct.Structure):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment