diff options
author | Steven Rostedt (VMware) <rostedt@goodmis.org> | 2019-04-01 22:52:21 -0400 |
---|---|---|
committer | Steven Rostedt (VMware) <rostedt@goodmis.org> | 2019-04-08 09:22:44 -0400 |
commit | 2f754e771b1a6feba670782e82c45555984ac43b (patch) | |
tree | 61cc094e172790fadfa6c95768317a2aa4030666 | |
parent | d0cd871ba0d613e09366e4b6a17946dfcf51db7c (diff) |
tracing: Have the error logs show up in the proper instances
As each instance has their own error_log file, it makes more sense that the
instances show the errors of their own instead of all error_logs having the
same data. Make it that the errors show up in the instance error_log file
that the error happens in. If no instance trace_array is available, then
NULL can be passed in which will create the error in the top level instance
(the one at the top of the tracefs directory).
Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org>
Reviewed-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
-rw-r--r-- | kernel/trace/trace.c | 55 | ||||
-rw-r--r-- | kernel/trace/trace.h | 5 | ||||
-rw-r--r-- | kernel/trace/trace_events_filter.c | 4 | ||||
-rw-r--r-- | kernel/trace/trace_events_hist.c | 3 | ||||
-rw-r--r-- | kernel/trace/trace_probe.c | 2 |
5 files changed, 46 insertions, 23 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 7978168f5041..3d55e9daae8c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -6897,25 +6897,22 @@ struct tracing_log_err { | |||
6897 | char cmd[MAX_FILTER_STR_VAL]; /* what caused err */ | 6897 | char cmd[MAX_FILTER_STR_VAL]; /* what caused err */ |
6898 | }; | 6898 | }; |
6899 | 6899 | ||
6900 | static LIST_HEAD(tracing_err_log); | ||
6901 | static DEFINE_MUTEX(tracing_err_log_lock); | 6900 | static DEFINE_MUTEX(tracing_err_log_lock); |
6902 | 6901 | ||
6903 | static unsigned int n_tracing_err_log_entries; | 6902 | struct tracing_log_err *get_tracing_log_err(struct trace_array *tr) |
6904 | |||
6905 | struct tracing_log_err *get_tracing_log_err(void) | ||
6906 | { | 6903 | { |
6907 | struct tracing_log_err *err; | 6904 | struct tracing_log_err *err; |
6908 | 6905 | ||
6909 | if (n_tracing_err_log_entries < TRACING_LOG_ERRS_MAX) { | 6906 | if (tr->n_err_log_entries < TRACING_LOG_ERRS_MAX) { |
6910 | err = kzalloc(sizeof(*err), GFP_KERNEL); | 6907 | err = kzalloc(sizeof(*err), GFP_KERNEL); |
6911 | if (!err) | 6908 | if (!err) |
6912 | err = ERR_PTR(-ENOMEM); | 6909 | err = ERR_PTR(-ENOMEM); |
6913 | n_tracing_err_log_entries++; | 6910 | tr->n_err_log_entries++; |
6914 | 6911 | ||
6915 | return err; | 6912 | return err; |
6916 | } | 6913 | } |
6917 | 6914 | ||
6918 | err = list_first_entry(&tracing_err_log, struct tracing_log_err, list); | 6915 | err = list_first_entry(&tr->err_log, struct tracing_log_err, list); |
6919 | list_del(&err->list); | 6916 | list_del(&err->list); |
6920 | 6917 | ||
6921 | return err; | 6918 | return err; |
@@ -6949,6 +6946,7 @@ unsigned int err_pos(char *cmd, const char *str) | |||
6949 | 6946 | ||
6950 | /** | 6947 | /** |
6951 | * tracing_log_err - write an error to the tracing error log | 6948 | * tracing_log_err - write an error to the tracing error log |
6949 | * @tr: The associated trace array for the error (NULL for top level array) | ||
6952 | * @loc: A string describing where the error occurred | 6950 | * @loc: A string describing where the error occurred |
6953 | * @cmd: The tracing command that caused the error | 6951 | * @cmd: The tracing command that caused the error |
6954 | * @errs: The array of loc-specific static error strings | 6952 | * @errs: The array of loc-specific static error strings |
@@ -6973,13 +6971,17 @@ unsigned int err_pos(char *cmd, const char *str) | |||
6973 | * existing callers for examples of how static strings are typically | 6971 | * existing callers for examples of how static strings are typically |
6974 | * defined for use with tracing_log_err(). | 6972 | * defined for use with tracing_log_err(). |
6975 | */ | 6973 | */ |
6976 | void tracing_log_err(const char *loc, const char *cmd, | 6974 | void tracing_log_err(struct trace_array *tr, |
6975 | const char *loc, const char *cmd, | ||
6977 | const char **errs, u8 type, u8 pos) | 6976 | const char **errs, u8 type, u8 pos) |
6978 | { | 6977 | { |
6979 | struct tracing_log_err *err; | 6978 | struct tracing_log_err *err; |
6980 | 6979 | ||
6980 | if (!tr) | ||
6981 | tr = &global_trace; | ||
6982 | |||
6981 | mutex_lock(&tracing_err_log_lock); | 6983 | mutex_lock(&tracing_err_log_lock); |
6982 | err = get_tracing_log_err(); | 6984 | err = get_tracing_log_err(tr); |
6983 | if (PTR_ERR(err) == -ENOMEM) { | 6985 | if (PTR_ERR(err) == -ENOMEM) { |
6984 | mutex_unlock(&tracing_err_log_lock); | 6986 | mutex_unlock(&tracing_err_log_lock); |
6985 | return; | 6987 | return; |
@@ -6993,34 +6995,38 @@ void tracing_log_err(const char *loc, const char *cmd, | |||
6993 | err->info.pos = pos; | 6995 | err->info.pos = pos; |
6994 | err->info.ts = local_clock(); | 6996 | err->info.ts = local_clock(); |
6995 | 6997 | ||
6996 | list_add_tail(&err->list, &tracing_err_log); | 6998 | list_add_tail(&err->list, &tr->err_log); |
6997 | mutex_unlock(&tracing_err_log_lock); | 6999 | mutex_unlock(&tracing_err_log_lock); |
6998 | } | 7000 | } |
6999 | 7001 | ||
7000 | static void clear_tracing_err_log(void) | 7002 | static void clear_tracing_err_log(struct trace_array *tr) |
7001 | { | 7003 | { |
7002 | struct tracing_log_err *err, *next; | 7004 | struct tracing_log_err *err, *next; |
7003 | 7005 | ||
7004 | mutex_lock(&tracing_err_log_lock); | 7006 | mutex_lock(&tracing_err_log_lock); |
7005 | list_for_each_entry_safe(err, next, &tracing_err_log, list) { | 7007 | list_for_each_entry_safe(err, next, &tr->err_log, list) { |
7006 | list_del(&err->list); | 7008 | list_del(&err->list); |
7007 | kfree(err); | 7009 | kfree(err); |
7008 | } | 7010 | } |
7009 | 7011 | ||
7010 | n_tracing_err_log_entries = 0; | 7012 | tr->n_err_log_entries = 0; |
7011 | mutex_unlock(&tracing_err_log_lock); | 7013 | mutex_unlock(&tracing_err_log_lock); |
7012 | } | 7014 | } |
7013 | 7015 | ||
7014 | static void *tracing_err_log_seq_start(struct seq_file *m, loff_t *pos) | 7016 | static void *tracing_err_log_seq_start(struct seq_file *m, loff_t *pos) |
7015 | { | 7017 | { |
7018 | struct trace_array *tr = m->private; | ||
7019 | |||
7016 | mutex_lock(&tracing_err_log_lock); | 7020 | mutex_lock(&tracing_err_log_lock); |
7017 | 7021 | ||
7018 | return seq_list_start(&tracing_err_log, *pos); | 7022 | return seq_list_start(&tr->err_log, *pos); |
7019 | } | 7023 | } |
7020 | 7024 | ||
7021 | static void *tracing_err_log_seq_next(struct seq_file *m, void *v, loff_t *pos) | 7025 | static void *tracing_err_log_seq_next(struct seq_file *m, void *v, loff_t *pos) |
7022 | { | 7026 | { |
7023 | return seq_list_next(v, &tracing_err_log, pos); | 7027 | struct trace_array *tr = m->private; |
7028 | |||
7029 | return seq_list_next(v, &tr->err_log, pos); | ||
7024 | } | 7030 | } |
7025 | 7031 | ||
7026 | static void tracing_err_log_seq_stop(struct seq_file *m, void *v) | 7032 | static void tracing_err_log_seq_stop(struct seq_file *m, void *v) |
@@ -7067,15 +7073,25 @@ static const struct seq_operations tracing_err_log_seq_ops = { | |||
7067 | 7073 | ||
7068 | static int tracing_err_log_open(struct inode *inode, struct file *file) | 7074 | static int tracing_err_log_open(struct inode *inode, struct file *file) |
7069 | { | 7075 | { |
7076 | struct trace_array *tr = inode->i_private; | ||
7070 | int ret = 0; | 7077 | int ret = 0; |
7071 | 7078 | ||
7079 | if (trace_array_get(tr) < 0) | ||
7080 | return -ENODEV; | ||
7081 | |||
7072 | /* If this file was opened for write, then erase contents */ | 7082 | /* If this file was opened for write, then erase contents */ |
7073 | if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) | 7083 | if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) |
7074 | clear_tracing_err_log(); | 7084 | clear_tracing_err_log(tr); |
7075 | 7085 | ||
7076 | if (file->f_mode & FMODE_READ) | 7086 | if (file->f_mode & FMODE_READ) { |
7077 | ret = seq_open(file, &tracing_err_log_seq_ops); | 7087 | ret = seq_open(file, &tracing_err_log_seq_ops); |
7078 | 7088 | if (!ret) { | |
7089 | struct seq_file *m = file->private_data; | ||
7090 | m->private = tr; | ||
7091 | } else { | ||
7092 | trace_array_put(tr); | ||
7093 | } | ||
7094 | } | ||
7079 | return ret; | 7095 | return ret; |
7080 | } | 7096 | } |
7081 | 7097 | ||
@@ -7091,6 +7107,7 @@ static const struct file_operations tracing_err_log_fops = { | |||
7091 | .write = tracing_err_log_write, | 7107 | .write = tracing_err_log_write, |
7092 | .read = seq_read, | 7108 | .read = seq_read, |
7093 | .llseek = seq_lseek, | 7109 | .llseek = seq_lseek, |
7110 | .release = tracing_release_generic_tr, | ||
7094 | }; | 7111 | }; |
7095 | 7112 | ||
7096 | static int tracing_buffers_open(struct inode *inode, struct file *filp) | 7113 | static int tracing_buffers_open(struct inode *inode, struct file *filp) |
@@ -8293,6 +8310,7 @@ struct trace_array *trace_array_create(const char *name) | |||
8293 | INIT_LIST_HEAD(&tr->systems); | 8310 | INIT_LIST_HEAD(&tr->systems); |
8294 | INIT_LIST_HEAD(&tr->events); | 8311 | INIT_LIST_HEAD(&tr->events); |
8295 | INIT_LIST_HEAD(&tr->hist_vars); | 8312 | INIT_LIST_HEAD(&tr->hist_vars); |
8313 | INIT_LIST_HEAD(&tr->err_log); | ||
8296 | 8314 | ||
8297 | if (allocate_trace_buffers(tr, trace_buf_size) < 0) | 8315 | if (allocate_trace_buffers(tr, trace_buf_size) < 0) |
8298 | goto out_free_tr; | 8316 | goto out_free_tr; |
@@ -9087,6 +9105,7 @@ __init static int tracer_alloc_buffers(void) | |||
9087 | INIT_LIST_HEAD(&global_trace.systems); | 9105 | INIT_LIST_HEAD(&global_trace.systems); |
9088 | INIT_LIST_HEAD(&global_trace.events); | 9106 | INIT_LIST_HEAD(&global_trace.events); |
9089 | INIT_LIST_HEAD(&global_trace.hist_vars); | 9107 | INIT_LIST_HEAD(&global_trace.hist_vars); |
9108 | INIT_LIST_HEAD(&global_trace.err_log); | ||
9090 | list_add(&global_trace.list, &ftrace_trace_arrays); | 9109 | list_add(&global_trace.list, &ftrace_trace_arrays); |
9091 | 9110 | ||
9092 | apply_trace_boot_options(); | 9111 | apply_trace_boot_options(); |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 809c5d7f0064..da00a3d508c1 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -293,11 +293,13 @@ struct trace_array { | |||
293 | int nr_topts; | 293 | int nr_topts; |
294 | bool clear_trace; | 294 | bool clear_trace; |
295 | int buffer_percent; | 295 | int buffer_percent; |
296 | unsigned int n_err_log_entries; | ||
296 | struct tracer *current_trace; | 297 | struct tracer *current_trace; |
297 | unsigned int trace_flags; | 298 | unsigned int trace_flags; |
298 | unsigned char trace_flags_index[TRACE_FLAGS_MAX_SIZE]; | 299 | unsigned char trace_flags_index[TRACE_FLAGS_MAX_SIZE]; |
299 | unsigned int flags; | 300 | unsigned int flags; |
300 | raw_spinlock_t start_lock; | 301 | raw_spinlock_t start_lock; |
302 | struct list_head err_log; | ||
301 | struct dentry *dir; | 303 | struct dentry *dir; |
302 | struct dentry *options; | 304 | struct dentry *options; |
303 | struct dentry *percpu_dir; | 305 | struct dentry *percpu_dir; |
@@ -1886,7 +1888,8 @@ extern ssize_t trace_parse_run_command(struct file *file, | |||
1886 | int (*createfn)(int, char**)); | 1888 | int (*createfn)(int, char**)); |
1887 | 1889 | ||
1888 | extern unsigned int err_pos(char *cmd, const char *str); | 1890 | extern unsigned int err_pos(char *cmd, const char *str); |
1889 | extern void tracing_log_err(const char *loc, const char *cmd, | 1891 | extern void tracing_log_err(struct trace_array *tr, |
1892 | const char *loc, const char *cmd, | ||
1890 | const char **errs, u8 type, u8 pos); | 1893 | const char **errs, u8 type, u8 pos); |
1891 | 1894 | ||
1892 | /* | 1895 | /* |
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 2b63930cd3e6..180ecb390baa 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
@@ -949,12 +949,12 @@ static void append_filter_err(struct trace_array *tr, | |||
949 | if (pe->lasterr > 0) { | 949 | if (pe->lasterr > 0) { |
950 | trace_seq_printf(s, "\n%*s", pos, "^"); | 950 | trace_seq_printf(s, "\n%*s", pos, "^"); |
951 | trace_seq_printf(s, "\nparse_error: %s\n", err_text[pe->lasterr]); | 951 | trace_seq_printf(s, "\nparse_error: %s\n", err_text[pe->lasterr]); |
952 | tracing_log_err("event filter parse error", | 952 | tracing_log_err(tr, "event filter parse error", |
953 | filter->filter_string, err_text, | 953 | filter->filter_string, err_text, |
954 | pe->lasterr, pe->lasterr_pos); | 954 | pe->lasterr, pe->lasterr_pos); |
955 | } else { | 955 | } else { |
956 | trace_seq_printf(s, "\nError: (%d)\n", pe->lasterr); | 956 | trace_seq_printf(s, "\nError: (%d)\n", pe->lasterr); |
957 | tracing_log_err("event filter parse error", | 957 | tracing_log_err(tr, "event filter parse error", |
958 | filter->filter_string, err_text, | 958 | filter->filter_string, err_text, |
959 | FILT_ERR_ERRNO, 0); | 959 | FILT_ERR_ERRNO, 0); |
960 | } | 960 | } |
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index a167e439e9a1..a1136e043f17 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c | |||
@@ -621,7 +621,8 @@ static void last_cmd_set(struct trace_event_file *file, char *str) | |||
621 | 621 | ||
622 | static void hist_err(struct trace_array *tr, u8 err_type, u8 err_pos) | 622 | static void hist_err(struct trace_array *tr, u8 err_type, u8 err_pos) |
623 | { | 623 | { |
624 | tracing_log_err(last_cmd_loc, last_cmd, err_text, err_type, err_pos); | 624 | tracing_log_err(tr, last_cmd_loc, last_cmd, err_text, |
625 | err_type, err_pos); | ||
625 | } | 626 | } |
626 | 627 | ||
627 | static void hist_err_clear(void) | 628 | static void hist_err_clear(void) |
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index e11f98c49d72..4cc2d467d34c 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c | |||
@@ -186,7 +186,7 @@ void __trace_probe_log_err(int offset, int err_type) | |||
186 | } | 186 | } |
187 | *(p - 1) = '\0'; | 187 | *(p - 1) = '\0'; |
188 | 188 | ||
189 | tracing_log_err(trace_probe_log.subsystem, command, | 189 | tracing_log_err(NULL, trace_probe_log.subsystem, command, |
190 | trace_probe_err_text, err_type, pos + offset); | 190 | trace_probe_err_text, err_type, pos + offset); |
191 | 191 | ||
192 | kfree(command); | 192 | kfree(command); |