~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/lib/dynamic_debug.c

Version: ~ [ linux-4.15-rc3 ] ~ [ linux-4.14.5 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.68 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.105 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.47 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.87 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.51 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.96 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.27.62 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * lib/dynamic_debug.c
  3  *
  4  * make pr_debug()/dev_dbg() calls runtime configurable based upon their
  5  * source module.
  6  *
  7  * Copyright (C) 2008 Jason Baron <jbaron@redhat.com>
  8  * By Greg Banks <gnb@melbourne.sgi.com>
  9  * Copyright (c) 2008 Silicon Graphics Inc.  All Rights Reserved.
 10  * Copyright (C) 2011 Bart Van Assche.  All Rights Reserved.
 11  * Copyright (C) 2013 Du, Changbin <changbin.du@gmail.com>
 12  */
 13 
 14 #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
 15 
 16 #include <linux/kernel.h>
 17 #include <linux/module.h>
 18 #include <linux/moduleparam.h>
 19 #include <linux/kallsyms.h>
 20 #include <linux/types.h>
 21 #include <linux/mutex.h>
 22 #include <linux/proc_fs.h>
 23 #include <linux/seq_file.h>
 24 #include <linux/list.h>
 25 #include <linux/sysctl.h>
 26 #include <linux/ctype.h>
 27 #include <linux/string.h>
 28 #include <linux/parser.h>
 29 #include <linux/string_helpers.h>
 30 #include <linux/uaccess.h>
 31 #include <linux/dynamic_debug.h>
 32 #include <linux/debugfs.h>
 33 #include <linux/slab.h>
 34 #include <linux/jump_label.h>
 35 #include <linux/hardirq.h>
 36 #include <linux/sched.h>
 37 #include <linux/device.h>
 38 #include <linux/netdevice.h>
 39 
 40 extern struct _ddebug __start___verbose[];
 41 extern struct _ddebug __stop___verbose[];
 42 
 43 struct ddebug_table {
 44         struct list_head link;
 45         const char *mod_name;
 46         unsigned int num_ddebugs;
 47         struct _ddebug *ddebugs;
 48 };
 49 
 50 struct ddebug_query {
 51         const char *filename;
 52         const char *module;
 53         const char *function;
 54         const char *format;
 55         unsigned int first_lineno, last_lineno;
 56 };
 57 
 58 struct ddebug_iter {
 59         struct ddebug_table *table;
 60         unsigned int idx;
 61 };
 62 
 63 static DEFINE_MUTEX(ddebug_lock);
 64 static LIST_HEAD(ddebug_tables);
 65 static int verbose;
 66 module_param(verbose, int, 0644);
 67 
 68 /* Return the path relative to source root */
 69 static inline const char *trim_prefix(const char *path)
 70 {
 71         int skip = strlen(__FILE__) - strlen("lib/dynamic_debug.c");
 72 
 73         if (strncmp(path, __FILE__, skip))
 74                 skip = 0; /* prefix mismatch, don't skip */
 75 
 76         return path + skip;
 77 }
 78 
 79 static struct { unsigned flag:8; char opt_char; } opt_array[] = {
 80         { _DPRINTK_FLAGS_PRINT, 'p' },
 81         { _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
 82         { _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
 83         { _DPRINTK_FLAGS_INCL_LINENO, 'l' },
 84         { _DPRINTK_FLAGS_INCL_TID, 't' },
 85         { _DPRINTK_FLAGS_NONE, '_' },
 86 };
 87 
 88 /* format a string into buf[] which describes the _ddebug's flags */
 89 static char *ddebug_describe_flags(struct _ddebug *dp, char *buf,
 90                                     size_t maxlen)
 91 {
 92         char *p = buf;
 93         int i;
 94 
 95         BUG_ON(maxlen < 6);
 96         for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
 97                 if (dp->flags & opt_array[i].flag)
 98                         *p++ = opt_array[i].opt_char;
 99         if (p == buf)
100                 *p++ = '_';
101         *p = '\0';
102 
103         return buf;
104 }
105 
106 #define vpr_info(fmt, ...)                                      \
107 do {                                                            \
108         if (verbose)                                            \
109                 pr_info(fmt, ##__VA_ARGS__);                    \
110 } while (0)
111 
112 static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
113 {
114         /* trim any trailing newlines */
115         int fmtlen = 0;
116 
117         if (query->format) {
118                 fmtlen = strlen(query->format);
119                 while (fmtlen && query->format[fmtlen - 1] == '\n')
120                         fmtlen--;
121         }
122 
123         vpr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" lineno=%u-%u\n",
124                  msg,
125                  query->function ? query->function : "",
126                  query->filename ? query->filename : "",
127                  query->module ? query->module : "",
128                  fmtlen, query->format ? query->format : "",
129                  query->first_lineno, query->last_lineno);
130 }
131 
132 /*
133  * Search the tables for _ddebug's which match the given `query' and
134  * apply the `flags' and `mask' to them.  Returns number of matching
135  * callsites, normally the same as number of changes.  If verbose,
136  * logs the changes.  Takes ddebug_lock.
137  */
138 static int ddebug_change(const struct ddebug_query *query,
139                         unsigned int flags, unsigned int mask)
140 {
141         int i;
142         struct ddebug_table *dt;
143         unsigned int newflags;
144         unsigned int nfound = 0;
145         char flagbuf[10];
146 
147         /* search for matching ddebugs */
148         mutex_lock(&ddebug_lock);
149         list_for_each_entry(dt, &ddebug_tables, link) {
150 
151                 /* match against the module name */
152                 if (query->module &&
153                     !match_wildcard(query->module, dt->mod_name))
154                         continue;
155 
156                 for (i = 0; i < dt->num_ddebugs; i++) {
157                         struct _ddebug *dp = &dt->ddebugs[i];
158 
159                         /* match against the source filename */
160                         if (query->filename &&
161                             !match_wildcard(query->filename, dp->filename) &&
162                             !match_wildcard(query->filename,
163                                            kbasename(dp->filename)) &&
164                             !match_wildcard(query->filename,
165                                            trim_prefix(dp->filename)))
166                                 continue;
167 
168                         /* match against the function */
169                         if (query->function &&
170                             !match_wildcard(query->function, dp->function))
171                                 continue;
172 
173                         /* match against the format */
174                         if (query->format &&
175                             !strstr(dp->format, query->format))
176                                 continue;
177 
178                         /* match against the line number range */
179                         if (query->first_lineno &&
180                             dp->lineno < query->first_lineno)
181                                 continue;
182                         if (query->last_lineno &&
183                             dp->lineno > query->last_lineno)
184                                 continue;
185 
186                         nfound++;
187 
188                         newflags = (dp->flags & mask) | flags;
189                         if (newflags == dp->flags)
190                                 continue;
191 #ifdef HAVE_JUMP_LABEL
192                         if (dp->flags & _DPRINTK_FLAGS_PRINT) {
193                                 if (!(flags & _DPRINTK_FLAGS_PRINT))
194                                         static_branch_disable(&dp->key.dd_key_true);
195                         } else if (flags & _DPRINTK_FLAGS_PRINT)
196                                 static_branch_enable(&dp->key.dd_key_true);
197 #endif
198                         dp->flags = newflags;
199                         vpr_info("changed %s:%d [%s]%s =%s\n",
200                                  trim_prefix(dp->filename), dp->lineno,
201                                  dt->mod_name, dp->function,
202                                  ddebug_describe_flags(dp, flagbuf,
203                                                        sizeof(flagbuf)));
204                 }
205         }
206         mutex_unlock(&ddebug_lock);
207 
208         if (!nfound && verbose)
209                 pr_info("no matches for query\n");
210 
211         return nfound;
212 }
213 
214 /*
215  * Split the buffer `buf' into space-separated words.
216  * Handles simple " and ' quoting, i.e. without nested,
217  * embedded or escaped \".  Return the number of words
218  * or <0 on error.
219  */
220 static int ddebug_tokenize(char *buf, char *words[], int maxwords)
221 {
222         int nwords = 0;
223 
224         while (*buf) {
225                 char *end;
226 
227                 /* Skip leading whitespace */
228                 buf = skip_spaces(buf);
229                 if (!*buf)
230                         break;  /* oh, it was trailing whitespace */
231                 if (*buf == '#')
232                         break;  /* token starts comment, skip rest of line */
233 
234                 /* find `end' of word, whitespace separated or quoted */
235                 if (*buf == '"' || *buf == '\'') {
236                         int quote = *buf++;
237                         for (end = buf; *end && *end != quote; end++)
238                                 ;
239                         if (!*end) {
240                                 pr_err("unclosed quote: %s\n", buf);
241                                 return -EINVAL; /* unclosed quote */
242                         }
243                 } else {
244                         for (end = buf; *end && !isspace(*end); end++)
245                                 ;
246                         BUG_ON(end == buf);
247                 }
248 
249                 /* `buf' is start of word, `end' is one past its end */
250                 if (nwords == maxwords) {
251                         pr_err("too many words, legal max <=%d\n", maxwords);
252                         return -EINVAL; /* ran out of words[] before bytes */
253                 }
254                 if (*end)
255                         *end++ = '\0';  /* terminate the word */
256                 words[nwords++] = buf;
257                 buf = end;
258         }
259 
260         if (verbose) {
261                 int i;
262                 pr_info("split into words:");
263                 for (i = 0; i < nwords; i++)
264                         pr_cont(" \"%s\"", words[i]);
265                 pr_cont("\n");
266         }
267 
268         return nwords;
269 }
270 
271 /*
272  * Parse a single line number.  Note that the empty string ""
273  * is treated as a special case and converted to zero, which
274  * is later treated as a "don't care" value.
275  */
276 static inline int parse_lineno(const char *str, unsigned int *val)
277 {
278         BUG_ON(str == NULL);
279         if (*str == '\0') {
280                 *val = 0;
281                 return 0;
282         }
283         if (kstrtouint(str, 10, val) < 0) {
284                 pr_err("bad line-number: %s\n", str);
285                 return -EINVAL;
286         }
287         return 0;
288 }
289 
290 static int check_set(const char **dest, char *src, char *name)
291 {
292         int rc = 0;
293 
294         if (*dest) {
295                 rc = -EINVAL;
296                 pr_err("match-spec:%s val:%s overridden by %s\n",
297                        name, *dest, src);
298         }
299         *dest = src;
300         return rc;
301 }
302 
303 /*
304  * Parse words[] as a ddebug query specification, which is a series
305  * of (keyword, value) pairs chosen from these possibilities:
306  *
307  * func <function-name>
308  * file <full-pathname>
309  * file <base-filename>
310  * module <module-name>
311  * format <escaped-string-to-find-in-format>
312  * line <lineno>
313  * line <first-lineno>-<last-lineno> // where either may be empty
314  *
315  * Only 1 of each type is allowed.
316  * Returns 0 on success, <0 on error.
317  */
318 static int ddebug_parse_query(char *words[], int nwords,
319                         struct ddebug_query *query, const char *modname)
320 {
321         unsigned int i;
322         int rc = 0;
323 
324         /* check we have an even number of words */
325         if (nwords % 2 != 0) {
326                 pr_err("expecting pairs of match-spec <value>\n");
327                 return -EINVAL;
328         }
329         memset(query, 0, sizeof(*query));
330 
331         if (modname)
332                 /* support $modname.dyndbg=<multiple queries> */
333                 query->module = modname;
334 
335         for (i = 0; i < nwords; i += 2) {
336                 if (!strcmp(words[i], "func")) {
337                         rc = check_set(&query->function, words[i+1], "func");
338                 } else if (!strcmp(words[i], "file")) {
339                         rc = check_set(&query->filename, words[i+1], "file");
340                 } else if (!strcmp(words[i], "module")) {
341                         rc = check_set(&query->module, words[i+1], "module");
342                 } else if (!strcmp(words[i], "format")) {
343                         string_unescape_inplace(words[i+1], UNESCAPE_SPACE |
344                                                             UNESCAPE_OCTAL |
345                                                             UNESCAPE_SPECIAL);
346                         rc = check_set(&query->format, words[i+1], "format");
347                 } else if (!strcmp(words[i], "line")) {
348                         char *first = words[i+1];
349                         char *last = strchr(first, '-');
350                         if (query->first_lineno || query->last_lineno) {
351                                 pr_err("match-spec: line used 2x\n");
352                                 return -EINVAL;
353                         }
354                         if (last)
355                                 *last++ = '\0';
356                         if (parse_lineno(first, &query->first_lineno) < 0)
357                                 return -EINVAL;
358                         if (last) {
359                                 /* range <first>-<last> */
360                                 if (parse_lineno(last, &query->last_lineno) < 0)
361                                         return -EINVAL;
362 
363                                 /* special case for last lineno not specified */
364                                 if (query->last_lineno == 0)
365                                         query->last_lineno = UINT_MAX;
366 
367                                 if (query->last_lineno < query->first_lineno) {
368                                         pr_err("last-line:%d < 1st-line:%d\n",
369                                                 query->last_lineno,
370                                                 query->first_lineno);
371                                         return -EINVAL;
372                                 }
373                         } else {
374                                 query->last_lineno = query->first_lineno;
375                         }
376                 } else {
377                         pr_err("unknown keyword \"%s\"\n", words[i]);
378                         return -EINVAL;
379                 }
380                 if (rc)
381                         return rc;
382         }
383         vpr_info_dq(query, "parsed");
384         return 0;
385 }
386 
387 /*
388  * Parse `str' as a flags specification, format [-+=][p]+.
389  * Sets up *maskp and *flagsp to be used when changing the
390  * flags fields of matched _ddebug's.  Returns 0 on success
391  * or <0 on error.
392  */
393 static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
394                                unsigned int *maskp)
395 {
396         unsigned flags = 0;
397         int op = '=', i;
398 
399         switch (*str) {
400         case '+':
401         case '-':
402         case '=':
403                 op = *str++;
404                 break;
405         default:
406                 pr_err("bad flag-op %c, at start of %s\n", *str, str);
407                 return -EINVAL;
408         }
409         vpr_info("op='%c'\n", op);
410 
411         for (; *str ; ++str) {
412                 for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
413                         if (*str == opt_array[i].opt_char) {
414                                 flags |= opt_array[i].flag;
415                                 break;
416                         }
417                 }
418                 if (i < 0) {
419                         pr_err("unknown flag '%c' in \"%s\"\n", *str, str);
420                         return -EINVAL;
421                 }
422         }
423         vpr_info("flags=0x%x\n", flags);
424 
425         /* calculate final *flagsp, *maskp according to mask and op */
426         switch (op) {
427         case '=':
428                 *maskp = 0;
429                 *flagsp = flags;
430                 break;
431         case '+':
432                 *maskp = ~0U;
433                 *flagsp = flags;
434                 break;
435         case '-':
436                 *maskp = ~flags;
437                 *flagsp = 0;
438                 break;
439         }
440         vpr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp);
441         return 0;
442 }
443 
444 static int ddebug_exec_query(char *query_string, const char *modname)
445 {
446         unsigned int flags = 0, mask = 0;
447         struct ddebug_query query;
448 #define MAXWORDS 9
449         int nwords, nfound;
450         char *words[MAXWORDS];
451 
452         nwords = ddebug_tokenize(query_string, words, MAXWORDS);
453         if (nwords <= 0) {
454                 pr_err("tokenize failed\n");
455                 return -EINVAL;
456         }
457         /* check flags 1st (last arg) so query is pairs of spec,val */
458         if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) {
459                 pr_err("flags parse failed\n");
460                 return -EINVAL;
461         }
462         if (ddebug_parse_query(words, nwords-1, &query, modname)) {
463                 pr_err("query parse failed\n");
464                 return -EINVAL;
465         }
466         /* actually go and implement the change */
467         nfound = ddebug_change(&query, flags, mask);
468         vpr_info_dq(&query, nfound ? "applied" : "no-match");
469 
470         return nfound;
471 }
472 
473 /* handle multiple queries in query string, continue on error, return
474    last error or number of matching callsites.  Module name is either
475    in param (for boot arg) or perhaps in query string.
476 */
477 static int ddebug_exec_queries(char *query, const char *modname)
478 {
479         char *split;
480         int i, errs = 0, exitcode = 0, rc, nfound = 0;
481 
482         for (i = 0; query; query = split) {
483                 split = strpbrk(query, ";\n");
484                 if (split)
485                         *split++ = '\0';
486 
487                 query = skip_spaces(query);
488                 if (!query || !*query || *query == '#')
489                         continue;
490 
491                 vpr_info("query %d: \"%s\"\n", i, query);
492 
493                 rc = ddebug_exec_query(query, modname);
494                 if (rc < 0) {
495                         errs++;
496                         exitcode = rc;
497                 } else {
498                         nfound += rc;
499                 }
500                 i++;
501         }
502         vpr_info("processed %d queries, with %d matches, %d errs\n",
503                  i, nfound, errs);
504 
505         if (exitcode)
506                 return exitcode;
507         return nfound;
508 }
509 
510 #define PREFIX_SIZE 64
511 
512 static int remaining(int wrote)
513 {
514         if (PREFIX_SIZE - wrote > 0)
515                 return PREFIX_SIZE - wrote;
516         return 0;
517 }
518 
519 static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
520 {
521         int pos_after_tid;
522         int pos = 0;
523 
524         *buf = '\0';
525 
526         if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
527                 if (in_interrupt())
528                         pos += snprintf(buf + pos, remaining(pos), "<intr> ");
529                 else
530                         pos += snprintf(buf + pos, remaining(pos), "[%d] ",
531                                         task_pid_vnr(current));
532         }
533         pos_after_tid = pos;
534         if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
535                 pos += snprintf(buf + pos, remaining(pos), "%s:",
536                                 desc->modname);
537         if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
538                 pos += snprintf(buf + pos, remaining(pos), "%s:",
539                                 desc->function);
540         if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
541                 pos += snprintf(buf + pos, remaining(pos), "%d:",
542                                 desc->lineno);
543         if (pos - pos_after_tid)
544                 pos += snprintf(buf + pos, remaining(pos), " ");
545         if (pos >= PREFIX_SIZE)
546                 buf[PREFIX_SIZE - 1] = '\0';
547 
548         return buf;
549 }
550 
551 void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
552 {
553         va_list args;
554         struct va_format vaf;
555         char buf[PREFIX_SIZE];
556 
557         BUG_ON(!descriptor);
558         BUG_ON(!fmt);
559 
560         va_start(args, fmt);
561 
562         vaf.fmt = fmt;
563         vaf.va = &args;
564 
565         printk(KERN_DEBUG "%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
566 
567         va_end(args);
568 }
569 EXPORT_SYMBOL(__dynamic_pr_debug);
570 
571 void __dynamic_dev_dbg(struct _ddebug *descriptor,
572                       const struct device *dev, const char *fmt, ...)
573 {
574         struct va_format vaf;
575         va_list args;
576 
577         BUG_ON(!descriptor);
578         BUG_ON(!fmt);
579 
580         va_start(args, fmt);
581 
582         vaf.fmt = fmt;
583         vaf.va = &args;
584 
585         if (!dev) {
586                 printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
587         } else {
588                 char buf[PREFIX_SIZE];
589 
590                 dev_printk_emit(LOGLEVEL_DEBUG, dev, "%s%s %s: %pV",
591                                 dynamic_emit_prefix(descriptor, buf),
592                                 dev_driver_string(dev), dev_name(dev),
593                                 &vaf);
594         }
595 
596         va_end(args);
597 }
598 EXPORT_SYMBOL(__dynamic_dev_dbg);
599 
600 #ifdef CONFIG_NET
601 
602 void __dynamic_netdev_dbg(struct _ddebug *descriptor,
603                           const struct net_device *dev, const char *fmt, ...)
604 {
605         struct va_format vaf;
606         va_list args;
607 
608         BUG_ON(!descriptor);
609         BUG_ON(!fmt);
610 
611         va_start(args, fmt);
612 
613         vaf.fmt = fmt;
614         vaf.va = &args;
615 
616         if (dev && dev->dev.parent) {
617                 char buf[PREFIX_SIZE];
618 
619                 dev_printk_emit(LOGLEVEL_DEBUG, dev->dev.parent,
620                                 "%s%s %s %s%s: %pV",
621                                 dynamic_emit_prefix(descriptor, buf),
622                                 dev_driver_string(dev->dev.parent),
623                                 dev_name(dev->dev.parent),
624                                 netdev_name(dev), netdev_reg_state(dev),
625                                 &vaf);
626         } else if (dev) {
627                 printk(KERN_DEBUG "%s%s: %pV", netdev_name(dev),
628                        netdev_reg_state(dev), &vaf);
629         } else {
630                 printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
631         }
632 
633         va_end(args);
634 }
635 EXPORT_SYMBOL(__dynamic_netdev_dbg);
636 
637 #endif
638 
639 #define DDEBUG_STRING_SIZE 1024
640 static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE];
641 
642 static __init int ddebug_setup_query(char *str)
643 {
644         if (strlen(str) >= DDEBUG_STRING_SIZE) {
645                 pr_warn("ddebug boot param string too large\n");
646                 return 0;
647         }
648         strlcpy(ddebug_setup_string, str, DDEBUG_STRING_SIZE);
649         return 1;
650 }
651 
652 __setup("ddebug_query=", ddebug_setup_query);
653 
654 /*
655  * File_ops->write method for <debugfs>/dynamic_debug/control.  Gathers the
656  * command text from userspace, parses and executes it.
657  */
658 #define USER_BUF_PAGE 4096
659 static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
660                                   size_t len, loff_t *offp)
661 {
662         char *tmpbuf;
663         int ret;
664 
665         if (len == 0)
666                 return 0;
667         if (len > USER_BUF_PAGE - 1) {
668                 pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
669                 return -E2BIG;
670         }
671         tmpbuf = memdup_user_nul(ubuf, len);
672         if (IS_ERR(tmpbuf))
673                 return PTR_ERR(tmpbuf);
674         vpr_info("read %d bytes from userspace\n", (int)len);
675 
676         ret = ddebug_exec_queries(tmpbuf, NULL);
677         kfree(tmpbuf);
678         if (ret < 0)
679                 return ret;
680 
681         *offp += len;
682         return len;
683 }
684 
685 /*
686  * Set the iterator to point to the first _ddebug object
687  * and return a pointer to that first object.  Returns
688  * NULL if there are no _ddebugs at all.
689  */
690 static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
691 {
692         if (list_empty(&ddebug_tables)) {
693                 iter->table = NULL;
694                 iter->idx = 0;
695                 return NULL;
696         }
697         iter->table = list_entry(ddebug_tables.next,
698                                  struct ddebug_table, link);
699         iter->idx = 0;
700         return &iter->table->ddebugs[iter->idx];
701 }
702 
703 /*
704  * Advance the iterator to point to the next _ddebug
705  * object from the one the iterator currently points at,
706  * and returns a pointer to the new _ddebug.  Returns
707  * NULL if the iterator has seen all the _ddebugs.
708  */
709 static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
710 {
711         if (iter->table == NULL)
712                 return NULL;
713         if (++iter->idx == iter->table->num_ddebugs) {
714                 /* iterate to next table */
715                 iter->idx = 0;
716                 if (list_is_last(&iter->table->link, &ddebug_tables)) {
717                         iter->table = NULL;
718                         return NULL;
719                 }
720                 iter->table = list_entry(iter->table->link.next,
721                                          struct ddebug_table, link);
722         }
723         return &iter->table->ddebugs[iter->idx];
724 }
725 
726 /*
727  * Seq_ops start method.  Called at the start of every
728  * read() call from userspace.  Takes the ddebug_lock and
729  * seeks the seq_file's iterator to the given position.
730  */
731 static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
732 {
733         struct ddebug_iter *iter = m->private;
734         struct _ddebug *dp;
735         int n = *pos;
736 
737         vpr_info("called m=%p *pos=%lld\n", m, (unsigned long long)*pos);
738 
739         mutex_lock(&ddebug_lock);
740 
741         if (!n)
742                 return SEQ_START_TOKEN;
743         if (n < 0)
744                 return NULL;
745         dp = ddebug_iter_first(iter);
746         while (dp != NULL && --n > 0)
747                 dp = ddebug_iter_next(iter);
748         return dp;
749 }
750 
751 /*
752  * Seq_ops next method.  Called several times within a read()
753  * call from userspace, with ddebug_lock held.  Walks to the
754  * next _ddebug object with a special case for the header line.
755  */
756 static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
757 {
758         struct ddebug_iter *iter = m->private;
759         struct _ddebug *dp;
760 
761         vpr_info("called m=%p p=%p *pos=%lld\n",
762                  m, p, (unsigned long long)*pos);
763 
764         if (p == SEQ_START_TOKEN)
765                 dp = ddebug_iter_first(iter);
766         else
767                 dp = ddebug_iter_next(iter);
768         ++*pos;
769         return dp;
770 }
771 
772 /*
773  * Seq_ops show method.  Called several times within a read()
774  * call from userspace, with ddebug_lock held.  Formats the
775  * current _ddebug as a single human-readable line, with a
776  * special case for the header line.
777  */
778 static int ddebug_proc_show(struct seq_file *m, void *p)
779 {
780         struct ddebug_iter *iter = m->private;
781         struct _ddebug *dp = p;
782         char flagsbuf[10];
783 
784         vpr_info("called m=%p p=%p\n", m, p);
785 
786         if (p == SEQ_START_TOKEN) {
787                 seq_puts(m,
788                          "# filename:lineno [module]function flags format\n");
789                 return 0;
790         }
791 
792         seq_printf(m, "%s:%u [%s]%s =%s \"",
793                    trim_prefix(dp->filename), dp->lineno,
794                    iter->table->mod_name, dp->function,
795                    ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
796         seq_escape(m, dp->format, "\t\r\n\"");
797         seq_puts(m, "\"\n");
798 
799         return 0;
800 }
801 
802 /*
803  * Seq_ops stop method.  Called at the end of each read()
804  * call from userspace.  Drops ddebug_lock.
805  */
806 static void ddebug_proc_stop(struct seq_file *m, void *p)
807 {
808         vpr_info("called m=%p p=%p\n", m, p);
809         mutex_unlock(&ddebug_lock);
810 }
811 
812 static const struct seq_operations ddebug_proc_seqops = {
813         .start = ddebug_proc_start,
814         .next = ddebug_proc_next,
815         .show = ddebug_proc_show,
816         .stop = ddebug_proc_stop
817 };
818 
819 /*
820  * File_ops->open method for <debugfs>/dynamic_debug/control.  Does
821  * the seq_file setup dance, and also creates an iterator to walk the
822  * _ddebugs.  Note that we create a seq_file always, even for O_WRONLY
823  * files where it's not needed, as doing so simplifies the ->release
824  * method.
825  */
826 static int ddebug_proc_open(struct inode *inode, struct file *file)
827 {
828         vpr_info("called\n");
829         return seq_open_private(file, &ddebug_proc_seqops,
830                                 sizeof(struct ddebug_iter));
831 }
832 
833 static const struct file_operations ddebug_proc_fops = {
834         .owner = THIS_MODULE,
835         .open = ddebug_proc_open,
836         .read = seq_read,
837         .llseek = seq_lseek,
838         .release = seq_release_private,
839         .write = ddebug_proc_write
840 };
841 
842 /*
843  * Allocate a new ddebug_table for the given module
844  * and add it to the global list.
845  */
846 int ddebug_add_module(struct _ddebug *tab, unsigned int n,
847                              const char *name)
848 {
849         struct ddebug_table *dt;
850         const char *new_name;
851 
852         dt = kzalloc(sizeof(*dt), GFP_KERNEL);
853         if (dt == NULL)
854                 return -ENOMEM;
855         new_name = kstrdup_const(name, GFP_KERNEL);
856         if (new_name == NULL) {
857                 kfree(dt);
858                 return -ENOMEM;
859         }
860         dt->mod_name = new_name;
861         dt->num_ddebugs = n;
862         dt->ddebugs = tab;
863 
864         mutex_lock(&ddebug_lock);
865         list_add_tail(&dt->link, &ddebug_tables);
866         mutex_unlock(&ddebug_lock);
867 
868         vpr_info("%u debug prints in module %s\n", n, dt->mod_name);
869         return 0;
870 }
871 EXPORT_SYMBOL_GPL(ddebug_add_module);
872 
873 /* helper for ddebug_dyndbg_(boot|module)_param_cb */
874 static int ddebug_dyndbg_param_cb(char *param, char *val,
875                                 const char *modname, int on_err)
876 {
877         char *sep;
878 
879         sep = strchr(param, '.');
880         if (sep) {
881                 /* needed only for ddebug_dyndbg_boot_param_cb */
882                 *sep = '\0';
883                 modname = param;
884                 param = sep + 1;
885         }
886         if (strcmp(param, "dyndbg"))
887                 return on_err; /* determined by caller */
888 
889         ddebug_exec_queries((val ? val : "+p"), modname);
890 
891         return 0; /* query failure shouldnt stop module load */
892 }
893 
894 /* handle both dyndbg and $module.dyndbg params at boot */
895 static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
896                                 const char *unused, void *arg)
897 {
898         vpr_info("%s=\"%s\"\n", param, val);
899         return ddebug_dyndbg_param_cb(param, val, NULL, 0);
900 }
901 
902 /*
903  * modprobe foo finds foo.params in boot-args, strips "foo.", and
904  * passes them to load_module().  This callback gets unknown params,
905  * processes dyndbg params, rejects others.
906  */
907 int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
908 {
909         vpr_info("module: %s %s=\"%s\"\n", module, param, val);
910         return ddebug_dyndbg_param_cb(param, val, module, -ENOENT);
911 }
912 
913 static void ddebug_table_free(struct ddebug_table *dt)
914 {
915         list_del_init(&dt->link);
916         kfree_const(dt->mod_name);
917         kfree(dt);
918 }
919 
920 /*
921  * Called in response to a module being unloaded.  Removes
922  * any ddebug_table's which point at the module.
923  */
924 int ddebug_remove_module(const char *mod_name)
925 {
926         struct ddebug_table *dt, *nextdt;
927         int ret = -ENOENT;
928 
929         vpr_info("removing module \"%s\"\n", mod_name);
930 
931         mutex_lock(&ddebug_lock);
932         list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
933                 if (!strcmp(dt->mod_name, mod_name)) {
934                         ddebug_table_free(dt);
935                         ret = 0;
936                 }
937         }
938         mutex_unlock(&ddebug_lock);
939         return ret;
940 }
941 EXPORT_SYMBOL_GPL(ddebug_remove_module);
942 
943 static void ddebug_remove_all_tables(void)
944 {
945         mutex_lock(&ddebug_lock);
946         while (!list_empty(&ddebug_tables)) {
947                 struct ddebug_table *dt = list_entry(ddebug_tables.next,
948                                                       struct ddebug_table,
949                                                       link);
950                 ddebug_table_free(dt);
951         }
952         mutex_unlock(&ddebug_lock);
953 }
954 
955 static __initdata int ddebug_init_success;
956 
957 static int __init dynamic_debug_init_debugfs(void)
958 {
959         struct dentry *dir, *file;
960 
961         if (!ddebug_init_success)
962                 return -ENODEV;
963 
964         dir = debugfs_create_dir("dynamic_debug", NULL);
965         if (!dir)
966                 return -ENOMEM;
967         file = debugfs_create_file("control", 0644, dir, NULL,
968                                         &ddebug_proc_fops);
969         if (!file) {
970                 debugfs_remove(dir);
971                 return -ENOMEM;
972         }
973         return 0;
974 }
975 
976 static int __init dynamic_debug_init(void)
977 {
978         struct _ddebug *iter, *iter_start;
979         const char *modname = NULL;
980         char *cmdline;
981         int ret = 0;
982         int n = 0, entries = 0, modct = 0;
983         int verbose_bytes = 0;
984 
985         if (__start___verbose == __stop___verbose) {
986                 pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
987                 return 1;
988         }
989         iter = __start___verbose;
990         modname = iter->modname;
991         iter_start = iter;
992         for (; iter < __stop___verbose; iter++) {
993                 entries++;
994                 verbose_bytes += strlen(iter->modname) + strlen(iter->function)
995                         + strlen(iter->filename) + strlen(iter->format);
996 
997                 if (strcmp(modname, iter->modname)) {
998                         modct++;
999                         ret = ddebug_add_module(iter_start, n, modname);
1000                         if (ret)
1001                                 goto out_err;
1002                         n = 0;
1003                         modname = iter->modname;
1004                         iter_start = iter;
1005                 }
1006                 n++;
1007         }
1008         ret = ddebug_add_module(iter_start, n, modname);
1009         if (ret)
1010                 goto out_err;
1011 
1012         ddebug_init_success = 1;
1013         vpr_info("%d modules, %d entries and %d bytes in ddebug tables, %d bytes in (readonly) verbose section\n",
1014                  modct, entries, (int)(modct * sizeof(struct ddebug_table)),
1015                  verbose_bytes + (int)(__stop___verbose - __start___verbose));
1016 
1017         /* apply ddebug_query boot param, dont unload tables on err */
1018         if (ddebug_setup_string[0] != '\0') {
1019                 pr_warn("ddebug_query param name is deprecated, change it to dyndbg\n");
1020                 ret = ddebug_exec_queries(ddebug_setup_string, NULL);
1021                 if (ret < 0)
1022                         pr_warn("Invalid ddebug boot param %s\n",
1023                                 ddebug_setup_string);
1024                 else
1025                         pr_info("%d changes by ddebug_query\n", ret);
1026         }
1027         /* now that ddebug tables are loaded, process all boot args
1028          * again to find and activate queries given in dyndbg params.
1029          * While this has already been done for known boot params, it
1030          * ignored the unknown ones (dyndbg in particular).  Reusing
1031          * parse_args avoids ad-hoc parsing.  This will also attempt
1032          * to activate queries for not-yet-loaded modules, which is
1033          * slightly noisy if verbose, but harmless.
1034          */
1035         cmdline = kstrdup(saved_command_line, GFP_KERNEL);
1036         parse_args("dyndbg params", cmdline, NULL,
1037                    0, 0, 0, NULL, &ddebug_dyndbg_boot_param_cb);
1038         kfree(cmdline);
1039         return 0;
1040 
1041 out_err:
1042         ddebug_remove_all_tables();
1043         return 0;
1044 }
1045 /* Allow early initialization for boot messages via boot param */
1046 early_initcall(dynamic_debug_init);
1047 
1048 /* Debugfs setup must be done later */
1049 fs_initcall(dynamic_debug_init_debugfs);
1050 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp