diff options
Diffstat (limited to 'kernel/trace/trace_events_hist.c')
| -rw-r--r-- | kernel/trace/trace_events_hist.c | 279 | 
1 files changed, 165 insertions, 114 deletions
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index a1d20421f4b0..ca6b0dff60c5 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -22,6 +22,57 @@  #define STR_VAR_LEN_MAX		32 /* must be multiple of sizeof(u64) */ +#define ERRORS								\ +	C(NONE,			"No error"),				\ +	C(DUPLICATE_VAR,	"Variable already defined"),		\ +	C(VAR_NOT_UNIQUE,	"Variable name not unique, need to use fully qualified name (subsys.event.var) for variable"), \ +	C(TOO_MANY_VARS,	"Too many variables defined"),		\ +	C(MALFORMED_ASSIGNMENT,	"Malformed assignment"),		\ +	C(NAMED_MISMATCH,	"Named hist trigger doesn't match existing named trigger (includes variables)"), \ +	C(TRIGGER_EEXIST,	"Hist trigger already exists"),		\ +	C(TRIGGER_ENOENT_CLEAR,	"Can't clear or continue a nonexistent hist trigger"), \ +	C(SET_CLOCK_FAIL,	"Couldn't set trace_clock"),		\ +	C(BAD_FIELD_MODIFIER,	"Invalid field modifier"),		\ +	C(TOO_MANY_SUBEXPR,	"Too many subexpressions (3 max)"),	\ +	C(TIMESTAMP_MISMATCH,	"Timestamp units in expression don't match"), \ +	C(TOO_MANY_FIELD_VARS,	"Too many field variables defined"),	\ +	C(EVENT_FILE_NOT_FOUND,	"Event file not found"),		\ +	C(HIST_NOT_FOUND,	"Matching event histogram not found"),	\ +	C(HIST_CREATE_FAIL,	"Couldn't create histogram for field"),	\ +	C(SYNTH_VAR_NOT_FOUND,	"Couldn't find synthetic variable"),	\ +	C(SYNTH_EVENT_NOT_FOUND,"Couldn't find synthetic event"),	\ +	C(SYNTH_TYPE_MISMATCH,	"Param type doesn't match synthetic event field type"), \ +	C(SYNTH_COUNT_MISMATCH,	"Param count doesn't match synthetic event field count"), \ +	C(FIELD_VAR_PARSE_FAIL,	"Couldn't parse field variable"),	\ +	C(VAR_CREATE_FIND_FAIL,	"Couldn't create or find variable"),	\ +	C(ONX_NOT_VAR,		"For onmax(x) or onchange(x), x must be a variable"), \ +	C(ONX_VAR_NOT_FOUND,	"Couldn't find onmax or onchange variable"), \ +	C(ONX_VAR_CREATE_FAIL,	"Couldn't create onmax or onchange variable"), \ +	C(FIELD_VAR_CREATE_FAIL,"Couldn't create field variable"),	\ +	C(TOO_MANY_PARAMS,	"Too many action params"),		\ +	C(PARAM_NOT_FOUND,	"Couldn't find param"),			\ +	C(INVALID_PARAM,	"Invalid action param"),		\ +	C(ACTION_NOT_FOUND,	"No action found"),			\ +	C(NO_SAVE_PARAMS,	"No params found for save()"),		\ +	C(TOO_MANY_SAVE_ACTIONS,"Can't have more than one save() action per hist"), \ +	C(ACTION_MISMATCH,	"Handler doesn't support action"),	\ +	C(NO_CLOSING_PAREN,	"No closing paren found"),		\ +	C(SUBSYS_NOT_FOUND,	"Missing subsystem"),			\ +	C(INVALID_SUBSYS_EVENT,	"Invalid subsystem or event name"),	\ +	C(INVALID_REF_KEY,	"Using variable references in keys not supported"), \ +	C(VAR_NOT_FOUND,	"Couldn't find variable"),		\ +	C(FIELD_NOT_FOUND,	"Couldn't find field"), + +#undef C +#define C(a, b)		HIST_ERR_##a + +enum { ERRORS }; + +#undef C +#define C(a, b)		b + +static const char *err_text[] = { ERRORS }; +  struct hist_field;  typedef u64 (*hist_field_fn_t) (struct hist_field *field, @@ -535,62 +586,49 @@ static struct track_data *track_data_alloc(unsigned int key_len,  	return data;  } -static char last_hist_cmd[MAX_FILTER_STR_VAL]; -static char hist_err_str[MAX_FILTER_STR_VAL]; +static char last_cmd[MAX_FILTER_STR_VAL]; +static char last_cmd_loc[MAX_FILTER_STR_VAL]; -static void last_cmd_set(char *str) +static int errpos(char *str)  { -	if (!str) -		return; - -	strncpy(last_hist_cmd, str, MAX_FILTER_STR_VAL - 1); +	return err_pos(last_cmd, str);  } -static void hist_err(char *str, char *var) +static void last_cmd_set(struct trace_event_file *file, char *str)  { -	int maxlen = MAX_FILTER_STR_VAL - 1; +	const char *system = NULL, *name = NULL; +	struct trace_event_call *call;  	if (!str)  		return; -	if (strlen(hist_err_str)) -		return; +	strncpy(last_cmd, str, MAX_FILTER_STR_VAL - 1); -	if (!var) -		var = ""; +	if (file) { +		call = file->event_call; -	if (strlen(hist_err_str) + strlen(str) + strlen(var) > maxlen) -		return; +		system = call->class->system; +		if (system) { +			name = trace_event_name(call); +			if (!name) +				system = NULL; +		} +	} -	strcat(hist_err_str, str); -	strcat(hist_err_str, var); +	if (system) +		snprintf(last_cmd_loc, MAX_FILTER_STR_VAL, "hist:%s:%s", system, name);  } -static void hist_err_event(char *str, char *system, char *event, char *var) +static void hist_err(struct trace_array *tr, u8 err_type, u8 err_pos)  { -	char err[MAX_FILTER_STR_VAL]; - -	if (system && var) -		snprintf(err, MAX_FILTER_STR_VAL, "%s.%s.%s", system, event, var); -	else if (system) -		snprintf(err, MAX_FILTER_STR_VAL, "%s.%s", system, event); -	else -		strscpy(err, var, MAX_FILTER_STR_VAL); - -	hist_err(str, err); +	tracing_log_err(tr, last_cmd_loc, last_cmd, err_text, +			err_type, err_pos);  }  static void hist_err_clear(void)  { -	hist_err_str[0] = '\0'; -} - -static bool have_hist_err(void) -{ -	if (strlen(hist_err_str)) -		return true; - -	return false; +	last_cmd[0] = '\0'; +	last_cmd_loc[0] = '\0';  }  struct synth_trace_event { @@ -1719,7 +1757,7 @@ static struct trace_event_file *find_var_file(struct trace_array *tr,  		if (find_var_field(var_hist_data, var_name)) {  			if (found) { -				hist_err_event("Variable name not unique, need to use fully qualified name (subsys.event.var) for variable: ", system, event_name, var_name); +				hist_err(tr, HIST_ERR_VAR_NOT_UNIQUE, errpos(var_name));  				return NULL;  			} @@ -1770,7 +1808,8 @@ find_match_var(struct hist_trigger_data *hist_data, char *var_name)  			hist_field = find_file_var(file, var_name);  			if (hist_field) {  				if (found) { -					hist_err_event("Variable name not unique, need to use fully qualified name (subsys.event.var) for variable: ", system, event_name, var_name); +					hist_err(tr, HIST_ERR_VAR_NOT_UNIQUE, +						 errpos(var_name));  					return ERR_PTR(-EINVAL);  				} @@ -1815,6 +1854,9 @@ static u64 hist_field_var_ref(struct hist_field *hist_field,  	struct hist_elt_data *elt_data;  	u64 var_val = 0; +	if (WARN_ON_ONCE(!elt)) +		return var_val; +  	elt_data = elt->private_data;  	var_val = elt_data->var_ref_vals[hist_field->var_ref_idx]; @@ -2002,11 +2044,11 @@ static int parse_action(char *str, struct hist_trigger_attrs *attrs)  		attrs->n_actions++;  		ret = 0;  	} -  	return ret;  } -static int parse_assignment(char *str, struct hist_trigger_attrs *attrs) +static int parse_assignment(struct trace_array *tr, +			    char *str, struct hist_trigger_attrs *attrs)  {  	int ret = 0; @@ -2062,7 +2104,7 @@ static int parse_assignment(char *str, struct hist_trigger_attrs *attrs)  		char *assignment;  		if (attrs->n_assignments == TRACING_MAP_VARS_MAX) { -			hist_err("Too many variables defined: ", str); +			hist_err(tr, HIST_ERR_TOO_MANY_VARS, errpos(str));  			ret = -EINVAL;  			goto out;  		} @@ -2079,7 +2121,8 @@ static int parse_assignment(char *str, struct hist_trigger_attrs *attrs)  	return ret;  } -static struct hist_trigger_attrs *parse_hist_trigger_attrs(char *trigger_str) +static struct hist_trigger_attrs * +parse_hist_trigger_attrs(struct trace_array *tr, char *trigger_str)  {  	struct hist_trigger_attrs *attrs;  	int ret = 0; @@ -2092,7 +2135,7 @@ static struct hist_trigger_attrs *parse_hist_trigger_attrs(char *trigger_str)  		char *str = strsep(&trigger_str, ":");  		if (strchr(str, '=')) { -			ret = parse_assignment(str, attrs); +			ret = parse_assignment(tr, str, attrs);  			if (ret)  				goto free;  		} else if (strcmp(str, "pause") == 0) @@ -2648,6 +2691,7 @@ static struct hist_field *parse_var_ref(struct hist_trigger_data *hist_data,  					char *var_name)  {  	struct hist_field *var_field = NULL, *ref_field = NULL; +	struct trace_array *tr = hist_data->event_file->tr;  	if (!is_var_ref(var_name))  		return NULL; @@ -2660,8 +2704,7 @@ static struct hist_field *parse_var_ref(struct hist_trigger_data *hist_data,  					   system, event_name);  	if (!ref_field) -		hist_err_event("Couldn't find variable: $", -			       system, event_name, var_name); +		hist_err(tr, HIST_ERR_VAR_NOT_FOUND, errpos(var_name));  	return ref_field;  } @@ -2672,6 +2715,7 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file,  {  	struct ftrace_event_field *field = NULL;  	char *field_name, *modifier, *str; +	struct trace_array *tr = file->tr;  	modifier = str = kstrdup(field_str, GFP_KERNEL);  	if (!modifier) @@ -2695,7 +2739,7 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file,  		else if (strcmp(modifier, "usecs") == 0)  			*flags |= HIST_FIELD_FL_TIMESTAMP_USECS;  		else { -			hist_err("Invalid field modifier: ", modifier); +			hist_err(tr, HIST_ERR_BAD_FIELD_MODIFIER, errpos(modifier));  			field = ERR_PTR(-EINVAL);  			goto out;  		} @@ -2711,7 +2755,7 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file,  	else {  		field = trace_find_event_field(file->event_call, field_name);  		if (!field || !field->size) { -			hist_err("Couldn't find field: ", field_name); +			hist_err(tr, HIST_ERR_FIELD_NOT_FOUND, errpos(field_name));  			field = ERR_PTR(-EINVAL);  			goto out;  		} @@ -2773,7 +2817,8 @@ static struct hist_field *parse_atom(struct hist_trigger_data *hist_data,  	s = local_field_var_ref(hist_data, ref_system, ref_event, ref_var);  	if (!s) { -		hist_field = parse_var_ref(hist_data, ref_system, ref_event, ref_var); +		hist_field = parse_var_ref(hist_data, ref_system, +					   ref_event, ref_var);  		if (hist_field) {  			if (var_name) {  				hist_field = create_alias(hist_data, hist_field, var_name); @@ -2822,7 +2867,7 @@ static struct hist_field *parse_unary(struct hist_trigger_data *hist_data,  	/* we support only -(xxx) i.e. explicit parens required */  	if (level > 3) { -		hist_err("Too many subexpressions (3 max): ", str); +		hist_err(file->tr, HIST_ERR_TOO_MANY_SUBEXPR, errpos(str));  		ret = -EINVAL;  		goto free;  	} @@ -2877,7 +2922,8 @@ static struct hist_field *parse_unary(struct hist_trigger_data *hist_data,  	return ERR_PTR(ret);  } -static int check_expr_operands(struct hist_field *operand1, +static int check_expr_operands(struct trace_array *tr, +			       struct hist_field *operand1,  			       struct hist_field *operand2)  {  	unsigned long operand1_flags = operand1->flags; @@ -2905,7 +2951,7 @@ static int check_expr_operands(struct hist_field *operand1,  	if ((operand1_flags & HIST_FIELD_FL_TIMESTAMP_USECS) !=  	    (operand2_flags & HIST_FIELD_FL_TIMESTAMP_USECS)) { -		hist_err("Timestamp units in expression don't match", NULL); +		hist_err(tr, HIST_ERR_TIMESTAMP_MISMATCH, 0);  		return -EINVAL;  	} @@ -2923,7 +2969,7 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,  	char *sep, *operand1_str;  	if (level > 3) { -		hist_err("Too many subexpressions (3 max): ", str); +		hist_err(file->tr, HIST_ERR_TOO_MANY_SUBEXPR, errpos(str));  		return ERR_PTR(-EINVAL);  	} @@ -2968,7 +3014,7 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,  		goto free;  	} -	ret = check_expr_operands(operand1, operand2); +	ret = check_expr_operands(file->tr, operand1, operand2);  	if (ret)  		goto free; @@ -3161,16 +3207,14 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data,  	int ret;  	if (target_hist_data->n_field_var_hists >= SYNTH_FIELDS_MAX) { -		hist_err_event("trace action: Too many field variables defined: ", -			       subsys_name, event_name, field_name); +		hist_err(tr, HIST_ERR_TOO_MANY_FIELD_VARS, errpos(field_name));  		return ERR_PTR(-EINVAL);  	}  	file = event_file(tr, subsys_name, event_name);  	if (IS_ERR(file)) { -		hist_err_event("trace action: Event file not found: ", -			       subsys_name, event_name, field_name); +		hist_err(tr, HIST_ERR_EVENT_FILE_NOT_FOUND, errpos(field_name));  		ret = PTR_ERR(file);  		return ERR_PTR(ret);  	} @@ -3183,8 +3227,7 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data,  	 */  	hist_data = find_compatible_hist(target_hist_data, file);  	if (!hist_data) { -		hist_err_event("trace action: Matching event histogram not found: ", -			       subsys_name, event_name, field_name); +		hist_err(tr, HIST_ERR_HIST_NOT_FOUND, errpos(field_name));  		return ERR_PTR(-EINVAL);  	} @@ -3245,8 +3288,7 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data,  		kfree(cmd);  		kfree(var_hist->cmd);  		kfree(var_hist); -		hist_err_event("trace action: Couldn't create histogram for field: ", -			       subsys_name, event_name, field_name); +		hist_err(tr, HIST_ERR_HIST_CREATE_FAIL, errpos(field_name));  		return ERR_PTR(ret);  	} @@ -3258,8 +3300,7 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data,  	if (IS_ERR_OR_NULL(event_var)) {  		kfree(var_hist->cmd);  		kfree(var_hist); -		hist_err_event("trace action: Couldn't find synthetic variable: ", -			       subsys_name, event_name, field_name); +		hist_err(tr, HIST_ERR_SYNTH_VAR_NOT_FOUND, errpos(field_name));  		return ERR_PTR(-EINVAL);  	} @@ -3392,25 +3433,26 @@ static struct field_var *create_field_var(struct hist_trigger_data *hist_data,  {  	struct hist_field *val = NULL, *var = NULL;  	unsigned long flags = HIST_FIELD_FL_VAR; +	struct trace_array *tr = file->tr;  	struct field_var *field_var;  	int ret = 0;  	if (hist_data->n_field_vars >= SYNTH_FIELDS_MAX) { -		hist_err("Too many field variables defined: ", field_name); +		hist_err(tr, HIST_ERR_TOO_MANY_FIELD_VARS, errpos(field_name));  		ret = -EINVAL;  		goto err;  	}  	val = parse_atom(hist_data, file, field_name, &flags, NULL);  	if (IS_ERR(val)) { -		hist_err("Couldn't parse field variable: ", field_name); +		hist_err(tr, HIST_ERR_FIELD_VAR_PARSE_FAIL, errpos(field_name));  		ret = PTR_ERR(val);  		goto err;  	}  	var = create_var(hist_data, file, field_name, val->size, val->type);  	if (IS_ERR(var)) { -		hist_err("Couldn't create or find variable: ", field_name); +		hist_err(tr, HIST_ERR_VAR_CREATE_FIND_FAIL, errpos(field_name));  		kfree(val);  		ret = PTR_ERR(var);  		goto err; @@ -3543,14 +3585,20 @@ static bool cond_snapshot_update(struct trace_array *tr, void *cond_data)  	struct track_data *track_data = tr->cond_snapshot->cond_data;  	struct hist_elt_data *elt_data, *track_elt_data;  	struct snapshot_context *context = cond_data; +	struct action_data *action;  	u64 track_val;  	if (!track_data)  		return false; +	action = track_data->action_data; +  	track_val = get_track_val(track_data->hist_data, context->elt,  				  track_data->action_data); +	if (!action->track_data.check_val(track_data->track_val, track_val)) +		return false; +  	track_data->track_val = track_val;  	memcpy(track_data->key, context->key, track_data->key_len); @@ -3737,19 +3785,20 @@ static int track_data_create(struct hist_trigger_data *hist_data,  {  	struct hist_field *var_field, *ref_field, *track_var = NULL;  	struct trace_event_file *file = hist_data->event_file; +	struct trace_array *tr = file->tr;  	char *track_data_var_str;  	int ret = 0;  	track_data_var_str = data->track_data.var_str;  	if (track_data_var_str[0] != '$') { -		hist_err("For onmax(x) or onchange(x), x must be a variable: ", track_data_var_str); +		hist_err(tr, HIST_ERR_ONX_NOT_VAR, errpos(track_data_var_str));  		return -EINVAL;  	}  	track_data_var_str++;  	var_field = find_target_event_var(hist_data, NULL, NULL, track_data_var_str);  	if (!var_field) { -		hist_err("Couldn't find onmax or onchange variable: ", track_data_var_str); +		hist_err(tr, HIST_ERR_ONX_VAR_NOT_FOUND, errpos(track_data_var_str));  		return -EINVAL;  	} @@ -3762,7 +3811,7 @@ static int track_data_create(struct hist_trigger_data *hist_data,  	if (data->handler == HANDLER_ONMAX)  		track_var = create_var(hist_data, file, "__max", sizeof(u64), "u64");  	if (IS_ERR(track_var)) { -		hist_err("Couldn't create onmax variable: ", "__max"); +		hist_err(tr, HIST_ERR_ONX_VAR_CREATE_FAIL, 0);  		ret = PTR_ERR(track_var);  		goto out;  	} @@ -3770,7 +3819,7 @@ static int track_data_create(struct hist_trigger_data *hist_data,  	if (data->handler == HANDLER_ONCHANGE)  		track_var = create_var(hist_data, file, "__change", sizeof(u64), "u64");  	if (IS_ERR(track_var)) { -		hist_err("Couldn't create onchange variable: ", "__change"); +		hist_err(tr, HIST_ERR_ONX_VAR_CREATE_FAIL, 0);  		ret = PTR_ERR(track_var);  		goto out;  	} @@ -3781,7 +3830,8 @@ static int track_data_create(struct hist_trigger_data *hist_data,  	return ret;  } -static int parse_action_params(char *params, struct action_data *data) +static int parse_action_params(struct trace_array *tr, char *params, +			       struct action_data *data)  {  	char *param, *saved_param;  	bool first_param = true; @@ -3789,20 +3839,20 @@ static int parse_action_params(char *params, struct action_data *data)  	while (params) {  		if (data->n_params >= SYNTH_FIELDS_MAX) { -			hist_err("Too many action params", ""); +			hist_err(tr, HIST_ERR_TOO_MANY_PARAMS, 0);  			goto out;  		}  		param = strsep(¶ms, ",");  		if (!param) { -			hist_err("No action param found", ""); +			hist_err(tr, HIST_ERR_PARAM_NOT_FOUND, 0);  			ret = -EINVAL;  			goto out;  		}  		param = strstrip(param);  		if (strlen(param) < 2) { -			hist_err("Invalid action param: ", param); +			hist_err(tr, HIST_ERR_INVALID_PARAM, errpos(param));  			ret = -EINVAL;  			goto out;  		} @@ -3826,7 +3876,7 @@ static int parse_action_params(char *params, struct action_data *data)  	return ret;  } -static int action_parse(char *str, struct action_data *data, +static int action_parse(struct trace_array *tr, char *str, struct action_data *data,  			enum handler_id handler)  {  	char *action_name; @@ -3834,14 +3884,14 @@ static int action_parse(char *str, struct action_data *data,  	strsep(&str, ".");  	if (!str) { -		hist_err("action parsing: No action found", ""); +		hist_err(tr, HIST_ERR_ACTION_NOT_FOUND, 0);  		ret = -EINVAL;  		goto out;  	}  	action_name = strsep(&str, "(");  	if (!action_name || !str) { -		hist_err("action parsing: No action found", ""); +		hist_err(tr, HIST_ERR_ACTION_NOT_FOUND, 0);  		ret = -EINVAL;  		goto out;  	} @@ -3850,12 +3900,12 @@ static int action_parse(char *str, struct action_data *data,  		char *params = strsep(&str, ")");  		if (!params) { -			hist_err("action parsing: No params found for %s", "save"); +			hist_err(tr, HIST_ERR_NO_SAVE_PARAMS, 0);  			ret = -EINVAL;  			goto out;  		} -		ret = parse_action_params(params, data); +		ret = parse_action_params(tr, params, data);  		if (ret)  			goto out; @@ -3864,7 +3914,7 @@ static int action_parse(char *str, struct action_data *data,  		else if (handler == HANDLER_ONCHANGE)  			data->track_data.check_val = check_track_val_changed;  		else { -			hist_err("action parsing: Handler doesn't support action: ", action_name); +			hist_err(tr, HIST_ERR_ACTION_MISMATCH, errpos(action_name));  			ret = -EINVAL;  			goto out;  		} @@ -3876,7 +3926,7 @@ static int action_parse(char *str, struct action_data *data,  		char *params = strsep(&str, ")");  		if (!str) { -			hist_err("action parsing: No closing paren found: %s", params); +			hist_err(tr, HIST_ERR_NO_CLOSING_PAREN, errpos(params));  			ret = -EINVAL;  			goto out;  		} @@ -3886,7 +3936,7 @@ static int action_parse(char *str, struct action_data *data,  		else if (handler == HANDLER_ONCHANGE)  			data->track_data.check_val = check_track_val_changed;  		else { -			hist_err("action parsing: Handler doesn't support action: ", action_name); +			hist_err(tr, HIST_ERR_ACTION_MISMATCH, errpos(action_name));  			ret = -EINVAL;  			goto out;  		} @@ -3901,7 +3951,7 @@ static int action_parse(char *str, struct action_data *data,  			data->use_trace_keyword = true;  		if (params) { -			ret = parse_action_params(params, data); +			ret = parse_action_params(tr, params, data);  			if (ret)  				goto out;  		} @@ -3954,7 +4004,7 @@ static struct action_data *track_data_parse(struct hist_trigger_data *hist_data,  		goto free;  	} -	ret = action_parse(str, data, handler); +	ret = action_parse(hist_data->event_file->tr, str, data, handler);  	if (ret)  		goto free;   out: @@ -4024,6 +4074,7 @@ trace_action_find_var(struct hist_trigger_data *hist_data,  		      struct action_data *data,  		      char *system, char *event, char *var)  { +	struct trace_array *tr = hist_data->event_file->tr;  	struct hist_field *hist_field;  	var++; /* skip '$' */ @@ -4039,7 +4090,7 @@ trace_action_find_var(struct hist_trigger_data *hist_data,  	}  	if (!hist_field) -		hist_err_event("trace action: Couldn't find param: $", system, event, var); +		hist_err(tr, HIST_ERR_PARAM_NOT_FOUND, errpos(var));  	return hist_field;  } @@ -4097,6 +4148,7 @@ trace_action_create_field_var(struct hist_trigger_data *hist_data,  static int trace_action_create(struct hist_trigger_data *hist_data,  			       struct action_data *data)  { +	struct trace_array *tr = hist_data->event_file->tr;  	char *event_name, *param, *system = NULL;  	struct hist_field *hist_field, *var_ref;  	unsigned int i, var_ref_idx; @@ -4114,7 +4166,7 @@ static int trace_action_create(struct hist_trigger_data *hist_data,  	event = find_synth_event(synth_event_name);  	if (!event) { -		hist_err("trace action: Couldn't find synthetic event: ", synth_event_name); +		hist_err(tr, HIST_ERR_SYNTH_EVENT_NOT_FOUND, errpos(synth_event_name));  		return -EINVAL;  	} @@ -4175,15 +4227,14 @@ static int trace_action_create(struct hist_trigger_data *hist_data,  			continue;  		} -		hist_err_event("trace action: Param type doesn't match synthetic event field type: ", -			       system, event_name, param); +		hist_err(tr, HIST_ERR_SYNTH_TYPE_MISMATCH, errpos(param));  		kfree(p);  		ret = -EINVAL;  		goto err;  	}  	if (field_pos != event->n_fields) { -		hist_err("trace action: Param count doesn't match synthetic event field count: ", event->name); +		hist_err(tr, HIST_ERR_SYNTH_COUNT_MISMATCH, errpos(event->name));  		ret = -EINVAL;  		goto err;  	} @@ -4202,6 +4253,7 @@ static int action_create(struct hist_trigger_data *hist_data,  			 struct action_data *data)  {  	struct trace_event_file *file = hist_data->event_file; +	struct trace_array *tr = file->tr;  	struct track_data *track_data;  	struct field_var *field_var;  	unsigned int i; @@ -4229,7 +4281,7 @@ static int action_create(struct hist_trigger_data *hist_data,  	if (data->action == ACTION_SAVE) {  		if (hist_data->n_save_vars) {  			ret = -EEXIST; -			hist_err("save action: Can't have more than one save() action per hist", ""); +			hist_err(tr, HIST_ERR_TOO_MANY_SAVE_ACTIONS, 0);  			goto out;  		} @@ -4242,7 +4294,8 @@ static int action_create(struct hist_trigger_data *hist_data,  			field_var = create_target_field_var(hist_data, NULL, NULL, param);  			if (IS_ERR(field_var)) { -				hist_err("save action: Couldn't create field variable: ", param); +				hist_err(tr, HIST_ERR_FIELD_VAR_CREATE_FAIL, +					 errpos(param));  				ret = PTR_ERR(field_var);  				kfree(param);  				goto out; @@ -4276,19 +4329,18 @@ static struct action_data *onmatch_parse(struct trace_array *tr, char *str)  	match_event = strsep(&str, ")");  	if (!match_event || !str) { -		hist_err("onmatch: Missing closing paren: ", match_event); +		hist_err(tr, HIST_ERR_NO_CLOSING_PAREN, errpos(match_event));  		goto free;  	}  	match_event_system = strsep(&match_event, ".");  	if (!match_event) { -		hist_err("onmatch: Missing subsystem for match event: ", match_event_system); +		hist_err(tr, HIST_ERR_SUBSYS_NOT_FOUND, errpos(match_event_system));  		goto free;  	}  	if (IS_ERR(event_file(tr, match_event_system, match_event))) { -		hist_err_event("onmatch: Invalid subsystem or event name: ", -			       match_event_system, match_event, NULL); +		hist_err(tr, HIST_ERR_INVALID_SUBSYS_EVENT, errpos(match_event));  		goto free;  	} @@ -4304,7 +4356,7 @@ static struct action_data *onmatch_parse(struct trace_array *tr, char *str)  		goto free;  	} -	ret = action_parse(str, data, HANDLER_ONMATCH); +	ret = action_parse(tr, str, data, HANDLER_ONMATCH);  	if (ret)  		goto free;   out: @@ -4373,13 +4425,14 @@ static int create_var_field(struct hist_trigger_data *hist_data,  			    struct trace_event_file *file,  			    char *var_name, char *expr_str)  { +	struct trace_array *tr = hist_data->event_file->tr;  	unsigned long flags = 0;  	if (WARN_ON(val_idx >= TRACING_MAP_VALS_MAX + TRACING_MAP_VARS_MAX))  		return -EINVAL;  	if (find_var(hist_data, file, var_name) && !hist_data->remove) { -		hist_err("Variable already defined: ", var_name); +		hist_err(tr, HIST_ERR_DUPLICATE_VAR, errpos(var_name));  		return -EINVAL;  	} @@ -4436,8 +4489,8 @@ static int create_key_field(struct hist_trigger_data *hist_data,  			    struct trace_event_file *file,  			    char *field_str)  { +	struct trace_array *tr = hist_data->event_file->tr;  	struct hist_field *hist_field = NULL; -  	unsigned long flags = 0;  	unsigned int key_size;  	int ret = 0; @@ -4459,8 +4512,8 @@ static int create_key_field(struct hist_trigger_data *hist_data,  			goto out;  		} -		if (hist_field->flags & HIST_FIELD_FL_VAR_REF) { -			hist_err("Using variable references as keys not supported: ", field_str); +		if (field_has_hist_vars(hist_field, 0))	{ +			hist_err(tr, HIST_ERR_INVALID_REF_KEY, errpos(field_str));  			destroy_hist_field(hist_field, 0);  			ret = -EINVAL;  			goto out; @@ -4561,6 +4614,7 @@ static void free_var_defs(struct hist_trigger_data *hist_data)  static int parse_var_defs(struct hist_trigger_data *hist_data)  { +	struct trace_array *tr = hist_data->event_file->tr;  	char *s, *str, *var_name, *field_str;  	unsigned int i, j, n_vars = 0;  	int ret = 0; @@ -4574,13 +4628,14 @@ static int parse_var_defs(struct hist_trigger_data *hist_data)  			var_name = strsep(&field_str, "=");  			if (!var_name || !field_str) { -				hist_err("Malformed assignment: ", var_name); +				hist_err(tr, HIST_ERR_MALFORMED_ASSIGNMENT, +					 errpos(var_name));  				ret = -EINVAL;  				goto free;  			}  			if (n_vars == TRACING_MAP_VARS_MAX) { -				hist_err("Too many variables defined: ", var_name); +				hist_err(tr, HIST_ERR_TOO_MANY_VARS, errpos(var_name));  				ret = -EINVAL;  				goto free;  			} @@ -5431,11 +5486,6 @@ static int hist_show(struct seq_file *m, void *v)  			hist_trigger_show(m, data, n++);  	} -	if (have_hist_err()) { -		seq_printf(m, "\nERROR: %s\n", hist_err_str); -		seq_printf(m, "  Last command: %s\n", last_hist_cmd); -	} -   out_unlock:  	mutex_unlock(&event_mutex); @@ -5800,6 +5850,7 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops,  {  	struct hist_trigger_data *hist_data = data->private_data;  	struct event_trigger_data *test, *named_data = NULL; +	struct trace_array *tr = file->tr;  	int ret = 0;  	if (hist_data->attrs->name) { @@ -5807,7 +5858,7 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops,  		if (named_data) {  			if (!hist_trigger_match(data, named_data, named_data,  						true)) { -				hist_err("Named hist trigger doesn't match existing named trigger (includes variables): ", hist_data->attrs->name); +				hist_err(tr, HIST_ERR_NAMED_MISMATCH, errpos(hist_data->attrs->name));  				ret = -EINVAL;  				goto out;  			} @@ -5828,7 +5879,7 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops,  			else if (hist_data->attrs->clear)  				hist_clear(test);  			else { -				hist_err("Hist trigger already exists", NULL); +				hist_err(tr, HIST_ERR_TRIGGER_EEXIST, 0);  				ret = -EEXIST;  			}  			goto out; @@ -5836,7 +5887,7 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops,  	}   new:  	if (hist_data->attrs->cont || hist_data->attrs->clear) { -		hist_err("Can't clear or continue a nonexistent hist trigger", NULL); +		hist_err(tr, HIST_ERR_TRIGGER_ENOENT_CLEAR, 0);  		ret = -ENOENT;  		goto out;  	} @@ -5861,7 +5912,7 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops,  		ret = tracing_set_clock(file->tr, hist_data->attrs->clock);  		if (ret) { -			hist_err("Couldn't set trace_clock: ", clock); +			hist_err(tr, HIST_ERR_SET_CLOCK_FAIL, errpos(clock));  			goto out;  		} @@ -6037,8 +6088,8 @@ static int event_hist_trigger_func(struct event_command *cmd_ops,  	lockdep_assert_held(&event_mutex);  	if (glob && strlen(glob)) { -		last_cmd_set(param);  		hist_err_clear(); +		last_cmd_set(file, param);  	}  	if (!param) @@ -6079,7 +6130,7 @@ static int event_hist_trigger_func(struct event_command *cmd_ops,  		trigger = strstrip(trigger);  	} -	attrs = parse_hist_trigger_attrs(trigger); +	attrs = parse_hist_trigger_attrs(file->tr, trigger);  	if (IS_ERR(attrs))  		return PTR_ERR(attrs);  |