Skip to content

Commit 1bd25a6

Browse files
committed
tracing: Show module names and addresses of last boot
Add the last boot module's names and addresses to the last_boot_info file. This only shows the module information from a previous boot. If the buffer is started and is recording the current boot, this file still will only show "current". ~# cat instances/boot_mapped/last_boot_info 10c00000 [kernel] ffffffffc00ca000 usb_serial_simple ffffffffc00ae000 usbserial ffffffffc008b000 bfq ~# echo function > instances/boot_mapped/current_tracer ~# cat instances/boot_mapped/last_boot_info # Current Cc: Masami Hiramatsu <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Cc: Andrew Morton <[email protected]> Link: https://lore.kernel.org/[email protected] Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent fd39e48 commit 1bd25a6

File tree

1 file changed

+89
-13
lines changed

1 file changed

+89
-13
lines changed

kernel/trace/trace.c

Lines changed: 89 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5999,6 +5999,8 @@ struct trace_scratch {
59995999
struct trace_mod_entry entries[];
60006000
};
60016001

6002+
static DEFINE_MUTEX(scratch_mutex);
6003+
60026004
static int save_mod(struct module *mod, void *data)
60036005
{
60046006
struct trace_array *tr = data;
@@ -6039,6 +6041,7 @@ static void update_last_data(struct trace_array *tr)
60396041
flex_array_size(tscratch, entries, tscratch->nr_entries));
60406042
tscratch->nr_entries = 0;
60416043

6044+
guard(mutex)(&scratch_mutex);
60426045
module_for_each_mod(save_mod, tr);
60436046
}
60446047

@@ -6876,15 +6879,47 @@ tracing_total_entries_read(struct file *filp, char __user *ubuf,
68766879
return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
68776880
}
68786881

6879-
static ssize_t
6880-
tracing_last_boot_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
6882+
#define LAST_BOOT_HEADER ((void *)1)
6883+
6884+
static void *l_next(struct seq_file *m, void *v, loff_t *pos)
68816885
{
6882-
struct trace_array *tr = filp->private_data;
6886+
struct trace_array *tr = m->private;
68836887
struct trace_scratch *tscratch = tr->scratch;
6884-
struct seq_buf seq;
6885-
char buf[64];
6888+
unsigned int index = *pos;
6889+
6890+
(*pos)++;
68866891

6887-
seq_buf_init(&seq, buf, 64);
6892+
if (*pos == 1)
6893+
return LAST_BOOT_HEADER;
6894+
6895+
/* Only show offsets of the last boot data */
6896+
if (!tscratch || !(tr->flags & TRACE_ARRAY_FL_LAST_BOOT))
6897+
return NULL;
6898+
6899+
/* *pos 0 is for the header, 1 is for the first module */
6900+
index--;
6901+
6902+
if (index >= tscratch->nr_entries)
6903+
return NULL;
6904+
6905+
return &tscratch->entries[index];
6906+
}
6907+
6908+
static void *l_start(struct seq_file *m, loff_t *pos)
6909+
{
6910+
mutex_lock(&scratch_mutex);
6911+
6912+
return l_next(m, NULL, pos);
6913+
}
6914+
6915+
static void l_stop(struct seq_file *m, void *p)
6916+
{
6917+
mutex_unlock(&scratch_mutex);
6918+
}
6919+
6920+
static void show_last_boot_header(struct seq_file *m, struct trace_array *tr)
6921+
{
6922+
struct trace_scratch *tscratch = tr->scratch;
68886923

68896924
/*
68906925
* Do not leak KASLR address. This only shows the KASLR address of
@@ -6894,11 +6929,52 @@ tracing_last_boot_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t
68946929
* should not be the same as the current boot.
68956930
*/
68966931
if (tscratch && (tr->flags & TRACE_ARRAY_FL_LAST_BOOT))
6897-
seq_buf_printf(&seq, "%lx\t[kernel]\n", tscratch->kaslr_addr);
6932+
seq_printf(m, "%lx\t[kernel]\n", tscratch->kaslr_addr);
68986933
else
6899-
seq_buf_puts(&seq, "# Current\n");
6934+
seq_puts(m, "# Current\n");
6935+
}
69006936

6901-
return simple_read_from_buffer(ubuf, cnt, ppos, buf, seq_buf_used(&seq));
6937+
static int l_show(struct seq_file *m, void *v)
6938+
{
6939+
struct trace_array *tr = m->private;
6940+
struct trace_mod_entry *entry = v;
6941+
6942+
if (v == LAST_BOOT_HEADER) {
6943+
show_last_boot_header(m, tr);
6944+
return 0;
6945+
}
6946+
6947+
seq_printf(m, "%lx\t%s\n", entry->mod_addr, entry->mod_name);
6948+
return 0;
6949+
}
6950+
6951+
static const struct seq_operations last_boot_seq_ops = {
6952+
.start = l_start,
6953+
.next = l_next,
6954+
.stop = l_stop,
6955+
.show = l_show,
6956+
};
6957+
6958+
static int tracing_last_boot_open(struct inode *inode, struct file *file)
6959+
{
6960+
struct trace_array *tr = inode->i_private;
6961+
struct seq_file *m;
6962+
int ret;
6963+
6964+
ret = tracing_check_open_get_tr(tr);
6965+
if (ret)
6966+
return ret;
6967+
6968+
ret = seq_open(file, &last_boot_seq_ops);
6969+
if (ret) {
6970+
trace_array_put(tr);
6971+
return ret;
6972+
}
6973+
6974+
m = file->private_data;
6975+
m->private = tr;
6976+
6977+
return 0;
69026978
}
69036979

69046980
static int tracing_buffer_meta_open(struct inode *inode, struct file *filp)
@@ -7527,10 +7603,10 @@ static const struct file_operations trace_time_stamp_mode_fops = {
75277603
};
75287604

75297605
static const struct file_operations last_boot_fops = {
7530-
.open = tracing_open_generic_tr,
7531-
.read = tracing_last_boot_read,
7532-
.llseek = generic_file_llseek,
7533-
.release = tracing_release_generic_tr,
7606+
.open = tracing_last_boot_open,
7607+
.read = seq_read,
7608+
.llseek = seq_lseek,
7609+
.release = tracing_seq_release,
75347610
};
75357611

75367612
#ifdef CONFIG_TRACER_SNAPSHOT

0 commit comments

Comments
 (0)