aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-22 22:40:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-22 22:40:39 -0400
commit7639dad93a5564579987abded4ec05e3db13659d (patch)
treed786a45e79672ee3ea04e93d60ec1da02cb17940
parent77ed402b7f53cbe50ae8384a172a5b9713020400 (diff)
parent8329e818f14926a6040df86b2668568bde342ebf (diff)
Merge tag 'trace-v4.7-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull motr tracing updates from Steven Rostedt: "Three more changes. - I forgot that I had another selftest to stress test the ftrace instance creation. It was actually suppose to go into the 4.6 merge window, but I never committed it. I almost forgot about it again, but noticed it was missing from your tree. - Soumya PN sent me a clean up patch to not disable interrupts when taking the tasklist_lock for read, as it's unnecessary because that lock is never taken for write in irq context. - Newer gcc's can cause the jump in the function_graph code to the global ftrace_stub label to be a short jump instead of a long one. As that jump is dynamically converted to jump to the trace code to do function graph tracing, and that conversion expects a long jump it can corrupt the ftrace_stub itself (it's directly after that call). One way to prevent gcc from using a short jump is to declare the ftrace_stub as a weak function, which we do here to keep gcc from optimizing too much" * tag 'trace-v4.7-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: ftrace/x86: Set ftrace_stub to weak to prevent gcc from using short jumps to it ftrace: Don't disable irqs when taking the tasklist_lock read_lock ftracetest: Add instance created, delete, read and enable event test
-rw-r--r--arch/x86/kernel/mcount_64.S3
-rw-r--r--kernel/trace/ftrace.c5
-rw-r--r--tools/testing/selftests/ftrace/test.d/instances/instance-event.tc143
3 files changed, 147 insertions, 4 deletions
diff --git a/arch/x86/kernel/mcount_64.S b/arch/x86/kernel/mcount_64.S
index ed48a9f465f8..61924222a9e1 100644
--- a/arch/x86/kernel/mcount_64.S
+++ b/arch/x86/kernel/mcount_64.S
@@ -182,7 +182,8 @@ GLOBAL(ftrace_graph_call)
182 jmp ftrace_stub 182 jmp ftrace_stub
183#endif 183#endif
184 184
185GLOBAL(ftrace_stub) 185/* This is weak to keep gas from relaxing the jumps */
186WEAK(ftrace_stub)
186 retq 187 retq
187END(ftrace_caller) 188END(ftrace_caller)
188 189
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index a6c8252d7776..900dbb1efff2 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -5737,7 +5737,6 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
5737{ 5737{
5738 int i; 5738 int i;
5739 int ret = 0; 5739 int ret = 0;
5740 unsigned long flags;
5741 int start = 0, end = FTRACE_RETSTACK_ALLOC_SIZE; 5740 int start = 0, end = FTRACE_RETSTACK_ALLOC_SIZE;
5742 struct task_struct *g, *t; 5741 struct task_struct *g, *t;
5743 5742
@@ -5753,7 +5752,7 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
5753 } 5752 }
5754 } 5753 }
5755 5754
5756 read_lock_irqsave(&tasklist_lock, flags); 5755 read_lock(&tasklist_lock);
5757 do_each_thread(g, t) { 5756 do_each_thread(g, t) {
5758 if (start == end) { 5757 if (start == end) {
5759 ret = -EAGAIN; 5758 ret = -EAGAIN;
@@ -5771,7 +5770,7 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
5771 } while_each_thread(g, t); 5770 } while_each_thread(g, t);
5772 5771
5773unlock: 5772unlock:
5774 read_unlock_irqrestore(&tasklist_lock, flags); 5773 read_unlock(&tasklist_lock);
5775free: 5774free:
5776 for (i = start; i < end; i++) 5775 for (i = start; i < end; i++)
5777 kfree(ret_stack_list[i]); 5776 kfree(ret_stack_list[i]);
diff --git a/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc b/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc
new file mode 100644
index 000000000000..5f2abd03f16b
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc
@@ -0,0 +1,143 @@
1#!/bin/sh
2# description: Test creation and deletion of trace instances while setting an event
3
4if [ ! -d instances ] ; then
5 echo "no instance directory with this kernel"
6 exit_unsupported;
7fi
8
9fail() { # mesg
10 rmdir foo 2>/dev/null
11 echo $1
12 set -e
13 exit $FAIL
14}
15
16cd instances
17
18# we don't want to fail on error
19set +e
20
21mkdir x
22rmdir x
23result=$?
24
25if [ $result -ne 0 ]; then
26 echo "instance rmdir not supported"
27 exit_unsupported
28fi
29
30instance_slam() {
31 while :; do
32 mkdir foo 2> /dev/null
33 rmdir foo 2> /dev/null
34 done
35}
36
37instance_read() {
38 while :; do
39 cat foo/trace 1> /dev/null 2>&1
40 done
41}
42
43instance_set() {
44 while :; do
45 echo 1 > foo/events/sched/sched_switch
46 done 2> /dev/null
47}
48
49instance_slam &
50p1=$!
51echo $p1
52
53instance_set &
54p2=$!
55echo $p2
56
57instance_read &
58p3=$!
59echo $p3
60
61sleep 1
62
63kill -1 $p3
64kill -1 $p2
65kill -1 $p1
66
67echo "Wait for processes to finish"
68wait $p1 $p2 $p3
69echo "all processes finished, wait for cleanup"
70sleep 1
71
72mkdir foo
73ls foo > /dev/null
74rmdir foo
75if [ -d foo ]; then
76 fail "foo still exists"
77fi
78exit 0
79
80
81
82
83instance_slam() {
84 while :; do
85 mkdir x
86 mkdir y
87 mkdir z
88 rmdir x
89 rmdir y
90 rmdir z
91 done 2>/dev/null
92}
93
94instance_slam &
95x=`jobs -l`
96p1=`echo $x | cut -d' ' -f2`
97echo $p1
98
99instance_slam &
100x=`jobs -l | tail -1`
101p2=`echo $x | cut -d' ' -f2`
102echo $p2
103
104instance_slam &
105x=`jobs -l | tail -1`
106p3=`echo $x | cut -d' ' -f2`
107echo $p3
108
109instance_slam &
110x=`jobs -l | tail -1`
111p4=`echo $x | cut -d' ' -f2`
112echo $p4
113
114instance_slam &
115x=`jobs -l | tail -1`
116p5=`echo $x | cut -d' ' -f2`
117echo $p5
118
119ls -lR >/dev/null
120sleep 1
121
122kill -1 $p1
123kill -1 $p2
124kill -1 $p3
125kill -1 $p4
126kill -1 $p5
127
128echo "Wait for processes to finish"
129wait $p1 $p2 $p3 $p4 $p5
130echo "all processes finished, wait for cleanup"
131
132mkdir x y z
133ls x y z
134rmdir x y z
135for d in x y z; do
136 if [ -d $d ]; then
137 fail "instance $d still exists"
138 fi
139done
140
141set -e
142
143exit 0