diff options
Diffstat (limited to 'kernel/trace/ring_buffer.c')
-rw-r--r-- | kernel/trace/ring_buffer.c | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 9edb628603ab..5434c16f2192 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -489,6 +489,7 @@ struct ring_buffer_per_cpu { | |||
489 | local_t commits; | 489 | local_t commits; |
490 | local_t pages_touched; | 490 | local_t pages_touched; |
491 | local_t pages_read; | 491 | local_t pages_read; |
492 | long last_pages_touch; | ||
492 | size_t shortest_full; | 493 | size_t shortest_full; |
493 | unsigned long read; | 494 | unsigned long read; |
494 | unsigned long read_bytes; | 495 | unsigned long read_bytes; |
@@ -2632,7 +2633,9 @@ static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer, | |||
2632 | static __always_inline void | 2633 | static __always_inline void |
2633 | rb_wakeups(struct ring_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer) | 2634 | rb_wakeups(struct ring_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer) |
2634 | { | 2635 | { |
2635 | bool pagebusy; | 2636 | size_t nr_pages; |
2637 | size_t dirty; | ||
2638 | size_t full; | ||
2636 | 2639 | ||
2637 | if (buffer->irq_work.waiters_pending) { | 2640 | if (buffer->irq_work.waiters_pending) { |
2638 | buffer->irq_work.waiters_pending = false; | 2641 | buffer->irq_work.waiters_pending = false; |
@@ -2646,24 +2649,27 @@ rb_wakeups(struct ring_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer) | |||
2646 | irq_work_queue(&cpu_buffer->irq_work.work); | 2649 | irq_work_queue(&cpu_buffer->irq_work.work); |
2647 | } | 2650 | } |
2648 | 2651 | ||
2649 | pagebusy = cpu_buffer->reader_page == cpu_buffer->commit_page; | 2652 | if (cpu_buffer->last_pages_touch == local_read(&cpu_buffer->pages_touched)) |
2653 | return; | ||
2650 | 2654 | ||
2651 | if (!pagebusy && cpu_buffer->irq_work.full_waiters_pending) { | 2655 | if (cpu_buffer->reader_page == cpu_buffer->commit_page) |
2652 | size_t nr_pages; | 2656 | return; |
2653 | size_t dirty; | ||
2654 | size_t full; | ||
2655 | 2657 | ||
2656 | full = cpu_buffer->shortest_full; | 2658 | if (!cpu_buffer->irq_work.full_waiters_pending) |
2657 | nr_pages = cpu_buffer->nr_pages; | 2659 | return; |
2658 | dirty = ring_buffer_nr_dirty_pages(buffer, cpu_buffer->cpu); | ||
2659 | if (full && nr_pages && (dirty * 100) <= full * nr_pages) | ||
2660 | return; | ||
2661 | 2660 | ||
2662 | cpu_buffer->irq_work.wakeup_full = true; | 2661 | cpu_buffer->last_pages_touch = local_read(&cpu_buffer->pages_touched); |
2663 | cpu_buffer->irq_work.full_waiters_pending = false; | 2662 | |
2664 | /* irq_work_queue() supplies it's own memory barriers */ | 2663 | full = cpu_buffer->shortest_full; |
2665 | irq_work_queue(&cpu_buffer->irq_work.work); | 2664 | nr_pages = cpu_buffer->nr_pages; |
2666 | } | 2665 | dirty = ring_buffer_nr_dirty_pages(buffer, cpu_buffer->cpu); |
2666 | if (full && nr_pages && (dirty * 100) <= full * nr_pages) | ||
2667 | return; | ||
2668 | |||
2669 | cpu_buffer->irq_work.wakeup_full = true; | ||
2670 | cpu_buffer->irq_work.full_waiters_pending = false; | ||
2671 | /* irq_work_queue() supplies it's own memory barriers */ | ||
2672 | irq_work_queue(&cpu_buffer->irq_work.work); | ||
2667 | } | 2673 | } |
2668 | 2674 | ||
2669 | /* | 2675 | /* |
@@ -4394,6 +4400,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) | |||
4394 | local_set(&cpu_buffer->commits, 0); | 4400 | local_set(&cpu_buffer->commits, 0); |
4395 | local_set(&cpu_buffer->pages_touched, 0); | 4401 | local_set(&cpu_buffer->pages_touched, 0); |
4396 | local_set(&cpu_buffer->pages_read, 0); | 4402 | local_set(&cpu_buffer->pages_read, 0); |
4403 | cpu_buffer->last_pages_touch = 0; | ||
4397 | cpu_buffer->shortest_full = 0; | 4404 | cpu_buffer->shortest_full = 0; |
4398 | cpu_buffer->read = 0; | 4405 | cpu_buffer->read = 0; |
4399 | cpu_buffer->read_bytes = 0; | 4406 | cpu_buffer->read_bytes = 0; |