tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
/*
|
|
|
|
* trace_events_hist - trace event hist triggers
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2015 Tom Zanussi <tom.zanussi@linux.intel.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/kallsyms.h>
|
|
|
|
#include <linux/mutex.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/stacktrace.h>
|
2017-02-04 08:27:20 +08:00
|
|
|
#include <linux/rculist.h>
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
|
|
|
#include "tracing_map.h"
|
|
|
|
#include "trace.h"
|
|
|
|
|
|
|
|
struct hist_field;
|
|
|
|
|
2018-01-16 10:51:54 +08:00
|
|
|
typedef u64 (*hist_field_fn_t) (struct hist_field *field,
|
|
|
|
struct tracing_map_elt *elt,
|
|
|
|
struct ring_buffer_event *rbe,
|
|
|
|
void *event);
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
2017-09-23 03:58:23 +08:00
|
|
|
#define HIST_FIELD_OPERANDS_MAX 2
|
2018-01-16 10:51:49 +08:00
|
|
|
#define HIST_FIELDS_MAX (TRACING_MAP_FIELDS_MAX + TRACING_MAP_VARS_MAX)
|
|
|
|
|
2018-01-16 10:51:52 +08:00
|
|
|
enum field_op_id {
|
|
|
|
FIELD_OP_NONE,
|
|
|
|
FIELD_OP_PLUS,
|
|
|
|
FIELD_OP_MINUS,
|
|
|
|
FIELD_OP_UNARY_MINUS,
|
|
|
|
};
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
struct hist_var {
|
|
|
|
char *name;
|
|
|
|
struct hist_trigger_data *hist_data;
|
|
|
|
unsigned int idx;
|
|
|
|
};
|
2017-09-23 03:58:23 +08:00
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
struct hist_field {
|
|
|
|
struct ftrace_event_field *field;
|
|
|
|
unsigned long flags;
|
|
|
|
hist_field_fn_t fn;
|
|
|
|
unsigned int size;
|
2016-03-04 02:54:44 +08:00
|
|
|
unsigned int offset;
|
2017-09-23 03:58:23 +08:00
|
|
|
unsigned int is_signed;
|
2018-01-16 10:51:55 +08:00
|
|
|
const char *type;
|
2017-09-23 03:58:23 +08:00
|
|
|
struct hist_field *operands[HIST_FIELD_OPERANDS_MAX];
|
2018-01-16 10:51:47 +08:00
|
|
|
struct hist_trigger_data *hist_data;
|
2018-01-16 10:51:49 +08:00
|
|
|
struct hist_var var;
|
2018-01-16 10:51:52 +08:00
|
|
|
enum field_op_id operator;
|
2018-01-16 10:51:56 +08:00
|
|
|
char *system;
|
|
|
|
char *event_name;
|
2018-01-16 10:51:52 +08:00
|
|
|
char *name;
|
2018-01-16 10:51:56 +08:00
|
|
|
unsigned int var_idx;
|
|
|
|
unsigned int var_ref_idx;
|
|
|
|
bool read_once;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
};
|
|
|
|
|
2018-01-16 10:51:54 +08:00
|
|
|
static u64 hist_field_none(struct hist_field *field,
|
|
|
|
struct tracing_map_elt *elt,
|
|
|
|
struct ring_buffer_event *rbe,
|
|
|
|
void *event)
|
2016-03-04 02:54:52 +08:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:54 +08:00
|
|
|
static u64 hist_field_counter(struct hist_field *field,
|
|
|
|
struct tracing_map_elt *elt,
|
|
|
|
struct ring_buffer_event *rbe,
|
|
|
|
void *event)
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:54 +08:00
|
|
|
static u64 hist_field_string(struct hist_field *hist_field,
|
|
|
|
struct tracing_map_elt *elt,
|
|
|
|
struct ring_buffer_event *rbe,
|
|
|
|
void *event)
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
{
|
|
|
|
char *addr = (char *)(event + hist_field->field->offset);
|
|
|
|
|
|
|
|
return (u64)(unsigned long)addr;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:54 +08:00
|
|
|
static u64 hist_field_dynstring(struct hist_field *hist_field,
|
|
|
|
struct tracing_map_elt *elt,
|
|
|
|
struct ring_buffer_event *rbe,
|
|
|
|
void *event)
|
2016-03-04 02:54:53 +08:00
|
|
|
{
|
|
|
|
u32 str_item = *(u32 *)(event + hist_field->field->offset);
|
|
|
|
int str_loc = str_item & 0xffff;
|
|
|
|
char *addr = (char *)(event + str_loc);
|
|
|
|
|
|
|
|
return (u64)(unsigned long)addr;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:54 +08:00
|
|
|
static u64 hist_field_pstring(struct hist_field *hist_field,
|
|
|
|
struct tracing_map_elt *elt,
|
|
|
|
struct ring_buffer_event *rbe,
|
|
|
|
void *event)
|
2016-03-04 02:54:53 +08:00
|
|
|
{
|
|
|
|
char **addr = (char **)(event + hist_field->field->offset);
|
|
|
|
|
|
|
|
return (u64)(unsigned long)*addr;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:54 +08:00
|
|
|
static u64 hist_field_log2(struct hist_field *hist_field,
|
|
|
|
struct tracing_map_elt *elt,
|
|
|
|
struct ring_buffer_event *rbe,
|
|
|
|
void *event)
|
2016-03-04 02:55:02 +08:00
|
|
|
{
|
2017-09-23 03:58:23 +08:00
|
|
|
struct hist_field *operand = hist_field->operands[0];
|
|
|
|
|
2018-01-16 10:51:54 +08:00
|
|
|
u64 val = operand->fn(operand, elt, rbe, event);
|
2016-03-04 02:55:02 +08:00
|
|
|
|
|
|
|
return (u64) ilog2(roundup_pow_of_two(val));
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:54 +08:00
|
|
|
static u64 hist_field_plus(struct hist_field *hist_field,
|
|
|
|
struct tracing_map_elt *elt,
|
|
|
|
struct ring_buffer_event *rbe,
|
|
|
|
void *event)
|
2018-01-16 10:51:52 +08:00
|
|
|
{
|
|
|
|
struct hist_field *operand1 = hist_field->operands[0];
|
|
|
|
struct hist_field *operand2 = hist_field->operands[1];
|
|
|
|
|
2018-01-16 10:51:54 +08:00
|
|
|
u64 val1 = operand1->fn(operand1, elt, rbe, event);
|
|
|
|
u64 val2 = operand2->fn(operand2, elt, rbe, event);
|
2018-01-16 10:51:52 +08:00
|
|
|
|
|
|
|
return val1 + val2;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:54 +08:00
|
|
|
static u64 hist_field_minus(struct hist_field *hist_field,
|
|
|
|
struct tracing_map_elt *elt,
|
|
|
|
struct ring_buffer_event *rbe,
|
|
|
|
void *event)
|
2018-01-16 10:51:52 +08:00
|
|
|
{
|
|
|
|
struct hist_field *operand1 = hist_field->operands[0];
|
|
|
|
struct hist_field *operand2 = hist_field->operands[1];
|
|
|
|
|
2018-01-16 10:51:54 +08:00
|
|
|
u64 val1 = operand1->fn(operand1, elt, rbe, event);
|
|
|
|
u64 val2 = operand2->fn(operand2, elt, rbe, event);
|
2018-01-16 10:51:52 +08:00
|
|
|
|
|
|
|
return val1 - val2;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:54 +08:00
|
|
|
static u64 hist_field_unary_minus(struct hist_field *hist_field,
|
|
|
|
struct tracing_map_elt *elt,
|
|
|
|
struct ring_buffer_event *rbe,
|
|
|
|
void *event)
|
2018-01-16 10:51:52 +08:00
|
|
|
{
|
|
|
|
struct hist_field *operand = hist_field->operands[0];
|
|
|
|
|
2018-01-16 10:51:54 +08:00
|
|
|
s64 sval = (s64)operand->fn(operand, elt, rbe, event);
|
2018-01-16 10:51:52 +08:00
|
|
|
u64 val = (u64)-sval;
|
|
|
|
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
#define DEFINE_HIST_FIELD_FN(type) \
|
2018-01-16 10:51:43 +08:00
|
|
|
static u64 hist_field_##type(struct hist_field *hist_field, \
|
2018-01-16 10:51:54 +08:00
|
|
|
struct tracing_map_elt *elt, \
|
|
|
|
struct ring_buffer_event *rbe, \
|
|
|
|
void *event) \
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
{ \
|
|
|
|
type *addr = (type *)(event + hist_field->field->offset); \
|
|
|
|
\
|
2016-03-04 02:54:53 +08:00
|
|
|
return (u64)(unsigned long)*addr; \
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFINE_HIST_FIELD_FN(s64);
|
|
|
|
DEFINE_HIST_FIELD_FN(u64);
|
|
|
|
DEFINE_HIST_FIELD_FN(s32);
|
|
|
|
DEFINE_HIST_FIELD_FN(u32);
|
|
|
|
DEFINE_HIST_FIELD_FN(s16);
|
|
|
|
DEFINE_HIST_FIELD_FN(u16);
|
|
|
|
DEFINE_HIST_FIELD_FN(s8);
|
|
|
|
DEFINE_HIST_FIELD_FN(u8);
|
|
|
|
|
|
|
|
#define for_each_hist_field(i, hist_data) \
|
|
|
|
for ((i) = 0; (i) < (hist_data)->n_fields; (i)++)
|
|
|
|
|
|
|
|
#define for_each_hist_val_field(i, hist_data) \
|
|
|
|
for ((i) = 0; (i) < (hist_data)->n_vals; (i)++)
|
|
|
|
|
|
|
|
#define for_each_hist_key_field(i, hist_data) \
|
|
|
|
for ((i) = (hist_data)->n_vals; (i) < (hist_data)->n_fields; (i)++)
|
|
|
|
|
2016-03-04 02:54:52 +08:00
|
|
|
#define HIST_STACKTRACE_DEPTH 16
|
|
|
|
#define HIST_STACKTRACE_SIZE (HIST_STACKTRACE_DEPTH * sizeof(unsigned long))
|
|
|
|
#define HIST_STACKTRACE_SKIP 5
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
#define HITCOUNT_IDX 0
|
2016-03-04 02:54:52 +08:00
|
|
|
#define HIST_KEY_SIZE_MAX (MAX_FILTER_STR_VAL + HIST_STACKTRACE_SIZE)
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
|
|
|
enum hist_field_flags {
|
2017-09-23 03:58:21 +08:00
|
|
|
HIST_FIELD_FL_HITCOUNT = 1 << 0,
|
|
|
|
HIST_FIELD_FL_KEY = 1 << 1,
|
|
|
|
HIST_FIELD_FL_STRING = 1 << 2,
|
|
|
|
HIST_FIELD_FL_HEX = 1 << 3,
|
|
|
|
HIST_FIELD_FL_SYM = 1 << 4,
|
|
|
|
HIST_FIELD_FL_SYM_OFFSET = 1 << 5,
|
|
|
|
HIST_FIELD_FL_EXECNAME = 1 << 6,
|
|
|
|
HIST_FIELD_FL_SYSCALL = 1 << 7,
|
|
|
|
HIST_FIELD_FL_STACKTRACE = 1 << 8,
|
|
|
|
HIST_FIELD_FL_LOG2 = 1 << 9,
|
2018-01-16 10:51:45 +08:00
|
|
|
HIST_FIELD_FL_TIMESTAMP = 1 << 10,
|
2018-01-16 10:51:48 +08:00
|
|
|
HIST_FIELD_FL_TIMESTAMP_USECS = 1 << 11,
|
2018-01-16 10:51:49 +08:00
|
|
|
HIST_FIELD_FL_VAR = 1 << 12,
|
2018-01-16 10:51:52 +08:00
|
|
|
HIST_FIELD_FL_EXPR = 1 << 13,
|
2018-01-16 10:51:56 +08:00
|
|
|
HIST_FIELD_FL_VAR_REF = 1 << 14,
|
2018-01-16 10:51:49 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct var_defs {
|
|
|
|
unsigned int n_vars;
|
|
|
|
char *name[TRACING_MAP_VARS_MAX];
|
|
|
|
char *expr[TRACING_MAP_VARS_MAX];
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct hist_trigger_attrs {
|
|
|
|
char *keys_str;
|
2016-03-04 02:54:43 +08:00
|
|
|
char *vals_str;
|
2016-03-04 02:54:45 +08:00
|
|
|
char *sort_key_str;
|
2016-03-04 02:54:59 +08:00
|
|
|
char *name;
|
2016-03-04 02:54:46 +08:00
|
|
|
bool pause;
|
|
|
|
bool cont;
|
2016-03-04 02:54:47 +08:00
|
|
|
bool clear;
|
2018-01-16 10:51:48 +08:00
|
|
|
bool ts_in_usecs;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
unsigned int map_bits;
|
2018-01-16 10:51:49 +08:00
|
|
|
|
|
|
|
char *assignment_str[TRACING_MAP_VARS_MAX];
|
|
|
|
unsigned int n_assignments;
|
|
|
|
|
|
|
|
struct var_defs var_defs;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct hist_trigger_data {
|
2018-01-16 10:51:49 +08:00
|
|
|
struct hist_field *fields[HIST_FIELDS_MAX];
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
unsigned int n_vals;
|
|
|
|
unsigned int n_keys;
|
|
|
|
unsigned int n_fields;
|
2018-01-16 10:51:49 +08:00
|
|
|
unsigned int n_vars;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
unsigned int key_size;
|
|
|
|
struct tracing_map_sort_key sort_keys[TRACING_MAP_SORT_KEYS_MAX];
|
|
|
|
unsigned int n_sort_keys;
|
|
|
|
struct trace_event_file *event_file;
|
|
|
|
struct hist_trigger_attrs *attrs;
|
|
|
|
struct tracing_map *map;
|
2018-01-16 10:51:45 +08:00
|
|
|
bool enable_timestamps;
|
2018-01-16 10:51:49 +08:00
|
|
|
bool remove;
|
2018-01-16 10:51:56 +08:00
|
|
|
struct hist_field *var_refs[TRACING_MAP_VARS_MAX];
|
|
|
|
unsigned int n_var_refs;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
};
|
|
|
|
|
2018-01-16 10:51:54 +08:00
|
|
|
static u64 hist_field_timestamp(struct hist_field *hist_field,
|
|
|
|
struct tracing_map_elt *elt,
|
|
|
|
struct ring_buffer_event *rbe,
|
|
|
|
void *event)
|
2018-01-16 10:51:48 +08:00
|
|
|
{
|
|
|
|
struct hist_trigger_data *hist_data = hist_field->hist_data;
|
|
|
|
struct trace_array *tr = hist_data->event_file->tr;
|
|
|
|
|
|
|
|
u64 ts = ring_buffer_event_time_stamp(rbe);
|
|
|
|
|
|
|
|
if (hist_data->attrs->ts_in_usecs && trace_clock_in_ns(tr))
|
|
|
|
ts = ns2usecs(ts);
|
|
|
|
|
|
|
|
return ts;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:56 +08:00
|
|
|
struct hist_var_data {
|
|
|
|
struct list_head list;
|
|
|
|
struct hist_trigger_data *hist_data;
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct hist_field *
|
|
|
|
check_field_for_var_ref(struct hist_field *hist_field,
|
|
|
|
struct hist_trigger_data *var_data,
|
|
|
|
unsigned int var_idx)
|
|
|
|
{
|
|
|
|
struct hist_field *found = NULL;
|
|
|
|
|
|
|
|
if (hist_field && hist_field->flags & HIST_FIELD_FL_VAR_REF) {
|
|
|
|
if (hist_field->var.idx == var_idx &&
|
|
|
|
hist_field->var.hist_data == var_data) {
|
|
|
|
found = hist_field;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct hist_field *
|
|
|
|
check_field_for_var_refs(struct hist_trigger_data *hist_data,
|
|
|
|
struct hist_field *hist_field,
|
|
|
|
struct hist_trigger_data *var_data,
|
|
|
|
unsigned int var_idx,
|
|
|
|
unsigned int level)
|
|
|
|
{
|
|
|
|
struct hist_field *found = NULL;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
if (level > 3)
|
|
|
|
return found;
|
|
|
|
|
|
|
|
if (!hist_field)
|
|
|
|
return found;
|
|
|
|
|
|
|
|
found = check_field_for_var_ref(hist_field, var_data, var_idx);
|
|
|
|
if (found)
|
|
|
|
return found;
|
|
|
|
|
|
|
|
for (i = 0; i < HIST_FIELD_OPERANDS_MAX; i++) {
|
|
|
|
struct hist_field *operand;
|
|
|
|
|
|
|
|
operand = hist_field->operands[i];
|
|
|
|
found = check_field_for_var_refs(hist_data, operand, var_data,
|
|
|
|
var_idx, level + 1);
|
|
|
|
if (found)
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct hist_field *find_var_ref(struct hist_trigger_data *hist_data,
|
|
|
|
struct hist_trigger_data *var_data,
|
|
|
|
unsigned int var_idx)
|
|
|
|
{
|
|
|
|
struct hist_field *hist_field, *found = NULL;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for_each_hist_field(i, hist_data) {
|
|
|
|
hist_field = hist_data->fields[i];
|
|
|
|
found = check_field_for_var_refs(hist_data, hist_field,
|
|
|
|
var_data, var_idx, 0);
|
|
|
|
if (found)
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct hist_field *find_any_var_ref(struct hist_trigger_data *hist_data,
|
|
|
|
unsigned int var_idx)
|
|
|
|
{
|
|
|
|
struct trace_array *tr = hist_data->event_file->tr;
|
|
|
|
struct hist_field *found = NULL;
|
|
|
|
struct hist_var_data *var_data;
|
|
|
|
|
|
|
|
list_for_each_entry(var_data, &tr->hist_vars, list) {
|
|
|
|
if (var_data->hist_data == hist_data)
|
|
|
|
continue;
|
|
|
|
found = find_var_ref(var_data->hist_data, hist_data, var_idx);
|
|
|
|
if (found)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool check_var_refs(struct hist_trigger_data *hist_data)
|
|
|
|
{
|
|
|
|
struct hist_field *field;
|
|
|
|
bool found = false;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for_each_hist_field(i, hist_data) {
|
|
|
|
field = hist_data->fields[i];
|
|
|
|
if (field && field->flags & HIST_FIELD_FL_VAR) {
|
|
|
|
if (find_any_var_ref(hist_data, field->var.idx)) {
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct hist_var_data *find_hist_vars(struct hist_trigger_data *hist_data)
|
|
|
|
{
|
|
|
|
struct trace_array *tr = hist_data->event_file->tr;
|
|
|
|
struct hist_var_data *var_data, *found = NULL;
|
|
|
|
|
|
|
|
list_for_each_entry(var_data, &tr->hist_vars, list) {
|
|
|
|
if (var_data->hist_data == hist_data) {
|
|
|
|
found = var_data;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool field_has_hist_vars(struct hist_field *hist_field,
|
|
|
|
unsigned int level)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (level > 3)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!hist_field)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (hist_field->flags & HIST_FIELD_FL_VAR ||
|
|
|
|
hist_field->flags & HIST_FIELD_FL_VAR_REF)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
for (i = 0; i < HIST_FIELD_OPERANDS_MAX; i++) {
|
|
|
|
struct hist_field *operand;
|
|
|
|
|
|
|
|
operand = hist_field->operands[i];
|
|
|
|
if (field_has_hist_vars(operand, level + 1))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool has_hist_vars(struct hist_trigger_data *hist_data)
|
|
|
|
{
|
|
|
|
struct hist_field *hist_field;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for_each_hist_field(i, hist_data) {
|
|
|
|
hist_field = hist_data->fields[i];
|
|
|
|
if (field_has_hist_vars(hist_field, 0))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int save_hist_vars(struct hist_trigger_data *hist_data)
|
|
|
|
{
|
|
|
|
struct trace_array *tr = hist_data->event_file->tr;
|
|
|
|
struct hist_var_data *var_data;
|
|
|
|
|
|
|
|
var_data = find_hist_vars(hist_data);
|
|
|
|
if (var_data)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (trace_array_get(tr) < 0)
|
|
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
var_data = kzalloc(sizeof(*var_data), GFP_KERNEL);
|
|
|
|
if (!var_data) {
|
|
|
|
trace_array_put(tr);
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
var_data->hist_data = hist_data;
|
|
|
|
list_add(&var_data->list, &tr->hist_vars);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void remove_hist_vars(struct hist_trigger_data *hist_data)
|
|
|
|
{
|
|
|
|
struct trace_array *tr = hist_data->event_file->tr;
|
|
|
|
struct hist_var_data *var_data;
|
|
|
|
|
|
|
|
var_data = find_hist_vars(hist_data);
|
|
|
|
if (!var_data)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (WARN_ON(check_var_refs(hist_data)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
list_del(&var_data->list);
|
|
|
|
|
|
|
|
kfree(var_data);
|
|
|
|
|
|
|
|
trace_array_put(tr);
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
static struct hist_field *find_var_field(struct hist_trigger_data *hist_data,
|
|
|
|
const char *var_name)
|
|
|
|
{
|
|
|
|
struct hist_field *hist_field, *found = NULL;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for_each_hist_field(i, hist_data) {
|
|
|
|
hist_field = hist_data->fields[i];
|
|
|
|
if (hist_field && hist_field->flags & HIST_FIELD_FL_VAR &&
|
|
|
|
strcmp(hist_field->var.name, var_name) == 0) {
|
|
|
|
found = hist_field;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct hist_field *find_var(struct hist_trigger_data *hist_data,
|
|
|
|
struct trace_event_file *file,
|
|
|
|
const char *var_name)
|
|
|
|
{
|
|
|
|
struct hist_trigger_data *test_data;
|
|
|
|
struct event_trigger_data *test;
|
|
|
|
struct hist_field *hist_field;
|
|
|
|
|
|
|
|
hist_field = find_var_field(hist_data, var_name);
|
|
|
|
if (hist_field)
|
|
|
|
return hist_field;
|
|
|
|
|
|
|
|
list_for_each_entry_rcu(test, &file->triggers, list) {
|
|
|
|
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
|
|
|
|
test_data = test->private_data;
|
|
|
|
hist_field = find_var_field(test_data, var_name);
|
|
|
|
if (hist_field)
|
|
|
|
return hist_field;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:56 +08:00
|
|
|
static struct trace_event_file *find_var_file(struct trace_array *tr,
|
|
|
|
char *system,
|
|
|
|
char *event_name,
|
|
|
|
char *var_name)
|
|
|
|
{
|
|
|
|
struct hist_trigger_data *var_hist_data;
|
|
|
|
struct hist_var_data *var_data;
|
|
|
|
struct trace_event_file *file, *found = NULL;
|
|
|
|
|
|
|
|
if (system)
|
|
|
|
return find_event_file(tr, system, event_name);
|
|
|
|
|
|
|
|
list_for_each_entry(var_data, &tr->hist_vars, list) {
|
|
|
|
var_hist_data = var_data->hist_data;
|
|
|
|
file = var_hist_data->event_file;
|
|
|
|
if (file == found)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (find_var_field(var_hist_data, var_name)) {
|
|
|
|
if (found)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
found = file;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct hist_field *find_file_var(struct trace_event_file *file,
|
|
|
|
const char *var_name)
|
|
|
|
{
|
|
|
|
struct hist_trigger_data *test_data;
|
|
|
|
struct event_trigger_data *test;
|
|
|
|
struct hist_field *hist_field;
|
|
|
|
|
|
|
|
list_for_each_entry_rcu(test, &file->triggers, list) {
|
|
|
|
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
|
|
|
|
test_data = test->private_data;
|
|
|
|
hist_field = find_var_field(test_data, var_name);
|
|
|
|
if (hist_field)
|
|
|
|
return hist_field;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct hist_field *find_event_var(struct hist_trigger_data *hist_data,
|
|
|
|
char *system,
|
|
|
|
char *event_name,
|
|
|
|
char *var_name)
|
|
|
|
{
|
|
|
|
struct trace_array *tr = hist_data->event_file->tr;
|
|
|
|
struct hist_field *hist_field = NULL;
|
|
|
|
struct trace_event_file *file;
|
|
|
|
|
|
|
|
file = find_var_file(tr, system, event_name, var_name);
|
|
|
|
if (!file)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
hist_field = find_file_var(file, var_name);
|
|
|
|
|
|
|
|
return hist_field;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:53 +08:00
|
|
|
struct hist_elt_data {
|
|
|
|
char *comm;
|
2018-01-16 10:51:56 +08:00
|
|
|
u64 *var_ref_vals;
|
2018-01-16 10:51:53 +08:00
|
|
|
};
|
|
|
|
|
2018-01-16 10:51:56 +08:00
|
|
|
static u64 hist_field_var_ref(struct hist_field *hist_field,
|
|
|
|
struct tracing_map_elt *elt,
|
|
|
|
struct ring_buffer_event *rbe,
|
|
|
|
void *event)
|
|
|
|
{
|
|
|
|
struct hist_elt_data *elt_data;
|
|
|
|
u64 var_val = 0;
|
|
|
|
|
|
|
|
elt_data = elt->private_data;
|
|
|
|
var_val = elt_data->var_ref_vals[hist_field->var_ref_idx];
|
|
|
|
|
|
|
|
return var_val;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool resolve_var_refs(struct hist_trigger_data *hist_data, void *key,
|
|
|
|
u64 *var_ref_vals, bool self)
|
|
|
|
{
|
|
|
|
struct hist_trigger_data *var_data;
|
|
|
|
struct tracing_map_elt *var_elt;
|
|
|
|
struct hist_field *hist_field;
|
|
|
|
unsigned int i, var_idx;
|
|
|
|
bool resolved = true;
|
|
|
|
u64 var_val = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < hist_data->n_var_refs; i++) {
|
|
|
|
hist_field = hist_data->var_refs[i];
|
|
|
|
var_idx = hist_field->var.idx;
|
|
|
|
var_data = hist_field->var.hist_data;
|
|
|
|
|
|
|
|
if (var_data == NULL) {
|
|
|
|
resolved = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((self && var_data != hist_data) ||
|
|
|
|
(!self && var_data == hist_data))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
var_elt = tracing_map_lookup(var_data->map, key);
|
|
|
|
if (!var_elt) {
|
|
|
|
resolved = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!tracing_map_var_set(var_elt, var_idx)) {
|
|
|
|
resolved = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (self || !hist_field->read_once)
|
|
|
|
var_val = tracing_map_read_var(var_elt, var_idx);
|
|
|
|
else
|
|
|
|
var_val = tracing_map_read_var_once(var_elt, var_idx);
|
|
|
|
|
|
|
|
var_ref_vals[i] = var_val;
|
|
|
|
}
|
|
|
|
|
|
|
|
return resolved;
|
|
|
|
}
|
|
|
|
|
2017-09-23 03:58:22 +08:00
|
|
|
static const char *hist_field_name(struct hist_field *field,
|
|
|
|
unsigned int level)
|
|
|
|
{
|
|
|
|
const char *field_name = "";
|
|
|
|
|
|
|
|
if (level > 1)
|
|
|
|
return field_name;
|
|
|
|
|
|
|
|
if (field->field)
|
|
|
|
field_name = field->field->name;
|
2017-09-23 03:58:23 +08:00
|
|
|
else if (field->flags & HIST_FIELD_FL_LOG2)
|
|
|
|
field_name = hist_field_name(field->operands[0], ++level);
|
2018-01-16 10:51:45 +08:00
|
|
|
else if (field->flags & HIST_FIELD_FL_TIMESTAMP)
|
|
|
|
field_name = "common_timestamp";
|
2018-01-16 10:51:56 +08:00
|
|
|
else if (field->flags & HIST_FIELD_FL_EXPR ||
|
|
|
|
field->flags & HIST_FIELD_FL_VAR_REF) {
|
|
|
|
if (field->system) {
|
|
|
|
static char full_name[MAX_FILTER_STR_VAL];
|
|
|
|
|
|
|
|
strcat(full_name, field->system);
|
|
|
|
strcat(full_name, ".");
|
|
|
|
strcat(full_name, field->event_name);
|
|
|
|
strcat(full_name, ".");
|
|
|
|
strcat(full_name, field->name);
|
|
|
|
field_name = full_name;
|
|
|
|
} else
|
|
|
|
field_name = field->name;
|
|
|
|
}
|
2017-09-23 03:58:22 +08:00
|
|
|
|
|
|
|
if (field_name == NULL)
|
|
|
|
field_name = "";
|
|
|
|
|
|
|
|
return field_name;
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
static hist_field_fn_t select_value_fn(int field_size, int field_is_signed)
|
|
|
|
{
|
|
|
|
hist_field_fn_t fn = NULL;
|
|
|
|
|
|
|
|
switch (field_size) {
|
|
|
|
case 8:
|
|
|
|
if (field_is_signed)
|
|
|
|
fn = hist_field_s64;
|
|
|
|
else
|
|
|
|
fn = hist_field_u64;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
if (field_is_signed)
|
|
|
|
fn = hist_field_s32;
|
|
|
|
else
|
|
|
|
fn = hist_field_u32;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if (field_is_signed)
|
|
|
|
fn = hist_field_s16;
|
|
|
|
else
|
|
|
|
fn = hist_field_u16;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (field_is_signed)
|
|
|
|
fn = hist_field_s8;
|
|
|
|
else
|
|
|
|
fn = hist_field_u8;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fn;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int parse_map_size(char *str)
|
|
|
|
{
|
|
|
|
unsigned long size, map_bits;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
strsep(&str, "=");
|
|
|
|
if (!str) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = kstrtoul(str, 0, &size);
|
|
|
|
if (ret)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
map_bits = ilog2(roundup_pow_of_two(size));
|
|
|
|
if (map_bits < TRACING_MAP_BITS_MIN ||
|
|
|
|
map_bits > TRACING_MAP_BITS_MAX)
|
|
|
|
ret = -EINVAL;
|
|
|
|
else
|
|
|
|
ret = map_bits;
|
|
|
|
out:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void destroy_hist_trigger_attrs(struct hist_trigger_attrs *attrs)
|
|
|
|
{
|
2018-01-16 10:51:49 +08:00
|
|
|
unsigned int i;
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
if (!attrs)
|
|
|
|
return;
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
for (i = 0; i < attrs->n_assignments; i++)
|
|
|
|
kfree(attrs->assignment_str[i]);
|
|
|
|
|
2016-03-04 02:54:59 +08:00
|
|
|
kfree(attrs->name);
|
2016-03-04 02:54:45 +08:00
|
|
|
kfree(attrs->sort_key_str);
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
kfree(attrs->keys_str);
|
2016-03-04 02:54:43 +08:00
|
|
|
kfree(attrs->vals_str);
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
kfree(attrs);
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:44 +08:00
|
|
|
static int parse_assignment(char *str, struct hist_trigger_attrs *attrs)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if ((strncmp(str, "key=", strlen("key=")) == 0) ||
|
|
|
|
(strncmp(str, "keys=", strlen("keys=")) == 0)) {
|
|
|
|
attrs->keys_str = kstrdup(str, GFP_KERNEL);
|
|
|
|
if (!attrs->keys_str) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
} else if ((strncmp(str, "val=", strlen("val=")) == 0) ||
|
|
|
|
(strncmp(str, "vals=", strlen("vals=")) == 0) ||
|
|
|
|
(strncmp(str, "values=", strlen("values=")) == 0)) {
|
|
|
|
attrs->vals_str = kstrdup(str, GFP_KERNEL);
|
|
|
|
if (!attrs->vals_str) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
} else if (strncmp(str, "sort=", strlen("sort=")) == 0) {
|
|
|
|
attrs->sort_key_str = kstrdup(str, GFP_KERNEL);
|
|
|
|
if (!attrs->sort_key_str) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
} else if (strncmp(str, "name=", strlen("name=")) == 0) {
|
|
|
|
attrs->name = kstrdup(str, GFP_KERNEL);
|
|
|
|
if (!attrs->name) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
} else if (strncmp(str, "size=", strlen("size=")) == 0) {
|
|
|
|
int map_bits = parse_map_size(str);
|
|
|
|
|
|
|
|
if (map_bits < 0) {
|
|
|
|
ret = map_bits;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
attrs->map_bits = map_bits;
|
2018-01-16 10:51:49 +08:00
|
|
|
} else {
|
|
|
|
char *assignment;
|
|
|
|
|
|
|
|
if (attrs->n_assignments == TRACING_MAP_VARS_MAX) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
assignment = kstrdup(str, GFP_KERNEL);
|
|
|
|
if (!assignment) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
attrs->assignment_str[attrs->n_assignments++] = assignment;
|
|
|
|
}
|
2018-01-16 10:51:44 +08:00
|
|
|
out:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
static struct hist_trigger_attrs *parse_hist_trigger_attrs(char *trigger_str)
|
|
|
|
{
|
|
|
|
struct hist_trigger_attrs *attrs;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
|
|
|
|
if (!attrs)
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
|
|
while (trigger_str) {
|
|
|
|
char *str = strsep(&trigger_str, ":");
|
|
|
|
|
2018-01-16 10:51:44 +08:00
|
|
|
if (strchr(str, '=')) {
|
|
|
|
ret = parse_assignment(str, attrs);
|
|
|
|
if (ret)
|
|
|
|
goto free;
|
|
|
|
} else if (strcmp(str, "pause") == 0)
|
2016-03-04 02:54:46 +08:00
|
|
|
attrs->pause = true;
|
|
|
|
else if ((strcmp(str, "cont") == 0) ||
|
|
|
|
(strcmp(str, "continue") == 0))
|
|
|
|
attrs->cont = true;
|
2016-03-04 02:54:47 +08:00
|
|
|
else if (strcmp(str, "clear") == 0)
|
|
|
|
attrs->clear = true;
|
2018-01-16 10:51:44 +08:00
|
|
|
else {
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
ret = -EINVAL;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!attrs->keys_str) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
|
|
|
return attrs;
|
|
|
|
free:
|
|
|
|
destroy_hist_trigger_attrs(attrs);
|
|
|
|
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:50 +08:00
|
|
|
static inline void save_comm(char *comm, struct task_struct *task)
|
|
|
|
{
|
|
|
|
if (!task->pid) {
|
|
|
|
strcpy(comm, "<idle>");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (WARN_ON_ONCE(task->pid < 0)) {
|
|
|
|
strcpy(comm, "<XXX>");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(comm, task->comm, TASK_COMM_LEN);
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:53 +08:00
|
|
|
static void hist_elt_data_free(struct hist_elt_data *elt_data)
|
|
|
|
{
|
|
|
|
kfree(elt_data->comm);
|
|
|
|
kfree(elt_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void hist_trigger_elt_data_free(struct tracing_map_elt *elt)
|
2016-03-04 02:54:50 +08:00
|
|
|
{
|
2018-01-16 10:51:53 +08:00
|
|
|
struct hist_elt_data *elt_data = elt->private_data;
|
|
|
|
|
|
|
|
hist_elt_data_free(elt_data);
|
2016-03-04 02:54:50 +08:00
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:53 +08:00
|
|
|
static int hist_trigger_elt_data_alloc(struct tracing_map_elt *elt)
|
2016-03-04 02:54:50 +08:00
|
|
|
{
|
|
|
|
struct hist_trigger_data *hist_data = elt->map->private_data;
|
2018-01-16 10:51:53 +08:00
|
|
|
unsigned int size = TASK_COMM_LEN;
|
|
|
|
struct hist_elt_data *elt_data;
|
2016-03-04 02:54:50 +08:00
|
|
|
struct hist_field *key_field;
|
|
|
|
unsigned int i;
|
|
|
|
|
2018-01-16 10:51:53 +08:00
|
|
|
elt_data = kzalloc(sizeof(*elt_data), GFP_KERNEL);
|
|
|
|
if (!elt_data)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2016-03-04 02:54:50 +08:00
|
|
|
for_each_hist_key_field(i, hist_data) {
|
|
|
|
key_field = hist_data->fields[i];
|
|
|
|
|
|
|
|
if (key_field->flags & HIST_FIELD_FL_EXECNAME) {
|
2018-01-16 10:51:53 +08:00
|
|
|
elt_data->comm = kzalloc(size, GFP_KERNEL);
|
|
|
|
if (!elt_data->comm) {
|
|
|
|
kfree(elt_data);
|
2016-03-04 02:54:50 +08:00
|
|
|
return -ENOMEM;
|
2018-01-16 10:51:53 +08:00
|
|
|
}
|
2016-03-04 02:54:50 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:53 +08:00
|
|
|
elt->private_data = elt_data;
|
|
|
|
|
2016-03-04 02:54:50 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:53 +08:00
|
|
|
static void hist_trigger_elt_data_init(struct tracing_map_elt *elt)
|
2016-03-04 02:54:50 +08:00
|
|
|
{
|
2018-01-16 10:51:53 +08:00
|
|
|
struct hist_elt_data *elt_data = elt->private_data;
|
2016-03-04 02:54:50 +08:00
|
|
|
|
2018-01-16 10:51:53 +08:00
|
|
|
if (elt_data->comm)
|
|
|
|
save_comm(elt_data->comm, current);
|
2016-03-04 02:54:50 +08:00
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:53 +08:00
|
|
|
static const struct tracing_map_ops hist_trigger_elt_data_ops = {
|
|
|
|
.elt_alloc = hist_trigger_elt_data_alloc,
|
|
|
|
.elt_free = hist_trigger_elt_data_free,
|
|
|
|
.elt_init = hist_trigger_elt_data_init,
|
2016-03-04 02:54:50 +08:00
|
|
|
};
|
|
|
|
|
2018-01-16 10:51:51 +08:00
|
|
|
static const char *get_hist_field_flags(struct hist_field *hist_field)
|
|
|
|
{
|
|
|
|
const char *flags_str = NULL;
|
|
|
|
|
|
|
|
if (hist_field->flags & HIST_FIELD_FL_HEX)
|
|
|
|
flags_str = "hex";
|
|
|
|
else if (hist_field->flags & HIST_FIELD_FL_SYM)
|
|
|
|
flags_str = "sym";
|
|
|
|
else if (hist_field->flags & HIST_FIELD_FL_SYM_OFFSET)
|
|
|
|
flags_str = "sym-offset";
|
|
|
|
else if (hist_field->flags & HIST_FIELD_FL_EXECNAME)
|
|
|
|
flags_str = "execname";
|
|
|
|
else if (hist_field->flags & HIST_FIELD_FL_SYSCALL)
|
|
|
|
flags_str = "syscall";
|
|
|
|
else if (hist_field->flags & HIST_FIELD_FL_LOG2)
|
|
|
|
flags_str = "log2";
|
|
|
|
else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP_USECS)
|
|
|
|
flags_str = "usecs";
|
|
|
|
|
|
|
|
return flags_str;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:52 +08:00
|
|
|
static void expr_field_str(struct hist_field *field, char *expr)
|
|
|
|
{
|
2018-01-16 10:51:56 +08:00
|
|
|
if (field->flags & HIST_FIELD_FL_VAR_REF)
|
|
|
|
strcat(expr, "$");
|
|
|
|
|
2018-01-16 10:51:52 +08:00
|
|
|
strcat(expr, hist_field_name(field, 0));
|
|
|
|
|
|
|
|
if (field->flags) {
|
|
|
|
const char *flags_str = get_hist_field_flags(field);
|
|
|
|
|
|
|
|
if (flags_str) {
|
|
|
|
strcat(expr, ".");
|
|
|
|
strcat(expr, flags_str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *expr_str(struct hist_field *field, unsigned int level)
|
|
|
|
{
|
|
|
|
char *expr;
|
|
|
|
|
|
|
|
if (level > 1)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
expr = kzalloc(MAX_FILTER_STR_VAL, GFP_KERNEL);
|
|
|
|
if (!expr)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (!field->operands[0]) {
|
|
|
|
expr_field_str(field, expr);
|
|
|
|
return expr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (field->operator == FIELD_OP_UNARY_MINUS) {
|
|
|
|
char *subexpr;
|
|
|
|
|
|
|
|
strcat(expr, "-(");
|
|
|
|
subexpr = expr_str(field->operands[0], ++level);
|
|
|
|
if (!subexpr) {
|
|
|
|
kfree(expr);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
strcat(expr, subexpr);
|
|
|
|
strcat(expr, ")");
|
|
|
|
|
|
|
|
kfree(subexpr);
|
|
|
|
|
|
|
|
return expr;
|
|
|
|
}
|
|
|
|
|
|
|
|
expr_field_str(field->operands[0], expr);
|
|
|
|
|
|
|
|
switch (field->operator) {
|
|
|
|
case FIELD_OP_MINUS:
|
|
|
|
strcat(expr, "-");
|
|
|
|
break;
|
|
|
|
case FIELD_OP_PLUS:
|
|
|
|
strcat(expr, "+");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
kfree(expr);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
expr_field_str(field->operands[1], expr);
|
|
|
|
|
|
|
|
return expr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int contains_operator(char *str)
|
|
|
|
{
|
|
|
|
enum field_op_id field_op = FIELD_OP_NONE;
|
|
|
|
char *op;
|
|
|
|
|
|
|
|
op = strpbrk(str, "+-");
|
|
|
|
if (!op)
|
|
|
|
return FIELD_OP_NONE;
|
|
|
|
|
|
|
|
switch (*op) {
|
|
|
|
case '-':
|
|
|
|
if (*str == '-')
|
|
|
|
field_op = FIELD_OP_UNARY_MINUS;
|
|
|
|
else
|
|
|
|
field_op = FIELD_OP_MINUS;
|
|
|
|
break;
|
|
|
|
case '+':
|
|
|
|
field_op = FIELD_OP_PLUS;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return field_op;
|
|
|
|
}
|
|
|
|
|
2017-09-23 03:58:23 +08:00
|
|
|
static void destroy_hist_field(struct hist_field *hist_field,
|
|
|
|
unsigned int level)
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
{
|
2017-09-23 03:58:23 +08:00
|
|
|
unsigned int i;
|
|
|
|
|
2018-01-16 10:51:52 +08:00
|
|
|
if (level > 3)
|
2017-09-23 03:58:23 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (!hist_field)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < HIST_FIELD_OPERANDS_MAX; i++)
|
|
|
|
destroy_hist_field(hist_field->operands[i], level + 1);
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
kfree(hist_field->var.name);
|
2018-01-16 10:51:52 +08:00
|
|
|
kfree(hist_field->name);
|
2018-01-16 10:51:55 +08:00
|
|
|
kfree(hist_field->type);
|
2018-01-16 10:51:49 +08:00
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
kfree(hist_field);
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:47 +08:00
|
|
|
static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data,
|
|
|
|
struct ftrace_event_field *field,
|
2018-01-16 10:51:49 +08:00
|
|
|
unsigned long flags,
|
|
|
|
char *var_name)
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
{
|
|
|
|
struct hist_field *hist_field;
|
|
|
|
|
|
|
|
if (field && is_function_field(field))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
hist_field = kzalloc(sizeof(struct hist_field), GFP_KERNEL);
|
|
|
|
if (!hist_field)
|
|
|
|
return NULL;
|
|
|
|
|
2018-01-16 10:51:47 +08:00
|
|
|
hist_field->hist_data = hist_data;
|
|
|
|
|
2018-01-16 10:51:52 +08:00
|
|
|
if (flags & HIST_FIELD_FL_EXPR)
|
|
|
|
goto out; /* caller will populate */
|
|
|
|
|
2018-01-16 10:51:56 +08:00
|
|
|
if (flags & HIST_FIELD_FL_VAR_REF) {
|
|
|
|
hist_field->fn = hist_field_var_ref;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
if (flags & HIST_FIELD_FL_HITCOUNT) {
|
|
|
|
hist_field->fn = hist_field_counter;
|
2018-01-16 10:51:55 +08:00
|
|
|
hist_field->size = sizeof(u64);
|
|
|
|
hist_field->type = kstrdup("u64", GFP_KERNEL);
|
|
|
|
if (!hist_field->type)
|
|
|
|
goto free;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:52 +08:00
|
|
|
if (flags & HIST_FIELD_FL_STACKTRACE) {
|
|
|
|
hist_field->fn = hist_field_none;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2016-03-04 02:55:02 +08:00
|
|
|
if (flags & HIST_FIELD_FL_LOG2) {
|
2017-09-23 03:58:23 +08:00
|
|
|
unsigned long fl = flags & ~HIST_FIELD_FL_LOG2;
|
2016-03-04 02:55:02 +08:00
|
|
|
hist_field->fn = hist_field_log2;
|
2018-01-16 10:51:49 +08:00
|
|
|
hist_field->operands[0] = create_hist_field(hist_data, field, fl, NULL);
|
2017-09-23 03:58:23 +08:00
|
|
|
hist_field->size = hist_field->operands[0]->size;
|
2018-01-16 10:51:55 +08:00
|
|
|
hist_field->type = kstrdup(hist_field->operands[0]->type, GFP_KERNEL);
|
|
|
|
if (!hist_field->type)
|
|
|
|
goto free;
|
2016-03-04 02:55:02 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:45 +08:00
|
|
|
if (flags & HIST_FIELD_FL_TIMESTAMP) {
|
|
|
|
hist_field->fn = hist_field_timestamp;
|
|
|
|
hist_field->size = sizeof(u64);
|
2018-01-16 10:51:55 +08:00
|
|
|
hist_field->type = kstrdup("u64", GFP_KERNEL);
|
|
|
|
if (!hist_field->type)
|
|
|
|
goto free;
|
2018-01-16 10:51:45 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2016-04-26 03:01:27 +08:00
|
|
|
if (WARN_ON_ONCE(!field))
|
|
|
|
goto out;
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
if (is_string_field(field)) {
|
|
|
|
flags |= HIST_FIELD_FL_STRING;
|
2016-03-04 02:54:53 +08:00
|
|
|
|
2018-01-16 10:51:55 +08:00
|
|
|
hist_field->size = MAX_FILTER_STR_VAL;
|
|
|
|
hist_field->type = kstrdup(field->type, GFP_KERNEL);
|
|
|
|
if (!hist_field->type)
|
|
|
|
goto free;
|
|
|
|
|
2016-03-04 02:54:53 +08:00
|
|
|
if (field->filter_type == FILTER_STATIC_STRING)
|
|
|
|
hist_field->fn = hist_field_string;
|
|
|
|
else if (field->filter_type == FILTER_DYN_STRING)
|
|
|
|
hist_field->fn = hist_field_dynstring;
|
|
|
|
else
|
|
|
|
hist_field->fn = hist_field_pstring;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
} else {
|
2018-01-16 10:51:55 +08:00
|
|
|
hist_field->size = field->size;
|
|
|
|
hist_field->is_signed = field->is_signed;
|
|
|
|
hist_field->type = kstrdup(field->type, GFP_KERNEL);
|
|
|
|
if (!hist_field->type)
|
|
|
|
goto free;
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
hist_field->fn = select_value_fn(field->size,
|
|
|
|
field->is_signed);
|
|
|
|
if (!hist_field->fn) {
|
2017-09-23 03:58:23 +08:00
|
|
|
destroy_hist_field(hist_field, 0);
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
out:
|
|
|
|
hist_field->field = field;
|
|
|
|
hist_field->flags = flags;
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
if (var_name) {
|
|
|
|
hist_field->var.name = kstrdup(var_name, GFP_KERNEL);
|
|
|
|
if (!hist_field->var.name)
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
return hist_field;
|
2018-01-16 10:51:49 +08:00
|
|
|
free:
|
|
|
|
destroy_hist_field(hist_field, 0);
|
|
|
|
return NULL;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void destroy_hist_fields(struct hist_trigger_data *hist_data)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
for (i = 0; i < HIST_FIELDS_MAX; i++) {
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
if (hist_data->fields[i]) {
|
2017-09-23 03:58:23 +08:00
|
|
|
destroy_hist_field(hist_data->fields[i], 0);
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
hist_data->fields[i] = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:56 +08:00
|
|
|
static int init_var_ref(struct hist_field *ref_field,
|
|
|
|
struct hist_field *var_field,
|
|
|
|
char *system, char *event_name)
|
|
|
|
{
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
ref_field->var.idx = var_field->var.idx;
|
|
|
|
ref_field->var.hist_data = var_field->hist_data;
|
|
|
|
ref_field->size = var_field->size;
|
|
|
|
ref_field->is_signed = var_field->is_signed;
|
|
|
|
ref_field->flags |= var_field->flags &
|
|
|
|
(HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS);
|
|
|
|
|
|
|
|
if (system) {
|
|
|
|
ref_field->system = kstrdup(system, GFP_KERNEL);
|
|
|
|
if (!ref_field->system)
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event_name) {
|
|
|
|
ref_field->event_name = kstrdup(event_name, GFP_KERNEL);
|
|
|
|
if (!ref_field->event_name) {
|
|
|
|
err = -ENOMEM;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ref_field->name = kstrdup(var_field->var.name, GFP_KERNEL);
|
|
|
|
if (!ref_field->name) {
|
|
|
|
err = -ENOMEM;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
|
|
|
ref_field->type = kstrdup(var_field->type, GFP_KERNEL);
|
|
|
|
if (!ref_field->type) {
|
|
|
|
err = -ENOMEM;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
out:
|
|
|
|
return err;
|
|
|
|
free:
|
|
|
|
kfree(ref_field->system);
|
|
|
|
kfree(ref_field->event_name);
|
|
|
|
kfree(ref_field->name);
|
|
|
|
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct hist_field *create_var_ref(struct hist_field *var_field,
|
|
|
|
char *system, char *event_name)
|
|
|
|
{
|
|
|
|
unsigned long flags = HIST_FIELD_FL_VAR_REF;
|
|
|
|
struct hist_field *ref_field;
|
|
|
|
|
|
|
|
ref_field = create_hist_field(var_field->hist_data, NULL, flags, NULL);
|
|
|
|
if (ref_field) {
|
|
|
|
if (init_var_ref(ref_field, var_field, system, event_name)) {
|
|
|
|
destroy_hist_field(ref_field, 0);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ref_field;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool is_var_ref(char *var_name)
|
|
|
|
{
|
|
|
|
if (!var_name || strlen(var_name) < 2 || var_name[0] != '$')
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *field_name_from_var(struct hist_trigger_data *hist_data,
|
|
|
|
char *var_name)
|
|
|
|
{
|
|
|
|
char *name, *field;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 0; i < hist_data->attrs->var_defs.n_vars; i++) {
|
|
|
|
name = hist_data->attrs->var_defs.name[i];
|
|
|
|
|
|
|
|
if (strcmp(var_name, name) == 0) {
|
|
|
|
field = hist_data->attrs->var_defs.expr[i];
|
|
|
|
if (contains_operator(field) || is_var_ref(field))
|
|
|
|
continue;
|
|
|
|
return field;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *local_field_var_ref(struct hist_trigger_data *hist_data,
|
|
|
|
char *system, char *event_name,
|
|
|
|
char *var_name)
|
|
|
|
{
|
|
|
|
struct trace_event_call *call;
|
|
|
|
|
|
|
|
if (system && event_name) {
|
|
|
|
call = hist_data->event_file->event_call;
|
|
|
|
|
|
|
|
if (strcmp(system, call->class->system) != 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (strcmp(event_name, trace_event_name(call)) != 0)
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!!system != !!event_name)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (!is_var_ref(var_name))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
var_name++;
|
|
|
|
|
|
|
|
return field_name_from_var(hist_data, var_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct hist_field *parse_var_ref(struct hist_trigger_data *hist_data,
|
|
|
|
char *system, char *event_name,
|
|
|
|
char *var_name)
|
|
|
|
{
|
|
|
|
struct hist_field *var_field = NULL, *ref_field = NULL;
|
|
|
|
|
|
|
|
if (!is_var_ref(var_name))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
var_name++;
|
|
|
|
|
|
|
|
var_field = find_event_var(hist_data, system, event_name, var_name);
|
|
|
|
if (var_field)
|
|
|
|
ref_field = create_var_ref(var_field, system, event_name);
|
|
|
|
|
|
|
|
return ref_field;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:52 +08:00
|
|
|
static struct ftrace_event_field *
|
|
|
|
parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file,
|
|
|
|
char *field_str, unsigned long *flags)
|
|
|
|
{
|
|
|
|
struct ftrace_event_field *field = NULL;
|
|
|
|
char *field_name, *modifier, *str;
|
|
|
|
|
|
|
|
modifier = str = kstrdup(field_str, GFP_KERNEL);
|
|
|
|
if (!modifier)
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
|
|
field_name = strsep(&modifier, ".");
|
|
|
|
if (modifier) {
|
|
|
|
if (strcmp(modifier, "hex") == 0)
|
|
|
|
*flags |= HIST_FIELD_FL_HEX;
|
|
|
|
else if (strcmp(modifier, "sym") == 0)
|
|
|
|
*flags |= HIST_FIELD_FL_SYM;
|
|
|
|
else if (strcmp(modifier, "sym-offset") == 0)
|
|
|
|
*flags |= HIST_FIELD_FL_SYM_OFFSET;
|
|
|
|
else if ((strcmp(modifier, "execname") == 0) &&
|
|
|
|
(strcmp(field_name, "common_pid") == 0))
|
|
|
|
*flags |= HIST_FIELD_FL_EXECNAME;
|
|
|
|
else if (strcmp(modifier, "syscall") == 0)
|
|
|
|
*flags |= HIST_FIELD_FL_SYSCALL;
|
|
|
|
else if (strcmp(modifier, "log2") == 0)
|
|
|
|
*flags |= HIST_FIELD_FL_LOG2;
|
|
|
|
else if (strcmp(modifier, "usecs") == 0)
|
|
|
|
*flags |= HIST_FIELD_FL_TIMESTAMP_USECS;
|
|
|
|
else {
|
|
|
|
field = ERR_PTR(-EINVAL);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(field_name, "common_timestamp") == 0) {
|
|
|
|
*flags |= HIST_FIELD_FL_TIMESTAMP;
|
|
|
|
hist_data->enable_timestamps = true;
|
|
|
|
if (*flags & HIST_FIELD_FL_TIMESTAMP_USECS)
|
|
|
|
hist_data->attrs->ts_in_usecs = true;
|
|
|
|
} else {
|
|
|
|
field = trace_find_event_field(file->event_call, field_name);
|
|
|
|
if (!field || !field->size) {
|
|
|
|
field = ERR_PTR(-EINVAL);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
out:
|
|
|
|
kfree(str);
|
|
|
|
|
|
|
|
return field;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct hist_field *parse_atom(struct hist_trigger_data *hist_data,
|
|
|
|
struct trace_event_file *file, char *str,
|
|
|
|
unsigned long *flags, char *var_name)
|
|
|
|
{
|
2018-01-16 10:51:56 +08:00
|
|
|
char *s, *ref_system = NULL, *ref_event = NULL, *ref_var = str;
|
2018-01-16 10:51:52 +08:00
|
|
|
struct ftrace_event_field *field = NULL;
|
|
|
|
struct hist_field *hist_field = NULL;
|
|
|
|
int ret = 0;
|
|
|
|
|
2018-01-16 10:51:56 +08:00
|
|
|
s = strchr(str, '.');
|
|
|
|
if (s) {
|
|
|
|
s = strchr(++s, '.');
|
|
|
|
if (s) {
|
|
|
|
ref_system = strsep(&str, ".");
|
|
|
|
if (!str) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
ref_event = strsep(&str, ".");
|
|
|
|
if (!str) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
ref_var = str;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
s = local_field_var_ref(hist_data, ref_system, ref_event, ref_var);
|
|
|
|
if (!s) {
|
|
|
|
hist_field = parse_var_ref(hist_data, ref_system, ref_event, ref_var);
|
|
|
|
if (hist_field) {
|
|
|
|
hist_data->var_refs[hist_data->n_var_refs] = hist_field;
|
|
|
|
hist_field->var_ref_idx = hist_data->n_var_refs++;
|
|
|
|
return hist_field;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
str = s;
|
|
|
|
|
2018-01-16 10:51:52 +08:00
|
|
|
field = parse_field(hist_data, file, str, flags);
|
|
|
|
if (IS_ERR(field)) {
|
|
|
|
ret = PTR_ERR(field);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
hist_field = create_hist_field(hist_data, field, *flags, var_name);
|
|
|
|
if (!hist_field) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
return hist_field;
|
|
|
|
out:
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
|
|
|
|
struct trace_event_file *file,
|
|
|
|
char *str, unsigned long flags,
|
|
|
|
char *var_name, unsigned int level);
|
|
|
|
|
|
|
|
static struct hist_field *parse_unary(struct hist_trigger_data *hist_data,
|
|
|
|
struct trace_event_file *file,
|
|
|
|
char *str, unsigned long flags,
|
|
|
|
char *var_name, unsigned int level)
|
|
|
|
{
|
|
|
|
struct hist_field *operand1, *expr = NULL;
|
|
|
|
unsigned long operand_flags;
|
|
|
|
int ret = 0;
|
|
|
|
char *s;
|
|
|
|
|
|
|
|
/* we support only -(xxx) i.e. explicit parens required */
|
|
|
|
|
|
|
|
if (level > 3) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
|
|
|
str++; /* skip leading '-' */
|
|
|
|
|
|
|
|
s = strchr(str, '(');
|
|
|
|
if (s)
|
|
|
|
str++;
|
|
|
|
else {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
|
|
|
s = strrchr(str, ')');
|
|
|
|
if (s)
|
|
|
|
*s = '\0';
|
|
|
|
else {
|
|
|
|
ret = -EINVAL; /* no closing ')' */
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
|
|
|
flags |= HIST_FIELD_FL_EXPR;
|
|
|
|
expr = create_hist_field(hist_data, NULL, flags, var_name);
|
|
|
|
if (!expr) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
|
|
|
operand_flags = 0;
|
|
|
|
operand1 = parse_expr(hist_data, file, str, operand_flags, NULL, ++level);
|
|
|
|
if (IS_ERR(operand1)) {
|
|
|
|
ret = PTR_ERR(operand1);
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
|
|
|
expr->flags |= operand1->flags &
|
|
|
|
(HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS);
|
|
|
|
expr->fn = hist_field_unary_minus;
|
|
|
|
expr->operands[0] = operand1;
|
|
|
|
expr->operator = FIELD_OP_UNARY_MINUS;
|
|
|
|
expr->name = expr_str(expr, 0);
|
2018-01-16 10:51:55 +08:00
|
|
|
expr->type = kstrdup(operand1->type, GFP_KERNEL);
|
|
|
|
if (!expr->type) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto free;
|
|
|
|
}
|
2018-01-16 10:51:52 +08:00
|
|
|
|
|
|
|
return expr;
|
|
|
|
free:
|
|
|
|
destroy_hist_field(expr, 0);
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int check_expr_operands(struct hist_field *operand1,
|
|
|
|
struct hist_field *operand2)
|
|
|
|
{
|
|
|
|
unsigned long operand1_flags = operand1->flags;
|
|
|
|
unsigned long operand2_flags = operand2->flags;
|
|
|
|
|
|
|
|
if ((operand1_flags & HIST_FIELD_FL_TIMESTAMP_USECS) !=
|
|
|
|
(operand2_flags & HIST_FIELD_FL_TIMESTAMP_USECS))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
|
|
|
|
struct trace_event_file *file,
|
|
|
|
char *str, unsigned long flags,
|
|
|
|
char *var_name, unsigned int level)
|
|
|
|
{
|
|
|
|
struct hist_field *operand1 = NULL, *operand2 = NULL, *expr = NULL;
|
|
|
|
unsigned long operand_flags;
|
|
|
|
int field_op, ret = -EINVAL;
|
|
|
|
char *sep, *operand1_str;
|
|
|
|
|
|
|
|
if (level > 3)
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
|
|
|
|
field_op = contains_operator(str);
|
|
|
|
|
|
|
|
if (field_op == FIELD_OP_NONE)
|
|
|
|
return parse_atom(hist_data, file, str, &flags, var_name);
|
|
|
|
|
|
|
|
if (field_op == FIELD_OP_UNARY_MINUS)
|
|
|
|
return parse_unary(hist_data, file, str, flags, var_name, ++level);
|
|
|
|
|
|
|
|
switch (field_op) {
|
|
|
|
case FIELD_OP_MINUS:
|
|
|
|
sep = "-";
|
|
|
|
break;
|
|
|
|
case FIELD_OP_PLUS:
|
|
|
|
sep = "+";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
|
|
|
operand1_str = strsep(&str, sep);
|
|
|
|
if (!operand1_str || !str)
|
|
|
|
goto free;
|
|
|
|
|
|
|
|
operand_flags = 0;
|
|
|
|
operand1 = parse_atom(hist_data, file, operand1_str,
|
|
|
|
&operand_flags, NULL);
|
|
|
|
if (IS_ERR(operand1)) {
|
|
|
|
ret = PTR_ERR(operand1);
|
|
|
|
operand1 = NULL;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* rest of string could be another expression e.g. b+c in a+b+c */
|
|
|
|
operand_flags = 0;
|
|
|
|
operand2 = parse_expr(hist_data, file, str, operand_flags, NULL, ++level);
|
|
|
|
if (IS_ERR(operand2)) {
|
|
|
|
ret = PTR_ERR(operand2);
|
|
|
|
operand2 = NULL;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = check_expr_operands(operand1, operand2);
|
|
|
|
if (ret)
|
|
|
|
goto free;
|
|
|
|
|
|
|
|
flags |= HIST_FIELD_FL_EXPR;
|
|
|
|
|
|
|
|
flags |= operand1->flags &
|
|
|
|
(HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS);
|
|
|
|
|
|
|
|
expr = create_hist_field(hist_data, NULL, flags, var_name);
|
|
|
|
if (!expr) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:56 +08:00
|
|
|
operand1->read_once = true;
|
|
|
|
operand2->read_once = true;
|
|
|
|
|
2018-01-16 10:51:52 +08:00
|
|
|
expr->operands[0] = operand1;
|
|
|
|
expr->operands[1] = operand2;
|
|
|
|
expr->operator = field_op;
|
|
|
|
expr->name = expr_str(expr, 0);
|
2018-01-16 10:51:55 +08:00
|
|
|
expr->type = kstrdup(operand1->type, GFP_KERNEL);
|
|
|
|
if (!expr->type) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto free;
|
|
|
|
}
|
2018-01-16 10:51:52 +08:00
|
|
|
|
|
|
|
switch (field_op) {
|
|
|
|
case FIELD_OP_MINUS:
|
|
|
|
expr->fn = hist_field_minus;
|
|
|
|
break;
|
|
|
|
case FIELD_OP_PLUS:
|
|
|
|
expr->fn = hist_field_plus;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
|
|
|
return expr;
|
|
|
|
free:
|
|
|
|
destroy_hist_field(operand1, 0);
|
|
|
|
destroy_hist_field(operand2, 0);
|
|
|
|
destroy_hist_field(expr, 0);
|
|
|
|
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
static int create_hitcount_val(struct hist_trigger_data *hist_data)
|
|
|
|
{
|
|
|
|
hist_data->fields[HITCOUNT_IDX] =
|
2018-01-16 10:51:49 +08:00
|
|
|
create_hist_field(hist_data, NULL, HIST_FIELD_FL_HITCOUNT, NULL);
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
if (!hist_data->fields[HITCOUNT_IDX])
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
hist_data->n_vals++;
|
2018-01-16 10:51:49 +08:00
|
|
|
hist_data->n_fields++;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
|
|
|
if (WARN_ON(hist_data->n_vals > TRACING_MAP_VALS_MAX))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
static int __create_val_field(struct hist_trigger_data *hist_data,
|
|
|
|
unsigned int val_idx,
|
|
|
|
struct trace_event_file *file,
|
|
|
|
char *var_name, char *field_str,
|
|
|
|
unsigned long flags)
|
2016-03-04 02:54:43 +08:00
|
|
|
{
|
2018-01-16 10:51:52 +08:00
|
|
|
struct hist_field *hist_field;
|
2016-03-04 02:54:43 +08:00
|
|
|
int ret = 0;
|
|
|
|
|
2018-01-16 10:51:52 +08:00
|
|
|
hist_field = parse_expr(hist_data, file, field_str, flags, var_name, 0);
|
|
|
|
if (IS_ERR(hist_field)) {
|
|
|
|
ret = PTR_ERR(hist_field);
|
2016-03-04 02:54:43 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:52 +08:00
|
|
|
hist_data->fields[val_idx] = hist_field;
|
|
|
|
|
2016-03-04 02:54:43 +08:00
|
|
|
++hist_data->n_vals;
|
2018-01-16 10:51:49 +08:00
|
|
|
++hist_data->n_fields;
|
2016-03-04 02:54:43 +08:00
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
if (WARN_ON(hist_data->n_vals > TRACING_MAP_VALS_MAX + TRACING_MAP_VARS_MAX))
|
2016-03-04 02:54:43 +08:00
|
|
|
ret = -EINVAL;
|
|
|
|
out:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
static int create_val_field(struct hist_trigger_data *hist_data,
|
|
|
|
unsigned int val_idx,
|
|
|
|
struct trace_event_file *file,
|
|
|
|
char *field_str)
|
|
|
|
{
|
|
|
|
if (WARN_ON(val_idx >= TRACING_MAP_VALS_MAX))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return __create_val_field(hist_data, val_idx, file, NULL, field_str, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int create_var_field(struct hist_trigger_data *hist_data,
|
|
|
|
unsigned int val_idx,
|
|
|
|
struct trace_event_file *file,
|
|
|
|
char *var_name, char *expr_str)
|
|
|
|
{
|
|
|
|
unsigned long flags = 0;
|
|
|
|
|
|
|
|
if (WARN_ON(val_idx >= TRACING_MAP_VALS_MAX + TRACING_MAP_VARS_MAX))
|
|
|
|
return -EINVAL;
|
|
|
|
if (find_var(hist_data, file, var_name) && !hist_data->remove) {
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
flags |= HIST_FIELD_FL_VAR;
|
|
|
|
hist_data->n_vars++;
|
|
|
|
if (WARN_ON(hist_data->n_vars > TRACING_MAP_VARS_MAX))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return __create_val_field(hist_data, val_idx, file, var_name, expr_str, flags);
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
static int create_val_fields(struct hist_trigger_data *hist_data,
|
|
|
|
struct trace_event_file *file)
|
|
|
|
{
|
2016-03-04 02:54:43 +08:00
|
|
|
char *fields_str, *field_str;
|
2018-01-16 10:51:49 +08:00
|
|
|
unsigned int i, j = 1;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = create_hitcount_val(hist_data);
|
2016-03-04 02:54:43 +08:00
|
|
|
if (ret)
|
|
|
|
goto out;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
2016-03-04 02:54:43 +08:00
|
|
|
fields_str = hist_data->attrs->vals_str;
|
|
|
|
if (!fields_str)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
strsep(&fields_str, "=");
|
|
|
|
if (!fields_str)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
for (i = 0, j = 1; i < TRACING_MAP_VALS_MAX &&
|
|
|
|
j < TRACING_MAP_VALS_MAX; i++) {
|
|
|
|
field_str = strsep(&fields_str, ",");
|
|
|
|
if (!field_str)
|
|
|
|
break;
|
2018-01-16 10:51:49 +08:00
|
|
|
|
2016-03-04 02:54:43 +08:00
|
|
|
if (strcmp(field_str, "hitcount") == 0)
|
|
|
|
continue;
|
2018-01-16 10:51:49 +08:00
|
|
|
|
2016-03-04 02:54:43 +08:00
|
|
|
ret = create_val_field(hist_data, j++, file, field_str);
|
|
|
|
if (ret)
|
|
|
|
goto out;
|
|
|
|
}
|
2018-01-16 10:51:49 +08:00
|
|
|
|
2016-03-04 02:54:43 +08:00
|
|
|
if (fields_str && (strcmp(fields_str, "hitcount") != 0))
|
|
|
|
ret = -EINVAL;
|
|
|
|
out:
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int create_key_field(struct hist_trigger_data *hist_data,
|
|
|
|
unsigned int key_idx,
|
2016-03-04 02:54:44 +08:00
|
|
|
unsigned int key_offset,
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
struct trace_event_file *file,
|
|
|
|
char *field_str)
|
|
|
|
{
|
2018-01-16 10:51:49 +08:00
|
|
|
struct hist_field *hist_field = NULL;
|
2018-01-16 10:51:52 +08:00
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
unsigned long flags = 0;
|
|
|
|
unsigned int key_size;
|
|
|
|
int ret = 0;
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
if (WARN_ON(key_idx >= HIST_FIELDS_MAX))
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
flags |= HIST_FIELD_FL_KEY;
|
|
|
|
|
2016-03-04 02:54:52 +08:00
|
|
|
if (strcmp(field_str, "stacktrace") == 0) {
|
|
|
|
flags |= HIST_FIELD_FL_STACKTRACE;
|
|
|
|
key_size = sizeof(unsigned long) * HIST_STACKTRACE_DEPTH;
|
2018-01-16 10:51:49 +08:00
|
|
|
hist_field = create_hist_field(hist_data, NULL, flags, NULL);
|
2016-03-04 02:54:52 +08:00
|
|
|
} else {
|
2018-01-16 10:51:52 +08:00
|
|
|
hist_field = parse_expr(hist_data, file, field_str, flags,
|
|
|
|
NULL, 0);
|
|
|
|
if (IS_ERR(hist_field)) {
|
|
|
|
ret = PTR_ERR(hist_field);
|
|
|
|
goto out;
|
2016-03-04 02:54:52 +08:00
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:56 +08:00
|
|
|
if (hist_field->flags & HIST_FIELD_FL_VAR_REF) {
|
|
|
|
destroy_hist_field(hist_field, 0);
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:52 +08:00
|
|
|
key_size = hist_field->size;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:52 +08:00
|
|
|
hist_data->fields[key_idx] = hist_field;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
|
|
|
key_size = ALIGN(key_size, sizeof(u64));
|
|
|
|
hist_data->fields[key_idx]->size = key_size;
|
2016-03-04 02:54:44 +08:00
|
|
|
hist_data->fields[key_idx]->offset = key_offset;
|
2018-01-16 10:51:52 +08:00
|
|
|
|
2016-03-04 02:54:44 +08:00
|
|
|
hist_data->key_size += key_size;
|
2018-01-16 10:51:52 +08:00
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
if (hist_data->key_size > HIST_KEY_SIZE_MAX) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
hist_data->n_keys++;
|
2018-01-16 10:51:49 +08:00
|
|
|
hist_data->n_fields++;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
|
|
|
if (WARN_ON(hist_data->n_keys > TRACING_MAP_KEYS_MAX))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
ret = key_size;
|
|
|
|
out:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int create_key_fields(struct hist_trigger_data *hist_data,
|
|
|
|
struct trace_event_file *file)
|
|
|
|
{
|
2016-03-04 02:54:44 +08:00
|
|
|
unsigned int i, key_offset = 0, n_vals = hist_data->n_vals;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
char *fields_str, *field_str;
|
|
|
|
int ret = -EINVAL;
|
|
|
|
|
|
|
|
fields_str = hist_data->attrs->keys_str;
|
|
|
|
if (!fields_str)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
strsep(&fields_str, "=");
|
|
|
|
if (!fields_str)
|
|
|
|
goto out;
|
|
|
|
|
2016-03-04 02:54:44 +08:00
|
|
|
for (i = n_vals; i < n_vals + TRACING_MAP_KEYS_MAX; i++) {
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
field_str = strsep(&fields_str, ",");
|
|
|
|
if (!field_str)
|
|
|
|
break;
|
2016-03-04 02:54:44 +08:00
|
|
|
ret = create_key_field(hist_data, i, key_offset,
|
|
|
|
file, field_str);
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
if (ret < 0)
|
|
|
|
goto out;
|
2016-03-04 02:54:44 +08:00
|
|
|
key_offset += ret;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
}
|
|
|
|
if (fields_str) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
ret = 0;
|
|
|
|
out:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
static int create_var_fields(struct hist_trigger_data *hist_data,
|
|
|
|
struct trace_event_file *file)
|
|
|
|
{
|
|
|
|
unsigned int i, j = hist_data->n_vals;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
unsigned int n_vars = hist_data->attrs->var_defs.n_vars;
|
|
|
|
|
|
|
|
for (i = 0; i < n_vars; i++) {
|
|
|
|
char *var_name = hist_data->attrs->var_defs.name[i];
|
|
|
|
char *expr = hist_data->attrs->var_defs.expr[i];
|
|
|
|
|
|
|
|
ret = create_var_field(hist_data, j++, file, var_name, expr);
|
|
|
|
if (ret)
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
out:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_var_defs(struct hist_trigger_data *hist_data)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 0; i < hist_data->attrs->var_defs.n_vars; i++) {
|
|
|
|
kfree(hist_data->attrs->var_defs.name[i]);
|
|
|
|
kfree(hist_data->attrs->var_defs.expr[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
hist_data->attrs->var_defs.n_vars = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int parse_var_defs(struct hist_trigger_data *hist_data)
|
|
|
|
{
|
|
|
|
char *s, *str, *var_name, *field_str;
|
|
|
|
unsigned int i, j, n_vars = 0;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < hist_data->attrs->n_assignments; i++) {
|
|
|
|
str = hist_data->attrs->assignment_str[i];
|
|
|
|
for (j = 0; j < TRACING_MAP_VARS_MAX; j++) {
|
|
|
|
field_str = strsep(&str, ",");
|
|
|
|
if (!field_str)
|
|
|
|
break;
|
|
|
|
|
|
|
|
var_name = strsep(&field_str, "=");
|
|
|
|
if (!var_name || !field_str) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n_vars == TRACING_MAP_VARS_MAX) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
|
|
|
s = kstrdup(var_name, GFP_KERNEL);
|
|
|
|
if (!s) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
hist_data->attrs->var_defs.name[n_vars] = s;
|
|
|
|
|
|
|
|
s = kstrdup(field_str, GFP_KERNEL);
|
|
|
|
if (!s) {
|
|
|
|
kfree(hist_data->attrs->var_defs.name[n_vars]);
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
hist_data->attrs->var_defs.expr[n_vars++] = s;
|
|
|
|
|
|
|
|
hist_data->attrs->var_defs.n_vars = n_vars;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
free:
|
|
|
|
free_var_defs(hist_data);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
static int create_hist_fields(struct hist_trigger_data *hist_data,
|
|
|
|
struct trace_event_file *file)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
ret = parse_var_defs(hist_data);
|
|
|
|
if (ret)
|
|
|
|
goto out;
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
ret = create_val_fields(hist_data, file);
|
|
|
|
if (ret)
|
|
|
|
goto out;
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
ret = create_var_fields(hist_data, file);
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
if (ret)
|
|
|
|
goto out;
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
ret = create_key_fields(hist_data, file);
|
|
|
|
if (ret)
|
|
|
|
goto out;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
out:
|
2018-01-16 10:51:49 +08:00
|
|
|
free_var_defs(hist_data);
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:45 +08:00
|
|
|
static int is_descending(const char *str)
|
|
|
|
{
|
|
|
|
if (!str)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (strcmp(str, "descending") == 0)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (strcmp(str, "ascending") == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
static int create_sort_keys(struct hist_trigger_data *hist_data)
|
|
|
|
{
|
2016-03-04 02:54:45 +08:00
|
|
|
char *fields_str = hist_data->attrs->sort_key_str;
|
|
|
|
struct tracing_map_sort_key *sort_key;
|
|
|
|
int descending, ret = 0;
|
2018-01-16 10:51:49 +08:00
|
|
|
unsigned int i, j, k;
|
2016-03-04 02:54:45 +08:00
|
|
|
|
|
|
|
hist_data->n_sort_keys = 1; /* we always have at least one, hitcount */
|
|
|
|
|
|
|
|
if (!fields_str)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
strsep(&fields_str, "=");
|
|
|
|
if (!fields_str) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < TRACING_MAP_SORT_KEYS_MAX; i++) {
|
2017-09-23 03:58:22 +08:00
|
|
|
struct hist_field *hist_field;
|
2016-03-04 02:54:45 +08:00
|
|
|
char *field_str, *field_name;
|
2017-09-23 03:58:22 +08:00
|
|
|
const char *test_name;
|
2016-03-04 02:54:45 +08:00
|
|
|
|
|
|
|
sort_key = &hist_data->sort_keys[i];
|
|
|
|
|
|
|
|
field_str = strsep(&fields_str, ",");
|
|
|
|
if (!field_str) {
|
|
|
|
if (i == 0)
|
|
|
|
ret = -EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((i == TRACING_MAP_SORT_KEYS_MAX - 1) && fields_str) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
2016-03-04 02:54:45 +08:00
|
|
|
field_name = strsep(&field_str, ".");
|
|
|
|
if (!field_name) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(field_name, "hitcount") == 0) {
|
|
|
|
descending = is_descending(field_str);
|
|
|
|
if (descending < 0) {
|
|
|
|
ret = descending;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
sort_key->descending = descending;
|
|
|
|
continue;
|
|
|
|
}
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
for (j = 1, k = 1; j < hist_data->n_fields; j++) {
|
|
|
|
unsigned int idx;
|
|
|
|
|
2017-09-23 03:58:22 +08:00
|
|
|
hist_field = hist_data->fields[j];
|
2018-01-16 10:51:49 +08:00
|
|
|
if (hist_field->flags & HIST_FIELD_FL_VAR)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
idx = k++;
|
|
|
|
|
2017-09-23 03:58:22 +08:00
|
|
|
test_name = hist_field_name(hist_field, 0);
|
|
|
|
|
|
|
|
if (strcmp(field_name, test_name) == 0) {
|
2018-01-16 10:51:49 +08:00
|
|
|
sort_key->field_idx = idx;
|
2016-03-04 02:54:45 +08:00
|
|
|
descending = is_descending(field_str);
|
|
|
|
if (descending < 0) {
|
|
|
|
ret = descending;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
sort_key->descending = descending;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (j == hist_data->n_fields) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-01-16 10:51:49 +08:00
|
|
|
|
2016-03-04 02:54:45 +08:00
|
|
|
hist_data->n_sort_keys = i;
|
|
|
|
out:
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void destroy_hist_data(struct hist_trigger_data *hist_data)
|
|
|
|
{
|
|
|
|
destroy_hist_trigger_attrs(hist_data->attrs);
|
|
|
|
destroy_hist_fields(hist_data);
|
|
|
|
tracing_map_destroy(hist_data->map);
|
|
|
|
kfree(hist_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int create_tracing_map_fields(struct hist_trigger_data *hist_data)
|
|
|
|
{
|
|
|
|
struct tracing_map *map = hist_data->map;
|
|
|
|
struct ftrace_event_field *field;
|
|
|
|
struct hist_field *hist_field;
|
2016-03-09 06:17:15 +08:00
|
|
|
int i, idx;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
|
|
|
for_each_hist_field(i, hist_data) {
|
|
|
|
hist_field = hist_data->fields[i];
|
|
|
|
if (hist_field->flags & HIST_FIELD_FL_KEY) {
|
|
|
|
tracing_map_cmp_fn_t cmp_fn;
|
|
|
|
|
|
|
|
field = hist_field->field;
|
|
|
|
|
2016-03-04 02:54:52 +08:00
|
|
|
if (hist_field->flags & HIST_FIELD_FL_STACKTRACE)
|
|
|
|
cmp_fn = tracing_map_cmp_none;
|
2018-01-16 10:51:45 +08:00
|
|
|
else if (!field)
|
|
|
|
cmp_fn = tracing_map_cmp_num(hist_field->size,
|
|
|
|
hist_field->is_signed);
|
2016-03-04 02:54:52 +08:00
|
|
|
else if (is_string_field(field))
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
cmp_fn = tracing_map_cmp_string;
|
|
|
|
else
|
|
|
|
cmp_fn = tracing_map_cmp_num(field->size,
|
|
|
|
field->is_signed);
|
2016-03-04 02:54:44 +08:00
|
|
|
idx = tracing_map_add_key_field(map,
|
|
|
|
hist_field->offset,
|
|
|
|
cmp_fn);
|
2018-01-16 10:51:49 +08:00
|
|
|
} else if (!(hist_field->flags & HIST_FIELD_FL_VAR))
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
idx = tracing_map_add_sum_field(map);
|
|
|
|
|
|
|
|
if (idx < 0)
|
|
|
|
return idx;
|
2018-01-16 10:51:49 +08:00
|
|
|
|
|
|
|
if (hist_field->flags & HIST_FIELD_FL_VAR) {
|
|
|
|
idx = tracing_map_add_var(map);
|
|
|
|
if (idx < 0)
|
|
|
|
return idx;
|
|
|
|
hist_field->var.idx = idx;
|
|
|
|
hist_field->var.hist_data = hist_data;
|
|
|
|
}
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct hist_trigger_data *
|
|
|
|
create_hist_data(unsigned int map_bits,
|
|
|
|
struct hist_trigger_attrs *attrs,
|
2018-01-16 10:51:49 +08:00
|
|
|
struct trace_event_file *file,
|
|
|
|
bool remove)
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
{
|
2016-03-04 02:54:50 +08:00
|
|
|
const struct tracing_map_ops *map_ops = NULL;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
struct hist_trigger_data *hist_data;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
hist_data = kzalloc(sizeof(*hist_data), GFP_KERNEL);
|
|
|
|
if (!hist_data)
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
|
|
hist_data->attrs = attrs;
|
2018-01-16 10:51:49 +08:00
|
|
|
hist_data->remove = remove;
|
2018-01-16 10:51:56 +08:00
|
|
|
hist_data->event_file = file;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
|
|
|
ret = create_hist_fields(hist_data, file);
|
|
|
|
if (ret)
|
|
|
|
goto free;
|
|
|
|
|
|
|
|
ret = create_sort_keys(hist_data);
|
|
|
|
if (ret)
|
|
|
|
goto free;
|
|
|
|
|
2018-01-16 10:51:53 +08:00
|
|
|
map_ops = &hist_trigger_elt_data_ops;
|
2016-03-04 02:54:50 +08:00
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
hist_data->map = tracing_map_create(map_bits, hist_data->key_size,
|
2016-03-04 02:54:50 +08:00
|
|
|
map_ops, hist_data);
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
if (IS_ERR(hist_data->map)) {
|
|
|
|
ret = PTR_ERR(hist_data->map);
|
|
|
|
hist_data->map = NULL;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = create_tracing_map_fields(hist_data);
|
|
|
|
if (ret)
|
|
|
|
goto free;
|
|
|
|
out:
|
|
|
|
return hist_data;
|
|
|
|
free:
|
|
|
|
hist_data->attrs = NULL;
|
|
|
|
|
|
|
|
destroy_hist_data(hist_data);
|
|
|
|
|
|
|
|
hist_data = ERR_PTR(ret);
|
|
|
|
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void hist_trigger_elt_update(struct hist_trigger_data *hist_data,
|
2018-01-16 10:51:43 +08:00
|
|
|
struct tracing_map_elt *elt, void *rec,
|
2018-01-16 10:51:56 +08:00
|
|
|
struct ring_buffer_event *rbe,
|
|
|
|
u64 *var_ref_vals)
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
{
|
2018-01-16 10:51:56 +08:00
|
|
|
struct hist_elt_data *elt_data;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
struct hist_field *hist_field;
|
2018-01-16 10:51:49 +08:00
|
|
|
unsigned int i, var_idx;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
u64 hist_val;
|
|
|
|
|
2018-01-16 10:51:56 +08:00
|
|
|
elt_data = elt->private_data;
|
|
|
|
elt_data->var_ref_vals = var_ref_vals;
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
for_each_hist_val_field(i, hist_data) {
|
|
|
|
hist_field = hist_data->fields[i];
|
2018-01-16 10:51:54 +08:00
|
|
|
hist_val = hist_field->fn(hist_field, elt, rbe, rec);
|
2018-01-16 10:51:49 +08:00
|
|
|
if (hist_field->flags & HIST_FIELD_FL_VAR) {
|
|
|
|
var_idx = hist_field->var.idx;
|
|
|
|
tracing_map_set_var(elt, var_idx, hist_val);
|
|
|
|
continue;
|
|
|
|
}
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
tracing_map_update_sum(elt, i, hist_val);
|
|
|
|
}
|
2018-01-16 10:51:49 +08:00
|
|
|
|
|
|
|
for_each_hist_key_field(i, hist_data) {
|
|
|
|
hist_field = hist_data->fields[i];
|
|
|
|
if (hist_field->flags & HIST_FIELD_FL_VAR) {
|
2018-01-16 10:51:54 +08:00
|
|
|
hist_val = hist_field->fn(hist_field, elt, rbe, rec);
|
2018-01-16 10:51:49 +08:00
|
|
|
var_idx = hist_field->var.idx;
|
|
|
|
tracing_map_set_var(elt, var_idx, hist_val);
|
|
|
|
}
|
|
|
|
}
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:54 +08:00
|
|
|
static inline void add_to_key(char *compound_key, void *key,
|
|
|
|
struct hist_field *key_field, void *rec)
|
|
|
|
{
|
|
|
|
size_t size = key_field->size;
|
|
|
|
|
|
|
|
if (key_field->flags & HIST_FIELD_FL_STRING) {
|
|
|
|
struct ftrace_event_field *field;
|
|
|
|
|
|
|
|
field = key_field->field;
|
|
|
|
if (field->filter_type == FILTER_DYN_STRING)
|
|
|
|
size = *(u32 *)(rec + field->offset) >> 16;
|
|
|
|
else if (field->filter_type == FILTER_PTR_STRING)
|
|
|
|
size = strlen(key);
|
|
|
|
else if (field->filter_type == FILTER_STATIC_STRING)
|
|
|
|
size = field->size;
|
|
|
|
|
|
|
|
/* ensure NULL-termination */
|
|
|
|
if (size > key_field->size - 1)
|
|
|
|
size = key_field->size - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(compound_key + key_field->offset, key, size);
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:42 +08:00
|
|
|
static void event_hist_trigger(struct event_trigger_data *data, void *rec,
|
2018-01-16 10:51:43 +08:00
|
|
|
struct ring_buffer_event *rbe)
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
{
|
|
|
|
struct hist_trigger_data *hist_data = data->private_data;
|
2016-03-04 02:54:54 +08:00
|
|
|
bool use_compound_key = (hist_data->n_keys > 1);
|
2016-03-04 02:54:52 +08:00
|
|
|
unsigned long entries[HIST_STACKTRACE_DEPTH];
|
2018-01-16 10:51:56 +08:00
|
|
|
u64 var_ref_vals[TRACING_MAP_VARS_MAX];
|
2016-03-04 02:54:44 +08:00
|
|
|
char compound_key[HIST_KEY_SIZE_MAX];
|
2018-01-16 10:51:54 +08:00
|
|
|
struct tracing_map_elt *elt = NULL;
|
2016-03-04 02:54:52 +08:00
|
|
|
struct stack_trace stacktrace;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
struct hist_field *key_field;
|
|
|
|
u64 field_contents;
|
|
|
|
void *key = NULL;
|
|
|
|
unsigned int i;
|
|
|
|
|
2016-03-04 02:54:54 +08:00
|
|
|
memset(compound_key, 0, hist_data->key_size);
|
2016-03-04 02:54:44 +08:00
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
for_each_hist_key_field(i, hist_data) {
|
|
|
|
key_field = hist_data->fields[i];
|
|
|
|
|
2016-03-04 02:54:52 +08:00
|
|
|
if (key_field->flags & HIST_FIELD_FL_STACKTRACE) {
|
|
|
|
stacktrace.max_entries = HIST_STACKTRACE_DEPTH;
|
|
|
|
stacktrace.entries = entries;
|
|
|
|
stacktrace.nr_entries = 0;
|
|
|
|
stacktrace.skip = HIST_STACKTRACE_SKIP;
|
2016-03-04 02:54:44 +08:00
|
|
|
|
2016-03-04 02:54:52 +08:00
|
|
|
memset(stacktrace.entries, 0, HIST_STACKTRACE_SIZE);
|
|
|
|
save_stack_trace(&stacktrace);
|
|
|
|
|
|
|
|
key = entries;
|
|
|
|
} else {
|
2018-01-16 10:51:54 +08:00
|
|
|
field_contents = key_field->fn(key_field, elt, rbe, rec);
|
2016-03-04 02:54:54 +08:00
|
|
|
if (key_field->flags & HIST_FIELD_FL_STRING) {
|
2016-03-04 02:54:52 +08:00
|
|
|
key = (void *)(unsigned long)field_contents;
|
2016-03-04 02:54:54 +08:00
|
|
|
use_compound_key = true;
|
|
|
|
} else
|
2016-03-04 02:54:52 +08:00
|
|
|
key = (void *)&field_contents;
|
2016-03-04 02:54:44 +08:00
|
|
|
}
|
2016-03-04 02:54:54 +08:00
|
|
|
|
|
|
|
if (use_compound_key)
|
|
|
|
add_to_key(compound_key, key, key_field, rec);
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:54 +08:00
|
|
|
if (use_compound_key)
|
2016-03-04 02:54:44 +08:00
|
|
|
key = compound_key;
|
|
|
|
|
2018-01-16 10:51:56 +08:00
|
|
|
if (hist_data->n_var_refs &&
|
|
|
|
!resolve_var_refs(hist_data, key, var_ref_vals, false))
|
|
|
|
return;
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
elt = tracing_map_insert(hist_data->map, key);
|
2018-01-16 10:51:56 +08:00
|
|
|
if (!elt)
|
|
|
|
return;
|
|
|
|
|
|
|
|
hist_trigger_elt_update(hist_data, elt, rec, rbe, var_ref_vals);
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:52 +08:00
|
|
|
static void hist_trigger_stacktrace_print(struct seq_file *m,
|
|
|
|
unsigned long *stacktrace_entries,
|
|
|
|
unsigned int max_entries)
|
|
|
|
{
|
|
|
|
char str[KSYM_SYMBOL_LEN];
|
|
|
|
unsigned int spaces = 8;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 0; i < max_entries; i++) {
|
|
|
|
if (stacktrace_entries[i] == ULONG_MAX)
|
|
|
|
return;
|
|
|
|
|
|
|
|
seq_printf(m, "%*c", 1 + spaces, ' ');
|
|
|
|
sprint_symbol(str, stacktrace_entries[i]);
|
|
|
|
seq_printf(m, "%s\n", str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
static void
|
|
|
|
hist_trigger_entry_print(struct seq_file *m,
|
|
|
|
struct hist_trigger_data *hist_data, void *key,
|
|
|
|
struct tracing_map_elt *elt)
|
|
|
|
{
|
|
|
|
struct hist_field *key_field;
|
2016-03-04 02:54:49 +08:00
|
|
|
char str[KSYM_SYMBOL_LEN];
|
2016-03-04 02:54:52 +08:00
|
|
|
bool multiline = false;
|
2017-09-23 03:58:22 +08:00
|
|
|
const char *field_name;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
unsigned int i;
|
|
|
|
u64 uval;
|
|
|
|
|
|
|
|
seq_puts(m, "{ ");
|
|
|
|
|
|
|
|
for_each_hist_key_field(i, hist_data) {
|
|
|
|
key_field = hist_data->fields[i];
|
|
|
|
|
|
|
|
if (i > hist_data->n_vals)
|
|
|
|
seq_puts(m, ", ");
|
|
|
|
|
2017-09-23 03:58:22 +08:00
|
|
|
field_name = hist_field_name(key_field, 0);
|
|
|
|
|
2016-03-04 02:54:48 +08:00
|
|
|
if (key_field->flags & HIST_FIELD_FL_HEX) {
|
|
|
|
uval = *(u64 *)(key + key_field->offset);
|
2017-09-23 03:58:22 +08:00
|
|
|
seq_printf(m, "%s: %llx", field_name, uval);
|
2016-03-04 02:54:49 +08:00
|
|
|
} else if (key_field->flags & HIST_FIELD_FL_SYM) {
|
|
|
|
uval = *(u64 *)(key + key_field->offset);
|
|
|
|
sprint_symbol_no_offset(str, uval);
|
2017-09-23 03:58:22 +08:00
|
|
|
seq_printf(m, "%s: [%llx] %-45s", field_name,
|
|
|
|
uval, str);
|
2016-03-04 02:54:49 +08:00
|
|
|
} else if (key_field->flags & HIST_FIELD_FL_SYM_OFFSET) {
|
|
|
|
uval = *(u64 *)(key + key_field->offset);
|
|
|
|
sprint_symbol(str, uval);
|
2017-09-23 03:58:22 +08:00
|
|
|
seq_printf(m, "%s: [%llx] %-55s", field_name,
|
|
|
|
uval, str);
|
2016-03-04 02:54:50 +08:00
|
|
|
} else if (key_field->flags & HIST_FIELD_FL_EXECNAME) {
|
2018-01-16 10:51:53 +08:00
|
|
|
struct hist_elt_data *elt_data = elt->private_data;
|
|
|
|
char *comm;
|
|
|
|
|
|
|
|
if (WARN_ON_ONCE(!elt_data))
|
|
|
|
return;
|
|
|
|
|
|
|
|
comm = elt_data->comm;
|
2016-03-04 02:54:50 +08:00
|
|
|
|
|
|
|
uval = *(u64 *)(key + key_field->offset);
|
2017-09-23 03:58:22 +08:00
|
|
|
seq_printf(m, "%s: %-16s[%10llu]", field_name,
|
|
|
|
comm, uval);
|
2016-03-04 02:54:51 +08:00
|
|
|
} else if (key_field->flags & HIST_FIELD_FL_SYSCALL) {
|
|
|
|
const char *syscall_name;
|
|
|
|
|
|
|
|
uval = *(u64 *)(key + key_field->offset);
|
|
|
|
syscall_name = get_syscall_name(uval);
|
|
|
|
if (!syscall_name)
|
|
|
|
syscall_name = "unknown_syscall";
|
|
|
|
|
2017-09-23 03:58:22 +08:00
|
|
|
seq_printf(m, "%s: %-30s[%3llu]", field_name,
|
|
|
|
syscall_name, uval);
|
2016-03-04 02:54:52 +08:00
|
|
|
} else if (key_field->flags & HIST_FIELD_FL_STACKTRACE) {
|
|
|
|
seq_puts(m, "stacktrace:\n");
|
|
|
|
hist_trigger_stacktrace_print(m,
|
|
|
|
key + key_field->offset,
|
|
|
|
HIST_STACKTRACE_DEPTH);
|
|
|
|
multiline = true;
|
2016-03-04 02:55:02 +08:00
|
|
|
} else if (key_field->flags & HIST_FIELD_FL_LOG2) {
|
2017-09-23 03:58:22 +08:00
|
|
|
seq_printf(m, "%s: ~ 2^%-2llu", field_name,
|
2016-03-04 02:55:02 +08:00
|
|
|
*(u64 *)(key + key_field->offset));
|
2016-03-04 02:54:48 +08:00
|
|
|
} else if (key_field->flags & HIST_FIELD_FL_STRING) {
|
2017-09-23 03:58:22 +08:00
|
|
|
seq_printf(m, "%s: %-50s", field_name,
|
2016-03-04 02:54:44 +08:00
|
|
|
(char *)(key + key_field->offset));
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
} else {
|
2016-03-04 02:54:44 +08:00
|
|
|
uval = *(u64 *)(key + key_field->offset);
|
2017-09-23 03:58:22 +08:00
|
|
|
seq_printf(m, "%s: %10llu", field_name, uval);
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:52 +08:00
|
|
|
if (!multiline)
|
|
|
|
seq_puts(m, " ");
|
|
|
|
|
|
|
|
seq_puts(m, "}");
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
|
|
|
seq_printf(m, " hitcount: %10llu",
|
|
|
|
tracing_map_read_sum(elt, HITCOUNT_IDX));
|
|
|
|
|
2016-03-04 02:54:43 +08:00
|
|
|
for (i = 1; i < hist_data->n_vals; i++) {
|
2017-09-23 03:58:22 +08:00
|
|
|
field_name = hist_field_name(hist_data->fields[i], 0);
|
|
|
|
|
2018-01-16 10:51:52 +08:00
|
|
|
if (hist_data->fields[i]->flags & HIST_FIELD_FL_VAR ||
|
|
|
|
hist_data->fields[i]->flags & HIST_FIELD_FL_EXPR)
|
2018-01-16 10:51:49 +08:00
|
|
|
continue;
|
|
|
|
|
2016-03-04 02:54:48 +08:00
|
|
|
if (hist_data->fields[i]->flags & HIST_FIELD_FL_HEX) {
|
2017-09-23 03:58:22 +08:00
|
|
|
seq_printf(m, " %s: %10llx", field_name,
|
2016-03-04 02:54:48 +08:00
|
|
|
tracing_map_read_sum(elt, i));
|
|
|
|
} else {
|
2017-09-23 03:58:22 +08:00
|
|
|
seq_printf(m, " %s: %10llu", field_name,
|
2016-03-04 02:54:48 +08:00
|
|
|
tracing_map_read_sum(elt, i));
|
|
|
|
}
|
2016-03-04 02:54:43 +08:00
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
seq_puts(m, "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static int print_entries(struct seq_file *m,
|
|
|
|
struct hist_trigger_data *hist_data)
|
|
|
|
{
|
|
|
|
struct tracing_map_sort_entry **sort_entries = NULL;
|
|
|
|
struct tracing_map *map = hist_data->map;
|
2016-03-09 06:17:15 +08:00
|
|
|
int i, n_entries;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
|
|
|
n_entries = tracing_map_sort_entries(map, hist_data->sort_keys,
|
|
|
|
hist_data->n_sort_keys,
|
|
|
|
&sort_entries);
|
|
|
|
if (n_entries < 0)
|
|
|
|
return n_entries;
|
|
|
|
|
|
|
|
for (i = 0; i < n_entries; i++)
|
|
|
|
hist_trigger_entry_print(m, hist_data,
|
|
|
|
sort_entries[i]->key,
|
|
|
|
sort_entries[i]->elt);
|
|
|
|
|
|
|
|
tracing_map_destroy_sort_entries(sort_entries, n_entries);
|
|
|
|
|
|
|
|
return n_entries;
|
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:57 +08:00
|
|
|
static void hist_trigger_show(struct seq_file *m,
|
|
|
|
struct event_trigger_data *data, int n)
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
{
|
|
|
|
struct hist_trigger_data *hist_data;
|
2017-08-23 19:23:09 +08:00
|
|
|
int n_entries;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
2016-03-04 02:54:57 +08:00
|
|
|
if (n > 0)
|
|
|
|
seq_puts(m, "\n\n");
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
|
|
|
seq_puts(m, "# event histogram\n#\n# trigger info: ");
|
|
|
|
data->ops->print(m, data->ops, data);
|
2016-03-04 02:54:57 +08:00
|
|
|
seq_puts(m, "#\n\n");
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
|
|
|
hist_data = data->private_data;
|
|
|
|
n_entries = print_entries(m, hist_data);
|
2017-08-23 19:23:09 +08:00
|
|
|
if (n_entries < 0)
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
n_entries = 0;
|
|
|
|
|
|
|
|
seq_printf(m, "\nTotals:\n Hits: %llu\n Entries: %u\n Dropped: %llu\n",
|
|
|
|
(u64)atomic64_read(&hist_data->map->hits),
|
|
|
|
n_entries, (u64)atomic64_read(&hist_data->map->drops));
|
2016-03-04 02:54:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int hist_show(struct seq_file *m, void *v)
|
|
|
|
{
|
|
|
|
struct event_trigger_data *data;
|
|
|
|
struct trace_event_file *event_file;
|
|
|
|
int n = 0, ret = 0;
|
|
|
|
|
|
|
|
mutex_lock(&event_mutex);
|
|
|
|
|
|
|
|
event_file = event_file_data(m->private);
|
|
|
|
if (unlikely(!event_file)) {
|
|
|
|
ret = -ENODEV;
|
|
|
|
goto out_unlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
list_for_each_entry_rcu(data, &event_file->triggers, list) {
|
|
|
|
if (data->cmd_ops->trigger_type == ETT_EVENT_HIST)
|
|
|
|
hist_trigger_show(m, data, n++);
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
out_unlock:
|
|
|
|
mutex_unlock(&event_mutex);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int event_hist_open(struct inode *inode, struct file *file)
|
|
|
|
{
|
|
|
|
return single_open(file, hist_show, file);
|
|
|
|
}
|
|
|
|
|
|
|
|
const struct file_operations event_hist_fops = {
|
|
|
|
.open = event_hist_open,
|
|
|
|
.read = seq_read,
|
|
|
|
.llseek = seq_lseek,
|
|
|
|
.release = single_release,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void hist_field_print(struct seq_file *m, struct hist_field *hist_field)
|
|
|
|
{
|
2017-09-23 03:58:22 +08:00
|
|
|
const char *field_name = hist_field_name(hist_field, 0);
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
if (hist_field->var.name)
|
|
|
|
seq_printf(m, "%s=", hist_field->var.name);
|
|
|
|
|
2018-01-16 10:51:45 +08:00
|
|
|
if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP)
|
|
|
|
seq_puts(m, "common_timestamp");
|
2018-01-16 10:51:56 +08:00
|
|
|
else if (field_name) {
|
|
|
|
if (hist_field->flags & HIST_FIELD_FL_VAR_REF)
|
|
|
|
seq_putc(m, '$');
|
2018-01-16 10:51:45 +08:00
|
|
|
seq_printf(m, "%s", field_name);
|
2018-01-16 10:51:56 +08:00
|
|
|
}
|
2018-01-16 10:51:45 +08:00
|
|
|
|
2016-03-04 02:54:48 +08:00
|
|
|
if (hist_field->flags) {
|
|
|
|
const char *flags_str = get_hist_field_flags(hist_field);
|
|
|
|
|
|
|
|
if (flags_str)
|
|
|
|
seq_printf(m, ".%s", flags_str);
|
|
|
|
}
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int event_hist_trigger_print(struct seq_file *m,
|
|
|
|
struct event_trigger_ops *ops,
|
|
|
|
struct event_trigger_data *data)
|
|
|
|
{
|
|
|
|
struct hist_trigger_data *hist_data = data->private_data;
|
2018-01-16 10:51:49 +08:00
|
|
|
struct hist_field *field;
|
|
|
|
bool have_var = false;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
unsigned int i;
|
|
|
|
|
2016-03-04 02:54:59 +08:00
|
|
|
seq_puts(m, "hist:");
|
|
|
|
|
|
|
|
if (data->name)
|
|
|
|
seq_printf(m, "%s:", data->name);
|
|
|
|
|
|
|
|
seq_puts(m, "keys=");
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
|
|
|
for_each_hist_key_field(i, hist_data) {
|
2018-01-16 10:51:49 +08:00
|
|
|
field = hist_data->fields[i];
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
|
|
|
if (i > hist_data->n_vals)
|
|
|
|
seq_puts(m, ",");
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
if (field->flags & HIST_FIELD_FL_STACKTRACE)
|
2016-03-04 02:54:52 +08:00
|
|
|
seq_puts(m, "stacktrace");
|
|
|
|
else
|
2018-01-16 10:51:49 +08:00
|
|
|
hist_field_print(m, field);
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
seq_puts(m, ":vals=");
|
2016-03-04 02:54:43 +08:00
|
|
|
|
|
|
|
for_each_hist_val_field(i, hist_data) {
|
2018-01-16 10:51:49 +08:00
|
|
|
field = hist_data->fields[i];
|
|
|
|
if (field->flags & HIST_FIELD_FL_VAR) {
|
|
|
|
have_var = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:43 +08:00
|
|
|
if (i == HITCOUNT_IDX)
|
|
|
|
seq_puts(m, "hitcount");
|
|
|
|
else {
|
|
|
|
seq_puts(m, ",");
|
2018-01-16 10:51:49 +08:00
|
|
|
hist_field_print(m, field);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (have_var) {
|
|
|
|
unsigned int n = 0;
|
|
|
|
|
|
|
|
seq_puts(m, ":");
|
|
|
|
|
|
|
|
for_each_hist_val_field(i, hist_data) {
|
|
|
|
field = hist_data->fields[i];
|
|
|
|
|
|
|
|
if (field->flags & HIST_FIELD_FL_VAR) {
|
|
|
|
if (n++)
|
|
|
|
seq_puts(m, ",");
|
|
|
|
hist_field_print(m, field);
|
|
|
|
}
|
2016-03-04 02:54:43 +08:00
|
|
|
}
|
|
|
|
}
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
|
|
|
seq_puts(m, ":sort=");
|
2016-03-04 02:54:45 +08:00
|
|
|
|
|
|
|
for (i = 0; i < hist_data->n_sort_keys; i++) {
|
|
|
|
struct tracing_map_sort_key *sort_key;
|
2018-01-16 10:51:49 +08:00
|
|
|
unsigned int idx, first_key_idx;
|
|
|
|
|
|
|
|
/* skip VAR vals */
|
|
|
|
first_key_idx = hist_data->n_vals - hist_data->n_vars;
|
2016-03-04 02:54:45 +08:00
|
|
|
|
|
|
|
sort_key = &hist_data->sort_keys[i];
|
2018-01-16 10:51:45 +08:00
|
|
|
idx = sort_key->field_idx;
|
|
|
|
|
2018-01-16 10:51:50 +08:00
|
|
|
if (WARN_ON(idx >= HIST_FIELDS_MAX))
|
2018-01-16 10:51:45 +08:00
|
|
|
return -EINVAL;
|
2016-03-04 02:54:45 +08:00
|
|
|
|
|
|
|
if (i > 0)
|
|
|
|
seq_puts(m, ",");
|
|
|
|
|
2018-01-16 10:51:45 +08:00
|
|
|
if (idx == HITCOUNT_IDX)
|
2016-03-04 02:54:45 +08:00
|
|
|
seq_puts(m, "hitcount");
|
2018-01-16 10:51:49 +08:00
|
|
|
else {
|
|
|
|
if (idx >= first_key_idx)
|
|
|
|
idx += hist_data->n_vars;
|
2016-03-04 02:54:45 +08:00
|
|
|
hist_field_print(m, hist_data->fields[idx]);
|
2018-01-16 10:51:49 +08:00
|
|
|
}
|
2016-03-04 02:54:45 +08:00
|
|
|
|
|
|
|
if (sort_key->descending)
|
|
|
|
seq_puts(m, ".descending");
|
|
|
|
}
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
seq_printf(m, ":size=%u", (1 << hist_data->map->map_bits));
|
|
|
|
|
|
|
|
if (data->filter_str)
|
|
|
|
seq_printf(m, " if %s", data->filter_str);
|
|
|
|
|
2016-03-04 02:54:46 +08:00
|
|
|
if (data->paused)
|
|
|
|
seq_puts(m, " [paused]");
|
|
|
|
else
|
|
|
|
seq_puts(m, " [active]");
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
|
|
|
|
seq_putc(m, '\n');
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:59 +08:00
|
|
|
static int event_hist_trigger_init(struct event_trigger_ops *ops,
|
|
|
|
struct event_trigger_data *data)
|
|
|
|
{
|
|
|
|
struct hist_trigger_data *hist_data = data->private_data;
|
|
|
|
|
|
|
|
if (!data->ref && hist_data->attrs->name)
|
|
|
|
save_named_trigger(hist_data->attrs->name, data);
|
|
|
|
|
|
|
|
data->ref++;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
static void event_hist_trigger_free(struct event_trigger_ops *ops,
|
|
|
|
struct event_trigger_data *data)
|
|
|
|
{
|
|
|
|
struct hist_trigger_data *hist_data = data->private_data;
|
|
|
|
|
|
|
|
if (WARN_ON_ONCE(data->ref <= 0))
|
|
|
|
return;
|
|
|
|
|
|
|
|
data->ref--;
|
|
|
|
if (!data->ref) {
|
2016-03-04 02:54:59 +08:00
|
|
|
if (data->name)
|
|
|
|
del_named_trigger(data);
|
2018-01-16 10:51:56 +08:00
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
trigger_data_free(data);
|
2018-01-16 10:51:56 +08:00
|
|
|
|
|
|
|
remove_hist_vars(hist_data);
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
destroy_hist_data(hist_data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct event_trigger_ops event_hist_trigger_ops = {
|
|
|
|
.func = event_hist_trigger,
|
|
|
|
.print = event_hist_trigger_print,
|
2016-03-04 02:54:59 +08:00
|
|
|
.init = event_hist_trigger_init,
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
.free = event_hist_trigger_free,
|
|
|
|
};
|
|
|
|
|
2016-03-04 02:54:59 +08:00
|
|
|
static int event_hist_trigger_named_init(struct event_trigger_ops *ops,
|
|
|
|
struct event_trigger_data *data)
|
|
|
|
{
|
|
|
|
data->ref++;
|
|
|
|
|
|
|
|
save_named_trigger(data->named_data->name, data);
|
|
|
|
|
|
|
|
event_hist_trigger_init(ops, data->named_data);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void event_hist_trigger_named_free(struct event_trigger_ops *ops,
|
|
|
|
struct event_trigger_data *data)
|
|
|
|
{
|
|
|
|
if (WARN_ON_ONCE(data->ref <= 0))
|
|
|
|
return;
|
|
|
|
|
|
|
|
event_hist_trigger_free(ops, data->named_data);
|
|
|
|
|
|
|
|
data->ref--;
|
|
|
|
if (!data->ref) {
|
|
|
|
del_named_trigger(data);
|
|
|
|
trigger_data_free(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct event_trigger_ops event_hist_trigger_named_ops = {
|
|
|
|
.func = event_hist_trigger,
|
|
|
|
.print = event_hist_trigger_print,
|
|
|
|
.init = event_hist_trigger_named_init,
|
|
|
|
.free = event_hist_trigger_named_free,
|
|
|
|
};
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
static struct event_trigger_ops *event_hist_get_trigger_ops(char *cmd,
|
|
|
|
char *param)
|
|
|
|
{
|
|
|
|
return &event_hist_trigger_ops;
|
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:47 +08:00
|
|
|
static void hist_clear(struct event_trigger_data *data)
|
|
|
|
{
|
|
|
|
struct hist_trigger_data *hist_data = data->private_data;
|
|
|
|
|
2016-03-04 02:54:59 +08:00
|
|
|
if (data->name)
|
|
|
|
pause_named_trigger(data);
|
2016-03-04 02:54:47 +08:00
|
|
|
|
|
|
|
synchronize_sched();
|
|
|
|
|
|
|
|
tracing_map_clear(hist_data->map);
|
|
|
|
|
2016-03-04 02:54:59 +08:00
|
|
|
if (data->name)
|
|
|
|
unpause_named_trigger(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool compatible_field(struct ftrace_event_field *field,
|
|
|
|
struct ftrace_event_field *test_field)
|
|
|
|
{
|
|
|
|
if (field == test_field)
|
|
|
|
return true;
|
|
|
|
if (field == NULL || test_field == NULL)
|
|
|
|
return false;
|
|
|
|
if (strcmp(field->name, test_field->name) != 0)
|
|
|
|
return false;
|
|
|
|
if (strcmp(field->type, test_field->type) != 0)
|
|
|
|
return false;
|
|
|
|
if (field->size != test_field->size)
|
|
|
|
return false;
|
|
|
|
if (field->is_signed != test_field->is_signed)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
2016-03-04 02:54:47 +08:00
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:57 +08:00
|
|
|
static bool hist_trigger_match(struct event_trigger_data *data,
|
2016-03-04 02:54:59 +08:00
|
|
|
struct event_trigger_data *data_test,
|
|
|
|
struct event_trigger_data *named_data,
|
|
|
|
bool ignore_filter)
|
2016-03-04 02:54:57 +08:00
|
|
|
{
|
|
|
|
struct tracing_map_sort_key *sort_key, *sort_key_test;
|
|
|
|
struct hist_trigger_data *hist_data, *hist_data_test;
|
|
|
|
struct hist_field *key_field, *key_field_test;
|
|
|
|
unsigned int i;
|
|
|
|
|
2016-03-04 02:54:59 +08:00
|
|
|
if (named_data && (named_data != data_test) &&
|
|
|
|
(named_data != data_test->named_data))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!named_data && is_named_trigger(data_test))
|
|
|
|
return false;
|
|
|
|
|
2016-03-04 02:54:57 +08:00
|
|
|
hist_data = data->private_data;
|
|
|
|
hist_data_test = data_test->private_data;
|
|
|
|
|
|
|
|
if (hist_data->n_vals != hist_data_test->n_vals ||
|
|
|
|
hist_data->n_fields != hist_data_test->n_fields ||
|
|
|
|
hist_data->n_sort_keys != hist_data_test->n_sort_keys)
|
|
|
|
return false;
|
|
|
|
|
2016-03-04 02:54:59 +08:00
|
|
|
if (!ignore_filter) {
|
|
|
|
if ((data->filter_str && !data_test->filter_str) ||
|
|
|
|
(!data->filter_str && data_test->filter_str))
|
|
|
|
return false;
|
|
|
|
}
|
2016-03-04 02:54:57 +08:00
|
|
|
|
|
|
|
for_each_hist_field(i, hist_data) {
|
|
|
|
key_field = hist_data->fields[i];
|
|
|
|
key_field_test = hist_data_test->fields[i];
|
|
|
|
|
|
|
|
if (key_field->flags != key_field_test->flags)
|
|
|
|
return false;
|
2016-03-04 02:54:59 +08:00
|
|
|
if (!compatible_field(key_field->field, key_field_test->field))
|
2016-03-04 02:54:57 +08:00
|
|
|
return false;
|
|
|
|
if (key_field->offset != key_field_test->offset)
|
|
|
|
return false;
|
2018-01-16 10:51:45 +08:00
|
|
|
if (key_field->size != key_field_test->size)
|
|
|
|
return false;
|
|
|
|
if (key_field->is_signed != key_field_test->is_signed)
|
|
|
|
return false;
|
2018-01-16 10:51:50 +08:00
|
|
|
if (!!key_field->var.name != !!key_field_test->var.name)
|
|
|
|
return false;
|
|
|
|
if (key_field->var.name &&
|
|
|
|
strcmp(key_field->var.name, key_field_test->var.name) != 0)
|
|
|
|
return false;
|
2016-03-04 02:54:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < hist_data->n_sort_keys; i++) {
|
|
|
|
sort_key = &hist_data->sort_keys[i];
|
|
|
|
sort_key_test = &hist_data_test->sort_keys[i];
|
|
|
|
|
|
|
|
if (sort_key->field_idx != sort_key_test->field_idx ||
|
|
|
|
sort_key->descending != sort_key_test->descending)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:59 +08:00
|
|
|
if (!ignore_filter && data->filter_str &&
|
2016-03-04 02:54:57 +08:00
|
|
|
(strcmp(data->filter_str, data_test->filter_str) != 0))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
static int hist_register_trigger(char *glob, struct event_trigger_ops *ops,
|
|
|
|
struct event_trigger_data *data,
|
|
|
|
struct trace_event_file *file)
|
|
|
|
{
|
2016-03-04 02:54:46 +08:00
|
|
|
struct hist_trigger_data *hist_data = data->private_data;
|
2016-03-04 02:54:59 +08:00
|
|
|
struct event_trigger_data *test, *named_data = NULL;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
int ret = 0;
|
|
|
|
|
2016-03-04 02:54:59 +08:00
|
|
|
if (hist_data->attrs->name) {
|
|
|
|
named_data = find_named_trigger(hist_data->attrs->name);
|
|
|
|
if (named_data) {
|
|
|
|
if (!hist_trigger_match(data, named_data, named_data,
|
|
|
|
true)) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hist_data->attrs->name && !named_data)
|
|
|
|
goto new;
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
list_for_each_entry_rcu(test, &file->triggers, list) {
|
|
|
|
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
|
2016-03-04 02:54:59 +08:00
|
|
|
if (!hist_trigger_match(data, test, named_data, false))
|
2016-03-04 02:54:57 +08:00
|
|
|
continue;
|
2016-03-04 02:54:46 +08:00
|
|
|
if (hist_data->attrs->pause)
|
|
|
|
test->paused = true;
|
|
|
|
else if (hist_data->attrs->cont)
|
|
|
|
test->paused = false;
|
2016-03-04 02:54:47 +08:00
|
|
|
else if (hist_data->attrs->clear)
|
|
|
|
hist_clear(test);
|
2016-03-04 02:54:46 +08:00
|
|
|
else
|
|
|
|
ret = -EEXIST;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
2016-03-04 02:54:59 +08:00
|
|
|
new:
|
2016-03-04 02:54:47 +08:00
|
|
|
if (hist_data->attrs->cont || hist_data->attrs->clear) {
|
2016-03-04 02:54:46 +08:00
|
|
|
ret = -ENOENT;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2016-06-30 08:56:00 +08:00
|
|
|
if (hist_data->attrs->pause)
|
|
|
|
data->paused = true;
|
|
|
|
|
2016-03-04 02:54:59 +08:00
|
|
|
if (named_data) {
|
|
|
|
destroy_hist_data(data->private_data);
|
|
|
|
data->private_data = named_data->private_data;
|
|
|
|
set_named_trigger_data(data, named_data);
|
|
|
|
data->ops = &event_hist_trigger_named_ops;
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
if (data->ops->init) {
|
|
|
|
ret = data->ops->init(data->ops, data);
|
|
|
|
if (ret < 0)
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret++;
|
|
|
|
|
2018-01-16 10:51:45 +08:00
|
|
|
if (hist_data->enable_timestamps)
|
|
|
|
tracing_set_time_stamp_abs(file->tr, true);
|
2018-01-16 10:51:56 +08:00
|
|
|
out:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int hist_trigger_enable(struct event_trigger_data *data,
|
|
|
|
struct trace_event_file *file)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
list_add_tail_rcu(&data->list, &file->triggers);
|
|
|
|
|
|
|
|
update_cond_flag(file);
|
2018-01-16 10:51:45 +08:00
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
if (trace_event_trigger_enable_disable(file, 1) < 0) {
|
|
|
|
list_del_rcu(&data->list);
|
|
|
|
update_cond_flag(file);
|
|
|
|
ret--;
|
|
|
|
}
|
2018-01-16 10:51:56 +08:00
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:56 +08:00
|
|
|
static bool hist_trigger_check_refs(struct event_trigger_data *data,
|
|
|
|
struct trace_event_file *file)
|
|
|
|
{
|
|
|
|
struct hist_trigger_data *hist_data = data->private_data;
|
|
|
|
struct event_trigger_data *test, *named_data = NULL;
|
|
|
|
|
|
|
|
if (hist_data->attrs->name)
|
|
|
|
named_data = find_named_trigger(hist_data->attrs->name);
|
|
|
|
|
|
|
|
list_for_each_entry_rcu(test, &file->triggers, list) {
|
|
|
|
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
|
|
|
|
if (!hist_trigger_match(data, test, named_data, false))
|
|
|
|
continue;
|
|
|
|
hist_data = test->private_data;
|
|
|
|
if (check_var_refs(hist_data))
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:57 +08:00
|
|
|
static void hist_unregister_trigger(char *glob, struct event_trigger_ops *ops,
|
|
|
|
struct event_trigger_data *data,
|
|
|
|
struct trace_event_file *file)
|
|
|
|
{
|
2016-03-04 02:54:59 +08:00
|
|
|
struct hist_trigger_data *hist_data = data->private_data;
|
|
|
|
struct event_trigger_data *test, *named_data = NULL;
|
2016-03-04 02:54:57 +08:00
|
|
|
bool unregistered = false;
|
|
|
|
|
2016-03-04 02:54:59 +08:00
|
|
|
if (hist_data->attrs->name)
|
|
|
|
named_data = find_named_trigger(hist_data->attrs->name);
|
|
|
|
|
2016-03-04 02:54:57 +08:00
|
|
|
list_for_each_entry_rcu(test, &file->triggers, list) {
|
|
|
|
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
|
2016-03-04 02:54:59 +08:00
|
|
|
if (!hist_trigger_match(data, test, named_data, false))
|
2016-03-04 02:54:57 +08:00
|
|
|
continue;
|
|
|
|
unregistered = true;
|
|
|
|
list_del_rcu(&test->list);
|
|
|
|
trace_event_trigger_enable_disable(file, 0);
|
|
|
|
update_cond_flag(file);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (unregistered && test->ops->free)
|
|
|
|
test->ops->free(test->ops, test);
|
2018-01-16 10:51:45 +08:00
|
|
|
|
|
|
|
if (hist_data->enable_timestamps) {
|
2018-01-16 10:51:49 +08:00
|
|
|
if (!hist_data->remove || unregistered)
|
2018-01-16 10:51:45 +08:00
|
|
|
tracing_set_time_stamp_abs(file->tr, false);
|
|
|
|
}
|
2016-03-04 02:54:57 +08:00
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:56 +08:00
|
|
|
static bool hist_file_check_refs(struct trace_event_file *file)
|
|
|
|
{
|
|
|
|
struct hist_trigger_data *hist_data;
|
|
|
|
struct event_trigger_data *test;
|
|
|
|
|
|
|
|
list_for_each_entry_rcu(test, &file->triggers, list) {
|
|
|
|
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
|
|
|
|
hist_data = test->private_data;
|
|
|
|
if (check_var_refs(hist_data))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:57 +08:00
|
|
|
static void hist_unreg_all(struct trace_event_file *file)
|
|
|
|
{
|
2016-06-30 08:55:59 +08:00
|
|
|
struct event_trigger_data *test, *n;
|
2018-01-16 10:51:45 +08:00
|
|
|
struct hist_trigger_data *hist_data;
|
2016-03-04 02:54:57 +08:00
|
|
|
|
2018-01-16 10:51:56 +08:00
|
|
|
if (hist_file_check_refs(file))
|
|
|
|
return;
|
|
|
|
|
2016-06-30 08:55:59 +08:00
|
|
|
list_for_each_entry_safe(test, n, &file->triggers, list) {
|
2016-03-04 02:54:57 +08:00
|
|
|
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
|
2018-01-16 10:51:45 +08:00
|
|
|
hist_data = test->private_data;
|
2016-03-04 02:54:57 +08:00
|
|
|
list_del_rcu(&test->list);
|
|
|
|
trace_event_trigger_enable_disable(file, 0);
|
|
|
|
update_cond_flag(file);
|
2018-01-16 10:51:45 +08:00
|
|
|
if (hist_data->enable_timestamps)
|
|
|
|
tracing_set_time_stamp_abs(file->tr, false);
|
2016-03-04 02:54:57 +08:00
|
|
|
if (test->ops->free)
|
|
|
|
test->ops->free(test->ops, test);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
static int event_hist_trigger_func(struct event_command *cmd_ops,
|
|
|
|
struct trace_event_file *file,
|
|
|
|
char *glob, char *cmd, char *param)
|
|
|
|
{
|
|
|
|
unsigned int hist_trigger_bits = TRACING_MAP_BITS_DEFAULT;
|
|
|
|
struct event_trigger_data *trigger_data;
|
|
|
|
struct hist_trigger_attrs *attrs;
|
|
|
|
struct event_trigger_ops *trigger_ops;
|
|
|
|
struct hist_trigger_data *hist_data;
|
2018-01-16 10:51:49 +08:00
|
|
|
bool remove = false;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
char *trigger;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if (!param)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
if (glob[0] == '!')
|
|
|
|
remove = true;
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
/* separate the trigger from the filter (k:v [if filter]) */
|
|
|
|
trigger = strsep(¶m, " \t");
|
|
|
|
if (!trigger)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
attrs = parse_hist_trigger_attrs(trigger);
|
|
|
|
if (IS_ERR(attrs))
|
|
|
|
return PTR_ERR(attrs);
|
|
|
|
|
|
|
|
if (attrs->map_bits)
|
|
|
|
hist_trigger_bits = attrs->map_bits;
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
hist_data = create_hist_data(hist_trigger_bits, attrs, file, remove);
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
if (IS_ERR(hist_data)) {
|
|
|
|
destroy_hist_trigger_attrs(attrs);
|
|
|
|
return PTR_ERR(hist_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
trigger_ops = cmd_ops->get_trigger_ops(cmd, trigger);
|
|
|
|
|
|
|
|
ret = -ENOMEM;
|
|
|
|
trigger_data = kzalloc(sizeof(*trigger_data), GFP_KERNEL);
|
|
|
|
if (!trigger_data)
|
|
|
|
goto out_free;
|
|
|
|
|
|
|
|
trigger_data->count = -1;
|
|
|
|
trigger_data->ops = trigger_ops;
|
|
|
|
trigger_data->cmd_ops = cmd_ops;
|
|
|
|
|
|
|
|
INIT_LIST_HEAD(&trigger_data->list);
|
|
|
|
RCU_INIT_POINTER(trigger_data->filter, NULL);
|
|
|
|
|
|
|
|
trigger_data->private_data = hist_data;
|
|
|
|
|
2016-03-04 02:54:57 +08:00
|
|
|
/* if param is non-empty, it's supposed to be a filter */
|
|
|
|
if (param && cmd_ops->set_filter) {
|
|
|
|
ret = cmd_ops->set_filter(param, trigger_data, file);
|
|
|
|
if (ret < 0)
|
|
|
|
goto out_free;
|
|
|
|
}
|
|
|
|
|
2018-01-16 10:51:49 +08:00
|
|
|
if (remove) {
|
2018-01-16 10:51:56 +08:00
|
|
|
if (hist_trigger_check_refs(trigger_data, file)) {
|
|
|
|
ret = -EBUSY;
|
|
|
|
goto out_free;
|
|
|
|
}
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file);
|
|
|
|
ret = 0;
|
|
|
|
goto out_free;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = cmd_ops->reg(glob, trigger_ops, trigger_data, file);
|
|
|
|
/*
|
|
|
|
* The above returns on success the # of triggers registered,
|
|
|
|
* but if it didn't register any it returns zero. Consider no
|
|
|
|
* triggers registered a failure too.
|
|
|
|
*/
|
|
|
|
if (!ret) {
|
2016-03-04 02:54:47 +08:00
|
|
|
if (!(attrs->pause || attrs->cont || attrs->clear))
|
2016-03-04 02:54:46 +08:00
|
|
|
ret = -ENOENT;
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
goto out_free;
|
|
|
|
} else if (ret < 0)
|
|
|
|
goto out_free;
|
2018-01-16 10:51:56 +08:00
|
|
|
|
|
|
|
if (get_named_trigger_data(trigger_data))
|
|
|
|
goto enable;
|
|
|
|
|
|
|
|
if (has_hist_vars(hist_data))
|
|
|
|
save_hist_vars(hist_data);
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
/* Just return zero, not the number of registered triggers */
|
|
|
|
ret = 0;
|
|
|
|
out:
|
|
|
|
return ret;
|
2018-01-16 10:51:56 +08:00
|
|
|
out_unreg:
|
|
|
|
cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file);
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
out_free:
|
|
|
|
if (cmd_ops->set_filter)
|
|
|
|
cmd_ops->set_filter(NULL, trigger_data, NULL);
|
|
|
|
|
2018-01-16 10:51:56 +08:00
|
|
|
remove_hist_vars(hist_data);
|
|
|
|
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
kfree(trigger_data);
|
|
|
|
|
|
|
|
destroy_hist_data(hist_data);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct event_command trigger_hist_cmd = {
|
|
|
|
.name = "hist",
|
|
|
|
.trigger_type = ETT_EVENT_HIST,
|
|
|
|
.flags = EVENT_CMD_FL_NEEDS_REC,
|
|
|
|
.func = event_hist_trigger_func,
|
|
|
|
.reg = hist_register_trigger,
|
2016-03-04 02:54:57 +08:00
|
|
|
.unreg = hist_unregister_trigger,
|
|
|
|
.unreg_all = hist_unreg_all,
|
tracing: Add 'hist' event trigger command
'hist' triggers allow users to continually aggregate trace events,
which can then be viewed afterwards by simply reading a 'hist' file
containing the aggregation in a human-readable format.
The basic idea is very simple and boils down to a mechanism whereby
trace events, rather than being exhaustively dumped in raw form and
viewed directly, are automatically 'compressed' into meaningful tables
completely defined by the user.
This is done strictly via single-line command-line commands and
without the aid of any kind of programming language or interpreter.
A surprising number of typical use cases can be accomplished by users
via this simple mechanism. In fact, a large number of the tasks that
users typically do using the more complicated script-based tracing
tools, at least during the initial stages of an investigation, can be
accomplished by simply specifying a set of keys and values to be used
in the creation of a hash table.
The Linux kernel trace event subsystem happens to provide an extensive
list of keys and values ready-made for such a purpose in the form of
the event format files associated with each trace event. By simply
consulting the format file for field names of interest and by plugging
them into the hist trigger command, users can create an endless number
of useful aggregations to help with investigating various properties
of the system. See Documentation/trace/events.txt for examples.
hist triggers are implemented on top of the existing event trigger
infrastructure, and as such are consistent with the existing triggers
from a user's perspective as well.
The basic syntax follows the existing trigger syntax. Users start an
aggregation by writing a 'hist' trigger to the event of interest's
trigger file:
# echo hist:keys=xxx [ if filter] > event/trigger
Once a hist trigger has been set up, by default it continually
aggregates every matching event into a hash table using the event key
and a value field named 'hitcount'.
To view the aggregation at any point in time, simply read the 'hist'
file in the same directory as the 'trigger' file:
# cat event/hist
The detailed syntax provides additional options for user control, and
is described exhaustively in Documentation/trace/events.txt and in the
virtual tracing/README file in the tracing subsystem.
Link: http://lkml.kernel.org/r/72d263b5e1853fe9c314953b65833c3aa75479f2.1457029949.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2016-03-04 02:54:42 +08:00
|
|
|
.get_trigger_ops = event_hist_get_trigger_ops,
|
|
|
|
.set_filter = set_trigger_filter,
|
|
|
|
};
|
|
|
|
|
|
|
|
__init int register_trigger_hist_cmd(void)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = register_event_command(&trigger_hist_cmd);
|
|
|
|
WARN_ON(ret < 0);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2016-03-04 02:54:55 +08:00
|
|
|
|
|
|
|
static void
|
2018-01-16 10:51:42 +08:00
|
|
|
hist_enable_trigger(struct event_trigger_data *data, void *rec,
|
|
|
|
struct ring_buffer_event *event)
|
2016-03-04 02:54:55 +08:00
|
|
|
{
|
|
|
|
struct enable_trigger_data *enable_data = data->private_data;
|
|
|
|
struct event_trigger_data *test;
|
|
|
|
|
|
|
|
list_for_each_entry_rcu(test, &enable_data->file->triggers, list) {
|
|
|
|
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
|
|
|
|
if (enable_data->enable)
|
|
|
|
test->paused = false;
|
|
|
|
else
|
|
|
|
test->paused = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2018-01-16 10:51:42 +08:00
|
|
|
hist_enable_count_trigger(struct event_trigger_data *data, void *rec,
|
|
|
|
struct ring_buffer_event *event)
|
2016-03-04 02:54:55 +08:00
|
|
|
{
|
|
|
|
if (!data->count)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (data->count != -1)
|
|
|
|
(data->count)--;
|
|
|
|
|
2018-01-16 10:51:42 +08:00
|
|
|
hist_enable_trigger(data, rec, event);
|
2016-03-04 02:54:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct event_trigger_ops hist_enable_trigger_ops = {
|
|
|
|
.func = hist_enable_trigger,
|
|
|
|
.print = event_enable_trigger_print,
|
|
|
|
.init = event_trigger_init,
|
|
|
|
.free = event_enable_trigger_free,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct event_trigger_ops hist_enable_count_trigger_ops = {
|
|
|
|
.func = hist_enable_count_trigger,
|
|
|
|
.print = event_enable_trigger_print,
|
|
|
|
.init = event_trigger_init,
|
|
|
|
.free = event_enable_trigger_free,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct event_trigger_ops hist_disable_trigger_ops = {
|
|
|
|
.func = hist_enable_trigger,
|
|
|
|
.print = event_enable_trigger_print,
|
|
|
|
.init = event_trigger_init,
|
|
|
|
.free = event_enable_trigger_free,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct event_trigger_ops hist_disable_count_trigger_ops = {
|
|
|
|
.func = hist_enable_count_trigger,
|
|
|
|
.print = event_enable_trigger_print,
|
|
|
|
.init = event_trigger_init,
|
|
|
|
.free = event_enable_trigger_free,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct event_trigger_ops *
|
|
|
|
hist_enable_get_trigger_ops(char *cmd, char *param)
|
|
|
|
{
|
|
|
|
struct event_trigger_ops *ops;
|
|
|
|
bool enable;
|
|
|
|
|
|
|
|
enable = (strcmp(cmd, ENABLE_HIST_STR) == 0);
|
|
|
|
|
|
|
|
if (enable)
|
|
|
|
ops = param ? &hist_enable_count_trigger_ops :
|
|
|
|
&hist_enable_trigger_ops;
|
|
|
|
else
|
|
|
|
ops = param ? &hist_disable_count_trigger_ops :
|
|
|
|
&hist_disable_trigger_ops;
|
|
|
|
|
|
|
|
return ops;
|
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:57 +08:00
|
|
|
static void hist_enable_unreg_all(struct trace_event_file *file)
|
|
|
|
{
|
2016-06-30 08:55:59 +08:00
|
|
|
struct event_trigger_data *test, *n;
|
2016-03-04 02:54:57 +08:00
|
|
|
|
2016-06-30 08:55:59 +08:00
|
|
|
list_for_each_entry_safe(test, n, &file->triggers, list) {
|
2016-03-04 02:54:57 +08:00
|
|
|
if (test->cmd_ops->trigger_type == ETT_HIST_ENABLE) {
|
|
|
|
list_del_rcu(&test->list);
|
|
|
|
update_cond_flag(file);
|
|
|
|
trace_event_trigger_enable_disable(file, 0);
|
|
|
|
if (test->ops->free)
|
|
|
|
test->ops->free(test->ops, test);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-04 02:54:55 +08:00
|
|
|
static struct event_command trigger_hist_enable_cmd = {
|
|
|
|
.name = ENABLE_HIST_STR,
|
|
|
|
.trigger_type = ETT_HIST_ENABLE,
|
|
|
|
.func = event_enable_trigger_func,
|
|
|
|
.reg = event_enable_register_trigger,
|
|
|
|
.unreg = event_enable_unregister_trigger,
|
2016-03-04 02:54:57 +08:00
|
|
|
.unreg_all = hist_enable_unreg_all,
|
2016-03-04 02:54:55 +08:00
|
|
|
.get_trigger_ops = hist_enable_get_trigger_ops,
|
|
|
|
.set_filter = set_trigger_filter,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct event_command trigger_hist_disable_cmd = {
|
|
|
|
.name = DISABLE_HIST_STR,
|
|
|
|
.trigger_type = ETT_HIST_ENABLE,
|
|
|
|
.func = event_enable_trigger_func,
|
|
|
|
.reg = event_enable_register_trigger,
|
|
|
|
.unreg = event_enable_unregister_trigger,
|
2016-03-04 02:54:57 +08:00
|
|
|
.unreg_all = hist_enable_unreg_all,
|
2016-03-04 02:54:55 +08:00
|
|
|
.get_trigger_ops = hist_enable_get_trigger_ops,
|
|
|
|
.set_filter = set_trigger_filter,
|
|
|
|
};
|
|
|
|
|
|
|
|
static __init void unregister_trigger_hist_enable_disable_cmds(void)
|
|
|
|
{
|
|
|
|
unregister_event_command(&trigger_hist_enable_cmd);
|
|
|
|
unregister_event_command(&trigger_hist_disable_cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
__init int register_trigger_hist_enable_disable_cmds(void)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = register_event_command(&trigger_hist_enable_cmd);
|
|
|
|
if (WARN_ON(ret < 0))
|
|
|
|
return ret;
|
|
|
|
ret = register_event_command(&trigger_hist_disable_cmd);
|
|
|
|
if (WARN_ON(ret < 0))
|
|
|
|
unregister_trigger_hist_enable_disable_cmds();
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|