Commit 0cf7f748 authored by 4ast's avatar 4ast Committed by GitHub

Merge pull request #1549 from iovisor/yhs_dev

fix a race condition between perf_reader munmap and read
parents 2af307b4 cd5d4a6c
...@@ -28,6 +28,12 @@ ...@@ -28,6 +28,12 @@
#include "libbpf.h" #include "libbpf.h"
#include "perf_reader.h" #include "perf_reader.h"
enum {
RB_NOT_USED = 0, // ring buffer not usd
RB_USED_IN_MUNMAP = 1, // used in munmap
RB_USED_IN_READ = 2, // used in read
};
struct perf_reader { struct perf_reader {
perf_reader_cb cb; perf_reader_cb cb;
perf_reader_raw_cb raw_cb; perf_reader_raw_cb raw_cb;
...@@ -36,6 +42,7 @@ struct perf_reader { ...@@ -36,6 +42,7 @@ struct perf_reader {
void *buf; // for keeping segmented data void *buf; // for keeping segmented data
size_t buf_size; size_t buf_size;
void *base; void *base;
int rb_use_state;
int page_size; int page_size;
int page_cnt; int page_cnt;
int fd; int fd;
...@@ -63,6 +70,7 @@ struct perf_reader * perf_reader_new(perf_reader_cb cb, ...@@ -63,6 +70,7 @@ struct perf_reader * perf_reader_new(perf_reader_cb cb,
void perf_reader_free(void *ptr) { void perf_reader_free(void *ptr) {
if (ptr) { if (ptr) {
struct perf_reader *reader = ptr; struct perf_reader *reader = ptr;
while (!__sync_bool_compare_and_swap(&reader->rb_use_state, RB_NOT_USED, RB_USED_IN_MUNMAP));
munmap(reader->base, reader->page_size * (reader->page_cnt + 1)); munmap(reader->base, reader->page_size * (reader->page_cnt + 1));
if (reader->fd >= 0) { if (reader->fd >= 0) {
ioctl(reader->fd, PERF_EVENT_IOC_DISABLE, 0); ioctl(reader->fd, PERF_EVENT_IOC_DISABLE, 0);
...@@ -220,6 +228,9 @@ void perf_reader_event_read(struct perf_reader *reader) { ...@@ -220,6 +228,9 @@ void perf_reader_event_read(struct perf_reader *reader) {
uint8_t *sentinel = (uint8_t *)reader->base + buffer_size + reader->page_size; uint8_t *sentinel = (uint8_t *)reader->base + buffer_size + reader->page_size;
uint8_t *begin, *end; uint8_t *begin, *end;
if (!__sync_bool_compare_and_swap(&reader->rb_use_state, RB_NOT_USED, RB_USED_IN_READ))
return;
// Consume all the events on this ring, calling the cb function for each one. // Consume all the events on this ring, calling the cb function for each one.
// The message may fall on the ring boundary, in which case copy the message // The message may fall on the ring boundary, in which case copy the message
// into a malloced buffer. // into a malloced buffer.
...@@ -268,6 +279,7 @@ void perf_reader_event_read(struct perf_reader *reader) { ...@@ -268,6 +279,7 @@ void perf_reader_event_read(struct perf_reader *reader) {
write_data_tail(perf_header, perf_header->data_tail + e->size); write_data_tail(perf_header, perf_header->data_tail + e->size);
} }
reader->rb_use_state = RB_NOT_USED;
} }
int perf_reader_poll(int num_readers, struct perf_reader **readers, int timeout) { int perf_reader_poll(int num_readers, struct perf_reader **readers, int timeout) {
......
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