14fa54
From 2ed07609b2a8ed19ce3dda7a50b18373a6a8bd5c Mon Sep 17 00:00:00 2001
14fa54
From: Dave Anderson <anderson@redhat.com>
14fa54
Date: Mon, 25 Mar 2019 11:48:39 -0400
14fa54
Subject: [PATCH 1/3] Fixes for the "trace.so" extension module: (1) The
14fa54
 reader_page can be empty if it was never read, do not record     it if it is
14fa54
 empty. Better yet, do not record any page that is     empty.  The struct
14fa54
 buffer_page "real_end" is not available in     older kernels, so it needs to
14fa54
 be tested if it exists before we     can use it. (2) In newer kernels, the
14fa54
 sp->type of kernel module symbols does not     contain the symbol type
14fa54
 character unless the module's debuginfo     data has been loaded into the
14fa54
 crash session.  Writing a garbage     type to the kallsyms file for trace-cmd
14fa54
 to read causes it to     crash, so just always write an 'm'. (3) Add the
14fa54
 "trace dump -t <trace.dat>" option to the SYNOPSIS line     of the help page.
14fa54
 (rostedt@goodmis.org)
14fa54
14fa54
---
14fa54
 trace.c | 32 +++++++++++++++++++++++++++++---
14fa54
 1 file changed, 29 insertions(+), 3 deletions(-)
14fa54
14fa54
diff --git a/trace.c b/trace.c
14fa54
index ad71951e8740..c26b6c7ec475 100644
14fa54
--- a/trace.c
14fa54
+++ b/trace.c
14fa54
@@ -43,6 +43,11 @@ static int max_buffer_available;
14fa54
  */
14fa54
 static int multiple_instances_available;
14fa54
 
14fa54
+/*
14fa54
+ * buffer_page has "real_end"
14fa54
+ */
14fa54
+static int buffer_page_real_end_available;
14fa54
+
14fa54
 #define koffset(struct, member) struct##_##member##_offset
14fa54
 
14fa54
 static int koffset(trace_array, current_trace);
14fa54
@@ -70,6 +75,7 @@ static int koffset(ring_buffer_per_cpu, entries);
14fa54
 static int koffset(buffer_page, read);
14fa54
 static int koffset(buffer_page, list);
14fa54
 static int koffset(buffer_page, page);
14fa54
+static int koffset(buffer_page, real_end);
14fa54
 
14fa54
 static int koffset(list_head, next);
14fa54
 
14fa54
@@ -229,6 +235,7 @@ static int init_offsets(void)
14fa54
 	init_offset(buffer_page, read);
14fa54
 	init_offset(buffer_page, list);
14fa54
 	init_offset(buffer_page, page);
14fa54
+	init_offset(buffer_page, real_end);
14fa54
 
14fa54
 	init_offset(list_head, next);
14fa54
 
14fa54
@@ -281,6 +288,7 @@ static void print_offsets(void)
14fa54
 	print_offset(buffer_page, read);
14fa54
 	print_offset(buffer_page, list);
14fa54
 	print_offset(buffer_page, page);
14fa54
+	print_offset(buffer_page, real_end);
14fa54
 
14fa54
 	print_offset(list_head, next);
14fa54
 
14fa54
@@ -295,6 +303,20 @@ static void print_offsets(void)
14fa54
 #undef print_offset
14fa54
 }
14fa54
 
14fa54
+static int buffer_page_has_data(ulong page)
14fa54
+{
14fa54
+	uint end;
14fa54
+
14fa54
+	if (!buffer_page_real_end_available)
14fa54
+		return 1;
14fa54
+
14fa54
+	/* Only write pages with data in it */
14fa54
+	read_value(end, page, buffer_page, real_end);
14fa54
+	return end;
14fa54
+out_fail:
14fa54
+	return 0;
14fa54
+}
14fa54
+
14fa54
 static int ftrace_init_pages(struct ring_buffer_per_cpu *cpu_buffer,
14fa54
 		unsigned nr_pages)
14fa54
 {
14fa54
@@ -361,7 +383,8 @@ static int ftrace_init_pages(struct ring_buffer_per_cpu *cpu_buffer,
14fa54
 
14fa54
 	/* Setup linear pages */
14fa54
 
14fa54
-	cpu_buffer->linear_pages[count++] = cpu_buffer->reader_page;
14fa54
+	if (buffer_page_has_data(cpu_buffer->reader_page))
14fa54
+		cpu_buffer->linear_pages[count++] = cpu_buffer->reader_page;
14fa54
 
14fa54
 	if (cpu_buffer->reader_page == cpu_buffer->commit_page)
14fa54
 		goto done;
14fa54
@@ -647,6 +670,8 @@ static int ftrace_init(void)
14fa54
 		ftrace_trace_arrays = sym_ftrace_trace_arrays->value;
14fa54
 	}
14fa54
 
14fa54
+	if (MEMBER_EXISTS("buffer_page", "real_end"))
14fa54
+		buffer_page_real_end_available = 1;
14fa54
 
14fa54
 	if (MEMBER_EXISTS("trace_array", "current_trace")) {
14fa54
 		encapsulated_current_trace = 1;
14fa54
@@ -1809,7 +1834,7 @@ static void cmd_ftrace(void)
14fa54
 static char *help_ftrace[] = {
14fa54
 "trace",
14fa54
 "show or dump the tracing info",
14fa54
-"[ <show [-c <cpulist>] [-f [no]<flagname>]> | <dump [-sm] <dest-dir>> ]",
14fa54
+"[ <show [-c <cpulist>] [-f [no]<flagname>]> | <dump [-sm] <dest-dir>> ] | <dump -t <trace.dat> ]",
14fa54
 "trace",
14fa54
 "    shows the current tracer and other informations.",
14fa54
 "",
14fa54
@@ -2184,7 +2209,8 @@ static int save_proc_kallsyms(int fd)
14fa54
 			if (!strncmp(sp->name, "_MODULE_", strlen("_MODULE_")))
14fa54
 				continue;
14fa54
 
14fa54
-			tmp_fprintf("%lx %c %s\t[%s]\n", sp->value, sp->type,
14fa54
+			/* Currently sp->type for modules is not trusted */
14fa54
+			tmp_fprintf("%lx %c %s\t[%s]\n", sp->value, 'm',
14fa54
 					sp->name, lm->mod_name);
14fa54
 		}
14fa54
 	}
14fa54
-- 
14fa54
2.17.1
14fa54