diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-10-20 03:20:48 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-10-20 03:20:48 -0400 |
commit | 6b5201c21d4022e71058cbd87b9dfe3116143af1 (patch) | |
tree | 6ded3a278fe1103f2ea180d9b9e39e47b1a5670a /kernel | |
parent | d4ec49d332aba29827504cc666205aef91a281c7 (diff) | |
parent | ba0e41ca81b935b958006c7120466e2217357827 (diff) |
Merge tag 'trace-v4.19-rc8-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Steven writes:
"tracing: A few small fixes to synthetic events
Masami found some issues with the creation of synthetic events. The
first two patches fix handling of unsigned type, and handling of a
space before an ending semi-colon.
The third patch adds a selftest to test the processing of synthetic
events."
* tag 'trace-v4.19-rc8-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
selftests: ftrace: Add synthetic event syntax testcase
tracing: Fix synthetic event to allow semicolon at end
tracing: Fix synthetic event to accept unsigned modifier
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/trace/trace_events_hist.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 85f6b01431c7..d239004aaf29 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c | |||
@@ -738,16 +738,30 @@ static void free_synth_field(struct synth_field *field) | |||
738 | kfree(field); | 738 | kfree(field); |
739 | } | 739 | } |
740 | 740 | ||
741 | static struct synth_field *parse_synth_field(char *field_type, | 741 | static struct synth_field *parse_synth_field(int argc, char **argv, |
742 | char *field_name) | 742 | int *consumed) |
743 | { | 743 | { |
744 | struct synth_field *field; | 744 | struct synth_field *field; |
745 | const char *prefix = NULL; | ||
746 | char *field_type = argv[0], *field_name; | ||
745 | int len, ret = 0; | 747 | int len, ret = 0; |
746 | char *array; | 748 | char *array; |
747 | 749 | ||
748 | if (field_type[0] == ';') | 750 | if (field_type[0] == ';') |
749 | field_type++; | 751 | field_type++; |
750 | 752 | ||
753 | if (!strcmp(field_type, "unsigned")) { | ||
754 | if (argc < 3) | ||
755 | return ERR_PTR(-EINVAL); | ||
756 | prefix = "unsigned "; | ||
757 | field_type = argv[1]; | ||
758 | field_name = argv[2]; | ||
759 | *consumed = 3; | ||
760 | } else { | ||
761 | field_name = argv[1]; | ||
762 | *consumed = 2; | ||
763 | } | ||
764 | |||
751 | len = strlen(field_name); | 765 | len = strlen(field_name); |
752 | if (field_name[len - 1] == ';') | 766 | if (field_name[len - 1] == ';') |
753 | field_name[len - 1] = '\0'; | 767 | field_name[len - 1] = '\0'; |
@@ -760,11 +774,15 @@ static struct synth_field *parse_synth_field(char *field_type, | |||
760 | array = strchr(field_name, '['); | 774 | array = strchr(field_name, '['); |
761 | if (array) | 775 | if (array) |
762 | len += strlen(array); | 776 | len += strlen(array); |
777 | if (prefix) | ||
778 | len += strlen(prefix); | ||
763 | field->type = kzalloc(len, GFP_KERNEL); | 779 | field->type = kzalloc(len, GFP_KERNEL); |
764 | if (!field->type) { | 780 | if (!field->type) { |
765 | ret = -ENOMEM; | 781 | ret = -ENOMEM; |
766 | goto free; | 782 | goto free; |
767 | } | 783 | } |
784 | if (prefix) | ||
785 | strcat(field->type, prefix); | ||
768 | strcat(field->type, field_type); | 786 | strcat(field->type, field_type); |
769 | if (array) { | 787 | if (array) { |
770 | strcat(field->type, array); | 788 | strcat(field->type, array); |
@@ -1009,7 +1027,7 @@ static int create_synth_event(int argc, char **argv) | |||
1009 | struct synth_field *field, *fields[SYNTH_FIELDS_MAX]; | 1027 | struct synth_field *field, *fields[SYNTH_FIELDS_MAX]; |
1010 | struct synth_event *event = NULL; | 1028 | struct synth_event *event = NULL; |
1011 | bool delete_event = false; | 1029 | bool delete_event = false; |
1012 | int i, n_fields = 0, ret = 0; | 1030 | int i, consumed = 0, n_fields = 0, ret = 0; |
1013 | char *name; | 1031 | char *name; |
1014 | 1032 | ||
1015 | mutex_lock(&synth_event_mutex); | 1033 | mutex_lock(&synth_event_mutex); |
@@ -1061,16 +1079,16 @@ static int create_synth_event(int argc, char **argv) | |||
1061 | goto err; | 1079 | goto err; |
1062 | } | 1080 | } |
1063 | 1081 | ||
1064 | field = parse_synth_field(argv[i], argv[i + 1]); | 1082 | field = parse_synth_field(argc - i, &argv[i], &consumed); |
1065 | if (IS_ERR(field)) { | 1083 | if (IS_ERR(field)) { |
1066 | ret = PTR_ERR(field); | 1084 | ret = PTR_ERR(field); |
1067 | goto err; | 1085 | goto err; |
1068 | } | 1086 | } |
1069 | fields[n_fields] = field; | 1087 | fields[n_fields++] = field; |
1070 | i++; n_fields++; | 1088 | i += consumed - 1; |
1071 | } | 1089 | } |
1072 | 1090 | ||
1073 | if (i < argc) { | 1091 | if (i < argc && strcmp(argv[i], ";") != 0) { |
1074 | ret = -EINVAL; | 1092 | ret = -EINVAL; |
1075 | goto err; | 1093 | goto err; |
1076 | } | 1094 | } |