Skip to contentSkip to conversation

tracing: Updates for 4.10

PATCH New Steven Rostedt 1 participant 18 messages Nov 23, 2016

Subsystems (9)
lore
Share & tools
lore

Steven Rostedt

author maintainer
#0 lore raw

cover tracing: Updates for 4.10

git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
for-next

Head SHA1: 7d436400223bb46e9f88e6bba6f8d867acf0d82c

Chunyan Zhang (6):
tracing: Add hook to function tracing for other subsystems to use stm class: ftrace: Add ftrace-export-over-stm driver
coresight: Mark stm_generic_packet() with notrace
intel_th: Mark sth_stm_packet() with notrace
stm dummy: Mark dummy_stm_packet() with notrace
stm: Mark the functions of writing STM with notrace

Masami Hiramatsu (8):
selftests: ftrace: Initialize ftrace before each test
selftests: ftrace: Add --quiet option not to show error logs on screen
selftests: ftrace: Check whether snapshot trigger is supported correctly
selftests: ftrace: Fix trigger-mod to run without syscall trace
selftests: ftrace: Hide ftracetest logs from git
selftests: ftrace: Introduce TMPDIR for temporary files
selftests: ftrace: Add a testcase for function filter glob match
selftests: ftrace: Add a testcase for types of kprobe event

Stephen Boyd (1):
recordmcount: arm: Implement make_nop

Steven Rostedt (1):
tracing: Add new trace_marker_raw

Steven Rostedt (Red Hat) (1):
tracing: Add error checks to creation of event files

----

 Documentation/trace/ftrace.txt                     |   6 +
 drivers/hwtracing/coresight/coresight-stm.c        |   2 +-
 drivers/hwtracing/intel_th/sth.c                   |  11 +-
 drivers/hwtracing/stm/Kconfig                      |  11 +
 drivers/hwtracing/stm/Makefile                     |   2 +
 drivers/hwtracing/stm/core.c                       |   7 +-
 drivers/hwtracing/stm/dummy_stm.c                  |   2 +-
 drivers/hwtracing/stm/ftrace.c                     |  87 ++++++
 include/linux/stm.h                                |   4 +-
 include/linux/trace.h                              |  28 ++
 kernel/trace/trace.c                               | 294 ++++++++++++++++++---
 kernel/trace/trace.h                               |   2 +
 kernel/trace/trace_entries.h                       |  15 ++
 kernel/trace/trace_events.c                        |  30 ++-
 kernel/trace/trace_output.c                        |  30 +++
 scripts/recordmcount.c                             |  65 +++++
 tools/testing/selftests/ftrace/.gitignore          |   1 +
 tools/testing/selftests/ftrace/ftracetest          |  12 +-
 .../ftrace/test.d/ftrace/func-filter-glob.tc       |  49 ++++
 tools/testing/selftests/ftrace/test.d/functions    |  28 ++
 .../ftrace/test.d/kprobe/kprobe_args_type.tc       |  37 +++
 .../ftrace/test.d/trigger/trigger-hist-mod.tc      |   2 +-
 .../ftrace/test.d/trigger/trigger-snapshot.tc      |   5 +
 23 files changed, 675 insertions(+), 55 deletions(-)
 create mode 100644 drivers/hwtracing/stm/ftrace.c
 create mode 100644 include/linux/trace.h
 create mode 100644 tools/testing/selftests/ftrace/.gitignore
 create mode 100644 tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc
 create mode 100644 tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_type.tc
author maintainer
#1 lore raw

PATCH 1/17 recordmcount: arm: Implement make_nop

From: Stephen Boyd <[email protected]>

In similar spirit to x86 and arm64 support, add a make_nop_arm() to replace calls to mcount with a nop in sections that aren't traced.

---
 scripts/recordmcount.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)
scripts/recordmcount.c +65 -0
index 5423a58d1b06..aeb34223167c 100644
@@ -213,6 +213,59 @@ static int make_nop_x86(void *map, size_t const offset)
 	return 0;
 }
 
