Skip to content

Commit

Permalink
Merge tag 'trace-v5.14-rc2' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/rostedt/linux-trace

Pull tracing fixes from Steven Rostedt:

 - Fix deadloop in ring buffer because of using stale "read" variable

 - Fix synthetic event use of field_pos as boolean and not an index

 - Fixed histogram special var "cpu" overriding event fields called
   "cpu"

 - Cleaned up error prone logic in alloc_synth_event()

 - Removed call to synchronize_rcu_tasks_rude() when not needed

 - Removed redundant initialization of a local variable "ret"

 - Fixed kernel crash when updating tracepoint callbacks of different
   priorities.

* tag 'trace-v5.14-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
  tracepoints: Update static_call before tp_funcs when adding a tracepoint
  ftrace: Remove redundant initialization of variable ret
  ftrace: Avoid synchronize_rcu_tasks_rude() call when not necessary
  tracing: Clean up alloc_synth_event()
  tracing/histogram: Rename "cpu" to "common_cpu"
  tracing: Synthetic event field_pos is an index not a boolean
  tracing: Fix bug in rb_per_cpu_empty() that might cause deadloop.
  • Loading branch information
torvalds committed Jul 23, 2021
2 parents 1af09ed + 352384d commit 05daae0
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Documentation/trace/histogram.rst
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ Documentation written by Tom Zanussi
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.
common_cpu int the cpu on which the event occurred.
====================== ==== =======================================

Extended error information
Expand Down
5 changes: 3 additions & 2 deletions kernel/trace/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -5985,7 +5985,8 @@ ftrace_graph_release(struct inode *inode, struct file *file)
* infrastructure to do the synchronization, thus we must do it
* ourselves.
*/
synchronize_rcu_tasks_rude();
if (old_hash != EMPTY_HASH)
synchronize_rcu_tasks_rude();

free_ftrace_hash(old_hash);
}
Expand Down Expand Up @@ -7544,7 +7545,7 @@ int ftrace_is_dead(void)
*/
int register_ftrace_function(struct ftrace_ops *ops)
{
int ret = -1;
int ret;

ftrace_ops_init(ops);

Expand Down
28 changes: 24 additions & 4 deletions kernel/trace/ring_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -3880,10 +3880,30 @@ static bool rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer)
if (unlikely(!head))
return true;

return reader->read == rb_page_commit(reader) &&
(commit == reader ||
(commit == head &&
head->read == rb_page_commit(commit)));
/* Reader should exhaust content in reader page */
if (reader->read != rb_page_commit(reader))
return false;

/*
* If writers are committing on the reader page, knowing all
* committed content has been read, the ring buffer is empty.
*/
if (commit == reader)
return true;

/*
* If writers are committing on a page other than reader page
* and head page, there should always be content to read.
*/
if (commit != head)
return false;

/*
* Writers are committing on the head page, we just need
* to care about there're committed data, and the reader will
* swap reader page with head page when it is to read data.
*/
return rb_page_commit(commit) == 0;
}

/**
Expand Down
4 changes: 4 additions & 0 deletions kernel/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -5609,6 +5609,10 @@ static const char readme_msg[] =
"\t [:name=histname1]\n"
"\t [:<handler>.<action>]\n"
"\t [if <filter>]\n\n"
"\t Note, special fields can be used as well:\n"
"\t common_timestamp - to record current timestamp\n"
"\t common_cpu - to record the CPU the event happened on\n"
"\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 sum called 'hitcount' is incremented. Keys and values\n"
Expand Down
22 changes: 16 additions & 6 deletions kernel/trace/trace_events_hist.c
Original file line number Diff line number Diff line change
Expand Up @@ -1111,7 +1111,7 @@ static const char *hist_field_name(struct hist_field *field,
field->flags & HIST_FIELD_FL_ALIAS)
field_name = hist_field_name(field->operands[0], ++level);
else if (field->flags & HIST_FIELD_FL_CPU)
field_name = "cpu";
field_name = "common_cpu";
else if (field->flags & HIST_FIELD_FL_EXPR ||
field->flags & HIST_FIELD_FL_VAR_REF) {
if (field->system) {
Expand Down Expand Up @@ -1991,14 +1991,24 @@ 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 if (strcmp(field_name, "cpu") == 0)
} else if (strcmp(field_name, "common_cpu") == 0)
*flags |= HIST_FIELD_FL_CPU;
else {
field = trace_find_event_field(file->event_call, field_name);
if (!field || !field->size) {
hist_err(tr, HIST_ERR_FIELD_NOT_FOUND, errpos(field_name));
field = ERR_PTR(-EINVAL);
goto out;
/*
* For backward compatibility, if field_name
* was "cpu", then we treat this the same as
* common_cpu.
*/
if (strcmp(field_name, "cpu") == 0) {
*flags |= HIST_FIELD_FL_CPU;
} else {
hist_err(tr, HIST_ERR_FIELD_NOT_FOUND,
errpos(field_name));
field = ERR_PTR(-EINVAL);
goto out;
}
}
}
out:
Expand Down Expand Up @@ -5085,7 +5095,7 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field)
seq_printf(m, "%s=", hist_field->var.name);

if (hist_field->flags & HIST_FIELD_FL_CPU)
seq_puts(m, "cpu");
seq_puts(m, "common_cpu");
else if (field_name) {
if (hist_field->flags & HIST_FIELD_FL_VAR_REF ||
hist_field->flags & HIST_FIELD_FL_ALIAS)
Expand Down
8 changes: 3 additions & 5 deletions kernel/trace/trace_events_synth.c
Original file line number Diff line number Diff line change
Expand Up @@ -893,15 +893,13 @@ static struct synth_event *alloc_synth_event(const char *name, int n_fields,
dyn_event_init(&event->devent, &synth_event_ops);

for (i = 0, j = 0; i < n_fields; i++) {
fields[i]->field_pos = i;
event->fields[i] = fields[i];

if (fields[i]->is_dynamic) {
event->dynamic_fields[j] = fields[i];
event->dynamic_fields[j]->field_pos = i;
if (fields[i]->is_dynamic)
event->dynamic_fields[j++] = fields[i];
event->n_dynamic_fields++;
}
}
event->n_dynamic_fields = j;
event->n_fields = n_fields;
out:
return event;
Expand Down
2 changes: 1 addition & 1 deletion kernel/trace/trace_synth.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ struct synth_field {
char *name;
size_t size;
unsigned int offset;
unsigned int field_pos;
bool is_signed;
bool is_string;
bool is_dynamic;
bool field_pos;
};

struct synth_event {
Expand Down
2 changes: 1 addition & 1 deletion kernel/tracepoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,8 @@ static int tracepoint_add_func(struct tracepoint *tp,
* a pointer to it. This array is referenced by __DO_TRACE from
* include/linux/tracepoint.h using rcu_dereference_sched().
*/
rcu_assign_pointer(tp->funcs, tp_funcs);
tracepoint_update_call(tp, tp_funcs, false);
rcu_assign_pointer(tp->funcs, tp_funcs);
static_key_enable(&tp->key);

release_probes(old);
Expand Down

0 comments on commit 05daae0

Please sign in to comment.