aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/events/ring_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/events/ring_buffer.c')
-rw-r--r--kernel/events/ring_buffer.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index 67b328337a41..232f00f273cb 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -296,6 +296,7 @@ void *perf_aux_output_begin(struct perf_output_handle *handle,
296 */ 296 */
297 if (!rb->aux_overwrite) { 297 if (!rb->aux_overwrite) {
298 aux_tail = ACCESS_ONCE(rb->user_page->aux_tail); 298 aux_tail = ACCESS_ONCE(rb->user_page->aux_tail);
299 handle->wakeup = local_read(&rb->aux_wakeup) + rb->aux_watermark;
299 if (aux_head - aux_tail < perf_aux_size(rb)) 300 if (aux_head - aux_tail < perf_aux_size(rb))
300 handle->size = CIRC_SPACE(aux_head, aux_tail, perf_aux_size(rb)); 301 handle->size = CIRC_SPACE(aux_head, aux_tail, perf_aux_size(rb));
301 302
@@ -359,9 +360,12 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
359 perf_event_aux_event(handle->event, aux_head, size, flags); 360 perf_event_aux_event(handle->event, aux_head, size, flags);
360 } 361 }
361 362
362 rb->user_page->aux_head = local_read(&rb->aux_head); 363 aux_head = rb->user_page->aux_head = local_read(&rb->aux_head);
363 364
364 perf_output_wakeup(handle); 365 if (aux_head - local_read(&rb->aux_wakeup) >= rb->aux_watermark) {
366 perf_output_wakeup(handle);
367 local_add(rb->aux_watermark, &rb->aux_wakeup);
368 }
365 handle->event = NULL; 369 handle->event = NULL;
366 370
367 local_set(&rb->aux_nest, 0); 371 local_set(&rb->aux_nest, 0);
@@ -383,6 +387,14 @@ int perf_aux_output_skip(struct perf_output_handle *handle, unsigned long size)
383 387
384 local_add(size, &rb->aux_head); 388 local_add(size, &rb->aux_head);
385 389
390 aux_head = rb->user_page->aux_head = local_read(&rb->aux_head);
391 if (aux_head - local_read(&rb->aux_wakeup) >= rb->aux_watermark) {
392 perf_output_wakeup(handle);
393 local_add(rb->aux_watermark, &rb->aux_wakeup);
394 handle->wakeup = local_read(&rb->aux_wakeup) +
395 rb->aux_watermark;
396 }
397
386 handle->head = aux_head; 398 handle->head = aux_head;
387 handle->size -= size; 399 handle->size -= size;
388 400
@@ -433,7 +445,7 @@ static void rb_free_aux_page(struct ring_buffer *rb, int idx)
433} 445}
434 446
435int rb_alloc_aux(struct ring_buffer *rb, struct perf_event *event, 447int rb_alloc_aux(struct ring_buffer *rb, struct perf_event *event,
436 pgoff_t pgoff, int nr_pages, int flags) 448 pgoff_t pgoff, int nr_pages, long watermark, int flags)
437{ 449{
438 bool overwrite = !(flags & RING_BUFFER_WRITABLE); 450 bool overwrite = !(flags & RING_BUFFER_WRITABLE);
439 int node = (event->cpu == -1) ? -1 : cpu_to_node(event->cpu); 451 int node = (event->cpu == -1) ? -1 : cpu_to_node(event->cpu);
@@ -497,6 +509,10 @@ int rb_alloc_aux(struct ring_buffer *rb, struct perf_event *event,
497 atomic_set(&rb->aux_refcount, 1); 509 atomic_set(&rb->aux_refcount, 1);
498 510
499 rb->aux_overwrite = overwrite; 511 rb->aux_overwrite = overwrite;
512 rb->aux_watermark = watermark;
513
514 if (!rb->aux_watermark && !rb->aux_overwrite)
515 rb->aux_watermark = nr_pages << (PAGE_SHIFT - 1);
500 516
501out: 517out:
502 if (!ret) 518 if (!ret)