+static unsigned char ideal_nop4_arm_le[4] = { 0x00, 0x00, 0xa0, 0xe1 }; /* mov r0, r0 */
+static unsigned char ideal_nop4_arm_be[4] = { 0xe1, 0xa0, 0x00, 0x00 }; /* mov r0, r0 */
+static unsigned char *ideal_nop4_arm;
+
+static unsigned char bl_mcount_arm_le[4] = { 0xfe, 0xff, 0xff, 0xeb }; /* bl */
+static unsigned char bl_mcount_arm_be[4] = { 0xeb, 0xff, 0xff, 0xfe }; /* bl */
+static unsigned char *bl_mcount_arm;
+
+static unsigned char push_arm_le[4] = { 0x04, 0xe0, 0x2d, 0xe5 }; /* push {lr} */
+static unsigned char push_arm_be[4] = { 0xe5, 0x2d, 0xe0, 0x04 }; /* push {lr} */
+static unsigned char *push_arm;
+
+static unsigned char ideal_nop2_thumb_le[2] = { 0x00, 0xbf }; /* nop */
+static unsigned char ideal_nop2_thumb_be[2] = { 0xbf, 0x00 }; /* nop */
+static unsigned char *ideal_nop2_thumb;
+
+static unsigned char push_bl_mcount_thumb_le[6] = { 0x00, 0xb5, 0xff, 0xf7, 0xfe, 0xff }; /* push {lr}, bl */
+static unsigned char push_bl_mcount_thumb_be[6] = { 0xb5, 0x00, 0xf7, 0xff, 0xff, 0xfe }; /* push {lr}, bl */
+static unsigned char *push_bl_mcount_thumb;
+
+static int make_nop_arm(void *map, size_t const offset)
+{
+	char *ptr;
+	int cnt = 1;
+	int nop_size;
+	size_t off = offset;
+
+	ptr = map + offset;
+	if (memcmp(ptr, bl_mcount_arm, 4) == 0) {
+		if (memcmp(ptr - 4, push_arm, 4) == 0) {
+			off -= 4;
+			cnt = 2;
+		}
+		ideal_nop = ideal_nop4_arm;
+		nop_size = 4;
+	} else if (memcmp(ptr - 2, push_bl_mcount_thumb, 6) == 0) {
+		cnt = 3;
+		nop_size = 2;
+		off -= 2;
+		ideal_nop = ideal_nop2_thumb;
+	} else
+		return -1;
+
+	/* Convert to nop */
+	ulseek(fd_map, off, SEEK_SET);
+
+	do {
+		uwrite(fd_map, ideal_nop, nop_size);
+	} while (--cnt > 0);
+
+	return 0;
+}
+
 static unsigned char ideal_nop4_arm64[4] = {0x1f, 0x20, 0x03, 0xd5};
 static int make_nop_arm64(void *map, size_t const offset)
 {
@@ -430,6 +483,11 @@ do_file(char const *const fname)
 			w2 = w2rev;
 			w8 = w8rev;
 		}
+		ideal_nop4_arm = ideal_nop4_arm_le;
+		bl_mcount_arm = bl_mcount_arm_le;
+		push_arm = push_arm_le;
+		ideal_nop2_thumb = ideal_nop2_thumb_le;
+		push_bl_mcount_thumb = push_bl_mcount_thumb_le;
 		break;
 	case ELFDATA2MSB:
 		if (*(unsigned char const *)&endian != 0) {
@@ -438,6 +496,11 @@ do_file(char const *const fname)
 			w2 = w2rev;
 			w8 = w8rev;
 		}
+		ideal_nop4_arm = ideal_nop4_arm_be;
+		bl_mcount_arm = bl_mcount_arm_be;
+		push_arm = push_arm_be;
+		ideal_nop2_thumb = ideal_nop2_thumb_be;
+		push_bl_mcount_thumb = push_bl_mcount_thumb_be;
 		break;
 	}  /* end switch */
 	if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0
@@ -463,6 +526,8 @@ do_file(char const *const fname)
 		break;
 	case EM_ARM:	 reltype = R_ARM_ABS32;
 			 altmcount = "__gnu_mcount_nc";
+			 make_nop = make_nop_arm;
+			 rel_type_nop = R_ARM_NONE;
 			 break;
 	case EM_AARCH64:
 			reltype = R_AARCH64_ABS64;
Signature · 1 line
2.10.2
author maintainer
#2 lore raw

PATCH 2/17 tracing: Add new trace_marker_raw

In reply to Steven Rostedt

From: Steven Rostedt <[email protected]>

A new file is created:

/sys/kernel/debug/tracing/trace_marker_raw

This allows for appications to create data structures and write the binary data directly into it, and then read the trace data out from trace_pipe_raw into the same type of data structure. This saves on converting numbers into ASCII that would be required by trace_marker.

---
 Documentation/trace/ftrace.txt |   6 ++
 kernel/trace/trace.c           | 165 +++++++++++++++++++++++++++++++++--------
 kernel/trace/trace.h           |   2 +
 kernel/trace/trace_entries.h   |  15 ++++
 kernel/trace/trace_output.c    |  30 ++++++++
 5 files changed, 187 insertions(+), 31 deletions(-)
Documentation/trace/ftrace.txt +6 -0
index 1bc66c1db0cb..6c374c5fe400 100644
@@ -396,6 +396,12 @@ of ftrace. Here is a list of some of the key files:
 
 		trace_fd = open("trace_marker", WR_ONLY);
 
+  trace_marker_raw:
+
+	This is similar to trace_marker above, but is meant for for binary data
+	to be written to it, where a tool can be used to parse the data
+	from trace_pipe_raw.
+
   uprobe_events:
  
 	Add dynamic tracepoints in programs.
kernel/trace/trace.c +134 -31

224 lines not on this page · raw message

kernel/trace/trace.h +2 -0
index 4b7918902ab8..9294f8606ade 100644
@@ -40,6 +40,7 @@ enum trace_type {
 	TRACE_BLK,
 	TRACE_BPUTS,
 	TRACE_HWLAT,
+	TRACE_RAW_DATA,
 
 	__TRACE_LAST_TYPE,
 };
