mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: jim.cromie@gmail.com
To: jbaron@redhat.com
Cc: greg@kroah.com, joe@perches.com, bart.vanassche@gmail.com,
	linux-kernel@vger.kernel.org, Jim Cromie <jim.cromie@gmail.com>
Subject: [PATCH 17/25] dynamic_debug: process multiple debug-queries on a line
Date: Wed, 30 Nov 2011 12:56:46 -0700	[thread overview]
Message-ID: <1322683014-13285-18-git-send-email-jim.cromie@gmail.com> (raw)
In-Reply-To: <1322683014-13285-1-git-send-email-jim.cromie@gmail.com>

From: Jim Cromie <jim.cromie@gmail.com>

Insert ddebug_exec_queries() in place of ddebug_exec_query().  It
splits the query string on [;\n], and calls ddebug_exec_query() on
each.  All queries are processed independent of errors, allowing a
query to fail, for example when a module is not installed.  Empty
lines and comments are skipped.  Errors are counted, and the last
error seen (negative) or the number of callsites found (0 or positive)
is returned.  Return code checks are altered accordingly.

With this, multiple queries can be given in ddebug_query, allowing
more selective enabling of callsites.  As a side effect, a set of
commands can be batched in:

	cat cmd-file > $DBGMT/dynamic_debug/control

We dont want a ddebug_query syntax error to kill the dynamic debug
facility, so dynamic_debug_init() zeros ddebug_exec_queries()'s return
code after logging the appropriate message, so that ddebug tables are
preserved and $DBGMT/dynamic_debug/control file is created.  This
would be appropriate even without accepting multiple queries.

This patch also alters ddebug_change() to return number of callsites
matched (which typically is the same as number of callsites changed).
ddebug_exec_query() also returns the number found, or a negative value
if theres a parse error on the query.

Splitting on [;\n] prevents their use in format-specs, but selecting
callsites on punctuation is brittle anyway, meaningful and selective
substrings are more typical.

Note: splitting queries on ';' before handling trailing #comments
means that a ';' also terminates a comment, and text after the ';' is
treated as another query.  This trailing query will almost certainly
result in a parse error and thus have no effect other than the error
message.  The double corner case with unexpected results is:

     ddebug_query="func foo +p # enable foo ; +p"

Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 Documentation/dynamic-debug-howto.txt |   17 +++-----
 lib/dynamic_debug.c                   |   73 ++++++++++++++++++++++++++-------
 2 files changed, 65 insertions(+), 25 deletions(-)

diff --git a/Documentation/dynamic-debug-howto.txt b/Documentation/dynamic-debug-howto.txt
index 378b5d1..989a892 100644
--- a/Documentation/dynamic-debug-howto.txt
+++ b/Documentation/dynamic-debug-howto.txt
@@ -12,7 +12,7 @@ dynamically enabled per-callsite.
 Dynamic debug has even more useful features:
 
  * Simple query language allows turning on and off debugging statements by
-   matching any combination of:
+   matching any combination of 0 or 1 of:
 
    - source filename
    - function name
@@ -92,18 +92,15 @@ nullarbor:~ # echo -c 'file svcsock.c\nline 1603 +p' >
 nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' >
 				<debugfs>/dynamic_debug/control
 
-Commands are bounded by a write() system call.  If you want to do
-multiple commands you need to do a separate "echo" for each, like:
+Command submissions are bounded by a write() system call.
+Multiple commands can be written together, separated by ';' or '\n'.
 
-nullarbor:~ # echo 'file svcsock.c line 1603 +p' > /proc/dprintk ;\
-> echo 'file svcsock.c line 1563 +p' > /proc/dprintk
+  ~# echo "func pnpacpi_get_resources +p; func pnp_assign_mem +p" \
+     > <debugfs>/dynamic_debug/control
 
-or even like:
+If your query set is big, you can batch them too:
 
