]> Pileus Git - ~andy/linux/blobdiff - lib/dynamic_debug.c
Merge branch 'for-linus-min' of git://git.kernel.org/pub/scm/linux/kernel/git/mason...
[~andy/linux] / lib / dynamic_debug.c
index 93fc5d500cd5e0aa90895d282dfd81150dcd1681..310c753cf83e27788e80ae81088b48ad824149be 100644 (file)
@@ -124,13 +124,13 @@ do {                                                                      \
 } while (0)
 
 /*
- * Search the tables for _ddebug's which match the given
- * `query' and apply the `flags' and `mask' to them.  Tells
- * the user which ddebug's were changed, or whether none
- * were matched.
+ * Search the tables for _ddebug's which match the given `query' and
+ * apply the `flags' and `mask' to them.  Returns number of matching
+ * callsites, normally the same as number of changes.  If verbose,
+ * logs the changes.  Takes ddebug_lock.
  */
-static void ddebug_change(const struct ddebug_query *query,
-                          unsigned int flags, unsigned int mask)
+static int ddebug_change(const struct ddebug_query *query,
+                       unsigned int flags, unsigned int mask)
 {
        int i;
        struct ddebug_table *dt;
@@ -192,6 +192,8 @@ static void ddebug_change(const struct ddebug_query *query,
 
        if (!nfound && verbose)
                pr_info("no matches for query\n");
+
+       return nfound;
 }
 
 /*
@@ -449,7 +451,7 @@ static int ddebug_exec_query(char *query_string)
        unsigned int flags = 0, mask = 0;
        struct ddebug_query query;
 #define MAXWORDS 9
-       int nwords;
+       int nwords, nfound;
        char *words[MAXWORDS];
 
        nwords = ddebug_tokenize(query_string, words, MAXWORDS);
@@ -461,8 +463,47 @@ static int ddebug_exec_query(char *query_string)
                return -EINVAL;
 
        /* actually go and implement the change */
-       ddebug_change(&query, flags, mask);
-       return 0;
+       nfound = ddebug_change(&query, flags, mask);
+       vpr_info_dq((&query), (nfound) ? "applied" : "no-match");
+
+       return nfound;
+}
+
+/* handle multiple queries in query string, continue on error, return
+   last error or number of matching callsites.  Module name is either
+   in param (for boot arg) or perhaps in query string.
+*/
+static int ddebug_exec_queries(char *query)
+{
+       char *split;
+       int i, errs = 0, exitcode = 0, rc, nfound = 0;
+
+       for (i = 0; query; query = split) {
+               split = strpbrk(query, ";\n");
+               if (split)
+                       *split++ = '\0';
+
+               query = skip_spaces(query);
+               if (!query || !*query || *query == '#')
+                       continue;
+
+               if (verbose)
+                       pr_info("query %d: \"%s\"\n", i, query);
+
+               rc = ddebug_exec_query(query);
+               if (rc < 0) {
+                       errs++;
+                       exitcode = rc;
+               } else
+                       nfound += rc;
+               i++;
+       }
+       pr_info("processed %d queries, with %d matches, %d errs\n",
+                i, nfound, errs);
+
+       if (exitcode)
+               return exitcode;
+       return nfound;
 }
 
 #define PREFIX_SIZE 64
@@ -615,9 +656,9 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
        if (verbose)
                pr_info("read %d bytes from userspace\n", (int)len);
 
-       ret = ddebug_exec_query(tmpbuf);
+       ret = ddebug_exec_queries(tmpbuf);
        kfree(tmpbuf);
-       if (ret)
+       if (ret < 0)
                return ret;
 
        *offp += len;
@@ -927,13 +968,15 @@ static int __init dynamic_debug_init(void)
 
        /* ddebug_query boot param got passed -> set it up */
        if (ddebug_setup_string[0] != '\0') {
-               ret = ddebug_exec_query(ddebug_setup_string);
-               if (ret)
+               ret = ddebug_exec_queries(ddebug_setup_string);
+               if (ret < 0)
                        pr_warn("Invalid ddebug boot param %s",
                                ddebug_setup_string);
                else
-                       pr_info("ddebug initialized with string %s",
-                               ddebug_setup_string);
+                       pr_info("%d changes by ddebug_query\n", ret);
+
+               /* keep tables even on ddebug_query parse error */
+               ret = 0;
        }
 
 out_free: