|
Matt Fleming |
668ba0 |
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
|
Matt Fleming |
668ba0 |
Date: Fri, 27 Oct 2017 17:28:38 +0200
|
|
Matt Fleming |
668ba0 |
Subject: tracing: Update the "tracing: Inter-event (e.g. latency) support" patch
|
|
Matt Fleming |
668ba0 |
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git
|
|
Matt Fleming |
668ba0 |
Git-commit: bcc67e53c6036b9bcec68d026efde8b2d72d7b6f
|
|
Matt Fleming |
668ba0 |
Patch-mainline: Queued in subsystem maintainer repository
|
|
Matt Fleming |
668ba0 |
References: SLE Realtime Extension
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
This commit is an all-in-one update of Tom Zanussi's "tracing:
|
|
Matt Fleming |
668ba0 |
Inter-event (e.g. latency) support" series from v2 to v3 as posted on
|
|
Matt Fleming |
668ba0 |
2017-09-22. It includes the thread
|
|
Matt Fleming |
668ba0 |
"[PATCH 0/9] tracing: Bug fixes and minor cleanup":
|
|
Matt Fleming |
668ba0 |
tracing: Steve's unofficial trace_recursive_lock() patch
|
|
Matt Fleming |
668ba0 |
tracing: Reverse the order of trace_types_lock and event_mutex
|
|
Matt Fleming |
668ba0 |
tracing: Exclude 'generic fields' from histograms
|
|
Matt Fleming |
668ba0 |
tracing: Remove lookups from tracing_map hitcount
|
|
Matt Fleming |
668ba0 |
tracing: Increase tracing map KEYS_MAX size
|
|
Matt Fleming |
668ba0 |
tracing: Make traceprobe parsing code reusable
|
|
Matt Fleming |
668ba0 |
tracing: Clean up hist_field_flags enum
|
|
Matt Fleming |
668ba0 |
tracing: Add hist_field_name() accessor
|
|
Matt Fleming |
668ba0 |
tracing: Reimplement log2
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
and "[PATCH v3 00/33] tracing: Inter-event (e.g. latency) support":
|
|
Matt Fleming |
668ba0 |
tracing: Add support to detect and avoid duplicates
|
|
Matt Fleming |
668ba0 |
tracing: Remove code which merges duplicates
|
|
Matt Fleming |
668ba0 |
ring-buffer: Add interface for setting absolute time stamps
|
|
Matt Fleming |
668ba0 |
ring-buffer: Redefine the unimplemented RINGBUF_TIME_TIME_STAMP
|
|
Matt Fleming |
668ba0 |
tracing: Give event triggers access to ring_buffer_event
|
|
Matt Fleming |
668ba0 |
tracing: Add ring buffer event param to hist field functions
|
|
Matt Fleming |
668ba0 |
tracing: Break out hist trigger assignment parsing
|
|
Matt Fleming |
668ba0 |
tracing: Add hist trigger timestamp support
|
|
Matt Fleming |
668ba0 |
tracing: Add per-element variable support to tracing_map
|
|
Matt Fleming |
668ba0 |
tracing: Add hist_data member to hist_field
|
|
Matt Fleming |
668ba0 |
tracing: Add usecs modifier for hist trigger timestamps
|
|
Matt Fleming |
668ba0 |
tracing: Add variable support to hist triggers
|
|
Matt Fleming |
668ba0 |
tracing: Account for variables in named trigger compatibility
|
|
Matt Fleming |
668ba0 |
tracing: Move get_hist_field_flags()
|
|
Matt Fleming |
668ba0 |
tracing: Add simple expression support to hist triggers
|
|
Matt Fleming |
668ba0 |
tracing: Generalize per-element hist trigger data
|
|
Matt Fleming |
668ba0 |
tracing: Pass tracing_map_elt to hist_field accessor functions
|
|
Matt Fleming |
668ba0 |
tracing: Add hist_field 'type' field
|
|
Matt Fleming |
668ba0 |
tracing: Add variable reference handling to hist triggers
|
|
Matt Fleming |
668ba0 |
tracing: Add hist trigger action hook
|
|
Matt Fleming |
668ba0 |
tracing: Add support for 'synthetic' events
|
|
Matt Fleming |
668ba0 |
tracing: Add support for 'field variables'
|
|
Matt Fleming |
668ba0 |
tracing: Add 'onmatch' hist trigger action support
|
|
Matt Fleming |
668ba0 |
tracing: Add 'onmax' hist trigger action support
|
|
Matt Fleming |
668ba0 |
tracing: Allow whitespace to surround hist trigger filter
|
|
Matt Fleming |
668ba0 |
tracing: Add cpu field for hist triggers
|
|
Matt Fleming |
668ba0 |
tracing: Add hist trigger support for variable reference aliases
|
|
Matt Fleming |
668ba0 |
tracing: Add 'last error' error facility for hist triggers
|
|
Matt Fleming |
668ba0 |
tracing: Add inter-event hist trigger Documentation
|
|
Matt Fleming |
668ba0 |
tracing: Make tracing_set_clock() non-static
|
|
Matt Fleming |
668ba0 |
tracing: Add a clock attribute for hist triggers
|
|
Matt Fleming |
668ba0 |
tracing: Increase trace_recursive_lock() limit for synthetic events
|
|
Matt Fleming |
668ba0 |
tracing: Add inter-event blurb to HIST_TRIGGERS config option
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
|
Matt Fleming |
668ba0 |
Signed-off-by: Mike Galbraith <mgalbraith@suse.de>
|
|
Matt Fleming |
668ba0 |
---
|
|
Matt Fleming |
668ba0 |
Documentation/trace/events.txt | 12 -
|
|
Matt Fleming |
668ba0 |
include/linux/tracepoint-defs.h | 1
|
|
Matt Fleming |
668ba0 |
kernel/trace/Kconfig | 3
|
|
Matt Fleming |
668ba0 |
kernel/trace/ring_buffer.c | 10 -
|
|
Matt Fleming |
668ba0 |
kernel/trace/trace.c | 5
|
|
Matt Fleming |
668ba0 |
kernel/trace/trace_events.c | 15 --
|
|
Matt Fleming |
668ba0 |
kernel/trace/trace_events_hist.c | 279 +++++++++++++++++++++------------------
|
|
Matt Fleming |
668ba0 |
kernel/trace/tracing_map.c | 10 -
|
|
Matt Fleming |
668ba0 |
kernel/tracepoint.c | 18 --
|
|
Matt Fleming |
668ba0 |
9 files changed, 188 insertions(+), 165 deletions(-)
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
--- a/Documentation/trace/events.txt
|
|
Matt Fleming |
668ba0 |
+++ b/Documentation/trace/events.txt
|
|
Matt Fleming |
668ba0 |
@@ -669,15 +669,15 @@ The following commands are supported:
|
|
Matt Fleming |
668ba0 |
The examples below provide a more concrete illustration of the
|
|
Matt Fleming |
668ba0 |
concepts and typical usage patterns discussed above.
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- 'synthetic' event fields
|
|
Matt Fleming |
668ba0 |
+ 'special' event fields
|
|
Matt Fleming |
668ba0 |
------------------------
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- There are a number of 'synthetic fields' available for use as keys
|
|
Matt Fleming |
668ba0 |
- or values in a hist trigger. These look like and behave as if they
|
|
Matt Fleming |
668ba0 |
- were event fields, but aren't actually part of the event's field
|
|
Matt Fleming |
668ba0 |
- definition or format file. They are however available for any
|
|
Matt Fleming |
668ba0 |
+ There are a number of 'special event fields' available for use as
|
|
Matt Fleming |
668ba0 |
+ keys or values in a hist trigger. These look like and behave as if
|
|
Matt Fleming |
668ba0 |
+ they were actual event fields, but aren't really part of the event's
|
|
Matt Fleming |
668ba0 |
+ field definition or format file. They are however available for any
|
|
Matt Fleming |
668ba0 |
event, and can be used anywhere an actual event field could be.
|
|
Matt Fleming |
668ba0 |
- 'Synthetic' field names are always prefixed with a '$' character to
|
|
Matt Fleming |
668ba0 |
+ 'Special' field names are always prefixed with a '$' character to
|
|
Matt Fleming |
668ba0 |
indicate that they're not normal fields (with the exception of
|
|
Matt Fleming |
668ba0 |
'cpu', for compatibility with existing filter usage):
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
--- a/include/linux/tracepoint-defs.h
|
|
Matt Fleming |
668ba0 |
+++ b/include/linux/tracepoint-defs.h
|
|
Matt Fleming |
668ba0 |
@@ -32,7 +32,6 @@ struct tracepoint {
|
|
Matt Fleming |
668ba0 |
int (*regfunc)(void);
|
|
Matt Fleming |
668ba0 |
void (*unregfunc)(void);
|
|
Matt Fleming |
668ba0 |
struct tracepoint_func __rcu *funcs;
|
|
Matt Fleming |
668ba0 |
- bool dynamic;
|
|
Matt Fleming |
668ba0 |
};
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
struct bpf_raw_event_map {
|
|
Matt Fleming |
668ba0 |
--- a/kernel/trace/Kconfig
|
|
Matt Fleming |
668ba0 |
+++ b/kernel/trace/Kconfig
|
|
Matt Fleming |
668ba0 |
@@ -585,6 +585,9 @@ config HIST_TRIGGERS
|
|
Matt Fleming |
668ba0 |
event activity as an initial guide for further investigation
|
|
Matt Fleming |
668ba0 |
using more advanced tools.
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
+ Inter-event tracing of quantities such as latencies is also
|
|
Matt Fleming |
668ba0 |
+ supported using hist triggers under this option.
|
|
Matt Fleming |
668ba0 |
+
|
|
Matt Fleming |
668ba0 |
See Documentation/trace/events.txt.
|
|
Matt Fleming |
668ba0 |
If in doubt, say N.
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
--- a/kernel/trace/ring_buffer.c
|
|
Matt Fleming |
668ba0 |
+++ b/kernel/trace/ring_buffer.c
|
|
Mel Gorman |
fb63c5 |
@@ -2603,16 +2603,16 @@ rb_wakeups(struct ring_buffer *buffer, s
|
|
Matt Fleming |
668ba0 |
* IRQ context
|
|
Matt Fleming |
668ba0 |
* NMI context
|
|
Matt Fleming |
668ba0 |
*
|
|
Matt Fleming |
668ba0 |
- * If for some reason the ring buffer starts to recurse, we
|
|
Matt Fleming |
668ba0 |
- * only allow that to happen at most 4 times (one for each
|
|
Matt Fleming |
668ba0 |
- * context). If it happens 5 times, then we consider this a
|
|
Mel Gorman |
fb63c5 |
- * recursive loop and do not let it go further.
|
|
Matt Fleming |
668ba0 |
+ * If for some reason the ring buffer starts to recurse, we only allow
|
|
Matt Fleming |
668ba0 |
+ * that to happen at most 6 times (one for each context, plus possibly
|
|
Matt Fleming |
668ba0 |
+ * two levels of synthetic event generation). If it happens 7 times,
|
|
Mel Gorman |
fb63c5 |
+ * then we consider this a recursive loop and do not let it go further.
|
|
Matt Fleming |
668ba0 |
*/
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
static __always_inline int
|
|
Matt Fleming |
668ba0 |
trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
- if (cpu_buffer->current_context >= 4)
|
|
Matt Fleming |
668ba0 |
+ if (cpu_buffer->current_context >= 6)
|
|
Matt Fleming |
668ba0 |
return 1;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
cpu_buffer->current_context++;
|
|
Matt Fleming |
668ba0 |
--- a/kernel/trace/trace.c
|
|
Matt Fleming |
668ba0 |
+++ b/kernel/trace/trace.c
|
|
Mel Gorman |
fb63c5 |
@@ -7599,6 +7599,7 @@ static int instance_mkdir(const char *na
|
|
Matt Fleming |
668ba0 |
struct trace_array *tr;
|
|
Matt Fleming |
668ba0 |
int ret;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
+ mutex_lock(&event_mutex);
|
|
Matt Fleming |
668ba0 |
mutex_lock(&trace_types_lock);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
ret = -EEXIST;
|
|
Mel Gorman |
fb63c5 |
@@ -7655,6 +7656,7 @@ static int instance_mkdir(const char *na
|
|
Matt Fleming |
668ba0 |
list_add(&tr->list, &ftrace_trace_arrays);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
mutex_unlock(&trace_types_lock);
|
|
Matt Fleming |
668ba0 |
+ mutex_unlock(&event_mutex);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
return 0;
|
|
Matt Fleming |
668ba0 |
|
|
Mel Gorman |
fb63c5 |
@@ -7666,6 +7668,7 @@ static int instance_mkdir(const char *na
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
out_unlock:
|
|
Matt Fleming |
668ba0 |
mutex_unlock(&trace_types_lock);
|
|
Matt Fleming |
668ba0 |
+ mutex_unlock(&event_mutex);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
return ret;
|
|
Matt Fleming |
668ba0 |
|
|
Mel Gorman |
fb63c5 |
@@ -7678,6 +7681,7 @@ static int instance_rmdir(const char *na
|
|
Matt Fleming |
668ba0 |
int ret;
|
|
Matt Fleming |
668ba0 |
int i;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
+ mutex_lock(&event_mutex);
|
|
Matt Fleming |
668ba0 |
mutex_lock(&trace_types_lock);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
ret = -ENODEV;
|
|
Mel Gorman |
fb63c5 |
@@ -7723,6 +7727,7 @@ static int instance_rmdir(const char *na
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
out_unlock:
|
|
Matt Fleming |
668ba0 |
mutex_unlock(&trace_types_lock);
|
|
Matt Fleming |
668ba0 |
+ mutex_unlock(&event_mutex);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
return ret;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
--- a/kernel/trace/trace_events.c
|
|
Matt Fleming |
668ba0 |
+++ b/kernel/trace/trace_events.c
|
|
Matt Fleming |
668ba0 |
@@ -2924,24 +2924,24 @@ create_event_toplevel_files(struct dentr
|
|
Matt Fleming |
668ba0 |
* creates the event hierachry in the @parent/events directory.
|
|
Matt Fleming |
668ba0 |
*
|
|
Matt Fleming |
668ba0 |
* Returns 0 on success.
|
|
Matt Fleming |
668ba0 |
+ *
|
|
Matt Fleming |
668ba0 |
+ * Must be called with event_mutex held.
|
|
Matt Fleming |
668ba0 |
*/
|
|
Matt Fleming |
668ba0 |
int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
int ret;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- mutex_lock(&event_mutex);
|
|
Matt Fleming |
668ba0 |
+ lockdep_assert_held(&event_mutex);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
ret = create_event_toplevel_files(parent, tr);
|
|
Matt Fleming |
668ba0 |
if (ret)
|
|
Matt Fleming |
668ba0 |
- goto out_unlock;
|
|
Matt Fleming |
668ba0 |
+ goto out;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
down_write(&trace_event_sem);
|
|
Matt Fleming |
668ba0 |
__trace_add_event_dirs(tr);
|
|
Matt Fleming |
668ba0 |
up_write(&trace_event_sem);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- out_unlock:
|
|
Matt Fleming |
668ba0 |
- mutex_unlock(&event_mutex);
|
|
Matt Fleming |
668ba0 |
-
|
|
Matt Fleming |
668ba0 |
+ out:
|
|
Matt Fleming |
668ba0 |
return ret;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
@@ -2970,9 +2970,10 @@ early_event_add_tracer(struct dentry *pa
|
|
Matt Fleming |
668ba0 |
return ret;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
+/* Must be called with event_mutex held */
|
|
Matt Fleming |
668ba0 |
int event_trace_del_tracer(struct trace_array *tr)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
- mutex_lock(&event_mutex);
|
|
Matt Fleming |
668ba0 |
+ lockdep_assert_held(&event_mutex);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
/* Disable any event triggers and associated soft-disabled events */
|
|
Matt Fleming |
668ba0 |
clear_event_triggers(tr);
|
|
Matt Fleming |
668ba0 |
@@ -2993,8 +2994,6 @@ int event_trace_del_tracer(struct trace_
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
tr->event_dir = NULL;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- mutex_unlock(&event_mutex);
|
|
Matt Fleming |
668ba0 |
-
|
|
Matt Fleming |
668ba0 |
return 0;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
--- a/kernel/trace/trace_events_hist.c
|
|
Matt Fleming |
668ba0 |
+++ b/kernel/trace/trace_events_hist.c
|
|
Matt Fleming |
668ba0 |
@@ -210,24 +210,24 @@ DEFINE_HIST_FIELD_FN(u8);
|
|
Matt Fleming |
668ba0 |
#define HIST_KEY_SIZE_MAX (MAX_FILTER_STR_VAL + HIST_STACKTRACE_SIZE)
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
enum hist_field_flags {
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_HITCOUNT = 1,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_KEY = 2,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_STRING = 4,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_HEX = 8,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_SYM = 16,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_SYM_OFFSET = 32,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_EXECNAME = 64,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_SYSCALL = 128,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_STACKTRACE = 256,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_LOG2 = 512,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_TIMESTAMP = 1024,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_TIMESTAMP_USECS = 2048,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_VAR = 4096,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_VAR_ONLY = 8192,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_EXPR = 16384,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_VAR_REF = 32768,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_CPU = 65536,
|
|
Matt Fleming |
668ba0 |
- HIST_FIELD_FL_ALIAS = 131072,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_HITCOUNT = 1 << 0,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_KEY = 1 << 1,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_STRING = 1 << 2,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_HEX = 1 << 3,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_SYM = 1 << 4,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_SYM_OFFSET = 1 << 5,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_EXECNAME = 1 << 6,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_SYSCALL = 1 << 7,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_STACKTRACE = 1 << 8,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_LOG2 = 1 << 9,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_TIMESTAMP = 1 << 10,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_TIMESTAMP_USECS = 1 << 11,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_VAR = 1 << 12,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_VAR_ONLY = 1 << 13,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_EXPR = 1 << 14,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_VAR_REF = 1 << 15,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_CPU = 1 << 16,
|
|
Matt Fleming |
668ba0 |
+ HIST_FIELD_FL_ALIAS = 1 << 17,
|
|
Matt Fleming |
668ba0 |
};
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
struct var_defs {
|
|
Matt Fleming |
668ba0 |
@@ -353,42 +353,22 @@ struct action_data {
|
|
Matt Fleming |
668ba0 |
};
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
-static char *hist_err_str;
|
|
Matt Fleming |
668ba0 |
-static char *last_hist_cmd;
|
|
Matt Fleming |
668ba0 |
-
|
|
Matt Fleming |
668ba0 |
-static int hist_err_alloc(void)
|
|
Matt Fleming |
668ba0 |
-{
|
|
Matt Fleming |
668ba0 |
- int ret = 0;
|
|
Matt Fleming |
668ba0 |
-
|
|
Matt Fleming |
668ba0 |
- last_hist_cmd = kzalloc(MAX_FILTER_STR_VAL, GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
- if (!last_hist_cmd)
|
|
Matt Fleming |
668ba0 |
- return -ENOMEM;
|
|
Matt Fleming |
668ba0 |
-
|
|
Matt Fleming |
668ba0 |
- hist_err_str = kzalloc(MAX_FILTER_STR_VAL, GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
- if (!hist_err_str) {
|
|
Matt Fleming |
668ba0 |
- kfree(last_hist_cmd);
|
|
Matt Fleming |
668ba0 |
- ret = -ENOMEM;
|
|
Matt Fleming |
668ba0 |
- }
|
|
Matt Fleming |
668ba0 |
-
|
|
Matt Fleming |
668ba0 |
- return ret;
|
|
Matt Fleming |
668ba0 |
-}
|
|
Matt Fleming |
668ba0 |
+static char last_hist_cmd[MAX_FILTER_STR_VAL];
|
|
Matt Fleming |
668ba0 |
+static char hist_err_str[MAX_FILTER_STR_VAL];
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
static void last_cmd_set(char *str)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
- if (!last_hist_cmd || !str)
|
|
Matt Fleming |
668ba0 |
- return;
|
|
Matt Fleming |
668ba0 |
-
|
|
Matt Fleming |
668ba0 |
- if (strlen(str) > MAX_FILTER_STR_VAL - 1)
|
|
Matt Fleming |
668ba0 |
+ if (!str)
|
|
Matt Fleming |
668ba0 |
return;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- strcpy(last_hist_cmd, str);
|
|
Matt Fleming |
668ba0 |
+ strncpy(last_hist_cmd, str, MAX_FILTER_STR_VAL - 1);
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
static void hist_err(char *str, char *var)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
int maxlen = MAX_FILTER_STR_VAL - 1;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- if (!hist_err_str || !str)
|
|
Matt Fleming |
668ba0 |
+ if (!str)
|
|
Matt Fleming |
668ba0 |
return;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
if (strlen(hist_err_str))
|
|
Matt Fleming |
668ba0 |
@@ -409,26 +389,23 @@ static void hist_err_event(char *str, ch
|
|
Matt Fleming |
668ba0 |
char err[MAX_FILTER_STR_VAL];
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
if (system && var)
|
|
Matt Fleming |
668ba0 |
- sprintf(err, "%s.%s.%s", system, event, var);
|
|
Matt Fleming |
668ba0 |
+ snprintf(err, MAX_FILTER_STR_VAL, "%s.%s.%s", system, event, var);
|
|
Matt Fleming |
668ba0 |
else if (system)
|
|
Matt Fleming |
668ba0 |
- sprintf(err, "%s.%s", system, event);
|
|
Matt Fleming |
668ba0 |
+ snprintf(err, MAX_FILTER_STR_VAL, "%s.%s", system, event);
|
|
Matt Fleming |
668ba0 |
else
|
|
Matt Fleming |
668ba0 |
- strcpy(err, var);
|
|
Matt Fleming |
668ba0 |
+ strncpy(err, var, MAX_FILTER_STR_VAL);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
hist_err(str, err);
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
static void hist_err_clear(void)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
- if (!hist_err_str)
|
|
Matt Fleming |
668ba0 |
- return;
|
|
Matt Fleming |
668ba0 |
-
|
|
Matt Fleming |
668ba0 |
hist_err_str[0] = '\0';
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
static bool have_hist_err(void)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
- if (hist_err_str && strlen(hist_err_str))
|
|
Matt Fleming |
668ba0 |
+ if (strlen(hist_err_str))
|
|
Matt Fleming |
668ba0 |
return true;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
return false;
|
|
Matt Fleming |
668ba0 |
@@ -508,7 +485,7 @@ static int synth_field_string_size(char
|
|
Matt Fleming |
668ba0 |
return -EINVAL;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
len = end - start;
|
|
Matt Fleming |
668ba0 |
- if (len > 2)
|
|
Matt Fleming |
668ba0 |
+ if (len > 3)
|
|
Matt Fleming |
668ba0 |
return -EINVAL;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
strncpy(buf, start, len);
|
|
Matt Fleming |
668ba0 |
@@ -631,12 +608,12 @@ static enum print_line_t print_synth_eve
|
|
Matt Fleming |
668ba0 |
if (tr->trace_flags & TRACE_ITER_VERBOSE)
|
|
Matt Fleming |
668ba0 |
trace_seq_printf(s, "%s ", fmt);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- sprintf(print_fmt, "%%s=%s%%s", fmt);
|
|
Matt Fleming |
668ba0 |
+ snprintf(print_fmt, sizeof(print_fmt), "%%s=%s%%s", fmt);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
/* parameter values */
|
|
Matt Fleming |
668ba0 |
if (se->fields[i]->is_string) {
|
|
Matt Fleming |
668ba0 |
trace_seq_printf(s, print_fmt, se->fields[i]->name,
|
|
Matt Fleming |
668ba0 |
- (char *)entry->fields[n_u64],
|
|
Matt Fleming |
668ba0 |
+ (char *)(long)entry->fields[n_u64],
|
|
Matt Fleming |
668ba0 |
i == se->n_fields - 1 ? "" : " ");
|
|
Matt Fleming |
668ba0 |
n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
|
|
Matt Fleming |
668ba0 |
} else {
|
|
Matt Fleming |
668ba0 |
@@ -681,7 +658,7 @@ static notrace void trace_event_raw_even
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
for (i = 0, n_u64 = 0; i < event->n_fields; i++) {
|
|
Matt Fleming |
668ba0 |
if (event->fields[i]->is_string) {
|
|
Matt Fleming |
668ba0 |
- char *str_val = (char *)var_ref_vals[var_ref_idx + i];
|
|
Matt Fleming |
668ba0 |
+ char *str_val = (char *)(long)var_ref_vals[var_ref_idx + i];
|
|
Matt Fleming |
668ba0 |
char *str_field = (char *)&entry->fields[n_u64];
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
strncpy(str_field, str_val, STR_VAR_LEN_MAX);
|
|
Matt Fleming |
668ba0 |
@@ -697,8 +674,10 @@ static notrace void trace_event_raw_even
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
static void free_synth_event_print_fmt(struct trace_event_call *call)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
- if (call)
|
|
Matt Fleming |
668ba0 |
+ if (call) {
|
|
Matt Fleming |
668ba0 |
kfree(call->print_fmt);
|
|
Matt Fleming |
668ba0 |
+ call->print_fmt = NULL;
|
|
Matt Fleming |
668ba0 |
+ }
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
static int __set_synth_event_print_fmt(struct synth_event *event,
|
|
Matt Fleming |
668ba0 |
@@ -827,27 +806,18 @@ static void free_synth_tracepoint(struct
|
|
Matt Fleming |
668ba0 |
static struct tracepoint *alloc_synth_tracepoint(char *name)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
struct tracepoint *tp;
|
|
Matt Fleming |
668ba0 |
- int ret = 0;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
tp = kzalloc(sizeof(*tp), GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
- if (!tp) {
|
|
Matt Fleming |
668ba0 |
- ret = -ENOMEM;
|
|
Matt Fleming |
668ba0 |
- goto free;
|
|
Matt Fleming |
668ba0 |
- }
|
|
Matt Fleming |
668ba0 |
+ if (!tp)
|
|
Matt Fleming |
668ba0 |
+ return ERR_PTR(-ENOMEM);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
tp->name = kstrdup(name, GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
if (!tp->name) {
|
|
Matt Fleming |
668ba0 |
- ret = -ENOMEM;
|
|
Matt Fleming |
668ba0 |
- goto free;
|
|
Matt Fleming |
668ba0 |
+ kfree(tp);
|
|
Matt Fleming |
668ba0 |
+ return ERR_PTR(-ENOMEM);
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- tp->dynamic = true;
|
|
Matt Fleming |
668ba0 |
-
|
|
Matt Fleming |
668ba0 |
return tp;
|
|
Matt Fleming |
668ba0 |
- free:
|
|
Matt Fleming |
668ba0 |
- free_synth_tracepoint(tp);
|
|
Matt Fleming |
668ba0 |
-
|
|
Matt Fleming |
668ba0 |
- return ERR_PTR(ret);
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
typedef void (*synth_probe_func_t) (void *__data, u64 *var_ref_vals,
|
|
Matt Fleming |
668ba0 |
@@ -869,8 +839,8 @@ static inline void trace_synth(struct sy
|
|
Matt Fleming |
668ba0 |
probe_func_ptr = rcu_dereference_sched((tp)->funcs);
|
|
Matt Fleming |
668ba0 |
if (probe_func_ptr) {
|
|
Matt Fleming |
668ba0 |
do {
|
|
Matt Fleming |
668ba0 |
- probe_func = (probe_func_ptr)->func;
|
|
Matt Fleming |
668ba0 |
- __data = (probe_func_ptr)->data;
|
|
Matt Fleming |
668ba0 |
+ probe_func = probe_func_ptr->func;
|
|
Matt Fleming |
668ba0 |
+ __data = probe_func_ptr->data;
|
|
Matt Fleming |
668ba0 |
probe_func(__data, var_ref_vals, var_ref_idx);
|
|
Matt Fleming |
668ba0 |
} while ((++probe_func_ptr)->func);
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
@@ -889,6 +859,7 @@ static struct synth_event *find_synth_ev
|
|
Matt Fleming |
668ba0 |
return NULL;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
+/* This function releases synth_event_mutex */
|
|
Matt Fleming |
668ba0 |
static int register_synth_event(struct synth_event *event)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
struct trace_event_call *call = &event->call;
|
|
Matt Fleming |
668ba0 |
@@ -923,6 +894,11 @@ static int register_synth_event(struct s
|
|
Matt Fleming |
668ba0 |
call->data = event;
|
|
Matt Fleming |
668ba0 |
call->tp = event->tp;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
+ /*
|
|
Matt Fleming |
668ba0 |
+ * trace_add_event_call() grabs event_mutex, but that can
|
|
Matt Fleming |
668ba0 |
+ * deadlock with a hist trigger cmd already holding it that
|
|
Matt Fleming |
668ba0 |
+ * can grab synth_event_mutex
|
|
Matt Fleming |
668ba0 |
+ */
|
|
Matt Fleming |
668ba0 |
mutex_unlock(&synth_event_mutex);
|
|
Matt Fleming |
668ba0 |
ret = trace_add_event_call(call);
|
|
Matt Fleming |
668ba0 |
mutex_lock(&synth_event_mutex);
|
|
Matt Fleming |
668ba0 |
@@ -946,6 +922,7 @@ static int register_synth_event(struct s
|
|
Matt Fleming |
668ba0 |
goto out;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
+/* This function releases synth_event_mutex */
|
|
Matt Fleming |
668ba0 |
static int unregister_synth_event(struct synth_event *event)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
struct trace_event_call *call = &event->call;
|
|
Matt Fleming |
668ba0 |
@@ -954,20 +931,18 @@ static int unregister_synth_event(struct
|
|
Matt Fleming |
668ba0 |
mutex_unlock(&synth_event_mutex);
|
|
Matt Fleming |
668ba0 |
ret = trace_remove_event_call(call);
|
|
Matt Fleming |
668ba0 |
mutex_lock(&synth_event_mutex);
|
|
Matt Fleming |
668ba0 |
- if (ret) {
|
|
Matt Fleming |
668ba0 |
- pr_warn("Failed to remove synthetic event: %s\n",
|
|
Matt Fleming |
668ba0 |
- trace_event_name(call));
|
|
Matt Fleming |
668ba0 |
- free_synth_event_print_fmt(call);
|
|
Matt Fleming |
668ba0 |
- unregister_trace_event(&call->event);
|
|
Matt Fleming |
668ba0 |
- }
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
return ret;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
-static void remove_synth_event(struct synth_event *event)
|
|
Matt Fleming |
668ba0 |
+static int remove_synth_event(struct synth_event *event)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
- unregister_synth_event(event);
|
|
Matt Fleming |
668ba0 |
- list_del(&event->list);
|
|
Matt Fleming |
668ba0 |
+ int ret = unregister_synth_event(event);
|
|
Matt Fleming |
668ba0 |
+
|
|
Matt Fleming |
668ba0 |
+ if (!ret)
|
|
Matt Fleming |
668ba0 |
+ list_del(&event->list);
|
|
Matt Fleming |
668ba0 |
+
|
|
Matt Fleming |
668ba0 |
+ return ret;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
static int add_synth_event(struct synth_event *event)
|
|
Matt Fleming |
668ba0 |
@@ -1050,6 +1025,7 @@ struct hist_var_data {
|
|
Matt Fleming |
668ba0 |
struct hist_trigger_data *hist_data;
|
|
Matt Fleming |
668ba0 |
};
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
+/* This function releases synth_event_mutex */
|
|
Matt Fleming |
668ba0 |
static int create_synth_event(int argc, char **argv)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
struct synth_field *field, *fields[SYNTH_FIELDS_MAX];
|
|
Matt Fleming |
668ba0 |
@@ -1084,8 +1060,9 @@ static int create_synth_event(int argc,
|
|
Matt Fleming |
668ba0 |
ret = -EBUSY;
|
|
Matt Fleming |
668ba0 |
goto out;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
- remove_synth_event(event);
|
|
Matt Fleming |
668ba0 |
- free_synth_event(event);
|
|
Matt Fleming |
668ba0 |
+ ret = remove_synth_event(event);
|
|
Matt Fleming |
668ba0 |
+ if (!ret)
|
|
Matt Fleming |
668ba0 |
+ free_synth_event(event);
|
|
Matt Fleming |
668ba0 |
goto out;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
ret = -EEXIST;
|
|
Matt Fleming |
668ba0 |
@@ -1140,6 +1117,7 @@ static int create_synth_event(int argc,
|
|
Matt Fleming |
668ba0 |
goto out;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
+/* This function releases synth_event_mutex */
|
|
Matt Fleming |
668ba0 |
static int release_all_synth_events(void)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
struct synth_event *event, *e;
|
|
Matt Fleming |
668ba0 |
@@ -1155,8 +1133,9 @@ static int release_all_synth_events(void
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
list_for_each_entry_safe(event, e, &synth_event_list, list) {
|
|
Matt Fleming |
668ba0 |
- remove_synth_event(event);
|
|
Matt Fleming |
668ba0 |
- free_synth_event(event);
|
|
Matt Fleming |
668ba0 |
+ ret = remove_synth_event(event);
|
|
Matt Fleming |
668ba0 |
+ if (!ret)
|
|
Matt Fleming |
668ba0 |
+ free_synth_event(event);
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
out:
|
|
Matt Fleming |
668ba0 |
mutex_unlock(&synth_event_mutex);
|
|
Matt Fleming |
668ba0 |
@@ -1260,7 +1239,7 @@ static u64 hist_field_cpu(struct hist_fi
|
|
Matt Fleming |
668ba0 |
struct ring_buffer_event *rbe,
|
|
Matt Fleming |
668ba0 |
void *event)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
- int cpu = raw_smp_processor_id();
|
|
Matt Fleming |
668ba0 |
+ int cpu = smp_processor_id();
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
return cpu;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
@@ -1732,17 +1711,33 @@ static int parse_assignment(char *str, s
|
|
Matt Fleming |
668ba0 |
int ret = 0;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
if ((strncmp(str, "key=", strlen("key=")) == 0) ||
|
|
Matt Fleming |
668ba0 |
- (strncmp(str, "keys=", strlen("keys=")) == 0))
|
|
Matt Fleming |
668ba0 |
+ (strncmp(str, "keys=", strlen("keys=")) == 0)) {
|
|
Matt Fleming |
668ba0 |
attrs->keys_str = kstrdup(str, GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
- else if ((strncmp(str, "val=", strlen("val=")) == 0) ||
|
|
Matt Fleming |
668ba0 |
+ if (!attrs->keys_str) {
|
|
Matt Fleming |
668ba0 |
+ ret = -ENOMEM;
|
|
Matt Fleming |
668ba0 |
+ goto out;
|
|
Matt Fleming |
668ba0 |
+ }
|
|
Matt Fleming |
668ba0 |
+ } else if ((strncmp(str, "val=", strlen("val=")) == 0) ||
|
|
Matt Fleming |
668ba0 |
(strncmp(str, "vals=", strlen("vals=")) == 0) ||
|
|
Matt Fleming |
668ba0 |
- (strncmp(str, "values=", strlen("values=")) == 0))
|
|
Matt Fleming |
668ba0 |
+ (strncmp(str, "values=", strlen("values=")) == 0)) {
|
|
Matt Fleming |
668ba0 |
attrs->vals_str = kstrdup(str, GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
- else if (strncmp(str, "sort=", strlen("sort=")) == 0)
|
|
Matt Fleming |
668ba0 |
+ if (!attrs->vals_str) {
|
|
Matt Fleming |
668ba0 |
+ ret = -ENOMEM;
|
|
Matt Fleming |
668ba0 |
+ goto out;
|
|
Matt Fleming |
668ba0 |
+ }
|
|
Matt Fleming |
668ba0 |
+ } else if (strncmp(str, "sort=", strlen("sort=")) == 0) {
|
|
Matt Fleming |
668ba0 |
attrs->sort_key_str = kstrdup(str, GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
- else if (strncmp(str, "name=", strlen("name=")) == 0)
|
|
Matt Fleming |
668ba0 |
+ if (!attrs->sort_key_str) {
|
|
Matt Fleming |
668ba0 |
+ ret = -ENOMEM;
|
|
Matt Fleming |
668ba0 |
+ goto out;
|
|
Matt Fleming |
668ba0 |
+ }
|
|
Matt Fleming |
668ba0 |
+ } else if (strncmp(str, "name=", strlen("name=")) == 0) {
|
|
Matt Fleming |
668ba0 |
attrs->name = kstrdup(str, GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
- else if (strncmp(str, "clock=", strlen("clock=")) == 0) {
|
|
Matt Fleming |
668ba0 |
+ if (!attrs->name) {
|
|
Matt Fleming |
668ba0 |
+ ret = -ENOMEM;
|
|
Matt Fleming |
668ba0 |
+ goto out;
|
|
Matt Fleming |
668ba0 |
+ }
|
|
Matt Fleming |
668ba0 |
+ } else if (strncmp(str, "clock=", strlen("clock=")) == 0) {
|
|
Matt Fleming |
668ba0 |
strsep(&str, "=");
|
|
Matt Fleming |
668ba0 |
if (!str) {
|
|
Matt Fleming |
668ba0 |
ret = -EINVAL;
|
|
Matt Fleming |
668ba0 |
@@ -1751,6 +1746,10 @@ static int parse_assignment(char *str, s
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
str = strstrip(str);
|
|
Matt Fleming |
668ba0 |
attrs->clock = kstrdup(str, GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
+ if (!attrs->clock) {
|
|
Matt Fleming |
668ba0 |
+ ret = -ENOMEM;
|
|
Matt Fleming |
668ba0 |
+ goto out;
|
|
Matt Fleming |
668ba0 |
+ }
|
|
Matt Fleming |
668ba0 |
} else if (strncmp(str, "size=", strlen("size=")) == 0) {
|
|
Matt Fleming |
668ba0 |
int map_bits = parse_map_size(str);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
@@ -1816,8 +1815,10 @@ static struct hist_trigger_attrs *parse_
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
if (!attrs->clock) {
|
|
Matt Fleming |
668ba0 |
attrs->clock = kstrdup("global", GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
- if (!attrs->clock)
|
|
Matt Fleming |
668ba0 |
+ if (!attrs->clock) {
|
|
Matt Fleming |
668ba0 |
+ ret = -ENOMEM;
|
|
Matt Fleming |
668ba0 |
goto free;
|
|
Matt Fleming |
668ba0 |
+ }
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
return attrs;
|
|
Matt Fleming |
668ba0 |
@@ -1842,19 +1843,22 @@ static inline void save_comm(char *comm,
|
|
Matt Fleming |
668ba0 |
memcpy(comm, task->comm, TASK_COMM_LEN);
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
-static void hist_trigger_elt_data_free(struct tracing_map_elt *elt)
|
|
Matt Fleming |
668ba0 |
+static void hist_elt_data_free(struct hist_elt_data *elt_data)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
- struct hist_trigger_data *hist_data = elt->map->private_data;
|
|
Matt Fleming |
668ba0 |
- struct hist_elt_data *private_data = elt->private_data;
|
|
Matt Fleming |
668ba0 |
- unsigned int i, n_str;
|
|
Matt Fleming |
668ba0 |
+ unsigned int i;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- n_str = hist_data->n_field_var_str + hist_data->n_max_var_str;
|
|
Matt Fleming |
668ba0 |
+ for (i = 0; i < SYNTH_FIELDS_MAX; i++)
|
|
Matt Fleming |
668ba0 |
+ kfree(elt_data->field_var_str[i]);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- for (i = 0; i < n_str; i++)
|
|
Matt Fleming |
668ba0 |
- kfree(private_data->field_var_str[i]);
|
|
Matt Fleming |
668ba0 |
+ kfree(elt_data->comm);
|
|
Matt Fleming |
668ba0 |
+ kfree(elt_data);
|
|
Matt Fleming |
668ba0 |
+}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- kfree(private_data->comm);
|
|
Matt Fleming |
668ba0 |
- kfree(private_data);
|
|
Matt Fleming |
668ba0 |
+static void hist_trigger_elt_data_free(struct tracing_map_elt *elt)
|
|
Matt Fleming |
668ba0 |
+{
|
|
Matt Fleming |
668ba0 |
+ struct hist_elt_data *elt_data = elt->private_data;
|
|
Matt Fleming |
668ba0 |
+
|
|
Matt Fleming |
668ba0 |
+ hist_elt_data_free(elt_data);
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
static int hist_trigger_elt_data_alloc(struct tracing_map_elt *elt)
|
|
Matt Fleming |
668ba0 |
@@ -1865,7 +1869,7 @@ static int hist_trigger_elt_data_alloc(s
|
|
Matt Fleming |
668ba0 |
struct hist_field *key_field;
|
|
Matt Fleming |
668ba0 |
unsigned int i, n_str;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- elt->private_data = elt_data = kzalloc(sizeof(*elt_data), GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
+ elt_data = kzalloc(sizeof(*elt_data), GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
if (!elt_data)
|
|
Matt Fleming |
668ba0 |
return -ENOMEM;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
@@ -1876,7 +1880,6 @@ static int hist_trigger_elt_data_alloc(s
|
|
Matt Fleming |
668ba0 |
elt_data->comm = kzalloc(size, GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
if (!elt_data->comm) {
|
|
Matt Fleming |
668ba0 |
kfree(elt_data);
|
|
Matt Fleming |
668ba0 |
- elt->private_data = NULL;
|
|
Matt Fleming |
668ba0 |
return -ENOMEM;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
break;
|
|
Matt Fleming |
668ba0 |
@@ -1890,20 +1893,22 @@ static int hist_trigger_elt_data_alloc(s
|
|
Matt Fleming |
668ba0 |
for (i = 0; i < n_str; i++) {
|
|
Matt Fleming |
668ba0 |
elt_data->field_var_str[i] = kzalloc(size, GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
if (!elt_data->field_var_str[i]) {
|
|
Matt Fleming |
668ba0 |
- hist_trigger_elt_data_free(elt);
|
|
Matt Fleming |
668ba0 |
+ hist_elt_data_free(elt_data);
|
|
Matt Fleming |
668ba0 |
return -ENOMEM;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
+ elt->private_data = elt_data;
|
|
Matt Fleming |
668ba0 |
+
|
|
Matt Fleming |
668ba0 |
return 0;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
static void hist_trigger_elt_data_init(struct tracing_map_elt *elt)
|
|
Matt Fleming |
668ba0 |
{
|
|
Matt Fleming |
668ba0 |
- struct hist_elt_data *private_data = elt->private_data;
|
|
Matt Fleming |
668ba0 |
+ struct hist_elt_data *elt_data = elt->private_data;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- if (private_data->comm)
|
|
Matt Fleming |
668ba0 |
- save_comm(private_data->comm, current);
|
|
Matt Fleming |
668ba0 |
+ if (elt_data->comm)
|
|
Matt Fleming |
668ba0 |
+ save_comm(elt_data->comm, current);
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
static const struct tracing_map_ops hist_trigger_elt_data_ops = {
|
|
Matt Fleming |
668ba0 |
@@ -2371,7 +2376,15 @@ struct hist_field *parse_atom(struct his
|
|
Matt Fleming |
668ba0 |
s = strchr(++s, '.');
|
|
Matt Fleming |
668ba0 |
if (s) {
|
|
Matt Fleming |
668ba0 |
ref_system = strsep(&str, ".");
|
|
Matt Fleming |
668ba0 |
+ if (!str) {
|
|
Matt Fleming |
668ba0 |
+ ret = -EINVAL;
|
|
Matt Fleming |
668ba0 |
+ goto out;
|
|
Matt Fleming |
668ba0 |
+ }
|
|
Matt Fleming |
668ba0 |
ref_event = strsep(&str, ".");
|
|
Matt Fleming |
668ba0 |
+ if (!str) {
|
|
Matt Fleming |
668ba0 |
+ ret = -EINVAL;
|
|
Matt Fleming |
668ba0 |
+ goto out;
|
|
Matt Fleming |
668ba0 |
+ }
|
|
Matt Fleming |
668ba0 |
ref_var = str;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
@@ -2452,8 +2465,10 @@ static struct hist_field *parse_unary(st
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
strsep(&str, "(");
|
|
Matt Fleming |
668ba0 |
- if (!str)
|
|
Matt Fleming |
668ba0 |
+ if (!str) {
|
|
Matt Fleming |
668ba0 |
+ ret = -EINVAL;
|
|
Matt Fleming |
668ba0 |
goto free;
|
|
Matt Fleming |
668ba0 |
+ }
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
flags |= HIST_FIELD_FL_EXPR;
|
|
Matt Fleming |
668ba0 |
expr = create_hist_field(hist_data, NULL, flags, var_name);
|
|
Matt Fleming |
668ba0 |
@@ -3111,8 +3126,10 @@ static int onmax_create(struct hist_trig
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
for (i = 0; i < data->n_params; i++) {
|
|
Matt Fleming |
668ba0 |
param = kstrdup(data->params[i], GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
- if (!param)
|
|
Matt Fleming |
668ba0 |
+ if (!param) {
|
|
Matt Fleming |
668ba0 |
+ ret = -ENOMEM;
|
|
Matt Fleming |
668ba0 |
goto out;
|
|
Matt Fleming |
668ba0 |
+ }
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
field_var = create_target_field_var(hist_data, NULL, NULL, param);
|
|
Matt Fleming |
668ba0 |
if (IS_ERR(field_var)) {
|
|
Matt Fleming |
668ba0 |
@@ -3144,8 +3161,10 @@ static int parse_action_params(char *par
|
|
Matt Fleming |
668ba0 |
goto out;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
param = strsep(¶ms, ",");
|
|
Matt Fleming |
668ba0 |
- if (!param)
|
|
Matt Fleming |
668ba0 |
+ if (!param) {
|
|
Matt Fleming |
668ba0 |
+ ret = -EINVAL;
|
|
Matt Fleming |
668ba0 |
goto out;
|
|
Matt Fleming |
668ba0 |
+ }
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
param = strstrip(param);
|
|
Matt Fleming |
668ba0 |
if (strlen(param) < 2) {
|
|
Matt Fleming |
668ba0 |
@@ -3196,8 +3215,10 @@ static struct action_data *onmax_parse(c
|
|
Matt Fleming |
668ba0 |
if (strncmp(onmax_fn_name, "save", strlen("save")) == 0) {
|
|
Matt Fleming |
668ba0 |
char *params = strsep(&str, ")");
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- if (!params)
|
|
Matt Fleming |
668ba0 |
+ if (!params) {
|
|
Matt Fleming |
668ba0 |
+ ret = -EINVAL;
|
|
Matt Fleming |
668ba0 |
goto free;
|
|
Matt Fleming |
668ba0 |
+ }
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
ret = parse_action_params(params, data);
|
|
Matt Fleming |
668ba0 |
if (ret)
|
|
Matt Fleming |
668ba0 |
@@ -3231,11 +3252,11 @@ static void onmatch_destroy(struct actio
|
|
Matt Fleming |
668ba0 |
for (i = 0; i < data->n_params; i++)
|
|
Matt Fleming |
668ba0 |
kfree(data->params[i]);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- kfree(data);
|
|
Matt Fleming |
668ba0 |
-
|
|
Matt Fleming |
668ba0 |
if (data->onmatch.synth_event)
|
|
Matt Fleming |
668ba0 |
data->onmatch.synth_event->ref--;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
+ kfree(data);
|
|
Matt Fleming |
668ba0 |
+
|
|
Matt Fleming |
668ba0 |
mutex_unlock(&synth_event_mutex);
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
@@ -3372,13 +3393,13 @@ static int onmatch_create(struct hist_tr
|
|
Matt Fleming |
668ba0 |
int ret = 0;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
mutex_lock(&synth_event_mutex);
|
|
Matt Fleming |
668ba0 |
-
|
|
Matt Fleming |
668ba0 |
event = find_synth_event(data->onmatch.synth_event_name);
|
|
Matt Fleming |
668ba0 |
if (!event) {
|
|
Matt Fleming |
668ba0 |
hist_err("onmatch: Couldn't find synthetic event: ", data->onmatch.synth_event_name);
|
|
Matt Fleming |
668ba0 |
- ret = -EINVAL;
|
|
Matt Fleming |
668ba0 |
- goto out;
|
|
Matt Fleming |
668ba0 |
+ mutex_unlock(&synth_event_mutex);
|
|
Matt Fleming |
668ba0 |
+ return -EINVAL;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
+ mutex_unlock(&synth_event_mutex);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
var_ref_idx = hist_data->n_var_refs;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
@@ -3386,8 +3407,10 @@ static int onmatch_create(struct hist_tr
|
|
Matt Fleming |
668ba0 |
char *p;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
p = param = kstrdup(data->params[i], GFP_KERNEL);
|
|
Matt Fleming |
668ba0 |
- if (!param)
|
|
Matt Fleming |
668ba0 |
+ if (!param) {
|
|
Matt Fleming |
668ba0 |
+ ret = -ENOMEM;
|
|
Matt Fleming |
668ba0 |
goto out;
|
|
Matt Fleming |
668ba0 |
+ }
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
system = strsep(¶m, ".");
|
|
Matt Fleming |
668ba0 |
if (!param) {
|
|
Matt Fleming |
668ba0 |
@@ -3401,6 +3424,7 @@ static int onmatch_create(struct hist_tr
|
|
Matt Fleming |
668ba0 |
goto out;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
+
|
|
Matt Fleming |
668ba0 |
if (param[0] == '$')
|
|
Matt Fleming |
668ba0 |
hist_field = onmatch_find_var(hist_data, data, system,
|
|
Matt Fleming |
668ba0 |
event_name, param);
|
|
Matt Fleming |
668ba0 |
@@ -3449,8 +3473,6 @@ static int onmatch_create(struct hist_tr
|
|
Matt Fleming |
668ba0 |
hist_data->actions[hist_data->n_actions++] = data;
|
|
Matt Fleming |
668ba0 |
event->ref++;
|
|
Matt Fleming |
668ba0 |
out:
|
|
Matt Fleming |
668ba0 |
- mutex_unlock(&synth_event_mutex);
|
|
Matt Fleming |
668ba0 |
-
|
|
Matt Fleming |
668ba0 |
return ret;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
@@ -4840,11 +4862,10 @@ static bool hist_trigger_match(struct ev
|
|
Matt Fleming |
668ba0 |
return false;
|
|
Matt Fleming |
668ba0 |
if (key_field->is_signed != key_field_test->is_signed)
|
|
Matt Fleming |
668ba0 |
return false;
|
|
Matt Fleming |
668ba0 |
- if ((key_field->var.name && !key_field_test->var.name) ||
|
|
Matt Fleming |
668ba0 |
- (!key_field->var.name && key_field_test->var.name))
|
|
Matt Fleming |
668ba0 |
+ if (!!key_field->var.name != !!key_field_test->var.name)
|
|
Matt Fleming |
668ba0 |
return false;
|
|
Matt Fleming |
668ba0 |
- if ((key_field->var.name && key_field_test->var.name) &&
|
|
Matt Fleming |
668ba0 |
- strcmp(key_field->var.name, key_field_test->var.name) != 0)
|
|
Matt Fleming |
668ba0 |
+ if (key_field->var.name &&
|
|
Matt Fleming |
668ba0 |
+ strcmp(key_field->var.name, key_field_test->var.name) != 0)
|
|
Matt Fleming |
668ba0 |
return false;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
@@ -5027,8 +5048,10 @@ static void hist_unregister_trigger(char
|
|
Matt Fleming |
668ba0 |
if (unregistered && test->ops->free)
|
|
Matt Fleming |
668ba0 |
test->ops->free(test->ops, test);
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- if (hist_data->enable_timestamps)
|
|
Matt Fleming |
668ba0 |
- tracing_set_time_stamp_abs(file->tr, false);
|
|
Matt Fleming |
668ba0 |
+ if (hist_data->enable_timestamps) {
|
|
Matt Fleming |
668ba0 |
+ if (!hist_data->remove || unregistered)
|
|
Matt Fleming |
668ba0 |
+ tracing_set_time_stamp_abs(file->tr, false);
|
|
Matt Fleming |
668ba0 |
+ }
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
static bool hist_file_check_refs(struct trace_event_file *file)
|
|
Matt Fleming |
668ba0 |
@@ -5041,7 +5064,6 @@ static bool hist_file_check_refs(struct
|
|
Matt Fleming |
668ba0 |
hist_data = test->private_data;
|
|
Matt Fleming |
668ba0 |
if (check_var_refs(hist_data))
|
|
Matt Fleming |
668ba0 |
return true;
|
|
Matt Fleming |
668ba0 |
- break;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
@@ -5093,7 +5115,10 @@ static int event_hist_trigger_func(struc
|
|
Matt Fleming |
668ba0 |
if (glob[0] == '!')
|
|
Matt Fleming |
668ba0 |
remove = true;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- /* separate the trigger from the filter (k:v [if filter]) */
|
|
Matt Fleming |
668ba0 |
+ /*
|
|
Matt Fleming |
668ba0 |
+ * separate the trigger from the filter (k:v [if filter])
|
|
Matt Fleming |
668ba0 |
+ * allowing for whitespace in the trigger
|
|
Matt Fleming |
668ba0 |
+ */
|
|
Matt Fleming |
668ba0 |
trigger = param;
|
|
Matt Fleming |
668ba0 |
p = strstr(param, " if");
|
|
Matt Fleming |
668ba0 |
if (!p)
|
|
Matt Fleming |
668ba0 |
@@ -5397,8 +5422,6 @@ static __init int trace_events_hist_init
|
|
Matt Fleming |
668ba0 |
goto err;
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- hist_err_alloc();
|
|
Matt Fleming |
668ba0 |
-
|
|
Matt Fleming |
668ba0 |
return err;
|
|
Matt Fleming |
668ba0 |
err:
|
|
Matt Fleming |
668ba0 |
pr_warn("Could not create tracefs 'synthetic_events' entry\n");
|
|
Matt Fleming |
668ba0 |
--- a/kernel/trace/tracing_map.c
|
|
Matt Fleming |
668ba0 |
+++ b/kernel/trace/tracing_map.c
|
|
Matt Fleming |
668ba0 |
@@ -524,6 +524,7 @@ __tracing_map_insert(struct tracing_map
|
|
Matt Fleming |
668ba0 |
u32 idx, key_hash, test_key;
|
|
Matt Fleming |
668ba0 |
int dup_try = 0;
|
|
Matt Fleming |
668ba0 |
struct tracing_map_entry *entry;
|
|
Matt Fleming |
668ba0 |
+ struct tracing_map_elt *val;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
key_hash = jhash(key, map->key_size, 0);
|
|
Matt Fleming |
668ba0 |
if (key_hash == 0)
|
|
Matt Fleming |
668ba0 |
@@ -536,12 +537,13 @@ __tracing_map_insert(struct tracing_map
|
|
Matt Fleming |
668ba0 |
test_key = entry->key;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
if (test_key && test_key == key_hash) {
|
|
Matt Fleming |
668ba0 |
- if (entry->val &&
|
|
Matt Fleming |
668ba0 |
- keys_match(key, entry->val->key, map->key_size)) {
|
|
Matt Fleming |
668ba0 |
+ val = READ_ONCE(entry->val);
|
|
Matt Fleming |
668ba0 |
+ if (val &&
|
|
Matt Fleming |
668ba0 |
+ keys_match(key, val->key, map->key_size)) {
|
|
Matt Fleming |
668ba0 |
if (!lookup_only)
|
|
Matt Fleming |
668ba0 |
atomic64_inc(&map->hits);
|
|
Matt Fleming |
668ba0 |
- return entry->val;
|
|
Matt Fleming |
668ba0 |
- } else if (unlikely(!entry->val)) {
|
|
Matt Fleming |
668ba0 |
+ return val;
|
|
Matt Fleming |
668ba0 |
+ } else if (unlikely(!val)) {
|
|
Matt Fleming |
668ba0 |
/*
|
|
Matt Fleming |
668ba0 |
* The key is present. But, val (pointer to elt
|
|
Matt Fleming |
668ba0 |
* struct) is still NULL. which means some other
|
|
Matt Fleming |
668ba0 |
--- a/kernel/tracepoint.c
|
|
Matt Fleming |
668ba0 |
+++ b/kernel/tracepoint.c
|
|
Matt Fleming |
668ba0 |
@@ -197,9 +197,7 @@ static int tracepoint_add_func(struct tr
|
|
Matt Fleming |
668ba0 |
struct tracepoint_func *old, *tp_funcs;
|
|
Matt Fleming |
668ba0 |
int ret;
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- if (tp->regfunc &&
|
|
Matt Fleming |
668ba0 |
- ((tp->dynamic && !(atomic_read(&tp->key.enabled) > 0)) ||
|
|
Matt Fleming |
668ba0 |
- !static_key_enabled(&tp->key))) {
|
|
Matt Fleming |
668ba0 |
+ if (tp->regfunc && !static_key_enabled(&tp->key)) {
|
|
Matt Fleming |
668ba0 |
ret = tp->regfunc();
|
|
Matt Fleming |
668ba0 |
if (ret < 0)
|
|
Matt Fleming |
668ba0 |
return ret;
|
|
Matt Fleming |
668ba0 |
@@ -221,9 +219,7 @@ static int tracepoint_add_func(struct tr
|
|
Matt Fleming |
668ba0 |
* is used.
|
|
Matt Fleming |
668ba0 |
*/
|
|
Matt Fleming |
668ba0 |
rcu_assign_pointer(tp->funcs, tp_funcs);
|
|
Matt Fleming |
668ba0 |
- if (tp->dynamic && !(atomic_read(&tp->key.enabled) > 0))
|
|
Matt Fleming |
668ba0 |
- atomic_inc(&tp->key.enabled);
|
|
Matt Fleming |
668ba0 |
- else if (!tp->dynamic && !static_key_enabled(&tp->key))
|
|
Matt Fleming |
668ba0 |
+ if (!static_key_enabled(&tp->key))
|
|
Matt Fleming |
668ba0 |
static_key_slow_inc(&tp->key);
|
|
Matt Fleming |
668ba0 |
release_probes(old);
|
|
Matt Fleming |
668ba0 |
return 0;
|
|
Matt Fleming |
668ba0 |
@@ -250,14 +246,10 @@ static int tracepoint_remove_func(struct
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
if (!tp_funcs) {
|
|
Matt Fleming |
668ba0 |
/* Removed last function */
|
|
Matt Fleming |
668ba0 |
- if (tp->unregfunc &&
|
|
Matt Fleming |
668ba0 |
- ((tp->dynamic && (atomic_read(&tp->key.enabled) > 0)) ||
|
|
Matt Fleming |
668ba0 |
- static_key_enabled(&tp->key)))
|
|
Matt Fleming |
668ba0 |
+ if (tp->unregfunc && static_key_enabled(&tp->key))
|
|
Matt Fleming |
668ba0 |
tp->unregfunc();
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
- if (tp->dynamic && (atomic_read(&tp->key.enabled) > 0))
|
|
Matt Fleming |
668ba0 |
- atomic_dec(&tp->key.enabled);
|
|
Matt Fleming |
668ba0 |
- else if (!tp->dynamic && static_key_enabled(&tp->key))
|
|
Matt Fleming |
668ba0 |
+ if (static_key_enabled(&tp->key))
|
|
Matt Fleming |
668ba0 |
static_key_slow_dec(&tp->key);
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
rcu_assign_pointer(tp->funcs, tp_funcs);
|
|
Matt Fleming |
668ba0 |
@@ -266,7 +258,7 @@ static int tracepoint_remove_func(struct
|
|
Matt Fleming |
668ba0 |
}
|
|
Matt Fleming |
668ba0 |
|
|
Matt Fleming |
668ba0 |
/**
|
|
Matt Fleming |
668ba0 |
- * tracepoint_probe_register_prio - Connect a probe to a tracepoint
|
|
Matt Fleming |
668ba0 |
+ * tracepoint_probe_register - Connect a probe to a tracepoint
|
|
Matt Fleming |
668ba0 |
* @tp: tracepoint
|
|
Matt Fleming |
668ba0 |
* @probe: probe handler
|
|
Matt Fleming |
668ba0 |
* @data: tracepoint data
|