aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2008-10-01 00:29:53 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-14 04:39:05 -0400
commitd769041f865330034131525ee6a7f72eb4af2a24 (patch)
tree5c0d93063585c9a94d3c8e8105cc7ad27f4fe0e8 /kernel/trace
parent70255b5e3f1bd1a5af5b1e425ec2c4db7c735112 (diff)
ring_buffer: implement new locking
The old "lock always" scheme had issues with lockdep, and was not very efficient anyways. This patch does a new design to be partially lockless on writes. Writes will add new entries to the per cpu pages by simply disabling interrupts. When a write needs to go to another page than it will grab the lock. A new "read page" has been added so that the reader can pull out a page from the ring buffer to read without worrying about the writer writing over it. This allows us to not take the lock for all reads. The lock is now only taken when a read needs to go to a new page. This is far from lockless, and interrupts still need to be disabled, but it is a step towards a more lockless solution, and it also solves a lot of the issues that were noticed by the first conversion of ftrace to the ring buffers. Note: the ring_buffer_{un}lock API has been removed. Signed-off-by: Steven Rostedt <srostedt@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/ring_buffer.c298
-rw-r--r--kernel/trace/trace.c113
2 files changed, 247 insertions, 164 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 8e7392fd0db9..9631abf2ae29 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -161,8 +161,10 @@ struct ring_buffer_per_cpu {
161 struct list_head pages; 161 struct list_head pages;
162 unsigned long head; /* read from head */ 162 unsigned long head; /* read from head */
163 unsigned long tail; /* write to tail */ 163 unsigned long tail; /* write to tail */
164 unsigned long reader;
164 struct buffer_page *head_page; 165 struct buffer_page *head_page;
165 struct buffer_page *tail_page; 166 struct buffer_page *tail_page;
167 struct buffer_page *reader_page;
166 unsigned long overrun; 168 unsigned long overrun;
167 unsigned long entries; 169 unsigned long entries;
168 u64 write_stamp; 170 u64 write_stamp;
@@ -260,6 +262,7 @@ static struct ring_buffer_per_cpu *
260rb_allocate_cpu_buffer(struct ring_buffer *buffer, int cpu) 262rb_allocate_cpu_buffer(struct ring_buffer *buffer, int cpu)
261{ 263{
262 struct ring_buffer_per_cpu *cpu_buffer; 264 struct ring_buffer_per_cpu *cpu_buffer;
265 unsigned long addr;
263 int ret; 266 int ret;
264 267
265 cpu_buffer = kzalloc_node(ALIGN(sizeof(*cpu_buffer), cache_line_size()), 268 cpu_buffer = kzalloc_node(ALIGN(sizeof(*cpu_buffer), cache_line_size()),
@@ -272,9 +275,16 @@ rb_allocate_cpu_buffer(struct ring_buffer *buffer, int cpu)
272 spin_lock_init(&cpu_buffer->lock); 275 spin_lock_init(&cpu_buffer->lock);
273 INIT_LIST_HEAD(&cpu_buffer->pages); 276 INIT_LIST_HEAD(&cpu_buffer->pages);
274 277
278 addr = __get_free_page(GFP_KERNEL);
279 if (!addr)
280 goto fail_free_buffer;
281 cpu_buffer->reader_page = (struct buffer_page *)virt_to_page(addr);
282 INIT_LIST_HEAD(&cpu_buffer->reader_page->list);
283 cpu_buffer->reader_page->size = 0;
284
275 ret = rb_allocate_pages(cpu_buffer, buffer->pages); 285 ret = rb_allocate_pages(cpu_buffer, buffer->pages);
276 if (ret < 0) 286 if (ret < 0)
277 goto fail_free_buffer; 287 goto fail_free_reader;
278 288
279 cpu_buffer->head_page 289 cpu_buffer->head_page
280 = list_entry(cpu_buffer->pages.next, struct buffer_page, list); 290 = list_entry(cpu_buffer->pages.next, struct buffer_page, list);
@@ -283,6 +293,9 @@ rb_allocate_cpu_buffer(struct ring_buffer *buffer, int cpu)
283 293
284 return cpu_buffer; 294 return cpu_buffer;
285 295
296 fail_free_reader:
297 free_buffer_page(cpu_buffer->reader_page);
298
286 fail_free_buffer: 299 fail_free_buffer:
287 kfree(cpu_buffer); 300 kfree(cpu_buffer);
288 return NULL; 301 return NULL;
@@ -293,6 +306,9 @@ static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer)
293 struct list_head *head = &cpu_buffer->pages; 306 struct list_head *head = &cpu_buffer->pages;
294 struct buffer_page *page, *tmp; 307 struct buffer_page *page, *tmp;
295 308
309 list_del_init(&cpu_buffer->reader_page->list);
310 free_buffer_page(cpu_buffer->reader_page);
311
296 list_for_each_entry_safe(page, tmp, head, list) { 312 list_for_each_entry_safe(page, tmp, head, list) {
297 list_del_init(&page->list); 313 list_del_init(&page->list);
298 free_buffer_page(page); 314 free_buffer_page(page);
@@ -538,8 +554,10 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size)
538 554
539static inline int rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer) 555static inline int rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer)
540{ 556{
541 return cpu_buffer->head_page == cpu_buffer->tail_page && 557 return (cpu_buffer->reader == cpu_buffer->reader_page->size &&
542 cpu_buffer->head == cpu_buffer->tail; 558 (cpu_buffer->tail_page == cpu_buffer->reader_page ||
559 (cpu_buffer->tail_page == cpu_buffer->head_page &&
560 cpu_buffer->head == cpu_buffer->tail)));
543} 561}
544 562
545static inline int rb_null_event(struct ring_buffer_event *event) 563static inline int rb_null_event(struct ring_buffer_event *event)
@@ -555,10 +573,10 @@ static inline void *rb_page_index(struct buffer_page *page, unsigned index)
555} 573}
556 574
557static inline struct ring_buffer_event * 575static inline struct ring_buffer_event *
558rb_head_event(struct ring_buffer_per_cpu *cpu_buffer) 576rb_reader_event(struct ring_buffer_per_cpu *cpu_buffer)
559{ 577{
560 return rb_page_index(cpu_buffer->head_page, 578 return rb_page_index(cpu_buffer->reader_page,
561 cpu_buffer->head); 579 cpu_buffer->reader);
562} 580}
563 581
564static inline struct ring_buffer_event * 582static inline struct ring_buffer_event *
@@ -610,15 +628,32 @@ rb_add_stamp(struct ring_buffer_per_cpu *cpu_buffer, u64 *ts)
610 cpu_buffer->write_stamp = *ts; 628 cpu_buffer->write_stamp = *ts;
611} 629}
612 630
613static void rb_reset_read_page(struct ring_buffer_per_cpu *cpu_buffer) 631static void rb_reset_head_page(struct ring_buffer_per_cpu *cpu_buffer)
614{ 632{
615 cpu_buffer->read_stamp = cpu_buffer->head_page->time_stamp;
616 cpu_buffer->head = 0; 633 cpu_buffer->head = 0;
617} 634}
618 635
619static void 636static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
620rb_reset_iter_read_page(struct ring_buffer_iter *iter)
621{ 637{
638 cpu_buffer->read_stamp = cpu_buffer->reader_page->time_stamp;
639 cpu_buffer->reader = 0;
640}
641
642static inline void rb_inc_iter(struct ring_buffer_iter *iter)
643{
644 struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
645
646 /*
647 * The iterator could be on the reader page (it starts there).
648 * But the head could have moved, since the reader was
649 * found. Check for this case and assign the iterator
650 * to the head page instead of next.
651 */
652 if (iter->head_page == cpu_buffer->reader_page)
653 iter->head_page = cpu_buffer->head_page;
654 else
655 rb_inc_page(cpu_buffer, &iter->head_page);
656
622 iter->read_stamp = iter->head_page->time_stamp; 657 iter->read_stamp = iter->head_page->time_stamp;
623 iter->head = 0; 658 iter->head = 0;
624} 659}
@@ -693,30 +728,39 @@ static struct ring_buffer_event *
693__rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, 728__rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
694 unsigned type, unsigned long length, u64 *ts) 729 unsigned type, unsigned long length, u64 *ts)
695{ 730{
696 struct buffer_page *head_page, *tail_page; 731 struct buffer_page *tail_page, *head_page, *reader_page;
697 unsigned long tail; 732 unsigned long tail;
698 struct ring_buffer *buffer = cpu_buffer->buffer; 733 struct ring_buffer *buffer = cpu_buffer->buffer;
699 struct ring_buffer_event *event; 734 struct ring_buffer_event *event;
700 735
736 /* No locking needed for tail page */
701 tail_page = cpu_buffer->tail_page; 737 tail_page = cpu_buffer->tail_page;
702 head_page = cpu_buffer->head_page;
703 tail = cpu_buffer->tail; 738 tail = cpu_buffer->tail;
704 739
705 if (tail + length > BUF_PAGE_SIZE) { 740 if (tail + length > BUF_PAGE_SIZE) {
706 struct buffer_page *next_page = tail_page; 741 struct buffer_page *next_page = tail_page;
707 742
743 spin_lock(&cpu_buffer->lock);
708 rb_inc_page(cpu_buffer, &next_page); 744 rb_inc_page(cpu_buffer, &next_page);
709 745
746 head_page = cpu_buffer->head_page;
747 reader_page = cpu_buffer->reader_page;
748
749 /* we grabbed the lock before incrementing */
750 WARN_ON(next_page == reader_page);
751
710 if (next_page == head_page) { 752 if (next_page == head_page) {
711 if (!(buffer->flags & RB_FL_OVERWRITE)) 753 if (!(buffer->flags & RB_FL_OVERWRITE)) {
754 spin_unlock(&cpu_buffer->lock);
712 return NULL;