| From: Vaibhav Nagarnaik <vnagarnaik@google.com> |
| Date: Fri, 7 Sep 2018 15:31:29 -0700 |
| Subject: ring-buffer: Allow for rescheduling when removing pages |
| |
| commit 83f365554e47997ec68dc4eca3f5dce525cd15c3 upstream. |
| |
| When reducing ring buffer size, pages are removed by scheduling a work |
| item on each CPU for the corresponding CPU ring buffer. After the pages |
| are removed from ring buffer linked list, the pages are free()d in a |
| tight loop. The loop does not give up CPU until all pages are removed. |
| In a worst case behavior, when lot of pages are to be freed, it can |
| cause system stall. |
| |
| After the pages are removed from the list, the free() can happen while |
| the work is rescheduled. Call cond_resched() in the loop to prevent the |
| system hangup. |
| |
| Link: http://lkml.kernel.org/r/20180907223129.71994-1-vnagarnaik@google.com |
| |
| Fixes: 83f40318dab00 ("ring-buffer: Make removal of ring buffer pages atomic") |
| Reported-by: Jason Behmer <jbehmer@google.com> |
| Signed-off-by: Vaibhav Nagarnaik <vnagarnaik@google.com> |
| Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| kernel/trace/ring_buffer.c | 2 ++ |
| 1 file changed, 2 insertions(+) |
| |
| --- a/kernel/trace/ring_buffer.c |
| +++ b/kernel/trace/ring_buffer.c |
| @@ -1541,6 +1541,8 @@ rb_remove_pages(struct ring_buffer_per_c |
| tmp_iter_page = first_page; |
| |
| do { |
| + cond_resched(); |
| + |
| to_remove_page = tmp_iter_page; |
| rb_inc_page(cpu_buffer, &tmp_iter_page); |
| |