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