Skip to content

Commit 950032f

Browse files
committed
ring-buffer: Add output of ring buffer meta page
Add a buffer_meta per-cpu file for the trace instance that is mapped to boot memory. This shows the current meta-data and can be used by user space tools to record off the current mappings to help reconstruct the ring buffer after a reboot. It does not expose any virtual addresses, just indexes into the sub-buffer pages. Link: https://lkml.kernel.org/r/[email protected] Cc: Masami Hiramatsu <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Vincent Donnefort <[email protected]> Cc: Joel Fernandes <[email protected]> Cc: Daniel Bristot de Oliveira <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Vineeth Pillai <[email protected]> Cc: Youssef Esmat <[email protected]> Cc: Beau Belgrave <[email protected]> Cc: Alexander Graf <[email protected]> Cc: Baoquan He <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: "Paul E. McKenney" <[email protected]> Cc: David Howells <[email protected]> Cc: Mike Rapoport <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Tony Luck <[email protected]> Cc: Guenter Roeck <[email protected]> Cc: Ross Zwisler <[email protected]> Cc: Kees Cook <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent 2124de7 commit 950032f

File tree

3 files changed

+107
-2
lines changed

3 files changed

+107
-2
lines changed

kernel/trace/ring_buffer.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include <asm/local64.h>
3333
#include <asm/local.h>
3434

