diff options
author | Steven Rostedt (VMware) <rostedt@goodmis.org> | 2019-04-01 22:30:22 -0400 |
---|---|---|
committer | Steven Rostedt (VMware) <rostedt@goodmis.org> | 2019-04-08 09:22:38 -0400 |
commit | d0cd871ba0d613e09366e4b6a17946dfcf51db7c (patch) | |
tree | 6970e5d1c74b3891706357533a95243a5a3edd7d | |
parent | 1e144d73f7295f766568c357448a11eb12868e29 (diff) |
tracing: Have histogram code pass around trace_array for error handling
Have the trace_array that associates the trace instance of the histogram
passed around to functions so that error handling can display the error
message in the proper instance.
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_events_hist.c | 142 |
1 files changed, 80 insertions, 62 deletions
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 071c62cacba7..a167e439e9a1 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c | |||
@@ -619,7 +619,7 @@ static void last_cmd_set(struct trace_event_file *file, char *str) | |||
619 | snprintf(last_cmd_loc, MAX_FILTER_STR_VAL, "hist:%s:%s", system, name); | 619 | snprintf(last_cmd_loc, MAX_FILTER_STR_VAL, "hist:%s:%s", system, name); |
620 | } | 620 | } |
621 | 621 | ||
622 | static void hist_err(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(last_cmd_loc, last_cmd, err_text, err_type, err_pos); |
625 | } | 625 | } |
@@ -1756,7 +1756,7 @@ static struct trace_event_file *find_var_file(struct trace_array *tr, | |||
1756 | 1756 | ||
1757 | if (find_var_field(var_hist_data, var_name)) { | 1757 | if (find_var_field(var_hist_data, var_name)) { |
1758 | if (found) { | 1758 | if (found) { |
1759 | hist_err(HIST_ERR_VAR_NOT_UNIQUE, errpos(var_name)); | 1759 | hist_err(tr, HIST_ERR_VAR_NOT_UNIQUE, errpos(var_name)); |
1760 | return NULL; | 1760 | return NULL; |
1761 | } | 1761 | } |
1762 | 1762 | ||
@@ -1807,7 +1807,8 @@ find_match_var(struct hist_trigger_data *hist_data, char *var_name) | |||
1807 | hist_field = find_file_var(file, var_name); | 1807 | hist_field = find_file_var(file, var_name); |
1808 | if (hist_field) { | 1808 | if (hist_field) { |
1809 | if (found) { | 1809 | if (found) { |
1810 | hist_err(HIST_ERR_VAR_NOT_UNIQUE, errpos(var_name)); | 1810 | hist_err(tr, HIST_ERR_VAR_NOT_UNIQUE, |
1811 | errpos(var_name)); | ||
1811 | return ERR_PTR(-EINVAL); | 1812 | return ERR_PTR(-EINVAL); |
1812 | } | 1813 | } |
1813 | 1814 | ||
@@ -2042,7 +2043,8 @@ static int parse_action(char *str, struct hist_trigger_attrs *attrs) | |||
2042 | return ret; | 2043 | return ret; |
2043 | } | 2044 | } |
2044 | 2045 | ||
2045 | static int parse_assignment(char *str, struct hist_trigger_attrs *attrs) | 2046 | static int parse_assignment(struct trace_array *tr, |
2047 | char *str, struct hist_trigger_attrs *attrs) | ||
2046 | { | 2048 | { |
2047 | int ret = 0; | 2049 | int ret = 0; |
2048 | 2050 | ||
@@ -2098,7 +2100,7 @@ static int parse_assignment(char *str, struct hist_trigger_attrs *attrs) | |||
2098 | char *assignment; | 2100 | char *assignment; |
2099 | 2101 | ||
2100 | if (attrs->n_assignments == TRACING_MAP_VARS_MAX) { | 2102 | if (attrs->n_assignments == TRACING_MAP_VARS_MAX) { |
2101 | hist_err(HIST_ERR_TOO_MANY_VARS, errpos(str)); | 2103 | hist_err(tr, HIST_ERR_TOO_MANY_VARS, errpos(str)); |
2102 | ret = -EINVAL; | 2104 | ret = -EINVAL; |
2103 | goto out; | 2105 | goto out; |
2104 | } | 2106 | } |
@@ -2115,7 +2117,8 @@ static int parse_assignment(char *str, struct hist_trigger_attrs *attrs) | |||
2115 | return ret; | 2117 | return ret; |
2116 | } | 2118 | } |
2117 | 2119 | ||
2118 | static struct hist_trigger_attrs *parse_hist_trigger_attrs(char *trigger_str) | 2120 | static struct hist_trigger_attrs * |
2121 | parse_hist_trigger_attrs(struct trace_array *tr, char *trigger_str) | ||
2119 | { | 2122 | { |
2120 | struct hist_trigger_attrs *attrs; | 2123 | struct hist_trigger_attrs *attrs; |
2121 | int ret = 0; | 2124 | int ret = 0; |
@@ -2128,7 +2131,7 @@ static struct hist_trigger_attrs *parse_hist_trigger_attrs(char *trigger_str) | |||
2128 | char *str = strsep(&trigger_str, ":"); | 2131 | char *str = strsep(&trigger_str, ":"); |
2129 | 2132 | ||
2130 | if (strchr(str, '=')) { | 2133 | if (strchr(str, '=')) { |
2131 | ret = parse_assignment(str, attrs); | 2134 | ret = parse_assignment(tr, str, attrs); |
2132 | if (ret) | 2135 | if (ret) |
2133 | goto free; | 2136 | goto free; |
2134 | } else if (strcmp(str, "pause") == 0) | 2137 | } else if (strcmp(str, "pause") == 0) |
@@ -2684,6 +2687,7 @@ static struct hist_field *parse_var_ref(struct hist_trigger_data *hist_data, | |||
2684 | char *var_name) | 2687 | char *var_name) |
2685 | { | 2688 | { |
2686 | struct hist_field *var_field = NULL, *ref_field = NULL; | 2689 | struct hist_field *var_field = NULL, *ref_field = NULL; |
2690 | struct trace_array *tr = hist_data->event_file->tr; | ||
2687 | 2691 | ||
2688 | if (!is_var_ref(var_name)) | 2692 | if (!is_var_ref(var_name)) |
2689 | return NULL; | 2693 | return NULL; |
@@ -2696,7 +2700,7 @@ static struct hist_field *parse_var_ref(struct hist_trigger_data *hist_data, | |||
2696 | system, event_name); | 2700 | system, event_name); |
2697 | 2701 | ||
2698 | if (!ref_field) | 2702 | if (!ref_field) |
2699 | hist_err(HIST_ERR_VAR_NOT_FOUND, errpos(var_name)); | 2703 | hist_err(tr, HIST_ERR_VAR_NOT_FOUND, errpos(var_name)); |
2700 | 2704 | ||
2701 | return ref_field; | 2705 | return ref_field; |
2702 | } | 2706 | } |
@@ -2707,6 +2711,7 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, | |||
2707 | { | 2711 | { |
2708 | struct ftrace_event_field *field = NULL; | 2712 | struct ftrace_event_field *field = NULL; |
2709 | char *field_name, *modifier, *str; | 2713 | char *field_name, *modifier, *str; |
2714 | struct trace_array *tr = file->tr; | ||
2710 | 2715 | ||
2711 | modifier = str = kstrdup(field_str, GFP_KERNEL); | 2716 | modifier = str = kstrdup(field_str, GFP_KERNEL); |
2712 | if (!modifier) | 2717 | if (!modifier) |
@@ -2730,7 +2735,7 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, | |||
2730 | else if (strcmp(modifier, "usecs") == 0) | 2735 | else if (strcmp(modifier, "usecs") == 0) |
2731 | *flags |= HIST_FIELD_FL_TIMESTAMP_USECS; | 2736 | *flags |= HIST_FIELD_FL_TIMESTAMP_USECS; |
2732 | else { | 2737 | else { |
2733 | hist_err(HIST_ERR_BAD_FIELD_MODIFIER, errpos(modifier)); | 2738 | hist_err(tr, HIST_ERR_BAD_FIELD_MODIFIER, errpos(modifier)); |
2734 | field = ERR_PTR(-EINVAL); | 2739 | field = ERR_PTR(-EINVAL); |
2735 | goto out; | 2740 | goto out; |
2736 | } | 2741 | } |
@@ -2746,7 +2751,7 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, | |||
2746 | else { | 2751 | else { |
2747 | field = trace_find_event_field(file->event_call, field_name); | 2752 | field = trace_find_event_field(file->event_call, field_name); |
2748 | if (!field || !field->size) { | 2753 | if (!field || !field->size) { |
2749 | hist_err(HIST_ERR_FIELD_NOT_FOUND, errpos(field_name)); | 2754 | hist_err(tr, HIST_ERR_FIELD_NOT_FOUND, errpos(field_name)); |
2750 | field = ERR_PTR(-EINVAL); | 2755 | field = ERR_PTR(-EINVAL); |
2751 | goto out; | 2756 | goto out; |
2752 | } | 2757 | } |
@@ -2808,7 +2813,8 @@ static struct hist_field *parse_atom(struct hist_trigger_data *hist_data, | |||
2808 | 2813 | ||
2809 | s = local_field_var_ref(hist_data, ref_system, ref_event, ref_var); | 2814 | s = local_field_var_ref(hist_data, ref_system, ref_event, ref_var); |
2810 | if (!s) { | 2815 | if (!s) { |
2811 | hist_field = parse_var_ref(hist_data, ref_system, ref_event, ref_var); | 2816 | hist_field = parse_var_ref(hist_data, ref_system, |
2817 | ref_event, ref_var); | ||
2812 | if (hist_field) { | 2818 | if (hist_field) { |
2813 | if (var_name) { | 2819 | if (var_name) { |
2814 | hist_field = create_alias(hist_data, hist_field, var_name); | 2820 | hist_field = create_alias(hist_data, hist_field, var_name); |
@@ -2857,7 +2863,7 @@ static struct hist_field *parse_unary(struct hist_trigger_data *hist_data, | |||
2857 | /* we support only -(xxx) i.e. explicit parens required */ | 2863 | /* we support only -(xxx) i.e. explicit parens required */ |
2858 | 2864 | ||
2859 | if (level > 3) { | 2865 | if (level > 3) { |
2860 | hist_err(HIST_ERR_TOO_MANY_SUBEXPR, errpos(str)); | 2866 | hist_err(file->tr, HIST_ERR_TOO_MANY_SUBEXPR, errpos(str)); |
2861 | ret = -EINVAL; | 2867 | ret = -EINVAL; |
2862 | goto free; | 2868 | goto free; |
2863 | } | 2869 | } |
@@ -2912,7 +2918,8 @@ static struct hist_field *parse_unary(struct hist_trigger_data *hist_data, | |||
2912 | return ERR_PTR(ret); | 2918 | return ERR_PTR(ret); |
2913 | } | 2919 | } |
2914 | 2920 | ||
2915 | static int check_expr_operands(struct hist_field *operand1, | 2921 | static int check_expr_operands(struct trace_array *tr, |
2922 | struct hist_field *operand1, | ||
2916 | struct hist_field *operand2) | 2923 | struct hist_field *operand2) |
2917 | { | 2924 | { |
2918 | unsigned long operand1_flags = operand1->flags; | 2925 | unsigned long operand1_flags = operand1->flags; |
@@ -2940,7 +2947,7 @@ static int check_expr_operands(struct hist_field *operand1, | |||
2940 | 2947 | ||
2941 | if ((operand1_flags & HIST_FIELD_FL_TIMESTAMP_USECS) != | 2948 | if ((operand1_flags & HIST_FIELD_FL_TIMESTAMP_USECS) != |
2942 | (operand2_flags & HIST_FIELD_FL_TIMESTAMP_USECS)) { | 2949 | (operand2_flags & HIST_FIELD_FL_TIMESTAMP_USECS)) { |
2943 | hist_err(HIST_ERR_TIMESTAMP_MISMATCH, 0); | 2950 | hist_err(tr, HIST_ERR_TIMESTAMP_MISMATCH, 0); |
2944 | return -EINVAL; | 2951 | return -EINVAL; |
2945 | } | 2952 | } |
2946 | 2953 | ||
@@ -2958,7 +2965,7 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, | |||
2958 | char *sep, *operand1_str; | 2965 | char *sep, *operand1_str; |
2959 | 2966 | ||
2960 | if (level > 3) { | 2967 | if (level > 3) { |
2961 | hist_err(HIST_ERR_TOO_MANY_SUBEXPR, errpos(str)); | 2968 | hist_err(file->tr, HIST_ERR_TOO_MANY_SUBEXPR, errpos(str)); |
2962 | return ERR_PTR(-EINVAL); | 2969 | return ERR_PTR(-EINVAL); |
2963 | } | 2970 | } |
2964 | 2971 | ||
@@ -3003,7 +3010,7 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, | |||
3003 | goto free; | 3010 | goto free; |
3004 | } | 3011 | } |
3005 | 3012 | ||
3006 | ret = check_expr_operands(operand1, operand2); | 3013 | ret = check_expr_operands(file->tr, operand1, operand2); |
3007 | if (ret) | 3014 | if (ret) |
3008 | goto free; | 3015 | goto free; |
3009 | 3016 | ||
@@ -3196,14 +3203,14 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data, | |||
3196 | int ret; | 3203 | int ret; |
3197 | 3204 | ||
3198 | if (target_hist_data->n_field_var_hists >= SYNTH_FIELDS_MAX) { | 3205 | if (target_hist_data->n_field_var_hists >= SYNTH_FIELDS_MAX) { |
3199 | hist_err(HIST_ERR_TOO_MANY_FIELD_VARS, errpos(field_name)); | 3206 | hist_err(tr, HIST_ERR_TOO_MANY_FIELD_VARS, errpos(field_name)); |
3200 | return ERR_PTR(-EINVAL); | 3207 | return ERR_PTR(-EINVAL); |
3201 | } | 3208 | } |
3202 | 3209 | ||
3203 | file = event_file(tr, subsys_name, event_name); | 3210 | file = event_file(tr, subsys_name, event_name); |
3204 | 3211 | ||
3205 | if (IS_ERR(file)) { | 3212 | if (IS_ERR(file)) { |
3206 | hist_err(HIST_ERR_EVENT_FILE_NOT_FOUND, errpos(field_name)); | 3213 | hist_err(tr, HIST_ERR_EVENT_FILE_NOT_FOUND, errpos(field_name)); |
3207 | ret = PTR_ERR(file); | 3214 | ret = PTR_ERR(file); |
3208 | return ERR_PTR(ret); | 3215 | return ERR_PTR(ret); |
3209 | } | 3216 | } |
@@ -3216,7 +3223,7 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data, | |||
3216 | */ | 3223 | */ |
3217 | hist_data = find_compatible_hist(target_hist_data, file); | 3224 | hist_data = find_compatible_hist(target_hist_data, file); |
3218 | if (!hist_data) { | 3225 | if (!hist_data) { |
3219 | hist_err(HIST_ERR_HIST_NOT_FOUND, errpos(field_name)); | 3226 | hist_err(tr, HIST_ERR_HIST_NOT_FOUND, errpos(field_name)); |
3220 | return ERR_PTR(-EINVAL); | 3227 | return ERR_PTR(-EINVAL); |
3221 | } | 3228 | } |
3222 | 3229 | ||
@@ -3277,7 +3284,7 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data, | |||
3277 | kfree(cmd); | 3284 | kfree(cmd); |
3278 | kfree(var_hist->cmd); | 3285 | kfree(var_hist->cmd); |
3279 | kfree(var_hist); | 3286 | kfree(var_hist); |
3280 | hist_err(HIST_ERR_HIST_CREATE_FAIL, errpos(field_name)); | 3287 | hist_err(tr, HIST_ERR_HIST_CREATE_FAIL, errpos(field_name)); |
3281 | return ERR_PTR(ret); | 3288 | return ERR_PTR(ret); |
3282 | } | 3289 | } |
3283 | 3290 | ||
@@ -3289,7 +3296,7 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data, | |||
3289 | if (IS_ERR_OR_NULL(event_var)) { | 3296 | if (IS_ERR_OR_NULL(event_var)) { |
3290 | kfree(var_hist->cmd); | 3297 | kfree(var_hist->cmd); |
3291 | kfree(var_hist); | 3298 | kfree(var_hist); |
3292 | hist_err(HIST_ERR_SYNTH_VAR_NOT_FOUND, errpos(field_name)); | 3299 | hist_err(tr, HIST_ERR_SYNTH_VAR_NOT_FOUND, errpos(field_name)); |
3293 | return ERR_PTR(-EINVAL); | 3300 | return ERR_PTR(-EINVAL); |
3294 | } | 3301 | } |
3295 | 3302 | ||
@@ -3422,25 +3429,26 @@ static struct field_var *create_field_var(struct hist_trigger_data *hist_data, | |||
3422 | { | 3429 | { |
3423 | struct hist_field *val = NULL, *var = NULL; | 3430 | struct hist_field *val = NULL, *var = NULL; |
3424 | unsigned long flags = HIST_FIELD_FL_VAR; | 3431 | unsigned long flags = HIST_FIELD_FL_VAR; |
3432 | struct trace_array *tr = file->tr; | ||
3425 | struct field_var *field_var; | 3433 | struct field_var *field_var; |
3426 | int ret = 0; | 3434 | int ret = 0; |
3427 | 3435 | ||
3428 | if (hist_data->n_field_vars >= SYNTH_FIELDS_MAX) { | 3436 | if (hist_data->n_field_vars >= SYNTH_FIELDS_MAX) { |
3429 | hist_err(HIST_ERR_TOO_MANY_FIELD_VARS, errpos(field_name)); | 3437 | hist_err(tr, HIST_ERR_TOO_MANY_FIELD_VARS, errpos(field_name)); |
3430 | ret = -EINVAL; | 3438 | ret = -EINVAL; |
3431 | goto err; | 3439 | goto err; |
3432 | } | 3440 | } |
3433 | 3441 | ||
3434 | val = parse_atom(hist_data, file, field_name, &flags, NULL); | 3442 | val = parse_atom(hist_data, file, field_name, &flags, NULL); |
3435 | if (IS_ERR(val)) { | 3443 | if (IS_ERR(val)) { |
3436 | hist_err(HIST_ERR_FIELD_VAR_PARSE_FAIL, errpos(field_name)); | 3444 | hist_err(tr, HIST_ERR_FIELD_VAR_PARSE_FAIL, errpos(field_name)); |
3437 | ret = PTR_ERR(val); | 3445 | ret = PTR_ERR(val); |
3438 | goto err; | 3446 | goto err; |
3439 | } | 3447 | } |
3440 | 3448 | ||
3441 | var = create_var(hist_data, file, field_name, val->size, val->type); | 3449 | var = create_var(hist_data, file, field_name, val->size, val->type); |
3442 | if (IS_ERR(var)) { | 3450 | if (IS_ERR(var)) { |
3443 | hist_err(HIST_ERR_VAR_CREATE_FIND_FAIL, errpos(field_name)); | 3451 | hist_err(tr, HIST_ERR_VAR_CREATE_FIND_FAIL, errpos(field_name)); |
3444 | kfree(val); | 3452 | kfree(val); |
3445 | ret = PTR_ERR(var); | 3453 | ret = PTR_ERR(var); |
3446 | goto err; | 3454 | goto err; |
@@ -3767,19 +3775,20 @@ static int track_data_create(struct hist_trigger_data *hist_data, | |||
3767 | { | 3775 | { |
3768 | struct hist_field *var_field, *ref_field, *track_var = NULL; | 3776 | struct hist_field *var_field, *ref_field, *track_var = NULL; |
3769 | struct trace_event_file *file = hist_data->event_file; | 3777 | struct trace_event_file *file = hist_data->event_file; |
3778 | struct trace_array *tr = file->tr; | ||
3770 | char *track_data_var_str; | 3779 | char *track_data_var_str; |
3771 | int ret = 0; | 3780 | int ret = 0; |
3772 | 3781 | ||
3773 | track_data_var_str = data->track_data.var_str; | 3782 | track_data_var_str = data->track_data.var_str; |
3774 | if (track_data_var_str[0] != '$') { | 3783 | if (track_data_var_str[0] != '$') { |
3775 | hist_err(HIST_ERR_ONX_NOT_VAR, errpos(track_data_var_str)); | 3784 | hist_err(tr, HIST_ERR_ONX_NOT_VAR, errpos(track_data_var_str)); |
3776 | return -EINVAL; | 3785 | return -EINVAL; |
3777 | } | 3786 | } |
3778 | track_data_var_str++; | 3787 | track_data_var_str++; |
3779 | 3788 | ||
3780 | var_field = find_target_event_var(hist_data, NULL, NULL, track_data_var_str); | 3789 | var_field = find_target_event_var(hist_data, NULL, NULL, track_data_var_str); |
3781 | if (!var_field) { | 3790 | if (!var_field) { |
3782 | hist_err(HIST_ERR_ONX_VAR_NOT_FOUND, errpos(track_data_var_str)); | 3791 | hist_err(tr, HIST_ERR_ONX_VAR_NOT_FOUND, errpos(track_data_var_str)); |
3783 | return -EINVAL; | 3792 | return -EINVAL; |
3784 | } | 3793 | } |
3785 | 3794 | ||
@@ -3792,7 +3801,7 @@ static int track_data_create(struct hist_trigger_data *hist_data, | |||
3792 | if (data->handler == HANDLER_ONMAX) | 3801 | if (data->handler == HANDLER_ONMAX) |
3793 | track_var = create_var(hist_data, file, "__max", sizeof(u64), "u64"); | 3802 | track_var = create_var(hist_data, file, "__max", sizeof(u64), "u64"); |
3794 | if (IS_ERR(track_var)) { | 3803 | if (IS_ERR(track_var)) { |
3795 | hist_err(HIST_ERR_ONX_VAR_CREATE_FAIL, 0); | 3804 | hist_err(tr, HIST_ERR_ONX_VAR_CREATE_FAIL, 0); |
3796 | ret = PTR_ERR(track_var); | 3805 | ret = PTR_ERR(track_var); |
3797 | goto out; | 3806 | goto out; |
3798 | } | 3807 | } |
@@ -3800,7 +3809,7 @@ static int track_data_create(struct hist_trigger_data *hist_data, | |||
3800 | if (data->handler == HANDLER_ONCHANGE) | 3809 | if (data->handler == HANDLER_ONCHANGE) |
3801 | track_var = create_var(hist_data, file, "__change", sizeof(u64), "u64"); | 3810 | track_var = create_var(hist_data, file, "__change", sizeof(u64), "u64"); |
3802 | if (IS_ERR(track_var)) { | 3811 | if (IS_ERR(track_var)) { |
3803 | hist_err(HIST_ERR_ONX_VAR_CREATE_FAIL, 0); | 3812 | hist_err(tr, HIST_ERR_ONX_VAR_CREATE_FAIL, 0); |
3804 | ret = PTR_ERR(track_var); | 3813 | ret = PTR_ERR(track_var); |
3805 | goto out; | 3814 | goto out; |
3806 | } | 3815 | } |
@@ -3811,7 +3820,8 @@ static int track_data_create(struct hist_trigger_data *hist_data, | |||
3811 | return ret; | 3820 | return ret; |
3812 | } | 3821 | } |
3813 | 3822 | ||
3814 | static int parse_action_params(char *params, struct action_data *data) | 3823 | static int parse_action_params(struct trace_array *tr, char *params, |
3824 | struct action_data *data) | ||
3815 | { | 3825 | { |
3816 | char *param, *saved_param; | 3826 | char *param, *saved_param; |
3817 | bool first_param = true; | 3827 | bool first_param = true; |
@@ -3819,20 +3829,20 @@ static int parse_action_params(char *params, struct action_data *data) | |||
3819 | 3829 | ||
3820 | while (params) { | 3830 | while (params) { |
3821 | if (data->n_params >= SYNTH_FIELDS_MAX) { | 3831 | if (data->n_params >= SYNTH_FIELDS_MAX) { |
3822 | hist_err(HIST_ERR_TOO_MANY_PARAMS, 0); | 3832 | hist_err(tr, HIST_ERR_TOO_MANY_PARAMS, 0); |
3823 | goto out; | 3833 | goto out; |
3824 | } | 3834 | } |
3825 | 3835 | ||
3826 | param = strsep(¶ms, ","); | 3836 | param = strsep(¶ms, ","); |
3827 | if (!param) { | 3837 | if (!param) { |
3828 | hist_err(HIST_ERR_PARAM_NOT_FOUND, 0); | 3838 | hist_err(tr, HIST_ERR_PARAM_NOT_FOUND, 0); |
3829 | ret = -EINVAL; | 3839 | ret = -EINVAL; |
3830 | goto out; | 3840 | goto out; |
3831 | } | 3841 | } |
3832 | 3842 | ||
3833 | param = strstrip(param); | 3843 | param = strstrip(param); |
3834 | if (strlen(param) < 2) { | 3844 | if (strlen(param) < 2) { |
3835 | hist_err(HIST_ERR_INVALID_PARAM, errpos(param)); | 3845 | hist_err(tr, HIST_ERR_INVALID_PARAM, errpos(param)); |
3836 | ret = -EINVAL; | 3846 | ret = -EINVAL; |
3837 | goto out; | 3847 | goto out; |
3838 | } | 3848 | } |
@@ -3856,7 +3866,7 @@ static int parse_action_params(char *params, struct action_data *data) | |||
3856 | return ret; | 3866 | return ret; |
3857 | } | 3867 | } |
3858 | 3868 | ||
3859 | static int action_parse(char *str, struct action_data *data, | 3869 | static int action_parse(struct trace_array *tr, char *str, struct action_data *data, |
3860 | enum handler_id handler) | 3870 | enum handler_id handler) |
3861 | { | 3871 | { |
3862 | char *action_name; | 3872 | char *action_name; |
@@ -3864,14 +3874,14 @@ static int action_parse(char *str, struct action_data *data, | |||
3864 | 3874 | ||
3865 | strsep(&str, "."); | 3875 | strsep(&str, "."); |
3866 | if (!str) { | 3876 | if (!str) { |
3867 | hist_err(HIST_ERR_ACTION_NOT_FOUND, 0); | 3877 | hist_err(tr, HIST_ERR_ACTION_NOT_FOUND, 0); |
3868 | ret = -EINVAL; | 3878 | ret = -EINVAL; |
3869 | goto out; | 3879 | goto out; |
3870 | } | 3880 | } |
3871 | 3881 | ||
3872 | action_name = strsep(&str, "("); | 3882 | action_name = strsep(&str, "("); |
3873 | if (!action_name || !str) { | 3883 | if (!action_name || !str) { |
3874 | hist_err(HIST_ERR_ACTION_NOT_FOUND, 0); | 3884 | hist_err(tr, HIST_ERR_ACTION_NOT_FOUND, 0); |
3875 | ret = -EINVAL; | 3885 | ret = -EINVAL; |
3876 | goto out; | 3886 | goto out; |
3877 | } | 3887 | } |
@@ -3880,12 +3890,12 @@ static int action_parse(char *str, struct action_data *data, | |||
3880 | char *params = strsep(&str, ")"); | 3890 | char *params = strsep(&str, ")"); |
3881 | 3891 | ||
3882 | if (!params) { | 3892 | if (!params) { |
3883 | hist_err(HIST_ERR_NO_SAVE_PARAMS, 0); | 3893 | hist_err(tr, HIST_ERR_NO_SAVE_PARAMS, 0); |
3884 | ret = -EINVAL; | 3894 | ret = -EINVAL; |
3885 | goto out; | 3895 | goto out; |
3886 | } | 3896 | } |
3887 | 3897 | ||
3888 | ret = parse_action_params(params, data); | 3898 | ret = parse_action_params(tr, params, data); |
3889 | if (ret) | 3899 | if (ret) |
3890 | goto out; | 3900 | goto out; |
3891 | 3901 | ||
@@ -3894,7 +3904,7 @@ static int action_parse(char *str, struct action_data *data, | |||
3894 | else if (handler == HANDLER_ONCHANGE) | 3904 | else if (handler == HANDLER_ONCHANGE) |
3895 | data->track_data.check_val = check_track_val_changed; | 3905 | data->track_data.check_val = check_track_val_changed; |
3896 | else { | 3906 | else { |
3897 | hist_err(HIST_ERR_ACTION_MISMATCH, errpos(action_name)); | 3907 | hist_err(tr, HIST_ERR_ACTION_MISMATCH, errpos(action_name)); |
3898 | ret = -EINVAL; | 3908 | ret = -EINVAL; |
3899 | goto out; | 3909 | goto out; |
3900 | } | 3910 | } |
@@ -3906,7 +3916,7 @@ static int action_parse(char *str, struct action_data *data, | |||
3906 | char *params = strsep(&str, ")"); | 3916 | char *params = strsep(&str, ")"); |
3907 | 3917 | ||
3908 | if (!str) { | 3918 | if (!str) { |
3909 | hist_err(HIST_ERR_NO_CLOSING_PAREN, errpos(params)); | 3919 | hist_err(tr, HIST_ERR_NO_CLOSING_PAREN, errpos(params)); |
3910 | ret = -EINVAL; | 3920 | ret = -EINVAL; |
3911 | goto out; | 3921 | goto out; |
3912 | } | 3922 | } |
@@ -3916,7 +3926,7 @@ static int action_parse(char *str, struct action_data *data, | |||
3916 | else if (handler == HANDLER_ONCHANGE) | 3926 | else if (handler == HANDLER_ONCHANGE) |
3917 | data->track_data.check_val = check_track_val_changed; | 3927 | data->track_data.check_val = check_track_val_changed; |
3918 | else { | 3928 | else { |
3919 | hist_err(HIST_ERR_ACTION_MISMATCH, errpos(action_name)); | 3929 | hist_err(tr, HIST_ERR_ACTION_MISMATCH, errpos(action_name)); |
3920 | ret = -EINVAL; | 3930 | ret = -EINVAL; |
3921 | goto out; | 3931 | goto out; |
3922 | } | 3932 | } |
@@ -3931,7 +3941,7 @@ static int action_parse(char *str, struct action_data *data, | |||
3931 | data->use_trace_keyword = true; | 3941 | data->use_trace_keyword = true; |
3932 | 3942 | ||
3933 | if (params) { | 3943 | if (params) { |
3934 | ret = parse_action_params(params, data); | 3944 | ret = parse_action_params(tr, params, data); |
3935 | if (ret) | 3945 | if (ret) |
3936 | goto out; | 3946 | goto out; |
3937 | } | 3947 | } |
@@ -3984,7 +3994,7 @@ static struct action_data *track_data_parse(struct hist_trigger_data *hist_data, | |||
3984 | goto free; | 3994 | goto free; |
3985 | } | 3995 | } |
3986 | 3996 | ||
3987 | ret = action_parse(str, data, handler); | 3997 | ret = action_parse(hist_data->event_file->tr, str, data, handler); |
3988 | if (ret) | 3998 | if (ret) |
3989 | goto free; | 3999 | goto free; |
3990 | out: | 4000 | out: |
@@ -4054,6 +4064,7 @@ trace_action_find_var(struct hist_trigger_data *hist_data, | |||
4054 | struct action_data *data, | 4064 | struct action_data *data, |
4055 | char *system, char *event, char *var) | 4065 | char *system, char *event, char *var) |
4056 | { | 4066 | { |
4067 | struct trace_array *tr = hist_data->event_file->tr; | ||
4057 | struct hist_field *hist_field; | 4068 | struct hist_field *hist_field; |
4058 | 4069 | ||
4059 | var++; /* skip '$' */ | 4070 | var++; /* skip '$' */ |
@@ -4069,7 +4080,7 @@ trace_action_find_var(struct hist_trigger_data *hist_data, | |||
4069 | } | 4080 | } |
4070 | 4081 | ||
4071 | if (!hist_field) | 4082 | if (!hist_field) |
4072 | hist_err(HIST_ERR_PARAM_NOT_FOUND, errpos(var)); | 4083 | hist_err(tr, HIST_ERR_PARAM_NOT_FOUND, errpos(var)); |
4073 | 4084 | ||
4074 | return hist_field; | 4085 | return hist_field; |
4075 | } | 4086 | } |
@@ -4127,6 +4138,7 @@ trace_action_create_field_var(struct hist_trigger_data *hist_data, | |||
4127 | static int trace_action_create(struct hist_trigger_data *hist_data, | 4138 | static int trace_action_create(struct hist_trigger_data *hist_data, |
4128 | struct action_data *data) | 4139 | struct action_data *data) |
4129 | { | 4140 | { |
4141 | struct trace_array *tr = hist_data->event_file->tr; | ||
4130 | char *event_name, *param, *system = NULL; | 4142 | char *event_name, *param, *system = NULL; |
4131 | struct hist_field *hist_field, *var_ref; | 4143 | struct hist_field *hist_field, *var_ref; |
4132 | unsigned int i, var_ref_idx; | 4144 | unsigned int i, var_ref_idx; |
@@ -4144,7 +4156,7 @@ static int trace_action_create(struct hist_trigger_data *hist_data, | |||
4144 | 4156 | ||
4145 | event = find_synth_event(synth_event_name); | 4157 | event = find_synth_event(synth_event_name); |
4146 | if (!event) { | 4158 | if (!event) { |
4147 | hist_err(HIST_ERR_SYNTH_EVENT_NOT_FOUND, errpos(synth_event_name)); | 4159 | hist_err(tr, HIST_ERR_SYNTH_EVENT_NOT_FOUND, errpos(synth_event_name)); |
4148 | return -EINVAL; | 4160 | return -EINVAL; |
4149 | } | 4161 | } |
4150 | 4162 | ||
@@ -4205,14 +4217,14 @@ static int trace_action_create(struct hist_trigger_data *hist_data, | |||
4205 | continue; | 4217 | continue; |
4206 | } | 4218 | } |
4207 | 4219 | ||
4208 | hist_err(HIST_ERR_SYNTH_TYPE_MISMATCH, errpos(param)); | 4220 | hist_err(tr, HIST_ERR_SYNTH_TYPE_MISMATCH, errpos(param)); |
4209 | kfree(p); | 4221 | kfree(p); |
4210 | ret = -EINVAL; | 4222 | ret = -EINVAL; |
4211 | goto err; | 4223 | goto err; |
4212 | } | 4224 | } |
4213 | 4225 | ||
4214 | if (field_pos != event->n_fields) { | 4226 | if (field_pos != event->n_fields) { |
4215 | hist_err(HIST_ERR_SYNTH_COUNT_MISMATCH, errpos(event->name)); | 4227 | hist_err(tr, HIST_ERR_SYNTH_COUNT_MISMATCH, errpos(event->name)); |
4216 | ret = -EINVAL; | 4228 | ret = -EINVAL; |
4217 | goto err; | 4229 | goto err; |
4218 | } | 4230 | } |
@@ -4231,6 +4243,7 @@ static int action_create(struct hist_trigger_data *hist_data, | |||
4231 | struct action_data *data) | 4243 | struct action_data *data) |
4232 | { | 4244 | { |
4233 | struct trace_event_file *file = hist_data->event_file; | 4245 | struct trace_event_file *file = hist_data->event_file; |
4246 | struct trace_array *tr = file->tr; | ||
4234 | struct track_data *track_data; | 4247 | struct track_data *track_data; |
4235 | struct field_var *field_var; | 4248 | struct field_var *field_var; |
4236 | unsigned int i; | 4249 | unsigned int i; |
@@ -4258,7 +4271,7 @@ static int action_create(struct hist_trigger_data *hist_data, | |||
4258 | if (data->action == ACTION_SAVE) { | 4271 | if (data->action == ACTION_SAVE) { |
4259 | if (hist_data->n_save_vars) { | 4272 | if (hist_data->n_save_vars) { |
4260 | ret = -EEXIST; | 4273 | ret = -EEXIST; |
4261 | hist_err(HIST_ERR_TOO_MANY_SAVE_ACTIONS, 0); | 4274 | hist_err(tr, HIST_ERR_TOO_MANY_SAVE_ACTIONS, 0); |
4262 | goto out; | 4275 | goto out; |
4263 | } | 4276 | } |
4264 | 4277 | ||
@@ -4271,7 +4284,8 @@ static int action_create(struct hist_trigger_data *hist_data, | |||
4271 | 4284 | ||
4272 | field_var = create_target_field_var(hist_data, NULL, NULL, param); | 4285 | field_var = create_target_field_var(hist_data, NULL, NULL, param); |
4273 | if (IS_ERR(field_var)) { | 4286 | if (IS_ERR(field_var)) { |
4274 | hist_err(HIST_ERR_FIELD_VAR_CREATE_FAIL, errpos(param)); | 4287 | hist_err(tr, HIST_ERR_FIELD_VAR_CREATE_FAIL, |
4288 | errpos(param)); | ||
4275 | ret = PTR_ERR(field_var); | 4289 | ret = PTR_ERR(field_var); |
4276 | kfree(param); | 4290 | kfree(param); |
4277 | goto out; | 4291 | goto out; |
@@ -4305,18 +4319,18 @@ static struct action_data *onmatch_parse(struct trace_array *tr, char *str) | |||
4305 | 4319 | ||
4306 | match_event = strsep(&str, ")"); | 4320 | match_event = strsep(&str, ")"); |
4307 | if (!match_event || !str) { | 4321 | if (!match_event || !str) { |
4308 | hist_err(HIST_ERR_NO_CLOSING_PAREN, errpos(match_event)); | 4322 | hist_err(tr, HIST_ERR_NO_CLOSING_PAREN, errpos(match_event)); |
4309 | goto free; | 4323 | goto free; |
4310 | } | 4324 | } |
4311 | 4325 | ||
4312 | match_event_system = strsep(&match_event, "."); | 4326 | match_event_system = strsep(&match_event, "."); |
4313 | if (!match_event) { | 4327 | if (!match_event) { |
4314 | hist_err(HIST_ERR_SUBSYS_NOT_FOUND, errpos(match_event_system)); | 4328 | hist_err(tr, HIST_ERR_SUBSYS_NOT_FOUND, errpos(match_event_system)); |
4315 | goto free; | 4329 | goto free; |
4316 | } | 4330 | } |
4317 | 4331 | ||
4318 | if (IS_ERR(event_file(tr, match_event_system, match_event))) { | 4332 | if (IS_ERR(event_file(tr, match_event_system, match_event))) { |
4319 | hist_err(HIST_ERR_INVALID_SUBSYS_EVENT, errpos(match_event)); | 4333 | hist_err(tr, HIST_ERR_INVALID_SUBSYS_EVENT, errpos(match_event)); |
4320 | goto free; | 4334 | goto free; |
4321 | } | 4335 | } |
4322 | 4336 | ||
@@ -4332,7 +4346,7 @@ static struct action_data *onmatch_parse(struct trace_array *tr, char *str) | |||
4332 | goto free; | 4346 | goto free; |
4333 | } | 4347 | } |
4334 | 4348 | ||
4335 | ret = action_parse(str, data, HANDLER_ONMATCH); | 4349 | ret = action_parse(tr, str, data, HANDLER_ONMATCH); |
4336 | if (ret) | 4350 | if (ret) |
4337 | goto free; | 4351 | goto free; |
4338 | out: | 4352 | out: |
@@ -4401,13 +4415,14 @@ static int create_var_field(struct hist_trigger_data *hist_data, | |||
4401 | struct trace_event_file *file, | 4415 | struct trace_event_file *file, |
4402 | char *var_name, char *expr_str) | 4416 | char *var_name, char *expr_str) |
4403 | { | 4417 | { |
4418 | struct trace_array *tr = hist_data->event_file->tr; | ||
4404 | unsigned long flags = 0; | 4419 | unsigned long flags = 0; |
4405 | 4420 | ||
4406 | if (WARN_ON(val_idx >= TRACING_MAP_VALS_MAX + TRACING_MAP_VARS_MAX)) | 4421 | if (WARN_ON(val_idx >= TRACING_MAP_VALS_MAX + TRACING_MAP_VARS_MAX)) |
4407 | return -EINVAL; | 4422 | return -EINVAL; |
4408 | 4423 | ||
4409 | if (find_var(hist_data, file, var_name) && !hist_data->remove) { | 4424 | if (find_var(hist_data, file, var_name) && !hist_data->remove) { |
4410 | hist_err(HIST_ERR_DUPLICATE_VAR, errpos(var_name)); | 4425 | hist_err(tr, HIST_ERR_DUPLICATE_VAR, errpos(var_name)); |
4411 | return -EINVAL; | 4426 | return -EINVAL; |
4412 | } | 4427 | } |
4413 | 4428 | ||
@@ -4464,8 +4479,8 @@ static int create_key_field(struct hist_trigger_data *hist_data, | |||
4464 | struct trace_event_file *file, | 4479 | struct trace_event_file *file, |
4465 | char *field_str) | 4480 | char *field_str) |
4466 | { | 4481 | { |
4482 | struct trace_array *tr = hist_data->event_file->tr; | ||
4467 | struct hist_field *hist_field = NULL; | 4483 | struct hist_field *hist_field = NULL; |
4468 | |||
4469 | unsigned long flags = 0; | 4484 | unsigned long flags = 0; |
4470 | unsigned int key_size; | 4485 | unsigned int key_size; |
4471 | int ret = 0; | 4486 | int ret = 0; |
@@ -4488,7 +4503,7 @@ static int create_key_field(struct hist_trigger_data *hist_data, | |||
4488 | } | 4503 | } |
4489 | 4504 | ||
4490 | if (hist_field->flags & HIST_FIELD_FL_VAR_REF) { | 4505 | if (hist_field->flags & HIST_FIELD_FL_VAR_REF) { |
4491 | hist_err(HIST_ERR_INVALID_REF_KEY, errpos(field_str)); | 4506 | hist_err(tr, HIST_ERR_INVALID_REF_KEY, errpos(field_str)); |
4492 | destroy_hist_field(hist_field, 0); | 4507 | destroy_hist_field(hist_field, 0); |
4493 | ret = -EINVAL; | 4508 | ret = -EINVAL; |
4494 | goto out; | 4509 | goto out; |
@@ -4589,6 +4604,7 @@ static void free_var_defs(struct hist_trigger_data *hist_data) | |||
4589 | 4604 | ||
4590 | static int parse_var_defs(struct hist_trigger_data *hist_data) | 4605 | static int parse_var_defs(struct hist_trigger_data *hist_data) |
4591 | { | 4606 | { |
4607 | struct trace_array *tr = hist_data->event_file->tr; | ||
4592 | char *s, *str, *var_name, *field_str; | 4608 | char *s, *str, *var_name, *field_str; |
4593 | unsigned int i, j, n_vars = 0; | 4609 | unsigned int i, j, n_vars = 0; |
4594 | int ret = 0; | 4610 | int ret = 0; |
@@ -4602,13 +4618,14 @@ static int parse_var_defs(struct hist_trigger_data *hist_data) | |||
4602 | 4618 | ||
4603 | var_name = strsep(&field_str, "="); | 4619 | var_name = strsep(&field_str, "="); |
4604 | if (!var_name || !field_str) { | 4620 | if (!var_name || !field_str) { |
4605 | hist_err(HIST_ERR_MALFORMED_ASSIGNMENT, errpos(var_name)); | 4621 | hist_err(tr, HIST_ERR_MALFORMED_ASSIGNMENT, |
4622 | errpos(var_name)); | ||
4606 | ret = -EINVAL; | 4623 | ret = -EINVAL; |
4607 | goto free; | 4624 | goto free; |
4608 | } | 4625 | } |
4609 | 4626 | ||
4610 | if (n_vars == TRACING_MAP_VARS_MAX) { | 4627 | if (n_vars == TRACING_MAP_VARS_MAX) { |
4611 | hist_err(HIST_ERR_TOO_MANY_VARS, errpos(var_name)); | 4628 | hist_err(tr, HIST_ERR_TOO_MANY_VARS, errpos(var_name)); |
4612 | ret = -EINVAL; | 4629 | ret = -EINVAL; |
4613 | goto free; | 4630 | goto free; |
4614 | } | 4631 | } |
@@ -5829,6 +5846,7 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops, | |||
5829 | { | 5846 | { |
5830 | struct hist_trigger_data *hist_data = data->private_data; | 5847 | struct hist_trigger_data *hist_data = data->private_data; |
5831 | struct event_trigger_data *test, *named_data = NULL; | 5848 | struct event_trigger_data *test, *named_data = NULL; |
5849 | struct trace_array *tr = file->tr; | ||
5832 | int ret = 0; | 5850 | int ret = 0; |
5833 | 5851 | ||
5834 | if (hist_data->attrs->name) { | 5852 | if (hist_data->attrs->name) { |
@@ -5836,7 +5854,7 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops, | |||
5836 | if (named_data) { | 5854 | if (named_data) { |
5837 | if (!hist_trigger_match(data, named_data, named_data, | 5855 | if (!hist_trigger_match(data, named_data, named_data, |
5838 | true)) { | 5856 | true)) { |
5839 | hist_err(HIST_ERR_NAMED_MISMATCH, errpos(hist_data->attrs->name)); | 5857 | hist_err(tr, HIST_ERR_NAMED_MISMATCH, errpos(hist_data->attrs->name)); |
5840 | ret = -EINVAL; | 5858 | ret = -EINVAL; |
5841 | goto out; | 5859 | goto out; |
5842 | } | 5860 | } |
@@ -5857,7 +5875,7 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops, | |||
5857 | else if (hist_data->attrs->clear) | 5875 | else if (hist_data->attrs->clear) |
5858 | hist_clear(test); | 5876 | hist_clear(test); |
5859 | else { | 5877 | else { |
5860 | hist_err(HIST_ERR_TRIGGER_EEXIST, 0); | 5878 | hist_err(tr, HIST_ERR_TRIGGER_EEXIST, 0); |
5861 | ret = -EEXIST; | 5879 | ret = -EEXIST; |
5862 | } | 5880 | } |
5863 | goto out; | 5881 | goto out; |
@@ -5865,7 +5883,7 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops, | |||
5865 | } | 5883 | } |
5866 | new: | 5884 | new: |
5867 | if (hist_data->attrs->cont || hist_data->attrs->clear) { | 5885 | if (hist_data->attrs->cont || hist_data->attrs->clear) { |
5868 | hist_err(HIST_ERR_TRIGGER_ENOENT_CLEAR, 0); | 5886 | hist_err(tr, HIST_ERR_TRIGGER_ENOENT_CLEAR, 0); |
5869 | ret = -ENOENT; | 5887 | ret = -ENOENT; |
5870 | goto out; | 5888 | goto out; |
5871 | } | 5889 | } |
@@ -5890,7 +5908,7 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops, | |||
5890 | 5908 | ||
5891 | ret = tracing_set_clock(file->tr, hist_data->attrs->clock); | 5909 | ret = tracing_set_clock(file->tr, hist_data->attrs->clock); |
5892 | if (ret) { | 5910 | if (ret) { |
5893 | hist_err(HIST_ERR_SET_CLOCK_FAIL, errpos(clock)); | 5911 | hist_err(tr, HIST_ERR_SET_CLOCK_FAIL, errpos(clock)); |
5894 | goto out; | 5912 | goto out; |
5895 | } | 5913 | } |
5896 | 5914 | ||
@@ -6108,7 +6126,7 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, | |||
6108 | trigger = strstrip(trigger); | 6126 | trigger = strstrip(trigger); |
6109 | } | 6127 | } |
6110 | 6128 | ||
6111 | attrs = parse_hist_trigger_attrs(trigger); | 6129 | attrs = parse_hist_trigger_attrs(file->tr, trigger); |
6112 | if (IS_ERR(attrs)) | 6130 | if (IS_ERR(attrs)) |
6113 | return PTR_ERR(attrs); | 6131 | return PTR_ERR(attrs); |
6114 | 6132 | ||