Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ring-buffer: Add non-consuming read for ring-buffer remotes

Hopefully, the remote will only swap pages on the kernel instruction (via
the swap_reader_page() callback). This means we know at what point the
ring-buffer geometry has changed. It is therefore possible to rearrange
the kernel view of that ring-buffer to allow non-consuming read.

Link: https://patch.msgid.link/20260309162516.2623589-5-vdonnefort@google.com
Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

authored by

Vincent Donnefort and committed by
Steven Rostedt (Google)
fbd1743e 2e67fabd

+69 -6
+69 -6
kernel/trace/ring_buffer.c
··· 5388 5388 return rb_num_of_entries(cpu_buffer); 5389 5389 } 5390 5390 5391 + static void rb_update_remote_head(struct ring_buffer_per_cpu *cpu_buffer) 5392 + { 5393 + struct buffer_page *next, *orig; 5394 + int retry = 3; 5395 + 5396 + orig = next = cpu_buffer->head_page; 5397 + rb_inc_page(&next); 5398 + 5399 + /* Run after the writer */ 5400 + while (cpu_buffer->head_page->page->time_stamp > next->page->time_stamp) { 5401 + rb_inc_page(&next); 5402 + 5403 + rb_list_head_clear(cpu_buffer->head_page->list.prev); 5404 + rb_inc_page(&cpu_buffer->head_page); 5405 + rb_set_list_to_head(cpu_buffer->head_page->list.prev); 5406 + 5407 + if (cpu_buffer->head_page == orig) { 5408 + if (WARN_ON_ONCE(!(--retry))) 5409 + return; 5410 + } 5411 + } 5412 + 5413 + orig = cpu_buffer->commit_page = cpu_buffer->head_page; 5414 + retry = 3; 5415 + 5416 + while (cpu_buffer->commit_page->page->time_stamp < next->page->time_stamp) { 5417 + rb_inc_page(&next); 5418 + rb_inc_page(&cpu_buffer->commit_page); 5419 + 5420 + if (cpu_buffer->commit_page == orig) { 5421 + if (WARN_ON_ONCE(!(--retry))) 5422 + return; 5423 + } 5424 + } 5425 + } 5426 + 5391 5427 static void rb_iter_reset(struct ring_buffer_iter *iter) 5392 5428 { 5393 5429 struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer; 5430 + 5431 + if (cpu_buffer->remote) { 5432 + rb_read_remote_meta_page(cpu_buffer); 5433 + rb_update_remote_head(cpu_buffer); 5434 + } 5394 5435 5395 5436 /* Iterator usage is expected to have record disabled */ 5396 5437 iter->head_page = cpu_buffer->reader_page; ··· 5585 5544 static struct buffer_page * 5586 5545 __rb_get_reader_page_from_remote(struct ring_buffer_per_cpu *cpu_buffer) 5587 5546 { 5588 - struct buffer_page *new_reader, *prev_reader; 5547 + struct buffer_page *new_reader, *prev_reader, *prev_head, *new_head, *last; 5589 5548 5590 5549 if (!rb_read_remote_meta_page(cpu_buffer)) 5591 5550 return NULL; ··· 5609 5568 5610 5569 WARN_ON_ONCE(prev_reader == new_reader); 5611 5570 5612 - cpu_buffer->reader_page->page = new_reader->page; 5613 - cpu_buffer->reader_page->id = new_reader->id; 5614 - cpu_buffer->reader_page->read = 0; 5615 - cpu_buffer->read_stamp = cpu_buffer->reader_page->page->time_stamp; 5571 + prev_head = new_reader; /* New reader was also the previous head */ 5572 + new_head = prev_head; 5573 + rb_inc_page(&new_head); 5574 + last = prev_head; 5575 + rb_dec_page(&last); 5576 + 5577 + /* Clear the old HEAD flag */ 5578 + rb_list_head_clear(cpu_buffer->head_page->list.prev); 5579 + 5580 + prev_reader->list.next = prev_head->list.next; 5581 + prev_reader->list.prev = prev_head->list.prev; 5582 + 5583 + /* Swap prev_reader with new_reader */ 5584 + last->list.next = &prev_reader->list; 5585 + new_head->list.prev = &prev_reader->list; 5586 + 5587 + new_reader->list.prev = &new_reader->list; 5588 + new_reader->list.next = &new_head->list; 5589 + 5590 + /* Reactivate the HEAD flag */ 5591 + rb_set_list_to_head(&last->list); 5592 + 5593 + cpu_buffer->head_page = new_head; 5594 + cpu_buffer->reader_page = new_reader; 5595 + cpu_buffer->pages = &new_head->list; 5596 + cpu_buffer->read_stamp = new_reader->page->time_stamp; 5616 5597 cpu_buffer->lost_events = cpu_buffer->meta_page->reader.lost_events; 5617 5598 5618 5599 return rb_page_size(cpu_buffer->reader_page) ? cpu_buffer->reader_page : NULL; ··· 6218 6155 struct ring_buffer_per_cpu *cpu_buffer; 6219 6156 struct ring_buffer_iter *iter; 6220 6157 6221 - if (!cpumask_test_cpu(cpu, buffer->cpumask) || buffer->remote) 6158 + if (!cpumask_test_cpu(cpu, buffer->cpumask)) 6222 6159 return NULL; 6223 6160 6224 6161 iter = kzalloc_obj(*iter, flags);