diff options
Diffstat (limited to 'kernel/trace')
| -rw-r--r-- | kernel/trace/trace.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_events_hist.c | 42 |
2 files changed, 39 insertions, 5 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index be6779f963c6..0460cc0f28fd 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -4918,7 +4918,7 @@ static const char readme_msg[] = | |||
| 4918 | "\t onmax(var) - invoke if var exceeds current max\n" | 4918 | "\t onmax(var) - invoke if var exceeds current max\n" |
| 4919 | "\t onchange(var) - invoke action if var changes\n\n" | 4919 | "\t onchange(var) - invoke action if var changes\n\n" |
| 4920 | "\t The available actions are:\n\n" | 4920 | "\t The available actions are:\n\n" |
| 4921 | "\t <synthetic_event>(param list) - generate synthetic event\n" | 4921 | "\t trace(<synthetic_event>,param list) - generate synthetic event\n" |
| 4922 | "\t save(field,...) - save current event fields\n" | 4922 | "\t save(field,...) - save current event fields\n" |
| 4923 | #ifdef CONFIG_TRACER_SNAPSHOT | 4923 | #ifdef CONFIG_TRACER_SNAPSHOT |
| 4924 | "\t snapshot() - snapshot the trace buffer\n" | 4924 | "\t snapshot() - snapshot the trace buffer\n" |
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 2f3323ca9d24..66386ba1425f 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c | |||
| @@ -419,6 +419,8 @@ struct action_data { | |||
| 419 | */ | 419 | */ |
| 420 | unsigned int var_ref_idx; | 420 | unsigned int var_ref_idx; |
| 421 | struct synth_event *synth_event; | 421 | struct synth_event *synth_event; |
| 422 | bool use_trace_keyword; | ||
| 423 | char *synth_event_name; | ||
| 422 | 424 | ||
| 423 | union { | 425 | union { |
| 424 | struct { | 426 | struct { |
| @@ -3700,6 +3702,8 @@ static void action_data_destroy(struct action_data *data) | |||
| 3700 | if (data->synth_event) | 3702 | if (data->synth_event) |
| 3701 | data->synth_event->ref--; | 3703 | data->synth_event->ref--; |
| 3702 | 3704 | ||
| 3705 | kfree(data->synth_event_name); | ||
| 3706 | |||
| 3703 | kfree(data); | 3707 | kfree(data); |
| 3704 | } | 3708 | } |
| 3705 | 3709 | ||
| @@ -3781,6 +3785,7 @@ static int track_data_create(struct hist_trigger_data *hist_data, | |||
| 3781 | static int parse_action_params(char *params, struct action_data *data) | 3785 | static int parse_action_params(char *params, struct action_data *data) |
| 3782 | { | 3786 | { |
| 3783 | char *param, *saved_param; | 3787 | char *param, *saved_param; |
| 3788 | bool first_param = true; | ||
| 3784 | int ret = 0; | 3789 | int ret = 0; |
| 3785 | 3790 | ||
| 3786 | while (params) { | 3791 | while (params) { |
| @@ -3809,6 +3814,13 @@ static int parse_action_params(char *params, struct action_data *data) | |||
| 3809 | goto out; | 3814 | goto out; |
| 3810 | } | 3815 | } |
| 3811 | 3816 | ||
| 3817 | if (first_param && data->use_trace_keyword) { | ||
| 3818 | data->synth_event_name = saved_param; | ||
| 3819 | first_param = false; | ||
| 3820 | continue; | ||
| 3821 | } | ||
| 3822 | first_param = false; | ||
| 3823 | |||
| 3812 | data->params[data->n_params++] = saved_param; | 3824 | data->params[data->n_params++] = saved_param; |
| 3813 | } | 3825 | } |
| 3814 | out: | 3826 | out: |
| @@ -3886,6 +3898,9 @@ static int action_parse(char *str, struct action_data *data, | |||
| 3886 | } else { | 3898 | } else { |
| 3887 | char *params = strsep(&str, ")"); | 3899 | char *params = strsep(&str, ")"); |
| 3888 | 3900 | ||
| 3901 | if (str_has_prefix(action_name, "trace")) | ||
| 3902 | data->use_trace_keyword = true; | ||
| 3903 | |||
| 3889 | if (params) { | 3904 | if (params) { |
| 3890 | ret = parse_action_params(params, data); | 3905 | ret = parse_action_params(params, data); |
| 3891 | if (ret) | 3906 | if (ret) |
| @@ -4088,13 +4103,19 @@ static int trace_action_create(struct hist_trigger_data *hist_data, | |||
| 4088 | unsigned int i, var_ref_idx; | 4103 | unsigned int i, var_ref_idx; |
| 4089 | unsigned int field_pos = 0; | 4104 | unsigned int field_pos = 0; |
| 4090 | struct synth_event *event; | 4105 | struct synth_event *event; |
| 4106 | char *synth_event_name; | ||
| 4091 | int ret = 0; | 4107 | int ret = 0; |
| 4092 | 4108 | ||
| 4093 | lockdep_assert_held(&event_mutex); | 4109 | lockdep_assert_held(&event_mutex); |
| 4094 | 4110 | ||
| 4095 | event = find_synth_event(data->action_name); | 4111 | if (data->use_trace_keyword) |
| 4112 | synth_event_name = data->synth_event_name; | ||
| 4113 | else | ||
| 4114 | synth_event_name = data->action_name; | ||
| 4115 | |||
| 4116 | event = find_synth_event(synth_event_name); | ||
| 4096 | if (!event) { | 4117 | if (!event) { |
| 4097 | hist_err("trace action: Couldn't find synthetic event: ", data->action_name); | 4118 | hist_err("trace action: Couldn't find synthetic event: ", synth_event_name); |
| 4098 | return -EINVAL; | 4119 | return -EINVAL; |
| 4099 | } | 4120 | } |
| 4100 | 4121 | ||
| @@ -4841,8 +4862,10 @@ static void print_action_spec(struct seq_file *m, | |||
| 4841 | seq_puts(m, ","); | 4862 | seq_puts(m, ","); |
| 4842 | } | 4863 | } |
| 4843 | } else if (data->action == ACTION_TRACE) { | 4864 | } else if (data->action == ACTION_TRACE) { |
| 4865 | if (data->use_trace_keyword) | ||
| 4866 | seq_printf(m, "%s", data->synth_event_name); | ||
| 4844 | for (i = 0; i < data->n_params; i++) { | 4867 | for (i = 0; i < data->n_params; i++) { |
| 4845 | if (i) | 4868 | if (i || data->use_trace_keyword) |
| 4846 | seq_puts(m, ","); | 4869 | seq_puts(m, ","); |
| 4847 | seq_printf(m, "%s", data->params[i]); | 4870 | seq_printf(m, "%s", data->params[i]); |
| 4848 | } | 4871 | } |
| @@ -4890,6 +4913,7 @@ static bool actions_match(struct hist_trigger_data *hist_data, | |||
| 4890 | for (i = 0; i < hist_data->n_actions; i++) { | 4913 | for (i = 0; i < hist_data->n_actions; i++) { |
| 4891 | struct action_data *data = hist_data->actions[i]; | 4914 | struct action_data *data = hist_data->actions[i]; |
| 4892 | struct action_data *data_test = hist_data_test->actions[i]; | 4915 | struct action_data *data_test = hist_data_test->actions[i]; |
| 4916 | char *action_name, *action_name_test; | ||
| 4893 | 4917 | ||
| 4894 | if (data->handler != data_test->handler) | 4918 | if (data->handler != data_test->handler) |
| 4895 | return false; | 4919 | return false; |
| @@ -4904,7 +4928,17 @@ static bool actions_match(struct hist_trigger_data *hist_data, | |||
| 4904 | return false; | 4928 | return false; |
| 4905 | } | 4929 | } |
| 4906 | 4930 | ||
| 4907 | if (strcmp(data->action_name, data_test->action_name) != 0) | 4931 | if (data->use_trace_keyword) |
| 4932 | action_name = data->synth_event_name; | ||
| 4933 | else | ||
| 4934 | action_name = data->action_name; | ||
| 4935 | |||
| 4936 | if (data_test->use_trace_keyword) | ||
| 4937 | action_name_test = data_test->synth_event_name; | ||
| 4938 | else | ||
| 4939 | action_name_test = data_test->action_name; | ||
| 4940 | |||
| 4941 | if (strcmp(action_name, action_name_test) != 0) | ||
| 4908 | return false; | 4942 | return false; |
| 4909 | 4943 | ||
| 4910 | if (data->handler == HANDLER_ONMATCH) { | 4944 | if (data->handler == HANDLER_ONMATCH) { |
