Three more changes.
1) 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. 2) 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. 3) 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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJXQhYQAAoJEKKk/i67LK/82pAH/3XzRCP366HqWnKdvluPB8vX UnVoXGAX1Eh2ZpvlPIJBXNYOZlnGRMMMAoeI+su31FoJHrzTzfGXvRynTkZPFZtd XakvHfACjtGtvi2MuCN1t9/d1ty/ob2o05KB9qc+JRlzHM09qTL/HX8hwZeEsMQ4 NYgEY4Y727LOSCrJieLktchpwtie77q8Wq25oiWIVWOyDjpCsPnZyaOqaQSANot9 Gd00cixbMam7Ba1BjoRsRQZaT2pYZ8vt7HDXDBfAOW1oOjalWARLhRg/zww1V3WD DEptuEeyAgMJS3v76Z6Sbk/QM7hyGUWCcmC2qaN1yc2n1Sh+zBOiN1eyiiUh/2U= =ERxv -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
7639dad93a
|
@ -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)
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue