]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'trace-v4.7-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 23 May 2016 02:40:39 +0000 (19:40 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 23 May 2016 02:40:39 +0000 (19:40 -0700)
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

arch/x86/kernel/mcount_64.S
kernel/trace/ftrace.c
tools/testing/selftests/ftrace/test.d/instances/instance-event.tc [new file with mode: 0644]

index ed48a9f465f84685d1ecdfb78075f869001e369b..61924222a9e1ceb4e582b961a0568a1301dc4b6b 100644 (file)
@@ -182,7 +182,8 @@ GLOBAL(ftrace_graph_call)
        jmp ftrace_stub
 #endif
 
-GLOBAL(ftrace_stub)
+/* This is weak to keep gas from relaxing the jumps */
+WEAK(ftrace_stub)
        retq
 END(ftrace_caller)
 
index a6c8252d7776b3954df1db09fb1831c603093c7c..900dbb1efff2bb8554e3fa6edeb4172af3594d55 100644 (file)
@@ -5737,7 +5737,6 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
 {
        int i;
        int ret = 0;
-       unsigned long flags;
        int start = 0, end = FTRACE_RETSTACK_ALLOC_SIZE;
        struct task_struct *g, *t;
 
@@ -5753,7 +5752,7 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
                }
        }
 
-       read_lock_irqsave(&tasklist_lock, flags);
+       read_lock(&tasklist_lock);
        do_each_thread(g, t) {
                if (start == end) {
                        ret = -EAGAIN;
@@ -5771,7 +5770,7 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
        } while_each_thread(g, t);
 
 unlock:
-       read_unlock_irqrestore(&tasklist_lock, flags);
+       read_unlock(&tasklist_lock);
 free:
        for (i = start; i < end; i++)
                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 (file)
index 0000000..5f2abd0
--- /dev/null
@@ -0,0 +1,143 @@
+#!/bin/sh
+# description: Test creation and deletion of trace instances while setting an event
+
+if [ ! -d instances ] ; then
+    echo "no instance directory with this kernel"
+    exit_unsupported;
+fi
+
+fail() { # mesg
+    rmdir foo 2>/dev/null
+    echo $1
+    set -e
+    exit $FAIL
+}
+
+cd instances
+
+# we don't want to fail on error
+set +e
+
+mkdir x
+rmdir x
+result=$?
+
+if [ $result -ne 0 ]; then
+    echo "instance rmdir not supported"
+    exit_unsupported
+fi
+
+instance_slam() {
+        while :; do
+                mkdir foo 2> /dev/null
+                rmdir foo 2> /dev/null
+        done
+}
+
+instance_read() {
+        while :; do
+                cat foo/trace 1> /dev/null 2>&1
+        done
+}
+
+instance_set() {
+        while :; do
+                echo 1 > foo/events/sched/sched_switch
+        done 2> /dev/null
+}
+
+instance_slam &
+p1=$!
+echo $p1
+
+instance_set &
+p2=$!
+echo $p2
+
+instance_read &
+p3=$!
+echo $p3
+
+sleep 1
+
+kill -1 $p3
+kill -1 $p2
+kill -1 $p1
+
+echo "Wait for processes to finish"
+wait $p1 $p2 $p3
+echo "all processes finished, wait for cleanup"
+sleep 1
+
+mkdir foo
+ls foo > /dev/null
+rmdir foo
+if [ -d foo ]; then
+        fail "foo still exists"
+fi
+exit 0
+
+
+
+
+instance_slam() {
+    while :; do
+       mkdir x
+       mkdir y
+       mkdir z
+       rmdir x
+       rmdir y
+       rmdir z
+    done 2>/dev/null
+}
+
+instance_slam &
+x=`jobs -l`
+p1=`echo $x | cut -d' ' -f2`
+echo $p1
+
+instance_slam &
+x=`jobs -l | tail -1`
+p2=`echo $x | cut -d' ' -f2`
+echo $p2
+
+instance_slam &
+x=`jobs -l | tail -1`
+p3=`echo $x | cut -d' ' -f2`
+echo $p3
+
+instance_slam &
+x=`jobs -l | tail -1`
+p4=`echo $x | cut -d' ' -f2`
+echo $p4
+
+instance_slam &
+x=`jobs -l | tail -1`
+p5=`echo $x | cut -d' ' -f2`
+echo $p5
+
+ls -lR >/dev/null
+sleep 1
+
+kill -1 $p1
+kill -1 $p2
+kill -1 $p3
+kill -1 $p4
+kill -1 $p5
+
+echo "Wait for processes to finish"
+wait $p1 $p2 $p3 $p4 $p5
+echo "all processes finished, wait for cleanup"
+
+mkdir x y z
+ls x y z
+rmdir x y z
+for d in x y z; do
+        if [ -d $d ]; then
+                fail "instance $d still exists"
+        fi
+done
+
+set -e
+
+exit 0