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) { ...@@ -561,8 +561,8 @@ StatusTuple BPF::detach_perf_event_all_cpu(open_probe_t& attr) {
bool has_error = false; bool has_error = false;
std::string err_msg; std::string err_msg;
for (const auto& it : *attr.per_cpu_fd) { for (const auto& it : *attr.per_cpu_fd) {
int res = close(it.second); int res = bpf_close_perf_event_fd(it.second);
if (res < 0) { if (res != 0) {
has_error = true; has_error = true;
err_msg += "Failed to close perf event FD " + std::to_string(it.second) + err_msg += "Failed to close perf event FD " + std::to_string(it.second) +
" For CPU " + std::to_string(it.first) + ": "; " 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, ...@@ -808,10 +808,21 @@ int bpf_attach_perf_event(int progfd, uint32_t ev_type, uint32_t ev_config,
return fd; return fd;
} }
int bpf_detach_perf_event(uint32_t ev_type, uint32_t ev_config) { int bpf_close_perf_event_fd(int fd) {
// Right now, there is nothing to do, but it's a good idea to encourage int res, error = 0;
// callers to detach anything they attach. if (fd >= 0) {
return 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) 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); ...@@ -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, int bpf_attach_perf_event(int progfd, uint32_t ev_type, uint32_t ev_config,
uint64_t sample_period, uint64_t sample_freq, uint64_t sample_period, uint64_t sample_freq,
pid_t pid, int cpu, int group_fd); 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_pin(int fd, const char *pathname);
int bpf_obj_get(const char *pathname); int bpf_obj_get(const char *pathname);
......
...@@ -730,13 +730,13 @@ class BPF(object): ...@@ -730,13 +730,13 @@ class BPF(object):
except KeyError: except KeyError:
raise Exception("Perf event type {} config {} not attached".format( raise Exception("Perf event type {} config {} not attached".format(
ev_type, ev_config)) ev_type, ev_config))
res = 0
for fd in fds.values(): for fd in fds.values():
os.close(fd) res = lib.bpf_close_perf_event_fd(fd) or res
res = lib.bpf_detach_perf_event(ev_type, ev_config) if res != 0:
if res < 0:
raise Exception("Failed to detach BPF from perf event") raise Exception("Failed to detach BPF from perf event")
del self.open_perf_events[(ev_type, ev_config)] del self.open_perf_events[(ev_type, ev_config)]
return res
def _add_uprobe(self, name, probe): def _add_uprobe(self, name, probe):
global _num_open_probes global _num_open_probes
......
...@@ -115,14 +115,15 @@ lib.perf_reader_free.argtypes = [ct.c_void_p] ...@@ -115,14 +115,15 @@ lib.perf_reader_free.argtypes = [ct.c_void_p]
lib.perf_reader_fd.restype = int lib.perf_reader_fd.restype = int
lib.perf_reader_fd.argtypes = [ct.c_void_p] 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_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, 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] 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 # bcc symbol helpers
class bcc_symbol(ct.Structure): 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