diff options
author | Steven Rostedt <srostedt@redhat.com> | 2009-02-13 15:56:43 -0500 |
---|---|---|
committer | Steven Rostedt <srostedt@redhat.com> | 2009-02-16 16:49:57 -0500 |
commit | 9f4801e30ad291e27284e873696da1ead92d68fa (patch) | |
tree | 2a374e89f4f4ecb13cbcf8f914076539e9096517 /kernel/trace/ftrace.c | |
parent | 7f24b31b01a271b62346d9df084b029e48612163 (diff) |
ftrace: break up ftrace_match_records into smaller components
Impact: clean up
ftrace_match_records does a lot of things that other features
can use. This patch breaks up ftrace_match_records and pulls
out ftrace_setup_glob and ftrace_match_record.
ftrace_setup_glob prepares a simple glob expression for use with
ftrace_match_record. ftrace_match_record compares a single record
with a glob type.
Breaking this up will allow for more features to run on individual
records.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r-- | kernel/trace/ftrace.c | 115 |
1 files changed, 75 insertions, 40 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index f397d7adb62e..fcec31323a10 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -1053,79 +1053,114 @@ enum { | |||
1053 | MATCH_END_ONLY, | 1053 | MATCH_END_ONLY, |
1054 | }; | 1054 | }; |
1055 | 1055 | ||
1056 | static void | 1056 | /* |
1057 | ftrace_match_records(unsigned char *buff, int len, int enable) | 1057 | * (static function - no need for kernel doc) |
1058 | * | ||
1059 | * Pass in a buffer containing a glob and this function will | ||
1060 | * set search to point to the search part of the buffer and | ||
1061 | * return the type of search it is (see enum above). | ||
1062 | * This does modify buff. | ||
1063 | * | ||
1064 | * Returns enum type. | ||
1065 | * search returns the pointer to use for comparison. | ||
1066 | * not returns 1 if buff started with a '!' | ||
1067 | * 0 otherwise. | ||
1068 | */ | ||
1069 | static int | ||
1070 | ftrace_setup_glob(unsigned char *buff, int len, char **search, int *not) | ||
1058 | { | 1071 | { |
1059 | char str[KSYM_SYMBOL_LEN]; | ||
1060 | char *search = NULL; | ||
1061 | struct ftrace_page *pg; | ||
1062 | struct dyn_ftrace *rec; | ||
1063 | int type = MATCH_FULL; | 1072 | int type = MATCH_FULL; |
1064 | unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; | 1073 | int i; |
1065 | unsigned i, match = 0, search_len = 0; | ||
1066 | int not = 0; | ||
1067 | 1074 | ||
1068 | if (buff[0] == '!') { | 1075 | if (buff[0] == '!') { |
1069 | not = 1; | 1076 | *not = 1; |
1070 | buff++; | 1077 | buff++; |
1071 | len--; | 1078 | len--; |
1072 | } | 1079 | } else |
1080 | *not = 0; | ||
1081 | |||
1082 | *search = buff; | ||
1073 | 1083 | ||
1074 | for (i = 0; i < len; i++) { | 1084 | for (i = 0; i < len; i++) { |
1075 | if (buff[i] == '*') { | 1085 | if (buff[i] == '*') { |
1076 | if (!i) { | 1086 | if (!i) { |
1077 | search = buff + i + 1; | 1087 | *search = buff + 1; |
1078 | type = MATCH_END_ONLY; | 1088 | type = MATCH_END_ONLY; |
1079 | search_len = len - (i + 1); | ||
1080 | } else { | 1089 | } else { |
1081 | if (type == MATCH_END_ONLY) { | 1090 | if (type == MATCH_END_ONLY) |
1082 | type = MATCH_MIDDLE_ONLY; | 1091 | type = MATCH_MIDDLE_ONLY; |
1083 | } else { | 1092 | else |
1084 | match = i; | ||
1085 | type = MATCH_FRONT_ONLY; | 1093 | type = MATCH_FRONT_ONLY; |
1086 | } | ||
1087 | buff[i] = 0; | 1094 | buff[i] = 0; |
1088 | break; | 1095 | break; |
1089 | } | 1096 | } |
1090 | } | 1097 | } |
1091 | } | 1098 | } |
1092 | 1099 | ||
1100 | return type; | ||
1101 | } | ||
1102 | |||
1103 | static int | ||
1104 | ftrace_match_record(struct dyn_ftrace *rec, char *regex, int len, int type) | ||
1105 | { | ||
1106 | char str[KSYM_SYMBOL_LEN]; | ||
1107 | int matched = 0; | ||
1108 | char *ptr; | ||
1109 | |||
1110 | kallsyms_lookup(rec->ip, NULL, NULL, NULL, str); | ||
1111 | switch (type) { | ||
1112 | case MATCH_FULL: | ||
1113 | if (strcmp(str, regex) == 0) | ||
1114 | matched = 1; | ||
1115 | break; | ||
1116 | case MATCH_FRONT_ONLY: | ||
1117 | if (strncmp(str, regex, len) == 0) | ||
1118 | matched = 1; | ||
1119 | break; | ||
1120 | case MATCH_MIDDLE_ONLY: | ||
1121 | if (strstr(str, regex)) | ||
1122 | matched = 1; | ||
1123 | break; | ||
1124 | case MATCH_END_ONLY: | ||
1125 | ptr = strstr(str, regex); | ||
1126 | if (ptr && (ptr[len] == 0)) | ||
1127 | matched = 1; | ||
1128 | break; | ||
1129 | } | ||
1130 | |||
1131 | return matched; | ||
1132 | } | ||
1133 | |||
1134 | static void ftrace_match_records(char *buff, int len, int enable) | ||
1135 | { | ||
1136 | char *search; | ||
1137 | struct ftrace_page *pg; | ||
1138 | struct dyn_ftrace *rec; | ||
1139 | int type; | ||
1140 | unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; | ||
1141 | unsigned search_len; | ||
1142 | int not; | ||
1143 | |||
1144 | type = ftrace_setup_glob(buff, len, &search, ¬); | ||
1145 | |||
1146 | search_len = strlen(search); | ||
1147 | |||
1093 | /* should not be called from interrupt context */ | 1148 | /* should not be called from interrupt context */ |
1094 | spin_lock(&ftrace_lock); | 1149 | spin_lock(&ftrace_lock); |
1095 | if (enable) | 1150 | if (enable) |
1096 | ftrace_filtered = 1; | 1151 | ftrace_filtered = 1; |
1097 | do_for_each_ftrace_rec(pg, rec) { | 1152 | do_for_each_ftrace_rec(pg, rec) { |
1098 | int matched = 0; | ||
1099 | char *ptr; | ||
1100 | 1153 | ||
1101 | if (rec->flags & FTRACE_FL_FAILED) | 1154 | if (rec->flags & FTRACE_FL_FAILED) |
1102 | continue; | 1155 | continue; |
1103 | kallsyms_lookup(rec->ip, NULL, NULL, NULL, str); | 1156 | |
1104 | switch (type) { | 1157 | if (ftrace_match_record(rec, search, search_len, type)) { |
1105 | case MATCH_FULL: | ||
1106 | if (strcmp(str, buff) == 0) | ||
1107 | matched = 1; | ||
1108 | break; | ||
1109 | case MATCH_FRONT_ONLY: | ||
1110 | if (memcmp(str, buff, match) == 0) | ||
1111 | matched = 1; | ||
1112 | break; | ||
1113 | case MATCH_MIDDLE_ONLY: | ||
1114 | if (strstr(str, search)) | ||
1115 | matched = 1; | ||
1116 | break; | ||
1117 | case MATCH_END_ONLY: | ||
1118 | ptr = strstr(str, search); | ||
1119 | if (ptr && (ptr[search_len] == 0)) | ||
1120 | matched = 1; | ||
1121 | break; | ||
1122 | } | ||
1123 | if (matched) { | ||
1124 | if (not) | 1158 | if (not) |
1125 | rec->flags &= ~flag; | 1159 | rec->flags &= ~flag; |
1126 | else | 1160 | else |
1127 | rec->flags |= flag; | 1161 | rec->flags |= flag; |
1128 | } | 1162 | } |
1163 | |||
1129 | } while_for_each_ftrace_rec(); | 1164 | } while_for_each_ftrace_rec(); |
1130 | spin_unlock(&ftrace_lock); | 1165 | spin_unlock(&ftrace_lock); |
1131 | } | 1166 | } |