2020-01-10 19:06:17 +03:00
// SPDX-License-Identifier: GPL-2.0
/*
* trace_boot . c
* Tracing kernel boot - time
*/
# define pr_fmt(fmt) "trace_boot: " fmt
2020-01-29 12:36:35 +03:00
# include <linux/bootconfig.h>
# include <linux/cpumask.h>
2020-01-10 19:06:17 +03:00
# include <linux/ftrace.h>
# include <linux/init.h>
2020-01-29 12:36:35 +03:00
# include <linux/kernel.h>
# include <linux/mutex.h>
# include <linux/string.h>
# include <linux/slab.h>
# include <linux/trace.h>
# include <linux/trace_events.h>
2020-01-10 19:06:17 +03:00
# include "trace.h"
# define MAX_BUF_LEN 256
static void __init
2020-01-10 19:07:04 +03:00
trace_boot_set_instance_options ( struct trace_array * tr , struct xbc_node * node )
2020-01-10 19:06:17 +03:00
{
struct xbc_node * anode ;
const char * p ;
char buf [ MAX_BUF_LEN ] ;
unsigned long v = 0 ;
/* Common ftrace options */
xbc_node_for_each_array_value ( node , " options " , anode , p ) {
if ( strlcpy ( buf , p , ARRAY_SIZE ( buf ) ) > = ARRAY_SIZE ( buf ) ) {
pr_err ( " String is too long: %s \n " , p ) ;
continue ;
}
if ( trace_set_options ( tr , buf ) < 0 )
pr_err ( " Failed to set option: %s \n " , buf ) ;
}
2020-09-10 11:55:15 +03:00
p = xbc_node_find_value ( node , " tracing_on " , NULL ) ;
if ( p & & * p ! = ' \0 ' ) {
if ( kstrtoul ( p , 10 , & v ) )
pr_err ( " Failed to set tracing on: %s \n " , p ) ;
if ( v )
tracer_tracing_on ( tr ) ;
else
tracer_tracing_off ( tr ) ;
}
2020-01-10 19:06:17 +03:00
p = xbc_node_find_value ( node , " trace_clock " , NULL ) ;
if ( p & & * p ! = ' \0 ' ) {
if ( tracing_set_clock ( tr , p ) < 0 )
pr_err ( " Failed to set trace clock: %s \n " , p ) ;
}
p = xbc_node_find_value ( node , " buffer_size " , NULL ) ;
if ( p & & * p ! = ' \0 ' ) {
v = memparse ( p , NULL ) ;
if ( v < PAGE_SIZE )
pr_err ( " Buffer size is too small: %s \n " , p ) ;
if ( tracing_resize_ring_buffer ( tr , v , RING_BUFFER_ALL_CPUS ) < 0 )
pr_err ( " Failed to resize trace buffer to %s \n " , p ) ;
}
2020-01-10 19:07:16 +03:00
p = xbc_node_find_value ( node , " cpumask " , NULL ) ;
if ( p & & * p ! = ' \0 ' ) {
cpumask_var_t new_mask ;
if ( alloc_cpumask_var ( & new_mask , GFP_KERNEL ) ) {
if ( cpumask_parse ( p , new_mask ) < 0 | |
tracing_set_cpumask ( tr , new_mask ) < 0 )
pr_err ( " Failed to set new CPU mask %s \n " , p ) ;
free_cpumask_var ( new_mask ) ;
}
}
2020-01-10 19:06:17 +03:00
}
# ifdef CONFIG_EVENT_TRACING
static void __init
trace_boot_enable_events ( struct trace_array * tr , struct xbc_node * node )
{
struct xbc_node * anode ;
char buf [ MAX_BUF_LEN ] ;
const char * p ;
xbc_node_for_each_array_value ( node , " events " , anode , p ) {
if ( strlcpy ( buf , p , ARRAY_SIZE ( buf ) ) > = ARRAY_SIZE ( buf ) ) {
pr_err ( " String is too long: %s \n " , p ) ;
continue ;
}
if ( ftrace_set_clr_event ( tr , buf , 1 ) < 0 )
pr_err ( " Failed to enable event: %s \n " , p ) ;
}
}
2020-01-10 19:06:29 +03:00
2020-01-10 19:06:41 +03:00
# ifdef CONFIG_KPROBE_EVENTS
static int __init
trace_boot_add_kprobe_event ( struct xbc_node * node , const char * event )
{
2020-01-29 21:59:30 +03:00
struct dynevent_cmd cmd ;
2020-01-10 19:06:41 +03:00
struct xbc_node * anode ;
char buf [ MAX_BUF_LEN ] ;
const char * val ;
2020-04-25 08:49:17 +03:00
int ret = 0 ;
2020-01-10 19:06:41 +03:00
2020-04-25 08:49:17 +03:00
xbc_node_for_each_array_value ( node , " probes " , anode , val ) {
kprobe_event_cmd_init ( & cmd , buf , MAX_BUF_LEN ) ;
2020-01-29 21:59:30 +03:00
2020-04-25 08:49:17 +03:00
ret = kprobe_event_gen_cmd_start ( & cmd , event , val ) ;
2020-06-18 19:33:01 +03:00
if ( ret ) {
pr_err ( " Failed to generate probe: %s \n " , buf ) ;
2020-04-25 08:49:17 +03:00
break ;
2020-06-18 19:33:01 +03:00
}
2020-01-10 19:06:41 +03:00
2020-04-25 08:49:17 +03:00
ret = kprobe_event_gen_cmd_end ( & cmd ) ;
2020-06-18 19:33:01 +03:00
if ( ret ) {
2020-04-25 08:49:17 +03:00
pr_err ( " Failed to add probe: %s \n " , buf ) ;
2020-06-18 19:33:01 +03:00
break ;
}
2020-01-10 19:06:41 +03:00
}
2020-01-29 21:59:30 +03:00
return ret ;
2020-01-10 19:06:41 +03:00
}
# else
static inline int __init
trace_boot_add_kprobe_event ( struct xbc_node * node , const char * event )
{
pr_err ( " Kprobe event is not supported. \n " ) ;
return - ENOTSUPP ;
}
# endif
2020-06-20 06:45:54 +03:00
# ifdef CONFIG_SYNTH_EVENTS
2020-01-10 19:06:52 +03:00
static int __init
trace_boot_add_synth_event ( struct xbc_node * node , const char * event )
{
2020-01-29 21:59:26 +03:00
struct dynevent_cmd cmd ;
2020-01-10 19:06:52 +03:00
struct xbc_node * anode ;
2020-01-29 21:59:26 +03:00
char buf [ MAX_BUF_LEN ] ;
2020-01-10 19:06:52 +03:00
const char * p ;
2020-01-29 21:59:26 +03:00
int ret ;
2020-01-10 19:06:52 +03:00
2020-01-29 21:59:26 +03:00
synth_event_cmd_init ( & cmd , buf , MAX_BUF_LEN ) ;
ret = synth_event_gen_cmd_start ( & cmd , event , NULL ) ;
if ( ret )
return ret ;
2020-01-10 19:06:52 +03:00
xbc_node_for_each_array_value ( node , " fields " , anode , p ) {
2020-01-29 21:59:26 +03:00
ret = synth_event_add_field_str ( & cmd , p ) ;
if ( ret )
return ret ;
2020-01-10 19:06:52 +03:00
}
2020-01-29 21:59:26 +03:00
ret = synth_event_gen_cmd_end ( & cmd ) ;
2020-01-10 19:06:52 +03:00
if ( ret < 0 )
pr_err ( " Failed to add synthetic event: %s \n " , buf ) ;
return ret ;
}
# else
static inline int __init
trace_boot_add_synth_event ( struct xbc_node * node , const char * event )
{
pr_err ( " Synthetic event is not supported. \n " ) ;
return - ENOTSUPP ;
}
# endif
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
# ifdef CONFIG_HIST_TRIGGERS
static int __init __printf ( 3 , 4 )
append_printf ( char * * bufp , char * end , const char * fmt , . . . )
{
va_list args ;
int ret ;
if ( * bufp = = end )
return - ENOSPC ;
va_start ( args , fmt ) ;
ret = vsnprintf ( * bufp , end - * bufp , fmt , args ) ;
if ( ret < end - * bufp ) {
* bufp + = ret ;
} else {
* bufp = end ;
ret = - ERANGE ;
}
va_end ( args ) ;
return ret ;
}
static int __init
append_str_nospace ( char * * bufp , char * end , const char * str )
{
char * p = * bufp ;
int len ;
while ( p < end - 1 & & * str ! = ' \0 ' ) {
if ( ! isspace ( * str ) )
* ( p + + ) = * str ;
str + + ;
}
* p = ' \0 ' ;
if ( p = = end - 1 ) {
* bufp = end ;
return - ENOSPC ;
}
len = p - * bufp ;
* bufp = p ;
return ( int ) len ;
}
static int __init
trace_boot_hist_add_array ( struct xbc_node * hnode , char * * bufp ,
char * end , const char * key )
{
2021-09-09 16:36:23 +03:00
struct xbc_node * anode ;
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
const char * p ;
char sep ;
2021-09-09 16:36:23 +03:00
p = xbc_node_find_value ( hnode , key , & anode ) ;
if ( p ) {
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
if ( ! anode ) {
pr_err ( " hist.%s requires value(s). \n " , key ) ;
return - EINVAL ;
}
append_printf ( bufp , end , " :%s " , key ) ;
sep = ' = ' ;
xbc_array_for_each_value ( anode , p ) {
append_printf ( bufp , end , " %c%s " , sep , p ) ;
if ( sep = = ' = ' )
sep = ' , ' ;
}
} else
return - ENOENT ;
return 0 ;
}
static int __init
tracing/boot: Support multiple handlers for per-event histogram
Support multiple handlers for per-event histogram in boot-time tracing.
Since the histogram can register multiple same handler-actions with
different parameters, this expands the syntax to support such cases.
With this update, the 'onmax', 'onchange' and 'onmatch' handler subkeys
under per-event histogram option will take a number subkeys optionally
as below. (see [.N])
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
onmax|onchange[.N] { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch[.N] { event = <EVENT>; <ACTION> [= <PARAM>] }
}
The 'N' must be a digit (or digit started word).
Thus user can add several handler-actions to the histogram,
for example,
ftrace.event.SOMEGROUP.SOMEEVENT.hist {
keys = SOME_ID; lat = common_timestamp.usecs-$ts0
onmatch.1 {
event = GROUP1.STARTEVENT1
trace = latency_event, SOME_ID, $lat
}
onmatch.2 {
event = GROUP2.STARTEVENT2
trace = latency_event, SOME_ID, $lat
}
}
Then, it can trace the elapsed time from GROUP1.STARTEVENT1 to
SOMEGROUP.SOMEEVENT, and from GROUP2.STARTEVENT2 to
SOMEGROUP.SOMEEVENT with SOME_ID key.
Link: https://lkml.kernel.org/r/162856124905.203126.14913731908137885922.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:29 +03:00
trace_boot_hist_add_one_handler ( struct xbc_node * hnode , char * * bufp ,
char * end , const char * handler ,
const char * param )
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
{
struct xbc_node * knode , * anode ;
const char * p ;
char sep ;
/* Compose 'handler' parameter */
p = xbc_node_find_value ( hnode , param , NULL ) ;
if ( ! p ) {
pr_err ( " hist.%s requires '%s' option. \n " ,
xbc_node_get_data ( hnode ) , param ) ;
return - EINVAL ;
}
tracing/boot: Support multiple handlers for per-event histogram
Support multiple handlers for per-event histogram in boot-time tracing.
Since the histogram can register multiple same handler-actions with
different parameters, this expands the syntax to support such cases.
With this update, the 'onmax', 'onchange' and 'onmatch' handler subkeys
under per-event histogram option will take a number subkeys optionally
as below. (see [.N])
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
onmax|onchange[.N] { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch[.N] { event = <EVENT>; <ACTION> [= <PARAM>] }
}
The 'N' must be a digit (or digit started word).
Thus user can add several handler-actions to the histogram,
for example,
ftrace.event.SOMEGROUP.SOMEEVENT.hist {
keys = SOME_ID; lat = common_timestamp.usecs-$ts0
onmatch.1 {
event = GROUP1.STARTEVENT1
trace = latency_event, SOME_ID, $lat
}
onmatch.2 {
event = GROUP2.STARTEVENT2
trace = latency_event, SOME_ID, $lat
}
}
Then, it can trace the elapsed time from GROUP1.STARTEVENT1 to
SOMEGROUP.SOMEEVENT, and from GROUP2.STARTEVENT2 to
SOMEGROUP.SOMEEVENT with SOME_ID key.
Link: https://lkml.kernel.org/r/162856124905.203126.14913731908137885922.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:29 +03:00
append_printf ( bufp , end , " :%s(%s) " , handler , p ) ;
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
/* Compose 'action' parameter */
2021-09-09 16:36:38 +03:00
knode = xbc_node_find_subkey ( hnode , " trace " ) ;
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
if ( ! knode )
2021-09-09 16:36:38 +03:00
knode = xbc_node_find_subkey ( hnode , " save " ) ;
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
if ( knode ) {
anode = xbc_node_get_child ( knode ) ;
if ( ! anode | | ! xbc_node_is_value ( anode ) ) {
pr_err ( " hist.%s.%s requires value(s). \n " ,
xbc_node_get_data ( hnode ) ,
xbc_node_get_data ( knode ) ) ;
return - EINVAL ;
}
append_printf ( bufp , end , " .%s " , xbc_node_get_data ( knode ) ) ;
sep = ' ( ' ;
xbc_array_for_each_value ( anode , p ) {
append_printf ( bufp , end , " %c%s " , sep , p ) ;
if ( sep = = ' ( ' )
sep = ' , ' ;
}
append_printf ( bufp , end , " ) " ) ;
2021-09-09 16:36:38 +03:00
} else if ( xbc_node_find_subkey ( hnode , " snapshot " ) ) {
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
append_printf ( bufp , end , " .snapshot() " ) ;
} else {
pr_err ( " hist.%s requires an action. \n " ,
xbc_node_get_data ( hnode ) ) ;
return - EINVAL ;
}
return 0 ;
}
tracing/boot: Support multiple handlers for per-event histogram
Support multiple handlers for per-event histogram in boot-time tracing.
Since the histogram can register multiple same handler-actions with
different parameters, this expands the syntax to support such cases.
With this update, the 'onmax', 'onchange' and 'onmatch' handler subkeys
under per-event histogram option will take a number subkeys optionally
as below. (see [.N])
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
onmax|onchange[.N] { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch[.N] { event = <EVENT>; <ACTION> [= <PARAM>] }
}
The 'N' must be a digit (or digit started word).
Thus user can add several handler-actions to the histogram,
for example,
ftrace.event.SOMEGROUP.SOMEEVENT.hist {
keys = SOME_ID; lat = common_timestamp.usecs-$ts0
onmatch.1 {
event = GROUP1.STARTEVENT1
trace = latency_event, SOME_ID, $lat
}
onmatch.2 {
event = GROUP2.STARTEVENT2
trace = latency_event, SOME_ID, $lat
}
}
Then, it can trace the elapsed time from GROUP1.STARTEVENT1 to
SOMEGROUP.SOMEEVENT, and from GROUP2.STARTEVENT2 to
SOMEGROUP.SOMEEVENT with SOME_ID key.
Link: https://lkml.kernel.org/r/162856124905.203126.14913731908137885922.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:29 +03:00
static int __init
trace_boot_hist_add_handlers ( struct xbc_node * hnode , char * * bufp ,
char * end , const char * param )
{
struct xbc_node * node ;
const char * p , * handler ;
2022-05-22 09:18:26 +03:00
int ret = 0 ;
tracing/boot: Support multiple handlers for per-event histogram
Support multiple handlers for per-event histogram in boot-time tracing.
Since the histogram can register multiple same handler-actions with
different parameters, this expands the syntax to support such cases.
With this update, the 'onmax', 'onchange' and 'onmatch' handler subkeys
under per-event histogram option will take a number subkeys optionally
as below. (see [.N])
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
onmax|onchange[.N] { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch[.N] { event = <EVENT>; <ACTION> [= <PARAM>] }
}
The 'N' must be a digit (or digit started word).
Thus user can add several handler-actions to the histogram,
for example,
ftrace.event.SOMEGROUP.SOMEEVENT.hist {
keys = SOME_ID; lat = common_timestamp.usecs-$ts0
onmatch.1 {
event = GROUP1.STARTEVENT1
trace = latency_event, SOME_ID, $lat
}
onmatch.2 {
event = GROUP2.STARTEVENT2
trace = latency_event, SOME_ID, $lat
}
}
Then, it can trace the elapsed time from GROUP1.STARTEVENT1 to
SOMEGROUP.SOMEEVENT, and from GROUP2.STARTEVENT2 to
SOMEGROUP.SOMEEVENT with SOME_ID key.
Link: https://lkml.kernel.org/r/162856124905.203126.14913731908137885922.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:29 +03:00
handler = xbc_node_get_data ( hnode ) ;
xbc_node_for_each_subkey ( hnode , node ) {
p = xbc_node_get_data ( node ) ;
if ( ! isdigit ( p [ 0 ] ) )
continue ;
/* All digit started node should be instances. */
ret = trace_boot_hist_add_one_handler ( node , bufp , end , handler , param ) ;
if ( ret < 0 )
break ;
}
2021-09-09 16:36:38 +03:00
if ( xbc_node_find_subkey ( hnode , param ) )
tracing/boot: Support multiple handlers for per-event histogram
Support multiple handlers for per-event histogram in boot-time tracing.
Since the histogram can register multiple same handler-actions with
different parameters, this expands the syntax to support such cases.
With this update, the 'onmax', 'onchange' and 'onmatch' handler subkeys
under per-event histogram option will take a number subkeys optionally
as below. (see [.N])
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
onmax|onchange[.N] { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch[.N] { event = <EVENT>; <ACTION> [= <PARAM>] }
}
The 'N' must be a digit (or digit started word).
Thus user can add several handler-actions to the histogram,
for example,
ftrace.event.SOMEGROUP.SOMEEVENT.hist {
keys = SOME_ID; lat = common_timestamp.usecs-$ts0
onmatch.1 {
event = GROUP1.STARTEVENT1
trace = latency_event, SOME_ID, $lat
}
onmatch.2 {
event = GROUP2.STARTEVENT2
trace = latency_event, SOME_ID, $lat
}
}
Then, it can trace the elapsed time from GROUP1.STARTEVENT1 to
SOMEGROUP.SOMEEVENT, and from GROUP2.STARTEVENT2 to
SOMEGROUP.SOMEEVENT with SOME_ID key.
Link: https://lkml.kernel.org/r/162856124905.203126.14913731908137885922.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:29 +03:00
ret = trace_boot_hist_add_one_handler ( hnode , bufp , end , handler , param ) ;
return ret ;
}
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
/*
* Histogram boottime tracing syntax .
*
2021-08-10 05:07:36 +03:00
* ftrace . [ instance . INSTANCE . ] event . GROUP . EVENT . hist [ . N ] {
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
* keys = < KEY > [ , . . . ]
* values = < VAL > [ , . . . ]
* sort = < SORT - KEY > [ , . . . ]
* size = < ENTRIES >
* name = < HISTNAME >
* var { < VAR > = < EXPR > . . . }
* pause | continue | clear
tracing/boot: Support multiple handlers for per-event histogram
Support multiple handlers for per-event histogram in boot-time tracing.
Since the histogram can register multiple same handler-actions with
different parameters, this expands the syntax to support such cases.
With this update, the 'onmax', 'onchange' and 'onmatch' handler subkeys
under per-event histogram option will take a number subkeys optionally
as below. (see [.N])
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
onmax|onchange[.N] { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch[.N] { event = <EVENT>; <ACTION> [= <PARAM>] }
}
The 'N' must be a digit (or digit started word).
Thus user can add several handler-actions to the histogram,
for example,
ftrace.event.SOMEGROUP.SOMEEVENT.hist {
keys = SOME_ID; lat = common_timestamp.usecs-$ts0
onmatch.1 {
event = GROUP1.STARTEVENT1
trace = latency_event, SOME_ID, $lat
}
onmatch.2 {
event = GROUP2.STARTEVENT2
trace = latency_event, SOME_ID, $lat
}
}
Then, it can trace the elapsed time from GROUP1.STARTEVENT1 to
SOMEGROUP.SOMEEVENT, and from GROUP2.STARTEVENT2 to
SOMEGROUP.SOMEEVENT with SOME_ID key.
Link: https://lkml.kernel.org/r/162856124905.203126.14913731908137885922.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:29 +03:00
* onmax | onchange [ . N ] { var = < VAR > ; < ACTION > [ = < PARAM > ] }
* onmatch [ . N ] { event = < EVENT > ; < ACTION > [ = < PARAM > ] }
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
* filter = < FILTER >
* }
*
* Where < ACTION > are ;
*
* trace = < EVENT > , < ARG1 > [ , . . . ]
* save = < ARG1 > [ , . . . ]
* snapshot
*/
static int __init
trace_boot_compose_hist_cmd ( struct xbc_node * hnode , char * buf , size_t size )
{
struct xbc_node * node , * knode ;
char * end = buf + size ;
const char * p ;
int ret = 0 ;
append_printf ( & buf , end , " hist " ) ;
ret = trace_boot_hist_add_array ( hnode , & buf , end , " keys " ) ;
if ( ret < 0 ) {
if ( ret = = - ENOENT )
pr_err ( " hist requires keys. \n " ) ;
return - EINVAL ;
}
ret = trace_boot_hist_add_array ( hnode , & buf , end , " values " ) ;
if ( ret = = - EINVAL )
return ret ;
ret = trace_boot_hist_add_array ( hnode , & buf , end , " sort " ) ;
if ( ret = = - EINVAL )
return ret ;
p = xbc_node_find_value ( hnode , " size " , NULL ) ;
if ( p )
append_printf ( & buf , end , " :size=%s " , p ) ;
p = xbc_node_find_value ( hnode , " name " , NULL ) ;
if ( p )
append_printf ( & buf , end , " :name=%s " , p ) ;
2021-09-09 16:36:38 +03:00
node = xbc_node_find_subkey ( hnode , " var " ) ;
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
if ( node ) {
xbc_node_for_each_key_value ( node , knode , p ) {
/* Expression must not include spaces. */
append_printf ( & buf , end , " :%s= " ,
xbc_node_get_data ( knode ) ) ;
append_str_nospace ( & buf , end , p ) ;
}
}
/* Histogram control attributes (mutual exclusive) */
2021-09-09 16:36:30 +03:00
if ( xbc_node_find_value ( hnode , " pause " , NULL ) )
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
append_printf ( & buf , end , " :pause " ) ;
2021-09-09 16:36:30 +03:00
else if ( xbc_node_find_value ( hnode , " continue " , NULL ) )
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
append_printf ( & buf , end , " :continue " ) ;
2021-09-09 16:36:30 +03:00
else if ( xbc_node_find_value ( hnode , " clear " , NULL ) )
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
append_printf ( & buf , end , " :clear " ) ;
/* Histogram handler and actions */
2021-09-09 16:36:38 +03:00
node = xbc_node_find_subkey ( hnode , " onmax " ) ;
tracing/boot: Support multiple handlers for per-event histogram
Support multiple handlers for per-event histogram in boot-time tracing.
Since the histogram can register multiple same handler-actions with
different parameters, this expands the syntax to support such cases.
With this update, the 'onmax', 'onchange' and 'onmatch' handler subkeys
under per-event histogram option will take a number subkeys optionally
as below. (see [.N])
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
onmax|onchange[.N] { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch[.N] { event = <EVENT>; <ACTION> [= <PARAM>] }
}
The 'N' must be a digit (or digit started word).
Thus user can add several handler-actions to the histogram,
for example,
ftrace.event.SOMEGROUP.SOMEEVENT.hist {
keys = SOME_ID; lat = common_timestamp.usecs-$ts0
onmatch.1 {
event = GROUP1.STARTEVENT1
trace = latency_event, SOME_ID, $lat
}
onmatch.2 {
event = GROUP2.STARTEVENT2
trace = latency_event, SOME_ID, $lat
}
}
Then, it can trace the elapsed time from GROUP1.STARTEVENT1 to
SOMEGROUP.SOMEEVENT, and from GROUP2.STARTEVENT2 to
SOMEGROUP.SOMEEVENT with SOME_ID key.
Link: https://lkml.kernel.org/r/162856124905.203126.14913731908137885922.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:29 +03:00
if ( node & & trace_boot_hist_add_handlers ( node , & buf , end , " var " ) < 0 )
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
return - EINVAL ;
2021-09-09 16:36:38 +03:00
node = xbc_node_find_subkey ( hnode , " onchange " ) ;
tracing/boot: Support multiple handlers for per-event histogram
Support multiple handlers for per-event histogram in boot-time tracing.
Since the histogram can register multiple same handler-actions with
different parameters, this expands the syntax to support such cases.
With this update, the 'onmax', 'onchange' and 'onmatch' handler subkeys
under per-event histogram option will take a number subkeys optionally
as below. (see [.N])
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
onmax|onchange[.N] { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch[.N] { event = <EVENT>; <ACTION> [= <PARAM>] }
}
The 'N' must be a digit (or digit started word).
Thus user can add several handler-actions to the histogram,
for example,
ftrace.event.SOMEGROUP.SOMEEVENT.hist {
keys = SOME_ID; lat = common_timestamp.usecs-$ts0
onmatch.1 {
event = GROUP1.STARTEVENT1
trace = latency_event, SOME_ID, $lat
}
onmatch.2 {
event = GROUP2.STARTEVENT2
trace = latency_event, SOME_ID, $lat
}
}
Then, it can trace the elapsed time from GROUP1.STARTEVENT1 to
SOMEGROUP.SOMEEVENT, and from GROUP2.STARTEVENT2 to
SOMEGROUP.SOMEEVENT with SOME_ID key.
Link: https://lkml.kernel.org/r/162856124905.203126.14913731908137885922.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:29 +03:00
if ( node & & trace_boot_hist_add_handlers ( node , & buf , end , " var " ) < 0 )
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
return - EINVAL ;
2021-09-09 16:36:38 +03:00
node = xbc_node_find_subkey ( hnode , " onmatch " ) ;
tracing/boot: Support multiple handlers for per-event histogram
Support multiple handlers for per-event histogram in boot-time tracing.
Since the histogram can register multiple same handler-actions with
different parameters, this expands the syntax to support such cases.
With this update, the 'onmax', 'onchange' and 'onmatch' handler subkeys
under per-event histogram option will take a number subkeys optionally
as below. (see [.N])
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
onmax|onchange[.N] { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch[.N] { event = <EVENT>; <ACTION> [= <PARAM>] }
}
The 'N' must be a digit (or digit started word).
Thus user can add several handler-actions to the histogram,
for example,
ftrace.event.SOMEGROUP.SOMEEVENT.hist {
keys = SOME_ID; lat = common_timestamp.usecs-$ts0
onmatch.1 {
event = GROUP1.STARTEVENT1
trace = latency_event, SOME_ID, $lat
}
onmatch.2 {
event = GROUP2.STARTEVENT2
trace = latency_event, SOME_ID, $lat
}
}
Then, it can trace the elapsed time from GROUP1.STARTEVENT1 to
SOMEGROUP.SOMEEVENT, and from GROUP2.STARTEVENT2 to
SOMEGROUP.SOMEEVENT with SOME_ID key.
Link: https://lkml.kernel.org/r/162856124905.203126.14913731908137885922.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:29 +03:00
if ( node & & trace_boot_hist_add_handlers ( node , & buf , end , " event " ) < 0 )
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
return - EINVAL ;
p = xbc_node_find_value ( hnode , " filter " , NULL ) ;
if ( p )
append_printf ( & buf , end , " if %s " , p ) ;
if ( buf = = end ) {
pr_err ( " hist exceeds the max command length. \n " ) ;
return - E2BIG ;
}
return 0 ;
}
2021-08-10 05:07:36 +03:00
static void __init
trace_boot_init_histograms ( struct trace_event_file * file ,
struct xbc_node * hnode , char * buf , size_t size )
{
struct xbc_node * node ;
const char * p ;
2021-08-10 05:07:44 +03:00
char * tmp ;
2021-08-10 05:07:36 +03:00
xbc_node_for_each_subkey ( hnode , node ) {
p = xbc_node_get_data ( node ) ;
if ( ! isdigit ( p [ 0 ] ) )
continue ;
/* All digit started node should be instances. */
if ( trace_boot_compose_hist_cmd ( node , buf , size ) = = 0 ) {
2021-08-10 05:07:44 +03:00
tmp = kstrdup ( buf , GFP_KERNEL ) ;
2021-10-15 22:55:50 +03:00
if ( ! tmp )
return ;
2021-08-10 05:07:36 +03:00
if ( trigger_process_regex ( file , buf ) < 0 )
2021-08-10 05:07:44 +03:00
pr_err ( " Failed to apply hist trigger: %s \n " , tmp ) ;
kfree ( tmp ) ;
2021-08-10 05:07:36 +03:00
}
}
2021-09-09 16:36:38 +03:00
if ( xbc_node_find_subkey ( hnode , " keys " ) ) {
2021-08-10 05:07:44 +03:00
if ( trace_boot_compose_hist_cmd ( hnode , buf , size ) = = 0 ) {
tmp = kstrdup ( buf , GFP_KERNEL ) ;
2021-10-15 22:55:50 +03:00
if ( ! tmp )
return ;
2021-08-10 05:07:36 +03:00
if ( trigger_process_regex ( file , buf ) < 0 )
2021-08-10 05:07:44 +03:00
pr_err ( " Failed to apply hist trigger: %s \n " , tmp ) ;
kfree ( tmp ) ;
}
2021-08-10 05:07:36 +03:00
}
}
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
# else
2021-08-10 05:07:36 +03:00
static void __init
trace_boot_init_histograms ( struct trace_event_file * file ,
struct xbc_node * hnode , char * buf , size_t size )
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
{
2021-08-10 05:07:36 +03:00
/* do nothing */
tracing/boot: Add per-event histogram action options
Add a hist-trigger action syntax support to boot-time tracing.
Currently, boot-time tracing supports per-event actions as option
strings. However, for the histogram action, it has a special syntax
and usually needs a long action definition.
To make it readable and fit to the bootconfig syntax, this introduces
a new options for histogram.
Here are the histogram action options for boot-time tracing.
ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
keys = <KEY>[,...]
values = <VAL>[,...]
sort = <SORT-KEY>[,...]
size = <ENTRIES>
name = <HISTNAME>
var { <VAR> = <EXPR> ... }
pause|continue|clear
onmax|onchange { var = <VAR>; <ACTION> [= <PARAM>] }
onmatch { event = <EVENT>; <ACTION> [= <PARAM>] }
filter = <FILTER>
}
Where <ACTION> is one of below;
trace = <EVENT>, <ARG1>[, ...]
save = <ARG1>[, ...]
snapshot
Link: https://lkml.kernel.org/r/162856124106.203126.10501871028479029087.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-08-10 05:07:21 +03:00
}
# endif
2020-01-10 19:06:29 +03:00
static void __init
trace_boot_init_one_event ( struct trace_array * tr , struct xbc_node * gnode ,
struct xbc_node * enode )
{
struct trace_event_file * file ;
struct xbc_node * anode ;
char buf [ MAX_BUF_LEN ] ;
const char * p , * group , * event ;
group = xbc_node_get_data ( gnode ) ;
event = xbc_node_get_data ( enode ) ;
2020-01-10 19:06:41 +03:00
if ( ! strcmp ( group , " kprobes " ) )
if ( trace_boot_add_kprobe_event ( enode , event ) < 0 )
return ;
2020-01-10 19:06:52 +03:00
if ( ! strcmp ( group , " synthetic " ) )
if ( trace_boot_add_synth_event ( enode , event ) < 0 )
return ;
2020-01-10 19:06:41 +03:00
2020-01-10 19:06:29 +03:00
mutex_lock ( & event_mutex ) ;
file = find_event_file ( tr , group , event ) ;
if ( ! file ) {
pr_err ( " Failed to find event: %s:%s \n " , group , event ) ;
goto out ;
}
p = xbc_node_find_value ( enode , " filter " , NULL ) ;
if ( p & & * p ! = ' \0 ' ) {
if ( strlcpy ( buf , p , ARRAY_SIZE ( buf ) ) > = ARRAY_SIZE ( buf ) )
pr_err ( " filter string is too long: %s \n " , p ) ;
else if ( apply_event_filter ( file , buf ) < 0 )
pr_err ( " Failed to apply filter: %s \n " , buf ) ;
}
2021-08-10 05:07:14 +03:00
if ( IS_ENABLED ( CONFIG_HIST_TRIGGERS ) ) {
xbc_node_for_each_array_value ( enode , " actions " , anode , p ) {
if ( strlcpy ( buf , p , ARRAY_SIZE ( buf ) ) > = ARRAY_SIZE ( buf ) )
pr_err ( " action string is too long: %s \n " , p ) ;
else if ( trigger_process_regex ( file , buf ) < 0 )
2021-08-10 05:07:44 +03:00
pr_err ( " Failed to apply an action: %s \n " , p ) ;
2021-08-10 05:07:14 +03:00
}
2021-09-09 16:36:38 +03:00
anode = xbc_node_find_subkey ( enode , " hist " ) ;
2021-08-10 05:07:36 +03:00
if ( anode )
trace_boot_init_histograms ( file , anode , buf , ARRAY_SIZE ( buf ) ) ;
2021-08-10 05:07:14 +03:00
} else if ( xbc_node_find_value ( enode , " actions " , NULL ) )
pr_err ( " Failed to apply event actions because CONFIG_HIST_TRIGGERS is not set. \n " ) ;
2020-01-10 19:06:29 +03:00
if ( xbc_node_find_value ( enode , " enable " , NULL ) ) {
if ( trace_event_enable_disable ( file , 1 , 0 ) < 0 )
pr_err ( " Failed to enable event node: %s:%s \n " ,
group , event ) ;
}
out :
mutex_unlock ( & event_mutex ) ;
}
static void __init
trace_boot_init_events ( struct trace_array * tr , struct xbc_node * node )
{
struct xbc_node * gnode , * enode ;
2021-06-02 17:33:00 +03:00
bool enable , enable_all = false ;
const char * data ;
2020-01-10 19:06:29 +03:00
2021-09-09 16:36:38 +03:00
node = xbc_node_find_subkey ( node , " event " ) ;
2020-01-10 19:06:29 +03:00
if ( ! node )
return ;
/* per-event key starts with "event.GROUP.EVENT" */
2021-09-08 22:38:03 +03:00
xbc_node_for_each_subkey ( node , gnode ) {
2021-06-02 17:33:00 +03:00
data = xbc_node_get_data ( gnode ) ;
if ( ! strcmp ( data , " enable " ) ) {
enable_all = true ;
continue ;
}
enable = false ;
2021-09-08 22:38:03 +03:00
xbc_node_for_each_subkey ( gnode , enode ) {
2021-06-02 17:33:00 +03:00
data = xbc_node_get_data ( enode ) ;
if ( ! strcmp ( data , " enable " ) ) {
enable = true ;
continue ;
}
2020-01-10 19:06:29 +03:00
trace_boot_init_one_event ( tr , gnode , enode ) ;
2021-06-02 17:33:00 +03:00
}
/* Event enablement must be done after event settings */
if ( enable ) {
data = xbc_node_get_data ( gnode ) ;
trace_array_set_clr_event ( tr , data , NULL , true ) ;
}
}
/* Ditto */
if ( enable_all )
trace_array_set_clr_event ( tr , NULL , NULL , true ) ;
2020-01-10 19:06:29 +03:00
}
2020-01-10 19:06:17 +03:00
# else
# define trace_boot_enable_events(tr, node) do {} while (0)
2020-01-10 19:06:29 +03:00
# define trace_boot_init_events(tr, node) do {} while (0)
2020-01-10 19:06:17 +03:00
# endif
2020-01-10 19:07:28 +03:00
# ifdef CONFIG_DYNAMIC_FTRACE
static void __init
trace_boot_set_ftrace_filter ( struct trace_array * tr , struct xbc_node * node )
{
struct xbc_node * anode ;
const char * p ;
char * q ;
xbc_node_for_each_array_value ( node , " ftrace.filters " , anode , p ) {
q = kstrdup ( p , GFP_KERNEL ) ;
if ( ! q )
return ;
if ( ftrace_set_filter ( tr - > ops , q , strlen ( q ) , 0 ) < 0 )
pr_err ( " Failed to add %s to ftrace filter \n " , p ) ;
else
ftrace_filter_param = true ;
kfree ( q ) ;
}
xbc_node_for_each_array_value ( node , " ftrace.notraces " , anode , p ) {
q = kstrdup ( p , GFP_KERNEL ) ;
if ( ! q )
return ;
if ( ftrace_set_notrace ( tr - > ops , q , strlen ( q ) , 0 ) < 0 )
pr_err ( " Failed to add %s to ftrace filter \n " , p ) ;
else
ftrace_filter_param = true ;
kfree ( q ) ;
}
}
# else
# define trace_boot_set_ftrace_filter(tr, node) do {} while (0)
# endif
2020-01-10 19:06:17 +03:00
static void __init
trace_boot_enable_tracer ( struct trace_array * tr , struct xbc_node * node )
{
const char * p ;
2020-01-10 19:07:28 +03:00
trace_boot_set_ftrace_filter ( tr , node ) ;
2020-01-10 19:06:17 +03:00
p = xbc_node_find_value ( node , " tracer " , NULL ) ;
if ( p & & * p ! = ' \0 ' ) {
if ( tracing_set_tracer ( tr , p ) < 0 )
pr_err ( " Failed to set given tracer: %s \n " , p ) ;
}
2020-10-10 18:28:09 +03:00
/* Since tracer can free snapshot buffer, allocate snapshot here.*/
if ( xbc_node_find_value ( node , " alloc_snapshot " , NULL ) ) {
if ( tracing_alloc_snapshot_instance ( tr ) < 0 )
pr_err ( " Failed to allocate snapshot buffer \n " ) ;
}
2020-01-10 19:06:17 +03:00
}
2020-01-10 19:07:04 +03:00
static void __init
trace_boot_init_one_instance ( struct trace_array * tr , struct xbc_node * node )
{
trace_boot_set_instance_options ( tr , node ) ;
trace_boot_init_events ( tr , node ) ;
trace_boot_enable_events ( tr , node ) ;
trace_boot_enable_tracer ( tr , node ) ;
}
static void __init
trace_boot_init_instances ( struct xbc_node * node )
{
struct xbc_node * inode ;
struct trace_array * tr ;
const char * p ;
2021-09-09 16:36:38 +03:00
node = xbc_node_find_subkey ( node , " instance " ) ;
2020-01-10 19:07:04 +03:00
if ( ! node )
return ;
2021-09-08 22:38:03 +03:00
xbc_node_for_each_subkey ( node , inode ) {
2020-01-10 19:07:04 +03:00
p = xbc_node_get_data ( inode ) ;
if ( ! p | | * p = = ' \0 ' )
continue ;
tr = trace_array_get_by_name ( p ) ;
2020-01-17 08:30:07 +03:00
if ( ! tr ) {
2020-01-10 19:07:04 +03:00
pr_err ( " Failed to get trace instance %s \n " , p ) ;
continue ;
}
trace_boot_init_one_instance ( tr , inode ) ;
2020-01-25 04:47:46 +03:00
trace_array_put ( tr ) ;
2020-01-10 19:07:04 +03:00
}
}
2020-01-10 19:06:17 +03:00
static int __init trace_boot_init ( void )
{
struct xbc_node * trace_node ;
struct trace_array * tr ;
trace_node = xbc_find_node ( " ftrace " ) ;
if ( ! trace_node )
return 0 ;
tr = top_trace_array ( ) ;
if ( ! tr )
return 0 ;
2020-01-10 19:07:04 +03:00
/* Global trace array is also one instance */
trace_boot_init_one_instance ( tr , trace_node ) ;
trace_boot_init_instances ( trace_node ) ;
2020-01-10 19:06:17 +03:00
2020-12-08 11:54:09 +03:00
disable_tracing_selftest ( " running boot-time tracing " ) ;
2020-01-10 19:06:17 +03:00
return 0 ;
}
2020-09-10 15:39:17 +03:00
/*
* Start tracing at the end of core - initcall , so that it starts tracing
* from the beginning of postcore_initcall .
*/
core_initcall_sync ( trace_boot_init ) ;