From: Namhyung Kim <namhyung@kernel.org>
To: Tom Zanussi <tom.zanussi@linux.intel.com>
Cc: rostedt@goodmis.org, daniel.wagner@bmw-carit.de,
masami.hiramatsu.pt@hitachi.com, josh@joshtriplett.org,
andi@firstfloor.org, mathieu.desnoyers@efficios.com,
peterz@infradead.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v12 10/30] tracing: Add 'hist' event trigger command
Date: Sun, 29 Nov 2015 23:54:09 +0900 [thread overview]
Message-ID: <20151129145409.GC16382@danjae.kornet> (raw)
In-Reply-To: <f34867efd8089a51f8bb4b5f2d3ba18dc0fce63e.1448303214.git.tom.zanussi@linux.intel.com>
Hi Tom,
On Mon, Nov 23, 2015 at 01:51:25PM -0600, Tom Zanussi wrote:
> '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.
>
> Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
> Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> ---
[SNIP]
> +static struct hist_trigger_data *
> +create_hist_data(unsigned int map_bits,
> + struct hist_trigger_attrs *attrs,
> + struct trace_event_file *file)
> +{
> + 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;
> +
> + ret = create_hist_fields(hist_data, file);
> + if (ret < 0)
> + goto free;
> +
> + ret = create_sort_keys(hist_data);
> + if (ret < 0)
> + goto free;
> +
> + hist_data->map = tracing_map_create(map_bits, hist_data->key_size,
> + NULL, hist_data);
> + 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;
> +
> + ret = tracing_map_init(hist_data->map);
> + if (ret)
> + goto free;
> +
> + hist_data->event_file = file;
> + out:
> + return hist_data;
> + free:
> + hist_data->attrs = NULL;
> +
> + destroy_hist_data(hist_data);
> + if (ret)
> + hist_data = ERR_PTR(ret);
> + else
> + hist_data = NULL;
Is this else part really needed? It seems that all code path to here
set the 'ret' non-zero. Otherwise ...
> +
> + goto out;
> +}
[SNIP]
> +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;
> + char *trigger;
> + int ret = 0;
> +
> + if (!param)
> + return -EINVAL;
> +
> + /* 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;
> +
> + hist_data = create_hist_data(hist_trigger_bits, attrs, file);
> + if (IS_ERR(hist_data)) {
... it should be IS_ERR_OR_NULL(hist_data) then.
Thanks,
Namhyung
> + 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;
> +
> + if (glob[0] == '!') {
> + cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file);
> + ret = 0;
> + goto out_free;
> + }
> +
> + if (!param) /* if param is non-empty, it's supposed to be a filter */
> + goto out_reg;
> +
> + if (!cmd_ops->set_filter)
> + goto out_reg;
> +
> + ret = cmd_ops->set_filter(param, trigger_data, file);
> + if (ret < 0)
> + goto out_free;
> + out_reg:
> + 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) {
> + ret = -ENOENT;
> + goto out_free;
> + } else if (ret < 0)
> + goto out_free;
> + /* Just return zero, not the number of registered triggers */
> + ret = 0;
> + out:
> + return ret;
> + out_free:
> + if (cmd_ops->set_filter)
> + cmd_ops->set_filter(NULL, trigger_data, NULL);
> +
> + kfree(trigger_data);
> +
> + destroy_hist_data(hist_data);
> + goto out;
> +}
> +
> +static struct event_command trigger_hist_cmd = {
> + .name = "hist",
> + .trigger_type = ETT_EVENT_HIST,
> + .needs_rec = true,
> + .func = event_hist_trigger_func,
> + .reg = hist_register_trigger,
> + .unreg = unregister_trigger,
> + .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;
> +}
> diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
> index 362ae86..1f1db3c 100644
> --- a/kernel/trace/trace_events_trigger.c
> +++ b/kernel/trace/trace_events_trigger.c
> @@ -1452,6 +1452,7 @@ __init int register_trigger_cmds(void)
> register_trigger_snapshot_cmd();
> register_trigger_stacktrace_cmd();
> register_trigger_enable_disable_cmds();
> + register_trigger_hist_cmd();
>
> return 0;
> }
> --
> 1.9.3
>
next prev parent reply other threads:[~2015-11-29 14:54 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-23 19:51 [PATCH 00/30] tracing: 'hist' triggers Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 01/30] tracing: Update cond flag when enabling or disabling a trigger Tom Zanussi
2015-11-23 21:29 ` Steven Rostedt
2015-11-25 1:27 ` Namhyung Kim
2015-11-23 19:51 ` [PATCH v12 02/30] tracing: Make ftrace_event_field checking functions available Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 03/30] tracing: Make event trigger " Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 04/30] tracing: Add event record param to trigger_ops.func() Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 05/30] tracing: Add get_syscall_name() Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 06/30] tracing: Add a per-event-trigger 'paused' field Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 07/30] tracing: Add needs_rec flag to event triggers Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 08/30] tracing: Add an unreg_all() callback to trigger commands Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 09/30] tracing: Add lock-free tracing_map Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 10/30] tracing: Add 'hist' event trigger command Tom Zanussi
2015-11-29 14:54 ` Namhyung Kim [this message]
2015-11-23 19:51 ` [PATCH v12 11/30] tracing: Add hist trigger support for multiple values ('vals=' param) Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 12/30] tracing: Add hist trigger support for compound keys Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 13/30] tracing: Add hist trigger support for user-defined sorting ('sort=' param) Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 14/30] tracing: Add hist trigger support for pausing and continuing a trace Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 15/30] tracing: Add hist trigger support for clearing " Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 16/30] tracing: Add hist trigger 'hex' modifier for displaying numeric fields Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 17/30] tracing: Add hist trigger 'sym' and 'sym-offset' modifiers Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 18/30] tracing: Add hist trigger 'execname' modifier Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 19/30] tracing: Add hist trigger 'syscall' modifier Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 20/30] tracing: Add hist trigger support for stacktraces as keys Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 21/30] tracing: Support string type key properly Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 22/30] tracing: Remove restriction on string position in hist trigger keys Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 23/30] tracing: Add enable_hist/disable_hist triggers Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 24/30] tracing: Add 'hist' trigger Documentation Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 25/30] tracing: Add support for multiple hist triggers per event Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 26/30] tracing: Add support for named triggers Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 27/30] tracing: Add support for named hist triggers Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 28/30] kselftests/ftrace : Add event trigger testcases Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 29/30] kselftests/ftrace: Add hist " Tom Zanussi
2015-11-23 19:51 ` [PATCH v12 30/30] tracing: Add hist trigger 'log2' modifier Tom Zanussi
2015-11-29 15:22 ` [PATCH 00/30] tracing: 'hist' triggers Namhyung Kim
2015-12-10 18:54 ` Tom Zanussi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20151129145409.GC16382@danjae.kornet \
--to=namhyung@kernel.org \
--cc=andi@firstfloor.org \
--cc=daniel.wagner@bmw-carit.de \
--cc=josh@joshtriplett.org \
--cc=linux-kernel@vger.kernel.org \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mathieu.desnoyers@efficios.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=tom.zanussi@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.