Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e86ae9ba authored by Tom Zanussi's avatar Tom Zanussi Committed by Steven Rostedt
Browse files

tracing: Add hist trigger support for clearing a trace

Allow users to append 'clear' to an existing trigger in order to have
the hash table cleared.

This expands the hist trigger syntax from this:
    # echo hist:keys=xxx:vals=yyy:sort=zzz.descending:pause/cont \
           [ if filter] >> event/trigger

to this:

    # echo hist:keys=xxx:vals=yyy:sort=zzz.descending:pause/cont/clear \
          [ if filter] >> event/trigger

Link: http://lkml.kernel.org/r/ae15dd0d9b2f7af07a37c1ff682063e2dbcdf160.1457029949.git.tom.zanussi@linux.intel.com



Signed-off-by: default avatarTom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: default avatarNamhyung Kim <namhyung@kernel.org>
Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parent 83e99914
Loading
Loading
Loading
Loading
+4 −1
Original line number Original line Diff line number Diff line
@@ -3837,7 +3837,7 @@ static const char readme_msg[] =
	"\t            [:values=<field1[,field2,...]>]\n"
	"\t            [:values=<field1[,field2,...]>]\n"
	"\t            [:sort=<field1[,field2,...]>]\n"
	"\t            [:sort=<field1[,field2,...]>]\n"
	"\t            [:size=#entries]\n"
	"\t            [:size=#entries]\n"
	"\t            [:pause][:continue]\n"
	"\t            [:pause][:continue][:clear]\n"
	"\t            [if <filter>]\n\n"
	"\t            [if <filter>]\n\n"
	"\t    When a matching event is hit, an entry is added to a hash\n"
	"\t    When a matching event is hit, an entry is added to a hash\n"
	"\t    table using the key(s) and value(s) named, and the value of a\n"
	"\t    table using the key(s) and value(s) named, and the value of a\n"
@@ -3857,6 +3857,9 @@ static const char readme_msg[] =
	"\t    trigger or to start a hist trigger but not log any events\n"
	"\t    trigger or to start a hist trigger but not log any events\n"
	"\t    until told to do so.  'continue' can be used to start or\n"
	"\t    until told to do so.  'continue' can be used to start or\n"
	"\t    restart a paused hist trigger.\n\n"
	"\t    restart a paused hist trigger.\n\n"
	"\t    The 'clear' parameter will clear the contents of a running\n"
	"\t    hist trigger and leave its current paused/active state\n"
	"\t    unchanged.\n\n"
#endif
#endif
;
;


+22 −2
Original line number Original line Diff line number Diff line
@@ -88,6 +88,7 @@ struct hist_trigger_attrs {
	char		*sort_key_str;
	char		*sort_key_str;
	bool		pause;
	bool		pause;
	bool		cont;
	bool		cont;
	bool		clear;
	unsigned int	map_bits;
	unsigned int	map_bits;
};
};


@@ -200,6 +201,8 @@ static struct hist_trigger_attrs *parse_hist_trigger_attrs(char *trigger_str)
		else if ((strcmp(str, "cont") == 0) ||
		else if ((strcmp(str, "cont") == 0) ||
			 (strcmp(str, "continue") == 0))
			 (strcmp(str, "continue") == 0))
			attrs->cont = true;
			attrs->cont = true;
		else if (strcmp(str, "clear") == 0)
			attrs->clear = true;
		else if (strncmp(str, "size=", strlen("size=")) == 0) {
		else if (strncmp(str, "size=", strlen("size=")) == 0) {
			int map_bits = parse_map_size(str);
			int map_bits = parse_map_size(str);


@@ -916,6 +919,21 @@ static struct event_trigger_ops *event_hist_get_trigger_ops(char *cmd,
	return &event_hist_trigger_ops;
	return &event_hist_trigger_ops;
}
}


static void hist_clear(struct event_trigger_data *data)
{
	struct hist_trigger_data *hist_data = data->private_data;
	bool paused;

	paused = data->paused;
	data->paused = true;

	synchronize_sched();

	tracing_map_clear(hist_data->map);

	data->paused = paused;
}

static int hist_register_trigger(char *glob, struct event_trigger_ops *ops,
static int hist_register_trigger(char *glob, struct event_trigger_ops *ops,
				 struct event_trigger_data *data,
				 struct event_trigger_data *data,
				 struct trace_event_file *file)
				 struct trace_event_file *file)
@@ -930,13 +948,15 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops,
				test->paused = true;
				test->paused = true;
			else if (hist_data->attrs->cont)
			else if (hist_data->attrs->cont)
				test->paused = false;
				test->paused = false;
			else if (hist_data->attrs->clear)
				hist_clear(test);
			else
			else
				ret = -EEXIST;
				ret = -EEXIST;
			goto out;
			goto out;
		}
		}
	}
	}


	if (hist_data->attrs->cont) {
	if (hist_data->attrs->cont || hist_data->attrs->clear) {
		ret = -ENOENT;
		ret = -ENOENT;
		goto out;
		goto out;
	}
	}
@@ -1035,7 +1055,7 @@ static int event_hist_trigger_func(struct event_command *cmd_ops,
	 * triggers registered a failure too.
	 * triggers registered a failure too.
	 */
	 */
	if (!ret) {
	if (!ret) {
		if (!(attrs->pause || attrs->cont))
		if (!(attrs->pause || attrs->cont || attrs->clear))
			ret = -ENOENT;
			ret = -ENOENT;
		goto out_free;
		goto out_free;
	} else if (ret < 0)
	} else if (ret < 0)