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

Commit 8b7622bf authored by Tom Zanussi's avatar Tom Zanussi Committed by Steven Rostedt (VMware)
Browse files

tracing: Add cpu field for hist triggers

A common key to use in a histogram is the cpuid - add a new cpu
'synthetic' field named 'cpu' for that purpose.

Link: http://lkml.kernel.org/r/89537645bfc957e0d76e2cacf5f0ada88691a6cc.1516069914.git.tom.zanussi@linux.intel.com



Signed-off-by: default avatarTom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent ec5ce098
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -172,6 +172,21 @@
  The examples below provide a more concrete illustration of the
  concepts and typical usage patterns discussed above.

  'special' event fields
  ------------------------

  There are a number of 'special event fields' available for use as
  keys or values in a hist trigger.  These look like and behave as if
  they were actual event fields, but aren't really part of the event's
  field definition or format file.  They are however available for any
  event, and can be used anywhere an actual event field could be.
  They are:

    common_timestamp       u64 - timestamp (from ring buffer) associated
                                 with the event, in nanoseconds.  May be
				 modified by .usecs to have timestamps
				 interpreted as microseconds.
    cpu                    int - the cpu on which the event occurred.

6.2 'hist' trigger examples
---------------------------
+27 −1
Original line number Diff line number Diff line
@@ -227,6 +227,7 @@ enum hist_field_flags {
	HIST_FIELD_FL_VAR		= 1 << 12,
	HIST_FIELD_FL_EXPR		= 1 << 13,
	HIST_FIELD_FL_VAR_REF		= 1 << 14,
	HIST_FIELD_FL_CPU		= 1 << 15,
};

struct var_defs {
@@ -1164,6 +1165,16 @@ static u64 hist_field_timestamp(struct hist_field *hist_field,
	return ts;
}

static u64 hist_field_cpu(struct hist_field *hist_field,
			  struct tracing_map_elt *elt,
			  struct ring_buffer_event *rbe,
			  void *event)
{
	int cpu = smp_processor_id();

	return cpu;
}

static struct hist_field *
check_field_for_var_ref(struct hist_field *hist_field,
			struct hist_trigger_data *var_data,
@@ -1602,6 +1613,8 @@ static const char *hist_field_name(struct hist_field *field,
		field_name = hist_field_name(field->operands[0], ++level);
	else if (field->flags & HIST_FIELD_FL_TIMESTAMP)
		field_name = "common_timestamp";
	else if (field->flags & HIST_FIELD_FL_CPU)
		field_name = "cpu";
	else if (field->flags & HIST_FIELD_FL_EXPR ||
		 field->flags & HIST_FIELD_FL_VAR_REF) {
		if (field->system) {
@@ -2109,6 +2122,15 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data,
		goto out;
	}

	if (flags & HIST_FIELD_FL_CPU) {
		hist_field->fn = hist_field_cpu;
		hist_field->size = sizeof(int);
		hist_field->type = kstrdup("unsigned int", GFP_KERNEL);
		if (!hist_field->type)
			goto free;
		goto out;
	}

	if (WARN_ON_ONCE(!field))
		goto out;

@@ -2345,7 +2367,9 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file,
		hist_data->enable_timestamps = true;
		if (*flags & HIST_FIELD_FL_TIMESTAMP_USECS)
			hist_data->attrs->ts_in_usecs = true;
	} else {
	} else if (strcmp(field_name, "cpu") == 0)
		*flags |= HIST_FIELD_FL_CPU;
	else {
		field = trace_find_event_field(file->event_call, field_name);
		if (!field || !field->size) {
			field = ERR_PTR(-EINVAL);
@@ -4619,6 +4643,8 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field)

	if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP)
		seq_puts(m, "common_timestamp");
	else if (hist_field->flags & HIST_FIELD_FL_CPU)
		seq_puts(m, "cpu");
	else if (field_name) {
		if (hist_field->flags & HIST_FIELD_FL_VAR_REF)
			seq_putc(m, '$');