diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/perf_counter.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 0dfe91094fd1..affe227d56a0 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
@@ -1161,7 +1161,16 @@ perf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
1161 | static unsigned int perf_poll(struct file *file, poll_table *wait) | 1161 | static unsigned int perf_poll(struct file *file, poll_table *wait) |
1162 | { | 1162 | { |
1163 | struct perf_counter *counter = file->private_data; | 1163 | struct perf_counter *counter = file->private_data; |
1164 | unsigned int events = POLLIN; | 1164 | struct perf_mmap_data *data; |
1165 | unsigned int events; | ||
1166 | |||
1167 | rcu_read_lock(); | ||
1168 | data = rcu_dereference(counter->data); | ||
1169 | if (data) | ||
1170 | events = atomic_xchg(&data->wakeup, 0); | ||
1171 | else | ||
1172 | events = POLL_HUP; | ||
1173 | rcu_read_unlock(); | ||
1165 | 1174 | ||
1166 | poll_wait(file, &counter->waitq, wait); | 1175 | poll_wait(file, &counter->waitq, wait); |
1167 | 1176 | ||
@@ -1425,7 +1434,7 @@ static int perf_output_write(struct perf_counter *counter, int nmi, | |||
1425 | 1434 | ||
1426 | do { | 1435 | do { |
1427 | offset = head = atomic_read(&data->head); | 1436 | offset = head = atomic_read(&data->head); |
1428 | head += sizeof(u64); | 1437 | head += size; |
1429 | } while (atomic_cmpxchg(&data->head, offset, head) != offset); | 1438 | } while (atomic_cmpxchg(&data->head, offset, head) != offset); |
1430 | 1439 | ||
1431 | wakeup = (offset >> PAGE_SHIFT) != (head >> PAGE_SHIFT); | 1440 | wakeup = (offset >> PAGE_SHIFT) != (head >> PAGE_SHIFT); |
@@ -1446,6 +1455,7 @@ static int perf_output_write(struct perf_counter *counter, int nmi, | |||
1446 | * generate a poll() wakeup for every page boundary crossed | 1455 | * generate a poll() wakeup for every page boundary crossed |
1447 | */ | 1456 | */ |
1448 | if (wakeup) { | 1457 | if (wakeup) { |
1458 | atomic_xchg(&data->wakeup, POLL_IN); | ||
1449 | __perf_counter_update_userpage(counter, data); | 1459 | __perf_counter_update_userpage(counter, data); |
1450 | if (nmi) { | 1460 | if (nmi) { |
1451 | counter->wakeup_pending = 1; | 1461 | counter->wakeup_pending = 1; |