@@ -331,6 +332,7 @@ extern void __ftrace_bad_type(void);
 		IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT);	\
 		IF_ASSIGN(var, ent, struct bputs_entry, TRACE_BPUTS);	\
 		IF_ASSIGN(var, ent, struct hwlat_entry, TRACE_HWLAT);	\
+		IF_ASSIGN(var, ent, struct raw_data_entry, TRACE_RAW_DATA);\
 		IF_ASSIGN(var, ent, struct trace_mmiotrace_rw,		\
 			  TRACE_MMIO_RW);				\
 		IF_ASSIGN(var, ent, struct trace_mmiotrace_map,		\
kernel/trace/trace_entries.h +15 -0
index d1cc37e78f99..eb7396b7e7c3 100644
@@ -244,6 +244,21 @@ FTRACE_ENTRY(print, print_entry,
 	FILTER_OTHER
 );
 
+FTRACE_ENTRY(raw_data, raw_data_entry,
+
+	TRACE_RAW_DATA,
+
+	F_STRUCT(
+		__field(	unsigned int,	id	)
+		__dynamic_array(	char,	buf	)
+	),
+
+	F_printk("id:%04x %08x",
+		 __entry->id, (int)__entry->buf[0]),
+
+	FILTER_OTHER
+);
+
 FTRACE_ENTRY(bputs, bputs_entry,
 
 	TRACE_BPUTS,
kernel/trace/trace_output.c +30 -0
index 3fc20422c166..5d33a7352919 100644
@@ -1288,6 +1288,35 @@ static struct trace_event trace_print_event = {
 	.funcs		= &trace_print_funcs,
 };
 
+static enum print_line_t trace_raw_data(struct trace_iterator *iter, int flags,
+					 struct trace_event *event)
+{
+	struct raw_data_entry *field;
+	int i;
+
+	trace_assign_type(field, iter->ent);
+
+	trace_seq_printf(&iter->seq, "# %x buf:", field->id);
+
+	for (i = 0; i < iter->ent_size - offsetof(struct raw_data_entry, buf); i++)
+		trace_seq_printf(&iter->seq, " %02x",
+				 (unsigned char)field->buf[i]);
+
+	trace_seq_putc(&iter->seq, '\n');
+
+	return trace_handle_return(&iter->seq);
+}
+
+static struct trace_event_functions trace_raw_data_funcs = {
+	.trace		= trace_raw_data,
+	.raw		= trace_raw_data,
+};
+
+static struct trace_event trace_raw_data_event = {
+	.type	 	= TRACE_RAW_DATA,
+	.funcs		= &trace_raw_data_funcs,
+};
+
 
 static struct trace_event *events[] __initdata = {
 	&trace_fn_event,
@@ -1299,6 +1328,7 @@ static struct trace_event *events[] __initdata = {
 	&trace_bprint_event,
 	&trace_print_event,
 	&trace_hwlat_event,
+	&trace_raw_data_event,
 	NULL
 };
 
Signature · 1 line
2.10.2
author maintainer
#3 lore raw

PATCH 3/17 selftests: ftrace: Initialize ftrace before each test

In reply to Steven Rostedt

From: Masami Hiramatsu <[email protected]>

Reset ftrace to initial state before running each test. This fixes some test cases to enable tracing before starting trace test. This can avoid false-positive failure when previous testcase fails while disabling tracing.

---
 tools/testing/selftests/ftrace/ftracetest       |  2 +-
 tools/testing/selftests/ftrace/test.d/functions | 28 +++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 1 deletion(-)
tools/testing/selftests/ftrace/ftracetest +1 -1
index 4c6a0bf8ba79..a03d366a4a2f 100755
@@ -228,7 +228,7 @@ trap 'SIG_RESULT=$XFAIL' $SIG_XFAIL
 
 __run_test() { # testfile
   # setup PID and PPID, $$ is not updated.
-  (cd $TRACING_DIR; read PID _ < /proc/self/stat ; set -e; set -x; . $1)
+  (cd $TRACING_DIR; read PID _ < /proc/self/stat; set -e; set -x; initialize_ftrace; . $1)
   [ $? -ne 0 ] && kill -s $SIG_FAIL $SIG_PID
 }
 
tools/testing/selftests/ftrace/test.d/functions +28 -0
index c37262f6c269..91de1a8e4f19 100644
@@ -23,3 +23,31 @@ reset_trigger() { # reset all current setting triggers
     done
 }
 
+reset_events_filter() { # reset all current setting filters
+    grep -v ^none events/*/*/filter |
+    while read line; do
+	echo 0 > `echo $line | cut -f1 -d:`
+    done
+}
+
+disable_events() {
+    echo 0 > events/enable
+}
+
+initialize_ftrace() { # Reset ftrace to initial-state
+# As the initial state, ftrace will be set to nop tracer,
+# no events, no triggers, no filters, no function filters,
+# no probes, and tracing on.
+    disable_tracing
+    reset_tracer
+    reset_trigger
+    reset_events_filter
+    disable_events
+    echo > set_event_pid	# event tracer is always on
+    [ -f set_ftrace_filter ] && echo | tee set_ftrace_*
+    [ -f set_graph_function ] && echo | tee set_graph_*
+    [ -f stack_trace_filter ] && echo > stack_trace_filter
+    [ -f kprobe_events ] && echo > kprobe_events
+    [ -f uprobe_events ] && echo > uprobe_events
+    enable_tracing
+}
Signature · 1 line
2.10.2
author maintainer
#4 lore raw

PATCH 4/17 selftests: ftrace: Add --quiet option not to show error logs on screen

In reply to Steven Rostedt

From: Masami Hiramatsu <[email protected]>

Since the verbose error logs scrolls out previous test results --quiet option suppress to show such message.

e.g.

 # ./ftracetest -q
=== Ftrace unit tests ===
[1] Basic trace file check	[PASS]
[2] Basic test for tracers	[PASS]
[3] Basic trace clock test	[PASS]
[4] Basic event tracing check	[PASS]
[5] event tracing - enable/disable with event level files	[PASS]
[6] event tracing - restricts events based on pid	[PASS]
[7] event tracing - enable/disable with subsystem level files	[PASS]
[8] event tracing - enable/disable with top level files	[PASS]
[9] ftrace - function graph filters with stack tracer	[UNSUPPORTED]
[10] ftrace - function graph filters	[UNSUPPORTED]
[11] ftrace - function profiler with function tracing	[UNSUPPORTED]
[12] Test creation and deletion of trace instances while setting an event
	[PASS]
[13] Test creation and deletion of trace instances	[PASS]
[14] Kprobe dynamic event - adding and removing	[UNSUPPORTED]
[15] Kprobe dynamic event - busy event check	[UNSUPPORTED]
[16] Kprobe dynamic event with arguments	[UNSUPPORTED]
[17] Kprobe dynamic event with function tracer	[UNSUPPORTED]
[18] Kretprobe dynamic event with arguments	[UNSUPPORTED]
[19] event trigger - test event enable/disable trigger	[PASS]
[20] event trigger - test trigger filter	[PASS]
[21] event trigger - test histogram modifiers	[UNSUPPORTED]
[22] event trigger - test histogram trigger	[UNSUPPORTED]
[23] event trigger - test multiple histogram triggers	[UNSUPPORTED]
[24] event trigger - test snapshot-trigger	[FAIL]
[25] event trigger - test stacktrace-trigger	[PASS]
[26] event trigger - test traceon/off trigger	[PASS]
# of passed:  14
# of failed:  1
# of unresolved:  0
# of untested:  0
# of unsupported:  11
# of xfailed:  0
# of undefined(test bug):  0
---
 tools/testing/selftests/ftrace/ftracetest | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
tools/testing/selftests/ftrace/ftracetest +7 -1
index a03d366a4a2f..d08235f65202 100755
@@ -14,6 +14,7 @@ echo " Options:"
 echo "		-h|--help  Show help message"
 echo "		-k|--keep  Keep passed test logs"
 echo "		-v|--verbose Show all stdout messages in testcases"
+echo "		-q|--quiet Do not show error log on stdout"
 echo "		-d|--debug Debug mode (trace all shell commands)"
 exit $1
 }
@@ -58,6 +59,10 @@ parse_opts() { # opts
       VERBOSE=1
       shift 1
     ;;
+    --quiet|-q)
+      BE_QUIET=1
+      shift 1
+    ;;
     --debug|-d)
       DEBUG=1
       shift 1
@@ -101,6 +106,7 @@ LOG_DIR=$TOP_DIR/logs/`date +%Y%m%d-%H%M%S`/
 KEEP_LOG=0
 DEBUG=0
 VERBOSE=0
+BE_QUIET=0
 # Parse command-line options
 parse_opts $*
 
@@ -249,7 +255,7 @@ run_test() { # testfile
     # Remove test log if the test was done as it was expected.
     [ $KEEP_LOG -eq 0 ] && rm $testlog
   else
-    catlog $testlog
+    [ $BE_QUIET -eq 0 ] && catlog $testlog
     TOTAL_RESULT=1
   fi
 }
Signature · 1 line
2.10.2
author maintainer
#5 lore raw

PATCH 5/17 selftests: ftrace: Check whether snapshot trigger is supported correctly

In reply to Steven Rostedt

From: Masami Hiramatsu <[email protected]>

If "snapshot" special file doesn't exist, that kernel does not support snapshot and snapshot trigger too. In that case snapshot trigger test results to unsupported instead of fail.

---
 tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc | 5 +++++
 1 file changed, 5 insertions(+)
tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc +5 -0
index f84b80d551a2..ed94f0c4e0e4 100644
@@ -23,6 +23,11 @@ if [ ! -f events/sched/sched_process_fork/trigger ]; then
     exit_unsupported
 fi
 
+if [ ! -f snapshot ]; then
+    echo "snapshot is not supported"
+    exit_unsupported
+fi
+
 reset_tracer
 do_reset
 
Signature · 1 line
2.10.2
author maintainer
#6 lore raw

PATCH 6/17 selftests: ftrace: Fix trigger-mod to run without syscall trace

In reply to Steven Rostedt

From: Masami Hiramatsu <[email protected]>

Since histogram trigger id.syscall depends on CONFIG_FTRACE_SYSCALLS, a testcase in trigger-modifier test fails if that config is disabled.

Fix this bug by using flexible pattern to check the histogram output.

---
 tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc +1 -1
index 0bf5085281f3..400e98b64948 100644
@@ -56,7 +56,7 @@ echo "Test histogram with syscall modifier"
 
 echo 'hist:keys=id.syscall' > events/raw_syscalls/sys_exit/trigger
 for i in `seq 1 10` ; do ( echo "forked" > /dev/null); done
-grep "id: sys_" events/raw_syscalls/sys_exit/hist > /dev/null || \
+grep "id: \(unknown_\|sys_\)" events/raw_syscalls/sys_exit/hist > /dev/null || \
     fail "syscall modifier on raw_syscalls/sys_exit did not work"
 
 
Signature · 1 line
2.10.2
author maintainer
#7 lore raw

PATCH 7/17 selftests: ftrace: Hide ftracetest logs from git

In reply to Steven Rostedt

From: Masami Hiramatsu <[email protected]>

Hide ftracetest result log directory from git.

---
 tools/testing/selftests/ftrace/.gitignore | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 tools/testing/selftests/ftrace/.gitignore
tools/testing/selftests/ftrace/.gitignore new file +1 -0
new file mode 100644
index 000000000000..98d8a5a63049
@@ -0,0 +1 @@
+logs
Signature · 1 line
2.10.2
author maintainer
#8 lore raw

PATCH 8/17 selftests: ftrace: Introduce TMPDIR for temporary files

In reply to Steven Rostedt

From: Masami Hiramatsu <[email protected]>

Introduce TMPDIR variable which is removed after each test is done, so that the test script can put their temporary files in that.

---
 tools/testing/selftests/ftrace/ftracetest | 2 ++
 1 file changed, 2 insertions(+)
tools/testing/selftests/ftrace/ftracetest +2 -0
index d08235f65202..685376b485a2 100755
@@ -242,6 +242,7 @@ __run_test() { # testfile
 run_test() { # testfile
   local testname=`basename $1`
   local testlog=`mktemp $LOG_DIR/${testname}-log.XXXXXX`
+  export TMPDIR=`mktemp -d /tmp/ftracetest-dir.XXXXXX`
   testcase $1
   echo "execute: "$1 > $testlog
   SIG_RESULT=0
@@ -258,6 +259,7 @@ run_test() { # testfile
     [ $BE_QUIET -eq 0 ] && catlog $testlog
     TOTAL_RESULT=1
   fi
+  rm -rf $TMPDIR
 }
 
 # load in the helper functions
Signature · 1 line
2.10.2
author maintainer
#9 lore raw

PATCH 9/17 selftests: ftrace: Add a testcase for function filter glob match

In reply to Steven Rostedt

From: Masami Hiramatsu <[email protected]>

Add function filter glob matching test case. This checks whether the kernel supports glob matching (front match, end match, middle match, side match, character class and '?').

Here is the test result.
-----
./ftracetest test.d/ftrace/func-filter-glob.tc
=== Ftrace unit tests ===
[1] ftrace - function glob filters [PASS]

  # of passed:  1
  # of failed:  0
  # of unresolved:  0
  # of untested:  0
  # of unsupported:  0
  # of xfailed:  0
  # of undefined(test bug):  0
  -----
---
 .../ftrace/test.d/ftrace/func-filter-glob.tc       | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc
tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc new file +49 -0
new file mode 100644
index 000000000000..9dcd0ca1f49c
@@ -0,0 +1,49 @@
+#!/bin/sh
+# description: ftrace - function glob filters
+
+# Make sure that function glob matching filter works.
+
+if ! grep -q function available_tracers; then
+    echo "no function tracer configured"
+    exit_unsupported
+fi
+
+disable_tracing
+clear_trace
+
+# filter by ?, schedule is always good
+if ! echo "sch?dule" > set_ftrace_filter; then
+    # test for powerpc 64
+    if ! echo ".sch?dule" > set_ftrace_filter; then
+	fail "can not enable schedule filter"
+    fi
+    cat set_ftrace_filter | grep '^.schedule$'
+else
+    cat set_ftrace_filter | grep '^schedule$'
+fi
+
+ftrace_filter_check() { # glob grep
+  echo "$1" > set_ftrace_filter
+  cut -f1 -d" " set_ftrace_filter > $TMPDIR/actual
+  cut -f1 -d" " available_filter_functions | grep "$2" > $TMPDIR/expected
+  DIFF=`diff $TMPDIR/actual $TMPDIR/expected`
+  test -z "$DIFF"
+}
+
+# filter by *, front match
+ftrace_filter_check '*schedule' '^.*schedule$'
+
+# filter by *, middle match
+ftrace_filter_check '*schedule*' '^.*schedule.*$'
+
+# filter by *, end match
+ftrace_filter_check 'schedule*' '^schedule.*$'
+
+# filter by *, both side match
+ftrace_filter_check 'sch*ule' '^sch.*ule$'
+
+# filter by char class.
+ftrace_filter_check '[Ss]y[Ss]_*' '^[Ss]y[Ss]_.*$'
+
+echo > set_ftrace_filter
+enable_tracing
Signature · 1 line
2.10.2
author maintainer
#10 lore raw

PATCH 10/17 selftests: ftrace: Add a testcase for types of kprobe event

In reply to Steven Rostedt

From: Masami Hiramatsu <[email protected]>

Add a testcase for types of kprobe event. This checks kprobe event can accept and correctly expressed the arguments typed as s32, u32, x32 and bitfield.

Here is the test result.
-----

  # ./ftracetest test.d/kprobe/kprobe_args_type.tc
  === Ftrace unit tests ===
  [1] Kprobes event arguments with types	[PASS]
  # of passed:  1
  # of failed:  0
  # of unresolved:  0
  # of untested:  0
  # of unsupported:  0
  # of xfailed:  0
  # of undefined(test bug):  0
  -----
---
 .../ftrace/test.d/kprobe/kprobe_args_type.tc       | 37 ++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_type.tc
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_type.tc new file +37 -0
new file mode 100644
index 000000000000..0a78705b43b2
@@ -0,0 +1,37 @@
+#!/bin/sh
+# description: Kprobes event arguments with types
+
+[ -f kprobe_events ] || exit_unsupported # this is configurable
+
+grep "x8/16/32/64" README > /dev/null || exit_unsupported # version issue
+
+echo 0 > events/enable
+echo > kprobe_events
+enable_tracing
+
+echo 'p:testprobe _do_fork $stack0:s32 $stack0:u32 $stack0:x32 $stack0:b8@4/32' > kprobe_events
+grep testprobe kprobe_events
+test -d events/kprobes/testprobe
+
+echo 1 > events/kprobes/testprobe/enable
+( echo "forked")
+echo 0 > events/kprobes/testprobe/enable
+ARGS=`tail -n 1 trace | sed -e 's/.* arg1=\(.*\) arg2=\(.*\) arg3=\(.*\) arg4=\(.*\)/\1 \2 \3 \4/'`
+
+check_types() {
+  X1=`printf "%x" $1 | tail -c 8`
+  X2=`printf "%x" $2`
+  X3=`printf "%x" $3`
+  test $X1 = $X2
+  test $X2 = $X3
+  test 0x$X3 = $3
+
+  B4=`printf "%x" $4`
+  B3=`echo -n $X3 | tail -c 3 | head -c 2`
+  test $B3 = $B4
+}
+check_types $ARGS
+
+echo "-:testprobe" >> kprobe_events
+clear_trace
+test -d events/kprobes/testprobe && exit 1 || exit 0
Signature · 1 line
2.10.2
author maintainer
#11 lore raw

PATCH 11/17 tracing: Add hook to function tracing for other subsystems to use

In reply to Steven Rostedt

From: Chunyan Zhang <[email protected]>

Currently Function traces can be only exported to the ring buffer. This adds a trace_export concept which can process traces and export them to a registered destination as an addition to the current one that outputs to Ftrace - i.e. ring buffer.

In this way, if we want function traces to be sent to other destinations rather than only to the ring buffer, we just need to register a new trace_export and implement its own .write() function for writing traces to storage.

With this patch, only function tracing (trace type is TRACE_FN) is supported.

---
 include/linux/trace.h |  28 +++++++++++
 kernel/trace/trace.c  | 129 +++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 156 insertions(+), 1 deletion(-)
 create mode 100644 include/linux/trace.h
include/linux/trace.h new file +28 -0
new file mode 100644
index 000000000000..9330a58e2651
@@ -0,0 +1,28 @@
+#ifndef _LINUX_TRACE_H
+#define _LINUX_TRACE_H
+
+#ifdef CONFIG_TRACING
+/*
+ * The trace export - an export of Ftrace output. The trace_export
+ * can process traces and export them to a registered destination as
+ * an addition to the current only output of Ftrace - i.e. ring buffer.
+ *
+ * If you want traces to be sent to some other place rather than ring
+ * buffer only, just need to register a new trace_export and implement
+ * its own .write() function for writing traces to the storage.
+ *
+ * next		- pointer to the next trace_export
+ * write	- copy traces which have been delt with ->commit() to
+ *		  the destination
+ */
+struct trace_export {
+	struct trace_export __rcu	*next;
+	void (*write)(const void *, unsigned int);
+};
+
+int register_ftrace_export(struct trace_export *export);
+int unregister_ftrace_export(struct trace_export *export);
+
+#endif	/* CONFIG_TRACING */
+
+#endif	/* _LINUX_TRACE_H */
kernel/trace/trace.c +128 -1

148 lines not on this page · raw message

Signature · 1 line
2.10.2
author maintainer
#12 lore raw

PATCH 12/17 stm class: ftrace: Add ftrace-export-over-stm driver

In reply to Steven Rostedt

From: Chunyan Zhang <[email protected]>

This patch adds a driver that models itself as an stm_source called stm_ftrace. Once the stm device and stm_ftrace have been linked via sysfs, the driver registers itself as a trace_export and everything passed to the interface from Ftrace subsystem will end up in the STM trace engine.

---
 drivers/hwtracing/stm/Kconfig  | 11 ++++++
 drivers/hwtracing/stm/Makefile |  2 +
 drivers/hwtracing/stm/ftrace.c | 87 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 100 insertions(+)
 create mode 100644 drivers/hwtracing/stm/ftrace.c
drivers/hwtracing/stm/Kconfig +11 -0
index 847a39b35307..723e2d90083d 100644
@@ -39,4 +39,15 @@ config STM_SOURCE_HEARTBEAT
 	  If you want to send heartbeat messages over STM devices,
 	  say Y.
 
+config STM_SOURCE_FTRACE
+	tristate "Copy the output from kernel Ftrace to STM engine"
+	depends on FUNCTION_TRACER
+	help
+	  This option can be used to copy the output from kernel Ftrace
+	  to STM engine. Enabling this option will introduce a slight
+	  timing effect.
+
+	  If you want to send kernel Ftrace messages over STM devices,
+	  say Y.
+
 endif
drivers/hwtracing/stm/Makefile +2 -0
index a9ce3d487e57..3abd84ce13d4 100644
@@ -6,6 +6,8 @@ obj-$(CONFIG_STM_DUMMY)	+= dummy_stm.o
 
 obj-$(CONFIG_STM_SOURCE_CONSOLE)	+= stm_console.o
 obj-$(CONFIG_STM_SOURCE_HEARTBEAT)	+= stm_heartbeat.o
+obj-$(CONFIG_STM_SOURCE_FTRACE)		+= stm_ftrace.o
 
 stm_console-y		:= console.o
 stm_heartbeat-y		:= heartbeat.o
+stm_ftrace-y		:= ftrace.o
drivers/hwtracing/stm/ftrace.c new file +87 -0

87 lines not on this page · raw message

Signature · 1 line
2.10.2
author maintainer
#13 lore raw

PATCH 13/17 coresight: Mark stm_generic_packet() with notrace

In reply to Steven Rostedt

From: Chunyan Zhang <[email protected]>

If CONFIG_STM_SOURCE_FTRACE is selected, Function trace data can be writen to sink via STM, all functions that related to writing data packets to STM should be marked 'notrace' to avoid being traced by Ftrace, otherwise the program would stall into an endless loop.

---
 drivers/hwtracing/coresight/coresight-stm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwtracing/coresight/coresight-stm.c +1 -1
index 49e0f1b925a5..b7543bd19c9e 100644
@@ -406,7 +406,7 @@ static long stm_generic_set_options(struct stm_data *stm_data,
 	return 0;
 }
 
-static ssize_t stm_generic_packet(struct stm_data *stm_data,
+static ssize_t notrace stm_generic_packet(struct stm_data *stm_data,
 				  unsigned int master,
 				  unsigned int channel,
 				  unsigned int packet,
Signature · 1 line
2.10.2
author maintainer
#14 lore raw

PATCH 14/17 intel_th: Mark sth_stm_packet() with notrace

In reply to Steven Rostedt

From: Chunyan Zhang <[email protected]>

If CONFIG_STM_SOURCE_FTRACE is selected, Function trace data can be writen to sink via STM, all functions that related to writing data packets to STM should be marked 'notrace' to avoid being traced by Ftrace, otherwise the program would stall into an endless loop.

---
 drivers/hwtracing/intel_th/sth.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/hwtracing/intel_th/sth.c +7 -4
index e1aee61dd7b3..b03444624648 100644
@@ -67,10 +67,13 @@ static void sth_iowrite(void __iomem *dest, const unsigned char *payload,
 	}
 }
 
-static ssize_t sth_stm_packet(struct stm_data *stm_data, unsigned int master,
-			      unsigned int channel, unsigned int packet,
-			      unsigned int flags, unsigned int size,
-			      const unsigned char *payload)
+static ssize_t notrace sth_stm_packet(struct stm_data *stm_data,
+				      unsigned int master,
+				      unsigned int channel,
+				      unsigned int packet,
+				      unsigned int flags,
+				      unsigned int size,
+				      const unsigned char *payload)
 {
 	struct sth_device *sth = container_of(stm_data, struct sth_device, stm);
 	struct intel_th_channel __iomem *out =
Signature · 1 line
2.10.2
author maintainer
#15 lore raw

PATCH 15/17 stm dummy: Mark dummy_stm_packet() with notrace

In reply to Steven Rostedt

From: Chunyan Zhang <[email protected]>

If CONFIG_STM_SOURCE_FTRACE is selected, Function trace data can be writen to sink via STM, all functions that related to writing data packets to STM should be marked 'notrace' to avoid being traced by Ftrace, otherwise the program would stall into an endless loop.

---
 drivers/hwtracing/stm/dummy_stm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwtracing/stm/dummy_stm.c +1 -1
index a86612d989f9..c5f94ca31c4d 100644
@@ -21,7 +21,7 @@
 #include <linux/slab.h>
 #include <linux/stm.h>
 
-static ssize_t
+static ssize_t notrace
 dummy_stm_packet(struct stm_data *stm_data, unsigned int master,
 		 unsigned int channel, unsigned int packet, unsigned int flags,
 		 unsigned int size, const unsigned char *payload)
Signature · 1 line
2.10.2
author maintainer
#16 lore raw

PATCH 16/17 stm: Mark the functions of writing STM with notrace

In reply to Steven Rostedt

From: Chunyan Zhang <[email protected]>

If CONFIG_STM_SOURCE_FTRACE is selected, Function trace data can be writen to sink via STM, all functions that related to writing data packets to STM should be marked 'notrace' to avoid being traced by Ftrace, otherwise the program would stall into an endless loop.

---
 drivers/hwtracing/stm/core.c | 7 ++++---
 include/linux/stm.h          | 4 ++--
 2 files changed, 6 insertions(+), 5 deletions(-)
drivers/hwtracing/stm/core.c +4 -3
index 51f81d64ca37..37d3bcbd2534 100644
@@ -425,7 +425,7 @@ static int stm_file_assign(struct stm_file *stmf, char *id, unsigned int width)
 	return ret;
 }
 
-static ssize_t stm_write(struct stm_data *data, unsigned int master,
+static ssize_t notrace stm_write(struct stm_data *data, unsigned int master,
 			  unsigned int channel, const char *buf, size_t count)
 {
 	unsigned int flags = STP_PACKET_TIMESTAMPED;
@@ -1121,8 +1121,9 @@ void stm_source_unregister_device(struct stm_source_data *data)
 }
 EXPORT_SYMBOL_GPL(stm_source_unregister_device);
 
-int stm_source_write(struct stm_source_data *data, unsigned int chan,
-		     const char *buf, size_t count)
+int notrace stm_source_write(struct stm_source_data *data,
+			     unsigned int chan,
+			     const char *buf, size_t count)
 {
 	struct stm_source_device *src = data->src;
 	struct stm_device *stm;
include/linux/stm.h +2 -2
index 8369d8a8cabd..210ff2292361 100644
@@ -133,7 +133,7 @@ int stm_source_register_device(struct device *parent,
 			       struct stm_source_data *data);
 void stm_source_unregister_device(struct stm_source_data *data);
 
-int stm_source_write(struct stm_source_data *data, unsigned int chan,
-		     const char *buf, size_t count);
+int notrace stm_source_write(struct stm_source_data *data, unsigned int chan,
+			     const char *buf, size_t count);
 
 #endif /* _STM_H_ */
Signature · 1 line
2.10.2
author maintainer
#17 lore raw

PATCH 17/17 tracing: Add error checks to creation of event files

In reply to Steven Rostedt

From: "Steven Rostedt (Red Hat)" <[email protected]>

The creation of the set_event_pid file was assigned to a variable "entry" but that variable was never used. Ideally, it should be used to check if the file was created and warn if it was not.

The files header_page, header_event should also be checked and a warning if they fail to be created.

The "enable" file was moved up, as it is a more crucial file to have and a hard failure (return -ENOMEM) should be returned if it is not created.

---
 kernel/trace/trace_events.c | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)
kernel/trace/trace_events.c +21 -9
index 03c0a48c3ac4..ba67ede48822 100644
@@ -2843,20 +2843,32 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr)
 		return -ENOMEM;
 	}
 
+	entry = trace_create_file("enable", 0644, d_events,
+				  tr, &ftrace_tr_enable_fops);
+	if (!entry) {
+		pr_warn("Could not create tracefs 'enable' entry\n");
+		return -ENOMEM;
+	}
+
+	/* There are not as crucial, just warn if they are not created */
+
 	entry = tracefs_create_file("set_event_pid", 0644, parent,
 				    tr, &ftrace_set_event_pid_fops);
+	if (!entry)
+		pr_warn("Could not create tracefs 'set_event_pid' entry\n");
 
 	/* ring buffer internal formats */
-	trace_create_file("header_page", 0444, d_events,
-			  ring_buffer_print_page_header,
-			  &ftrace_show_header_fops);
-
-	trace_create_file("header_event", 0444, d_events,
-			  ring_buffer_print_entry_header,
-			  &ftrace_show_header_fops);
+	entry = trace_create_file("header_page", 0444, d_events,
+				  ring_buffer_print_page_header,
+				  &ftrace_show_header_fops);
+	if (!entry)
+		pr_warn("Could not create tracefs 'header_page' entry\n");
 
-	trace_create_file("enable", 0644, d_events,
-			  tr, &ftrace_tr_enable_fops);
+	entry = trace_create_file("header_event", 0444, d_events,
+				  ring_buffer_print_entry_header,
+				  &ftrace_show_header_fops);
+	if (!entry)
+		pr_warn("Could not create tracefs 'header_event' entry\n");
 
 	tr->event_dir = d_events;
 
Signature · 1 line
2.10.2