Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7639dad9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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)

+2 −3
Original line number Diff line number Diff line
@@ -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]);
+143 −0
Original line number Diff line number Diff line
#!/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