]> git.karo-electronics.de Git - linux-beck.git/commitdiff
ftrace: break up ftrace_match_records into smaller components
authorSteven Rostedt <srostedt@redhat.com>
Fri, 13 Feb 2009 20:56:43 +0000 (15:56 -0500)
committerSteven Rostedt <srostedt@redhat.com>
Mon, 16 Feb 2009 21:49:57 +0000 (16:49 -0500)
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>
kernel/trace/ftrace.c

index f397d7adb62ebc70eff71ab1cf5be9ad55bcab04..fcec31323a10cd668143b1e1d9dbafec27d2adf6 100644 (file)
@@ -1053,79 +1053,114 @@ enum {
        MATCH_END_ONLY,
 };
 
-static void
-ftrace_match_records(unsigned char *buff, int len, int enable)
+/*
+ * (static function - no need for kernel doc)
+ *
+ * Pass in a buffer containing a glob and this function will
+ * set search to point to the search part of the buffer and
+ * return the type of search it is (see enum above).
+ * This does modify buff.
+ *
+ * Returns enum type.
+ *  search returns the pointer to use for comparison.
+ *  not returns 1 if buff started with a '!'
+ *     0 otherwise.
+ */
+static int
+ftrace_setup_glob(unsigned char *buff, int len, char **search, int *not)
 {
-       char str[KSYM_SYMBOL_LEN];
-       char *search = NULL;
-       struct ftrace_page *pg;
-       struct dyn_ftrace *rec;
        int type = MATCH_FULL;
-       unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
-       unsigned i, match = 0, search_len = 0;
-       int not = 0;
+       int i;
 
        if (buff[0] == '!') {
-               not = 1;
+               *not = 1;
                buff++;
                len--;
-       }
+       } else
+               *not = 0;
+
+       *search = buff;
 
        for (i = 0; i < len; i++) {
                if (buff[i] == '*') {
                        if (!i) {
-                               search = buff + i + 1;
+                               *search = buff + 1;
                                type = MATCH_END_ONLY;
-                               search_len = len - (i + 1);
                        } else {
-                               if (type == MATCH_END_ONLY) {
+                               if (type == MATCH_END_ONLY)
                                        type = MATCH_MIDDLE_ONLY;
-                               } else {
-                                       match = i;
+                               else
                                        type = MATCH_FRONT_ONLY;
-                               }
                                buff[i] = 0;
                                break;
                        }
                }
        }
 
+       return type;
+}
+
+static int
+ftrace_match_record(struct dyn_ftrace *rec, char *regex, int len, int type)
+{
+       char str[KSYM_SYMBOL_LEN];
+       int matched = 0;
+       char *ptr;
+
+       kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
+       switch (type) {
+       case MATCH_FULL:
+               if (strcmp(str, regex) == 0)
+                       matched = 1;
+               break;
+       case MATCH_FRONT_ONLY:
+               if (strncmp(str, regex, len) == 0)
+                       matched = 1;
+               break;
+       case MATCH_MIDDLE_ONLY:
+               if (strstr(str, regex))
+                       matched = 1;
+               break;
+       case MATCH_END_ONLY:
+               ptr = strstr(str, regex);
+               if (ptr && (ptr[len] == 0))
+                       matched = 1;
+               break;
+       }
+
+       return matched;
+}
+
+static void ftrace_match_records(char *buff, int len, int enable)
+{
+       char *search;
+       struct ftrace_page *pg;
+       struct dyn_ftrace *rec;
+       int type;
+       unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
+       unsigned search_len;
+       int not;
+
+       type = ftrace_setup_glob(buff, len, &search, &not);
+
+       search_len = strlen(search);
+
        /* should not be called from interrupt context */
        spin_lock(&ftrace_lock);
        if (enable)
                ftrace_filtered = 1;
        do_for_each_ftrace_rec(pg, rec) {
-               int matched = 0;
-               char *ptr;
 
                if (rec->flags & FTRACE_FL_FAILED)
                        continue;
-               kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
-               switch (type) {
-               case MATCH_FULL:
-                       if (strcmp(str, buff) == 0)
-                               matched = 1;
-                       break;
-               case MATCH_FRONT_ONLY:
-                       if (memcmp(str, buff, match) == 0)
-                               matched = 1;
-                       break;
-               case MATCH_MIDDLE_ONLY:
-                       if (strstr(str, search))
-                               matched = 1;
-                       break;
-               case MATCH_END_ONLY:
-                       ptr = strstr(str, search);
-                       if (ptr && (ptr[search_len] == 0))
-                               matched = 1;
-                       break;
-               }
-               if (matched) {
+
+               if (ftrace_match_record(rec, search, search_len, type)) {
                        if (not)
                                rec->flags &= ~flag;
                        else
                                rec->flags |= flag;
                }
+
        } while_for_each_ftrace_rec();
        spin_unlock(&ftrace_lock);
 }