-nullarbor:~ # (
-> echo 'file svcsock.c line 1603 +p' ;\
-> echo 'file svcsock.c line 1563 +p' ;\
-> ) > /proc/dprintk
+  ~# cat query-batch-file > <debugfs>/dynamic_debug/control
 
 At the syntactical level, a command comprises a sequence of match
 specifications, followed by a flags change specification.
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 1a0e9bd..516ad4e 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -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:
-- 
1.7.7.3


  parent reply	other threads:[~2011-11-30 19:58 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-11-30 19:56 [patch 00/25] dynamic-debug during module initialization jim.cromie
2011-11-30 19:56 ` [PATCH 01/25] kernel/module.c: fix compile err, warnings under ifdef DEBUGP jim.cromie
2011-11-30 19:56 ` [PATCH 02/25] dynamic_debug: fix whitespace complaints from scripts/cleanfile jim.cromie
2011-11-30 19:56 ` [PATCH 03/25] dynamic_debug: drop enabled field from struct _ddebug, use _DPRINTK_FLAGS_PRINT jim.cromie
2011-11-30 19:56 ` [PATCH 04/25] dynamic_debug: make dynamic-debug supersede DEBUG ccflag jim.cromie
2011-11-30 22:03   ` Jason Baron
2011-11-30 22:16     ` Joe Perches
2011-12-01  0:26       ` Jim Cromie
2011-11-30 19:56 ` [PATCH 05/25] dynamic_debug: change verbosity at runtime jim.cromie
2011-11-30 19:56 ` [PATCH 06/25] dynamic_debug: replace strcpy with strlcpy, in ddebug_setup_query() jim.cromie
2011-11-30 19:56 ` [PATCH 07/25] dynamic_debug: pr_err() call should not depend upon verbosity jim.cromie
2011-11-30 19:56 ` [PATCH 08/25] dynamic_debug: drop explicit !=NULL checks jim.cromie
2011-11-30 19:56 ` [PATCH 09/25] dynamic_debug: describe_flags with '=[pmflt_]*' jim.cromie
2011-11-30 19:56 ` [PATCH 10/25] dynamic_debug: tighten up error checking on debug queries jim.cromie
2011-11-30 19:56 ` [PATCH 11/25] dynamic_debug: early return if _ddebug table is empty jim.cromie
2011-11-30 19:56 ` [PATCH 12/25] dynamic_debug: reduce lineno field to a saner 18 bits jim.cromie
2011-11-30 19:56 ` [PATCH 13/25] dynamic_debug: chop off comments in ddebug_tokenize jim.cromie
2011-11-30 19:56 ` [PATCH 14/25] dynamic_debug: enlarge command/query write buffer jim.cromie
2011-11-30 19:56 ` [PATCH 15/25] dynamic_debug: add trim_prefix() to provide source-root relative paths jim.cromie
2011-11-30 19:56 ` [PATCH 16/25] dynamic_debug: factor vpr_info_dq out of ddebug_parse_query jim.cromie
2011-11-30 19:56 ` jim.cromie [this message]
2011-11-30 19:56 ` [PATCH 18/25] dynamic_debug: Introduce global fake module param module.ddebug jim.cromie
2011-12-01  2:19   ` Rusty Russell
2011-12-01  8:15     ` Jim Cromie
2011-12-02  0:50       ` Rusty Russell
2011-11-30 19:56 ` [PATCH 19/25] pnp: if CONFIG_DYNAMIC_DEBUG, use pnp.ddebug instead of pnp.debug jim.cromie
2011-12-01 11:15   ` Thomas Renninger
2011-12-05  5:42     ` Jim Cromie
2011-12-05 14:47       ` Thomas Renninger
2011-12-05 19:15         ` Jim Cromie
2011-12-05 21:44           ` Thomas Renninger
2011-11-30 19:56 ` [PATCH 20/25] dynamic_debug: rename ddebug param to dyndbg, plus minor tweaks jim.cromie
2011-11-30 19:56 ` [PATCH 21/25] dynamic_debug: handle $module.dyndbg="+mfp" boot-line args jim.cromie
2011-11-30 19:56 ` [PATCH 22/25] dynamic_debug: add modname arg to exec_query callchain jim.cromie
2011-11-30 19:56 ` [PATCH 23/25] dynamic_debug: allow wildcard modname in boot-line query jim.cromie
2011-11-30 19:56 ` [PATCH 24/25] kernel/module: replace DEBUGP with pr_debug jim.cromie
2011-11-30 19:56 ` [PATCH 25/25] dynamic_debug: protect "dyndbg" fake module param name at compile-time jim.cromie
2011-12-01 21:20 ` [patch 00/25] dynamic-debug during module initialization Jason Baron
2011-12-03 15:56   ` Jim Cromie
     [not found] ` <201203051614.29457.trenn@suse.de>
     [not found]   ` <CAJfuBxw=kL5j2VNxXLqiY3ftY3n7MQnY5SkfB09Nscyw8Fh9Zw@mail.gmail.com>
     [not found]     ` <201203061002.57810.trenn@suse.de>
     [not found]       ` <20120306144754.GA2421@redhat.com>
2012-03-07  0:30         ` [PATCH 18/25] dynamic_debug: Introduce global fake module param module.ddebug Rusty Russell
2011-11-30 20:27 [patch 00/25] dynamic-debug enhancements Jim Cromie
2011-12-06 18:59 ` Jim Cromie
2011-12-06 19:11   ` [patch 00/24 ] dynamic debug enhancements: multi-queries during mod-init jim.cromie
2011-12-06 19:11     ` [PATCH 17/25] dynamic_debug: process multiple debug-queries on a line jim.cromie
2011-12-12 23:12 [PATCH 01/25] kernel/module.c: fix compile err, warnings under ifdef DEBUGP, switch to pr_debug jim.cromie
2011-12-12 23:12 ` [PATCH 17/25] dynamic_debug: process multiple debug-queries on a line jim.cromie

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1322683014-13285-18-git-send-email-jim.cromie@gmail.com \
    --to=jim.cromie@gmail.com \
    --cc=bart.vanassche@gmail.com \
    --cc=greg@kroah.com \
    --cc=jbaron@redhat.com \
    --cc=joe@perches.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®