]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - kernel/events/ring_buffer.c
perf/core: Keep AUX flags in the output handle
[mirror_ubuntu-artful-kernel.git] / kernel / events / ring_buffer.c
index 257fa460b846032744e2da500d489d0995678571..9654e55c38d6dbba7af8db7100a0a9919b498a9e 100644 (file)
@@ -297,6 +297,19 @@ ring_buffer_init(struct ring_buffer *rb, long watermark, int flags)
                rb->paused = 1;
 }
 
+void perf_aux_output_flag(struct perf_output_handle *handle, u64 flags)
+{
+       /*
+        * OVERWRITE is determined by perf_aux_output_end() and can't
+        * be passed in directly.
+        */
+       if (WARN_ON_ONCE(flags & PERF_AUX_FLAG_OVERWRITE))
+               return;
+
+       handle->aux_flags |= flags;
+}
+EXPORT_SYMBOL_GPL(perf_aux_output_flag);
+
 /*
  * This is called before hardware starts writing to the AUX area to
  * obtain an output handle and make sure there's room in the buffer.
@@ -360,6 +373,7 @@ void *perf_aux_output_begin(struct perf_output_handle *handle,
        handle->event = event;
        handle->head = aux_head;
        handle->size = 0;
+       handle->aux_flags = 0;
 
        /*
         * In overwrite mode, AUX data stores do not depend on aux_tail,
@@ -408,34 +422,32 @@ err:
  * of the AUX buffer management code is that after pmu::stop(), the AUX
  * transaction must be stopped and therefore drop the AUX reference count.
  */
-void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
-                        bool truncated)
+void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
 {
        struct ring_buffer *rb = handle->rb;
-       bool wakeup = truncated;
+       bool wakeup = !!handle->aux_flags;
        unsigned long aux_head;
-       u64 flags = 0;
-
-       if (truncated)
-               flags |= PERF_AUX_FLAG_TRUNCATED;
 
        /* in overwrite mode, driver provides aux_head via handle */
        if (rb->aux_overwrite) {
-               flags |= PERF_AUX_FLAG_OVERWRITE;
+               handle->aux_flags |= PERF_AUX_FLAG_OVERWRITE;
 
                aux_head = handle->head;
                local_set(&rb->aux_head, aux_head);
        } else {
+               handle->aux_flags &= ~PERF_AUX_FLAG_OVERWRITE;
+
                aux_head = local_read(&rb->aux_head);
                local_add(size, &rb->aux_head);
        }
 
-       if (size || flags) {
+       if (size || handle->aux_flags) {
                /*
                 * Only send RECORD_AUX if we have something useful to communicate
                 */
 
-               perf_event_aux_event(handle->event, aux_head, size, flags);
+               perf_event_aux_event(handle->event, aux_head, size,
+                                    handle->aux_flags);
        }
 
        aux_head = rb->user_page->aux_head = local_read(&rb->aux_head);
@@ -446,7 +458,7 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
        }
 
        if (wakeup) {
-               if (truncated)
+               if (handle->aux_flags & PERF_AUX_FLAG_TRUNCATED)
                        handle->event->pending_disable = 1;
                perf_output_wakeup(handle);
        }