Commit 7639dad9 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 77ed402b 8329e818
...@@ -182,7 +182,8 @@ GLOBAL(ftrace_graph_call) ...@@ -182,7 +182,8 @@ GLOBAL(ftrace_graph_call)
jmp ftrace_stub jmp ftrace_stub
#endif #endif
GLOBAL(ftrace_stub) /* This is weak to keep gas from relaxing the jumps */
WEAK(ftrace_stub)
retq retq
END(ftrace_caller) END(ftrace_caller)
......
...@@ -5737,7 +5737,6 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) ...@@ -5737,7 +5737,6 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
{ {
int i; int i;
int ret = 0; int ret = 0;
unsigned long flags;
int start = 0, end = FTRACE_RETSTACK_ALLOC_SIZE; int start = 0, end = FTRACE_RETSTACK_ALLOC_SIZE;
struct task_struct *g, *t; struct task_struct *g, *t;
...@@ -5753,7 +5752,7 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) ...@@ -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) { do_each_thread(g, t) {
if (start == end) { if (start == end) {
ret = -EAGAIN; ret = -EAGAIN;
...@@ -5771,7 +5770,7 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) ...@@ -5771,7 +5770,7 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
} while_each_thread(g, t); } while_each_thread(g, t);
unlock: unlock:
read_unlock_irqrestore(&tasklist_lock, flags); read_unlock(&tasklist_lock);
free: free:
for (i = start; i < end; i++) for (i = start; i < end; i++)
kfree(ret_stack_list[i]); kfree(ret_stack_list[i]);
......
#!/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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment