trace: Fix epoll hang when we race with new entries
[platform/adaptation/renesas_rcar/renesas_kernel.git] / kernel / trace / ring_buffer.c
index 0954450..773aba8 100644 (file)
@@ -626,8 +626,22 @@ int ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu,
                work = &cpu_buffer->irq_work;
        }
 
-       work->waiters_pending = true;
        poll_wait(filp, &work->waiters, poll_table);
+       work->waiters_pending = true;
+       /*
+        * There's a tight race between setting the waiters_pending and
+        * checking if the ring buffer is empty.  Once the waiters_pending bit
+        * is set, the next event will wake the task up, but we can get stuck
+        * if there's only a single event in.
+        *
+        * FIXME: Ideally, we need a memory barrier on the writer side as well,
+        * but adding a memory barrier to all events will cause too much of a
+        * performance hit in the fast path.  We only need a memory barrier when
+        * the buffer goes from empty to having content.  But as this race is
+        * extremely small, and it's not a problem if another event comes in, we
+        * will fix it later.
+        */
+       smp_mb();
 
        if ((cpu == RING_BUFFER_ALL_CPUS && !ring_buffer_empty(buffer)) ||
            (cpu != RING_BUFFER_ALL_CPUS && !ring_buffer_empty_cpu(buffer, cpu)))
@@ -1981,7 +1995,7 @@ rb_add_time_stamp(struct ring_buffer_event *event, u64 delta)
 
 /**
  * rb_update_event - update event type and data
- * @event: the even to update
+ * @event: the event to update
  * @type: the type of event
  * @length: the size of the event field in the ring buffer
  *
@@ -3354,21 +3368,16 @@ static void rb_iter_reset(struct ring_buffer_iter *iter)
        struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
 
        /* Iterator usage is expected to have record disabled */
-       if (list_empty(&cpu_buffer->reader_page->list)) {
-               iter->head_page = rb_set_head_page(cpu_buffer);
-               if (unlikely(!iter->head_page))
-                       return;
-               iter->head = iter->head_page->read;
-       } else {
-               iter->head_page = cpu_buffer->reader_page;
-               iter->head = cpu_buffer->reader_page->read;
-       }
+       iter->head_page = cpu_buffer->reader_page;
+       iter->head = cpu_buffer->reader_page->read;
+
+       iter->cache_reader_page = iter->head_page;
+       iter->cache_read = iter->head;
+
        if (iter->head)
                iter->read_stamp = cpu_buffer->read_stamp;
        else
                iter->read_stamp = iter->head_page->page->time_stamp;
-       iter->cache_reader_page = cpu_buffer->reader_page;
-       iter->cache_read = cpu_buffer->read;
 }
 
 /**
@@ -3761,12 +3770,14 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
                return NULL;
 
        /*
-        * We repeat when a time extend is encountered.
-        * Since the time extend is always attached to a data event,
-        * we should never loop more than once.
-        * (We never hit the following condition more than twice).
+        * We repeat when a time extend is encountered or we hit
+        * the end of the page. Since the time extend is always attached
+        * to a data event, we should never loop more than three times.
+        * Once for going to next page, once on time extend, and
+        * finally once to get the event.
+        * (We never hit the following condition more than thrice).
         */
-       if (RB_WARN_ON(cpu_buffer, ++nr_loops > 2))
+       if (RB_WARN_ON(cpu_buffer, ++nr_loops > 3))
                return NULL;
 
        if (rb_per_cpu_empty(cpu_buffer))