|
@@ -296,6 +296,7 @@ void *perf_aux_output_begin(struct perf_output_handle *handle,
|
|
|
*/
|
|
|
if (!rb->aux_overwrite) {
|
|
|
aux_tail = ACCESS_ONCE(rb->user_page->aux_tail);
|
|
|
+ handle->wakeup = local_read(&rb->aux_wakeup) + rb->aux_watermark;
|
|
|
if (aux_head - aux_tail < perf_aux_size(rb))
|
|
|
handle->size = CIRC_SPACE(aux_head, aux_tail, perf_aux_size(rb));
|
|
|
|
|
@@ -359,9 +360,12 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
|
|
|
perf_event_aux_event(handle->event, aux_head, size, flags);
|
|
|
}
|
|
|
|
|
|
- rb->user_page->aux_head = local_read(&rb->aux_head);
|
|
|
+ aux_head = rb->user_page->aux_head = local_read(&rb->aux_head);
|
|
|
|
|
|
- perf_output_wakeup(handle);
|
|
|
+ if (aux_head - local_read(&rb->aux_wakeup) >= rb->aux_watermark) {
|
|
|
+ perf_output_wakeup(handle);
|
|
|
+ local_add(rb->aux_watermark, &rb->aux_wakeup);
|
|
|
+ }
|
|
|
handle->event = NULL;
|
|
|
|
|
|
local_set(&rb->aux_nest, 0);
|
|
@@ -383,6 +387,14 @@ int perf_aux_output_skip(struct perf_output_handle *handle, unsigned long size)
|
|
|
|
|
|
local_add(size, &rb->aux_head);
|
|
|
|
|
|
+ aux_head = rb->user_page->aux_head = local_read(&rb->aux_head);
|
|
|
+ if (aux_head - local_read(&rb->aux_wakeup) >= rb->aux_watermark) {
|
|
|
+ perf_output_wakeup(handle);
|
|
|
+ local_add(rb->aux_watermark, &rb->aux_wakeup);
|
|
|
+ handle->wakeup = local_read(&rb->aux_wakeup) +
|
|
|
+ rb->aux_watermark;
|
|
|
+ }
|
|
|
+
|
|
|
handle->head = aux_head;
|
|
|
handle->size -= size;
|
|
|
|
|
@@ -433,7 +445,7 @@ static void rb_free_aux_page(struct ring_buffer *rb, int idx)
|
|
|
}
|
|
|
|
|
|
int rb_alloc_aux(struct ring_buffer *rb, struct perf_event *event,
|
|
|
- pgoff_t pgoff, int nr_pages, int flags)
|
|
|
+ pgoff_t pgoff, int nr_pages, long watermark, int flags)
|
|
|
{
|
|
|
bool overwrite = !(flags & RING_BUFFER_WRITABLE);
|
|
|
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,
|
|
|
atomic_set(&rb->aux_refcount, 1);
|
|
|
|
|
|
rb->aux_overwrite = overwrite;
|
|
|
+ rb->aux_watermark = watermark;
|
|
|
+
|
|
|
+ if (!rb->aux_watermark && !rb->aux_overwrite)
|
|
|
+ rb->aux_watermark = nr_pages << (PAGE_SHIFT - 1);
|
|
|
|
|
|
out:
|
|
|
if (!ret)
|