linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: Tom Zanussi <tom.zanussi@linux.intel.com>
Cc: masami.hiramatsu.pt@hitachi.com, namhyung@kernel.org,
	josh@joshtriplett.org, andi@firstfloor.org,
	mathieu.desnoyers@efficios.com, peterz@infradead.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v13 09/29] tracing: Add 'hist' event trigger command
Date: Fri, 19 Feb 2016 16:23:18 -0500	[thread overview]
Message-ID: <20160219162318.10de33fe@gandalf.local.home> (raw)
In-Reply-To: <15dc2e4792676582404b398c020926c412c63dcb.1449767187.git.tom.zanussi@linux.intel.com>

On Thu, 10 Dec 2015 12:50:51 -0600
Tom Zanussi <tom.zanussi@linux.intel.com> wrote:

> diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
> new file mode 100644
> index 0000000..213aa79
> --- /dev/null
> +++ b/kernel/trace/trace_events_hist.c
> @@ -0,0 +1,837 @@
> +/*
> + * 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>
> +
> +#include "tracing_map.h"
> +#include "trace.h"
> +
> +struct hist_field;
> +
> +typedef u64 (*hist_field_fn_t) (struct hist_field *field, void *event);
> +
> +struct hist_field {
> +	struct ftrace_event_field	*field;
> +	unsigned long			flags;
> +	hist_field_fn_t			fn;
> +	unsigned int			size;
> +};
> +
> +static u64 hist_field_counter(struct hist_field *field, void *event)
> +{
> +	return 1;
> +}
> +
> +static u64 hist_field_string(struct hist_field *hist_field, void *event)
> +{
> +	char *addr = (char *)(event + hist_field->field->offset);
> +
> +	return (u64)(unsigned long)addr;
> +}
> +
> +#define DEFINE_HIST_FIELD_FN(type)					\
> +static u64 hist_field_##type(struct hist_field *hist_field, void *event)\
> +{									\
> +	type *addr = (type *)(event + hist_field->field->offset);	\
> +									\
> +	return (u64)*addr;						\
> +}
> +
> +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++)

The above should have parenthesis around the macro variables.

e.g.

 (hist_data)->n_fields

> +
> +#define HITCOUNT_IDX		0
> +#define HIST_KEY_MAX		1
> +#define HIST_KEY_SIZE_MAX	MAX_FILTER_STR_VAL
> +
> +enum hist_field_flags {
> +	HIST_FIELD_HITCOUNT	= 1,
> +	HIST_FIELD_KEY		= 2,
> +	HIST_FIELD_STRING	= 4,

Note, please add "_FL" to the enums to denote they are flags (used for
bitmask).

e.g. HIST_FIELD_FL_HITCOUNT


> +};
> +
> +struct hist_trigger_attrs {
> +	char		*keys_str;
> +	unsigned int	map_bits;
> +};
> +
> +struct hist_trigger_data {
> +	struct hist_field               *fields[TRACING_MAP_FIELDS_MAX];

Hmm I'm confused, TRACING_MAP_FIELDS_MAX == 4

But below it we index into fields with n_fields. Which look to me can
be much bigger than 4.

Or is there some correlation between n_vals, n_keys and 4?

> +	unsigned int			n_vals;
> +	unsigned int			n_keys;
> +	unsigned int			n_fields;
> +	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;
> +};
> +
> +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)
> +{
> +	if (!attrs)
> +		return;
> +
> +	kfree(attrs->keys_str);
> +	kfree(attrs);
> +}
> +
> +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, ":");
> +
> +		if (!strncmp(str, "keys", strlen("keys")) ||
> +		    !strncmp(str, "key", strlen("key")))

nit, I prefer "strncmp(x,y,n) == 0" as it shows an equals, and, at
least to me, easier to quickly understand.

But not so nit,  if !strncmp(str, "keys", strlen("keys")) then
 !strcmp(str, "key", strlen("key")) is true!

It has the same result as:

 if (!strncmp(str, "key", strlen("key")))

That is equivalent to if (x > 12 || x > 10) where
if (x > 10) will do.

Is that suppose to be a full match or partial match?

> +			attrs->keys_str = kstrdup(str, GFP_KERNEL);
> +		else if (!strncmp(str, "size", strlen("size"))) {

Is it OK to allow "sizeUgaBooga=10"?

Perhaps the compare should be against "size=" ?

Same for the keys above.

> +			int map_bits = parse_map_size(str);
> +
> +			if (map_bits < 0) {
> +				ret = map_bits;
> +				goto free;
> +			}
> +			attrs->map_bits = map_bits;
> +		} else {
> +			ret = -EINVAL;
> +			goto free;
> +		}
> +	}
> +
> +	if (!attrs->keys_str) {
> +		ret = -EINVAL;
> +		goto free;
> +	}
> +
> +	return attrs;
> + free:
> +	destroy_hist_trigger_attrs(attrs);
> +
> +	return ERR_PTR(ret);
> +}
> +

I stopped here. I'll review the rest later.

-- Steve

  reply	other threads:[~2016-02-19 21:23 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-10 18:50 [PATCH 00/29] tracing: 'hist' triggers Tom Zanussi
2015-12-10 18:50 ` [PATCH v13 01/29] tracing: Make ftrace_event_field checking functions available Tom Zanussi
2015-12-10 18:50 ` [PATCH v13 02/29] tracing: Make event trigger " Tom Zanussi
2015-12-10 18:50 ` [PATCH v13 03/29] tracing: Add event record param to trigger_ops.func() Tom Zanussi
2015-12-10 18:50 ` [PATCH v13 04/29] tracing: Add get_syscall_name() Tom Zanussi
2015-12-10 18:50 ` [PATCH v13 05/29] tracing: Add a per-event-trigger 'paused' field Tom Zanussi
2015-12-10 18:50 ` [PATCH v13 06/29] tracing: Add needs_rec flag to event triggers Tom Zanussi
2016-02-19 19:30   ` Steven Rostedt
2016-02-19 22:35     ` Steven Rostedt
2016-02-19 23:31       ` Tom Zanussi
2016-02-20  1:27         ` Steven Rostedt
2015-12-10 18:50 ` [PATCH v13 07/29] tracing: Add an unreg_all() callback to trigger commands Tom Zanussi
2015-12-10 18:50 ` [PATCH v13 08/29] tracing: Add lock-free tracing_map Tom Zanussi
2016-02-19 19:38   ` Steven Rostedt
2015-12-10 18:50 ` [PATCH v13 09/29] tracing: Add 'hist' event trigger command Tom Zanussi
2016-02-19 21:23   ` Steven Rostedt [this message]
2016-02-19 23:27     ` Tom Zanussi
2016-02-20  1:55       ` Steven Rostedt
2015-12-10 18:50 ` [PATCH v13 10/29] tracing: Add hist trigger support for multiple values ('vals=' param) Tom Zanussi
2015-12-10 18:50 ` [PATCH v13 11/29] tracing: Add hist trigger support for compound keys Tom Zanussi
2015-12-10 18:50 ` [PATCH v13 12/29] tracing: Add hist trigger support for user-defined sorting ('sort=' param) Tom Zanussi
2015-12-10 18:50 ` [PATCH v13 13/29] tracing: Add hist trigger support for pausing and continuing a trace Tom Zanussi
2015-12-10 18:50 ` [PATCH v13 14/29] tracing: Add hist trigger support for clearing " Tom Zanussi
2015-12-10 18:50 ` [PATCH v13 15/29] tracing: Add hist trigger 'hex' modifier for displaying numeric fields Tom Zanussi
2015-12-10 18:50 ` [PATCH v13 16/29] tracing: Add hist trigger 'sym' and 'sym-offset' modifiers Tom Zanussi
2015-12-10 18:50 ` [PATCH v13 17/29] tracing: Add hist trigger 'execname' modifier Tom Zanussi
2015-12-10 18:51 ` [PATCH v13 18/29] tracing: Add hist trigger 'syscall' modifier Tom Zanussi
2015-12-10 18:51 ` [PATCH v13 19/29] tracing: Add hist trigger support for stacktraces as keys Tom Zanussi
2015-12-10 18:51 ` [PATCH v13 20/29] tracing: Support string type key properly Tom Zanussi
2015-12-10 18:51 ` [PATCH v13 21/29] tracing: Remove restriction on string position in hist trigger keys Tom Zanussi
2015-12-10 18:51 ` [PATCH v13 22/29] tracing: Add enable_hist/disable_hist triggers Tom Zanussi
2015-12-10 18:51 ` [PATCH v13 23/29] tracing: Add 'hist' trigger Documentation Tom Zanussi
2015-12-10 18:51 ` [PATCH v13 24/29] tracing: Add support for multiple hist triggers per event Tom Zanussi
2015-12-10 18:51 ` [PATCH v13 25/29] tracing: Add support for named triggers Tom Zanussi
2015-12-10 18:51 ` [PATCH v13 26/29] tracing: Add support for named hist triggers Tom Zanussi
2015-12-10 18:51 ` [PATCH v13 27/29] kselftests/ftrace : Add event trigger testcases Tom Zanussi
2015-12-10 18:51 ` [PATCH v13 28/29] kselftests/ftrace: Add hist " Tom Zanussi
2015-12-10 18:51 ` [PATCH v13 29/29] tracing: Add hist trigger 'log2' modifier Tom Zanussi
2016-02-12 16:17 ` [PATCH 00/29] tracing: 'hist' triggers Tom Zanussi
2016-02-12 16:59   ` Steven Rostedt
2016-02-16 22:43     ` Tom Zanussi
2016-02-16 23:42       ` Steven Rostedt
2016-02-17  2:57       ` 平松雅巳 / HIRAMATU,MASAMI
2016-02-19 15:24         ` 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=20160219162318.10de33fe@gandalf.local.home \
    --to=rostedt@goodmis.org \
    --cc=andi@firstfloor.org \
    --cc=josh@joshtriplett.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=masami.hiramatsu.pt@hitachi.com \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).