perf/core: Bail out early if the request AUX area is out of bound
[linux-2.6-microblaze.git] / kernel / events / ring_buffer.c
index a0433f3..e8d82c2 100644 (file)
@@ -191,9 +191,10 @@ __perf_output_begin(struct perf_output_handle *handle,
 
        perf_output_get_handle(handle);
 
+       offset = local_read(&rb->head);
        do {
+               head = offset;
                tail = READ_ONCE(rb->user_page->data_tail);
-               offset = head = local_read(&rb->head);
                if (!rb->overwrite) {
                        if (unlikely(!ring_buffer_has_space(head, tail,
                                                            perf_data_size(rb),
@@ -217,7 +218,7 @@ __perf_output_begin(struct perf_output_handle *handle,
                        head += size;
                else
                        head -= size;
-       } while (local_cmpxchg(&rb->head, offset, head) != offset);
+       } while (!local_try_cmpxchg(&rb->head, &offset, head));
 
        if (backward) {
                offset = head;
@@ -699,6 +700,12 @@ int rb_alloc_aux(struct perf_buffer *rb, struct perf_event *event,
                watermark = 0;
        }
 
+       /*
+        * kcalloc_node() is unable to allocate buffer if the size is larger
+        * than: PAGE_SIZE << MAX_ORDER; directly bail out in this case.
+        */
+       if (get_order((unsigned long)nr_pages * sizeof(void *)) > MAX_ORDER)
+               return -ENOMEM;
        rb->aux_pages = kcalloc_node(nr_pages, sizeof(void *), GFP_KERNEL,
                                     node);
        if (!rb->aux_pages)