mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
Tracing fixes for v6.14:
- Fix crash from bad histogram entry
An error path in the histogram creation could leave an entry
in a link list that gets freed. Then when a new entry is added
it can cause a u-a-f bug. This is fixed by restructuring the code
so that the histogram is consistent on failure and everything is
cleaned up appropriately.
- Fix fprobe self test
The fprobe self test relies on no function being attached by ftrace.
BPF programs can attach to functions via ftrace and systemd now
does so. This causes those functions to appear in the enabled_functions
list which holds all functions attached by ftrace. The selftest also
uses that file to see if functions are being connected correctly.
It counts the functions in the file, but if there's already functions
in the file, it fails. Instead, add the number of functions in the file
at the start of the test to all the calculations during the test.
- Fix potential division by zero of the function profiler stddev
The calculated divisor that calculates the standard deviation of
the function times can overflow. If the overflow happens to land
on zero, that can cause a division by zero. Check for zero from
the calculation before doing the division.
TODO: Catch when it ever overflows and report it accordingly.
For now, just prevent the system from crashing.
-----BEGIN PGP SIGNATURE-----
iIoEABYIADIWIQRRSw7ePDh/lE+zeZMp5XQQmuv6qgUCZ8HqYBQccm9zdGVkdEBn
b29kbWlzLm9yZwAKCRAp5XQQmuv6qpoXAP90gvO2LfjItjZVjBYudr4GOzcsjAAK
cZ2vL2LJp3hT4QD+Kud2YaZqzrV8tvFFBikO7FvEV3zZpnw48895pIgcoww=
=NLe0
-----END PGP SIGNATURE-----
Merge tag 'trace-v6.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace
Pull tracing fixes from Steven Rostedt:
- Fix crash from bad histogram entry
An error path in the histogram creation could leave an entry in a
link list that gets freed. Then when a new entry is added it can
cause a u-a-f bug. This is fixed by restructuring the code so that
the histogram is consistent on failure and everything is cleaned up
appropriately.
- Fix fprobe self test
The fprobe self test relies on no function being attached by ftrace.
BPF programs can attach to functions via ftrace and systemd now does
so. This causes those functions to appear in the enabled_functions
list which holds all functions attached by ftrace. The selftest also
uses that file to see if functions are being connected correctly. It
counts the functions in the file, but if there's already functions in
the file, it fails. Instead, add the number of functions in the file
at the start of the test to all the calculations during the test.
- Fix potential division by zero of the function profiler stddev
The calculated divisor that calculates the standard deviation of the
function times can overflow. If the overflow happens to land on zero,
that can cause a division by zero. Check for zero from the
calculation before doing the division.
TODO: Catch when it ever overflows and report it accordingly. For
now, just prevent the system from crashing.
* tag 'trace-v6.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
ftrace: Avoid potential division by zero in function_stat_show()
selftests/ftrace: Let fprobe test consider already enabled functions
tracing: Fix bad hist from corrupting named_triggers list
This commit is contained in:
commit
5c44ddaf7d
|
|
@ -540,6 +540,7 @@ static int function_stat_show(struct seq_file *m, void *v)
|
|||
static struct trace_seq s;
|
||||
unsigned long long avg;
|
||||
unsigned long long stddev;
|
||||
unsigned long long stddev_denom;
|
||||
#endif
|
||||
guard(mutex)(&ftrace_profile_lock);
|
||||
|
||||
|
|
@ -559,23 +560,19 @@ static int function_stat_show(struct seq_file *m, void *v)
|
|||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
seq_puts(m, " ");
|
||||
|
||||
/* Sample standard deviation (s^2) */
|
||||
if (rec->counter <= 1)
|
||||
stddev = 0;
|
||||
else {
|
||||
/*
|
||||
* Apply Welford's method:
|
||||
* s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2)
|
||||
*/
|
||||
/*
|
||||
* Variance formula:
|
||||
* s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2)
|
||||
* Maybe Welford's method is better here?
|
||||
* Divide only by 1000 for ns^2 -> us^2 conversion.
|
||||
* trace_print_graph_duration will divide by 1000 again.
|
||||
*/
|
||||
stddev = 0;
|
||||
stddev_denom = rec->counter * (rec->counter - 1) * 1000;
|
||||
if (stddev_denom) {
|
||||
stddev = rec->counter * rec->time_squared -
|
||||
rec->time * rec->time;
|
||||
|
||||
/*
|
||||
* Divide only 1000 for ns^2 -> us^2 conversion.
|
||||
* trace_print_graph_duration will divide 1000 again.
|
||||
*/
|
||||
stddev = div64_ul(stddev,
|
||||
rec->counter * (rec->counter - 1) * 1000);
|
||||
stddev = div64_ul(stddev, stddev_denom);
|
||||
}
|
||||
|
||||
trace_seq_init(&s);
|
||||
|
|
|
|||
|
|
@ -6724,27 +6724,27 @@ static int event_hist_trigger_parse(struct event_command *cmd_ops,
|
|||
if (existing_hist_update_only(glob, trigger_data, file))
|
||||
goto out_free;
|
||||
|
||||
if (!get_named_trigger_data(trigger_data)) {
|
||||
|
||||
ret = create_actions(hist_data);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
|
||||
if (has_hist_vars(hist_data) || hist_data->n_var_refs) {
|
||||
ret = save_hist_vars(hist_data);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = tracing_map_init(hist_data->map);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = event_trigger_register(cmd_ops, file, glob, trigger_data);
|
||||
if (ret < 0)
|
||||
goto out_free;
|
||||
|
||||
if (get_named_trigger_data(trigger_data))
|
||||
goto enable;
|
||||
|
||||
ret = create_actions(hist_data);
|
||||
if (ret)
|
||||
goto out_unreg;
|
||||
|
||||
if (has_hist_vars(hist_data) || hist_data->n_var_refs) {
|
||||
ret = save_hist_vars(hist_data);
|
||||
if (ret)
|
||||
goto out_unreg;
|
||||
}
|
||||
|
||||
ret = tracing_map_init(hist_data->map);
|
||||
if (ret)
|
||||
goto out_unreg;
|
||||
enable:
|
||||
ret = hist_trigger_enable(trigger_data, file);
|
||||
if (ret)
|
||||
goto out_unreg;
|
||||
|
|
|
|||
|
|
@ -10,12 +10,16 @@ PLACE=$FUNCTION_FORK
|
|||
PLACE2="kmem_cache_free"
|
||||
PLACE3="schedule_timeout"
|
||||
|
||||
# Some functions may have BPF programs attached, therefore
|
||||
# count already enabled_functions before tests start
|
||||
ocnt=`cat enabled_functions | wc -l`
|
||||
|
||||
echo "f:myevent1 $PLACE" >> dynamic_events
|
||||
|
||||
# Make sure the event is attached and is the only one
|
||||
grep -q $PLACE enabled_functions
|
||||
cnt=`cat enabled_functions | wc -l`
|
||||
if [ $cnt -ne 1 ]; then
|
||||
if [ $cnt -ne $((ocnt + 1)) ]; then
|
||||
exit_fail
|
||||
fi
|
||||
|
||||
|
|
@ -23,7 +27,7 @@ echo "f:myevent2 $PLACE%return" >> dynamic_events
|
|||
|
||||
# It should till be the only attached function
|
||||
cnt=`cat enabled_functions | wc -l`
|
||||
if [ $cnt -ne 1 ]; then
|
||||
if [ $cnt -ne $((ocnt + 1)) ]; then
|
||||
exit_fail
|
||||
fi
|
||||
|
||||
|
|
@ -32,7 +36,7 @@ echo "f:myevent3 $PLACE2" >> dynamic_events
|
|||
|
||||
grep -q $PLACE2 enabled_functions
|
||||
cnt=`cat enabled_functions | wc -l`
|
||||
if [ $cnt -ne 2 ]; then
|
||||
if [ $cnt -ne $((ocnt + 2)) ]; then
|
||||
exit_fail
|
||||
fi
|
||||
|
||||
|
|
@ -49,7 +53,7 @@ grep -q myevent1 dynamic_events
|
|||
|
||||
# should still have 2 left
|
||||
cnt=`cat enabled_functions | wc -l`
|
||||
if [ $cnt -ne 2 ]; then
|
||||
if [ $cnt -ne $((ocnt + 2)) ]; then
|
||||
exit_fail
|
||||
fi
|
||||
|
||||
|
|
@ -57,7 +61,7 @@ echo > dynamic_events
|
|||
|
||||
# Should have none left
|
||||
cnt=`cat enabled_functions | wc -l`
|
||||
if [ $cnt -ne 0 ]; then
|
||||
if [ $cnt -ne $ocnt ]; then
|
||||
exit_fail
|
||||
fi
|
||||
|
||||
|
|
@ -65,7 +69,7 @@ echo "f:myevent4 $PLACE" >> dynamic_events
|
|||
|
||||
# Should only have one enabled
|
||||
cnt=`cat enabled_functions | wc -l`
|
||||
if [ $cnt -ne 1 ]; then
|
||||
if [ $cnt -ne $((ocnt + 1)) ]; then
|
||||
exit_fail
|
||||
fi
|
||||
|
||||
|
|
@ -73,7 +77,7 @@ echo > dynamic_events
|
|||
|
||||
# Should have none left
|
||||
cnt=`cat enabled_functions | wc -l`
|
||||
if [ $cnt -ne 0 ]; then
|
||||
if [ $cnt -ne $ocnt ]; then
|
||||
exit_fail
|
||||
fi
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user