kernel/trace/simple_ring_buffer.c
Source file repositories/reference/linux-study-clean/kernel/trace/simple_ring_buffer.c
File Facts
- System
- Linux kernel
- Corpus path
kernel/trace/simple_ring_buffer.c- Extension
.c- Size
- 13800 bytes
- Lines
- 518
- Domain
- Core OS
- Bucket
- Scheduler, Processes, Timers, Sync, And Syscalls
- Inferred role
- Core OS: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/atomic.hlinux/simple_ring_buffer.hasm/barrier.hasm/local.h
Detected Declarations
enum simple_rb_link_typefunction simple_bpage_set_head_linkfunction simple_bpage_unset_head_linkfunction simple_bpage_set_normal_linkfunction simple_bpage_resetfunction simple_bpage_initfunction simple_rb_loadedfunction simple_rb_find_headfunction simple_ring_buffer_swap_reader_pagefunction rb_event_sizefunction rb_event_add_ts_extendfunction simple_rb_reserve_nextfunction simple_ring_buffer_commitfunction simple_rb_enable_tracingfunction simple_ring_buffer_resetfunction simple_ring_buffer_init_mmfunction __unload_pagefunction simple_ring_buffer_unload_mmfunction simple_ring_buffer_unloadfunction simple_ring_buffer_enable_tracingexport simple_ring_buffer_swap_reader_pageexport simple_ring_buffer_reserveexport simple_ring_buffer_commitexport simple_ring_buffer_resetexport simple_ring_buffer_initexport simple_ring_buffer_unloadexport simple_ring_buffer_enable_tracing
Annotated Snippet
switch (link & ~SIMPLE_RB_LINK_MASK) {
/* Found the head */
case SIMPLE_RB_LINK_HEAD:
cpu_buffer->head_page = head;
return 0;
/* The writer caught the head, we can spin, that won't be long */
case SIMPLE_RB_LINK_HEAD_MOVING:
goto spin;
}
head = simple_bpage_next_page(head);
}
return -EBUSY;
}
/**
* simple_ring_buffer_swap_reader_page - Swap ring-buffer head with the reader
* @cpu_buffer: A simple_rb_per_cpu
*
* This function enables consuming reading. It ensures the current head page will not be overwritten
* and can be safely read.
*
* Returns 0 on success, -ENODEV if @cpu_buffer was unloaded or -EBUSY if we failed to catch the
* head page.
*/
int simple_ring_buffer_swap_reader_page(struct simple_rb_per_cpu *cpu_buffer)
{
struct simple_buffer_page *last, *head, *reader;
unsigned long overrun;
int retry = 8;
int ret;
if (!simple_rb_loaded(cpu_buffer))
return -ENODEV;
reader = cpu_buffer->reader_page;
do {
/* Run after the writer to find the head */
ret = simple_rb_find_head(cpu_buffer);
if (ret)
return ret;
head = cpu_buffer->head_page;
/* Connect the reader page around the header page */
reader->link.next = head->link.next;
reader->link.prev = head->link.prev;
/* The last page before the head */
last = simple_bpage_from_link(head->link.prev);
/* The reader page points to the new header page */
simple_bpage_set_head_link(reader);
overrun = cpu_buffer->meta->overrun;
} while (!simple_bpage_unset_head_link(last, reader, SIMPLE_RB_LINK_NORMAL) && retry--);
if (!retry)
return -EINVAL;
cpu_buffer->head_page = simple_bpage_from_link(reader->link.next);
cpu_buffer->head_page->link.prev = &reader->link;
cpu_buffer->reader_page = head;
cpu_buffer->meta->reader.lost_events = overrun - cpu_buffer->last_overrun;
cpu_buffer->meta->reader.id = cpu_buffer->reader_page->id;
cpu_buffer->last_overrun = overrun;
return 0;
}
EXPORT_SYMBOL_GPL(simple_ring_buffer_swap_reader_page);
static struct simple_buffer_page *simple_rb_move_tail(struct simple_rb_per_cpu *cpu_buffer)
{
struct simple_buffer_page *tail, *new_tail;
tail = cpu_buffer->tail_page;
new_tail = simple_bpage_next_page(tail);
if (simple_bpage_unset_head_link(tail, new_tail, SIMPLE_RB_LINK_HEAD_MOVING)) {
/*
* Oh no! we've caught the head. There is none anymore and
* swap_reader will spin until we set the new one. Overrun must
* be written first, to make sure we report the correct number
* of lost events.
*/
simple_rb_meta_inc(cpu_buffer->meta->overrun, new_tail->entries);
simple_rb_meta_inc(cpu_buffer->meta->pages_lost, 1);
Annotation
- Immediate include surface: `linux/atomic.h`, `linux/simple_ring_buffer.h`, `asm/barrier.h`, `asm/local.h`.
- Detected declarations: `enum simple_rb_link_type`, `function simple_bpage_set_head_link`, `function simple_bpage_unset_head_link`, `function simple_bpage_set_normal_link`, `function simple_bpage_reset`, `function simple_bpage_init`, `function simple_rb_loaded`, `function simple_rb_find_head`, `function simple_ring_buffer_swap_reader_page`, `function rb_event_size`.
- Atlas domain: Core OS / Scheduler, Processes, Timers, Sync, And Syscalls.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.