35+
#include "trace.h"
36+
3537
/*
3638
* The "absolute" timestamp in the buffer is only 59 bits.
3739
* If a clock has the 5 MSBs set, it needs to be saved and
@@ -1647,6 +1649,81 @@ static void rb_range_meta_init(struct trace_buffer *buffer, int nr_pages)
16471649
}
16481650
}
16491651

1652+
static void *rbm_start(struct seq_file *m, loff_t *pos)
1653+
{
1654+
struct ring_buffer_per_cpu *cpu_buffer = m->private;
1655+
struct ring_buffer_meta *meta = cpu_buffer->ring_meta;
1656+
unsigned long val;
1657+
1658+
if (!meta)
1659+
return NULL;
1660+
1661+
if (*pos > meta->nr_subbufs)
1662+
return NULL;
1663+
1664+
val = *pos;
1665+
val++;
1666+
1667+
return (void *)val;
1668+
}
1669+
1670+
static void *rbm_next(struct seq_file *m, void *v, loff_t *pos)
1671+
{
1672+
(*pos)++;
1673+
1674+
return rbm_start(m, pos);
1675+
}
1676+
1677+
static int rb_meta_subbuf_idx(struct ring_buffer_meta *meta, void *subbuf);
1678+
1679+
static int rbm_show(struct seq_file *m, void *v)
1680+
{
1681+
struct ring_buffer_per_cpu *cpu_buffer = m->private;
1682+
struct ring_buffer_meta *meta = cpu_buffer->ring_meta;
1683+
unsigned long val = (unsigned long)v;
1684+
1685+
if (val == 1) {
1686+
seq_printf(m, "head_buffer: %d\n",
1687+
rb_meta_subbuf_idx(meta, (void *)meta->head_buffer));
1688+
seq_printf(m, "commit_buffer: %d\n",
1689+
rb_meta_subbuf_idx(meta, (void *)meta->commit_buffer));
1690+
seq_printf(m, "subbuf_size: %d\n", meta->subbuf_size);
1691+
seq_printf(m, "nr_subbufs: %d\n", meta->nr_subbufs);
1692+
return 0;
1693+
}
1694+
1695+
val -= 2;
1696+
seq_printf(m, "buffer[%ld]: %d\n", val, meta->buffers[val]);
1697+
1698+
return 0;
1699+
}
1700+
1701+
static void rbm_stop(struct seq_file *m, void *p)
1702+
{
1703+
}
1704+
1705+
static const struct seq_operations rb_meta_seq_ops = {
1706+
.start = rbm_start,
1707+
.next = rbm_next,
1708+
.show = rbm_show,
1709+
.stop = rbm_stop,
1710+
};
1711+
1712+
int ring_buffer_meta_seq_init(struct file *file, struct trace_buffer *buffer, int cpu)
1713+
{
1714+
struct seq_file *m;
1715+
int ret;
1716+
1717+
ret = seq_open(file, &rb_meta_seq_ops);
1718+
if (ret)
1719+
return ret;
1720+
1721+
m = file->private_data;
1722+
m->private = buffer->buffers[cpu];
1723+
1724+
return 0;
1725+
}
1726+
16501727
static int __rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
16511728
long nr_pages, struct list_head *pages)
16521729
{

kernel/trace/trace.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5018,7 +5018,7 @@ static int show_traces_open(struct inode *inode, struct file *file)
50185018
return 0;
50195019
}
50205020

5021-
static int show_traces_release(struct inode *inode, struct file *file)
5021+
static int tracing_seq_release(struct inode *inode, struct file *file)
50225022
{
50235023
struct trace_array *tr = inode->i_private;
50245024

@@ -5059,7 +5059,7 @@ static const struct file_operations show_traces_fops = {
50595059
.open = show_traces_open,
50605060
.read = seq_read,
50615061
.llseek = seq_lseek,
5062-
.release = show_traces_release,
5062+
.release = tracing_seq_release,
50635063
};
50645064

50655065
static ssize_t
@@ -6860,6 +6860,22 @@ tracing_total_entries_read(struct file *filp, char __user *ubuf,
68606860
return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
68616861
}
68626862

6863+
static int tracing_buffer_meta_open(struct inode *inode, struct file *filp)
6864+
{
6865+
struct trace_array *tr = inode->i_private;
6866+
int cpu = tracing_get_cpu(inode);
6867+
int ret;
6868+
6869+
ret = tracing_check_open_get_tr(tr);
6870+
if (ret)
6871+
return ret;
6872+
6873+
ret = ring_buffer_meta_seq_init(filp, tr->array_buffer.buffer, cpu);
6874+
if (ret < 0)
6875+
__trace_array_put(tr);
6876+
return ret;
6877+
}
6878+
68636879
static ssize_t
68646880
tracing_free_buffer_write(struct file *filp, const char __user *ubuf,
68656881
size_t cnt, loff_t *ppos)
@@ -7436,6 +7452,13 @@ static const struct file_operations tracing_entries_fops = {
74367452
.release = tracing_release_generic_tr,
74377453
};
74387454

7455+
static const struct file_operations tracing_buffer_meta_fops = {
7456+
.open = tracing_buffer_meta_open,
7457+
.read = seq_read,
7458+
.llseek = seq_lseek,
7459+
.release = tracing_seq_release,
7460+
};
7461+
74397462
static const struct file_operations tracing_total_entries_fops = {
74407463
.open = tracing_open_generic_tr,
74417464
.read = tracing_total_entries_read,
@@ -8668,6 +8691,9 @@ tracing_init_tracefs_percpu(struct trace_array *tr, long cpu)
86688691
trace_create_cpu_file("buffer_size_kb", TRACE_MODE_READ, d_cpu,
86698692
tr, cpu, &tracing_entries_fops);
86708693

8694+
if (tr->range_addr_start)
8695+
trace_create_cpu_file("buffer_meta", TRACE_MODE_READ, d_cpu,
8696+
tr, cpu, &tracing_buffer_meta_fops);
86718697
#ifdef CONFIG_TRACER_SNAPSHOT
86728698
if (!tr->range_addr_start) {
86738699
trace_create_cpu_file("snapshot", TRACE_MODE_WRITE, d_cpu,

kernel/trace/trace.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,8 @@ trace_buffer_lock_reserve(struct trace_buffer *buffer,
645645
unsigned long len,
646646
unsigned int trace_ctx);
647647

648+
int ring_buffer_meta_seq_init(struct file *file, struct trace_buffer *buffer, int cpu);
649+
648650
struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
649651
struct trace_array_cpu *data);
650652

0 commit comments

Comments
 (0)