0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #define pr_fmt(fmt) "dyndbg: " fmt
0015
0016 #include <linux/kernel.h>
0017 #include <linux/module.h>
0018 #include <linux/moduleparam.h>
0019 #include <linux/kallsyms.h>
0020 #include <linux/types.h>
0021 #include <linux/mutex.h>
0022 #include <linux/proc_fs.h>
0023 #include <linux/seq_file.h>
0024 #include <linux/list.h>
0025 #include <linux/sysctl.h>
0026 #include <linux/ctype.h>
0027 #include <linux/string.h>
0028 #include <linux/parser.h>
0029 #include <linux/string_helpers.h>
0030 #include <linux/uaccess.h>
0031 #include <linux/dynamic_debug.h>
0032 #include <linux/debugfs.h>
0033 #include <linux/slab.h>
0034 #include <linux/jump_label.h>
0035 #include <linux/hardirq.h>
0036 #include <linux/sched.h>
0037 #include <linux/device.h>
0038 #include <linux/netdevice.h>
0039
0040 #include <rdma/ib_verbs.h>
0041
0042 extern struct _ddebug __start___dyndbg[];
0043 extern struct _ddebug __stop___dyndbg[];
0044
0045 struct ddebug_table {
0046 struct list_head link;
0047 const char *mod_name;
0048 unsigned int num_ddebugs;
0049 struct _ddebug *ddebugs;
0050 };
0051
0052 struct ddebug_query {
0053 const char *filename;
0054 const char *module;
0055 const char *function;
0056 const char *format;
0057 unsigned int first_lineno, last_lineno;
0058 };
0059
0060 struct ddebug_iter {
0061 struct ddebug_table *table;
0062 unsigned int idx;
0063 };
0064
0065 struct flag_settings {
0066 unsigned int flags;
0067 unsigned int mask;
0068 };
0069
0070 static DEFINE_MUTEX(ddebug_lock);
0071 static LIST_HEAD(ddebug_tables);
0072 static int verbose;
0073 module_param(verbose, int, 0644);
0074 MODULE_PARM_DESC(verbose, " dynamic_debug/control processing "
0075 "( 0 = off (default), 1 = module add/rm, 2 = >control summary, 3 = parsing, 4 = per-site changes)");
0076
0077
0078 static inline const char *trim_prefix(const char *path)
0079 {
0080 int skip = strlen(__FILE__) - strlen("lib/dynamic_debug.c");
0081
0082 if (strncmp(path, __FILE__, skip))
0083 skip = 0;
0084
0085 return path + skip;
0086 }
0087
0088 static struct { unsigned flag:8; char opt_char; } opt_array[] = {
0089 { _DPRINTK_FLAGS_PRINT, 'p' },
0090 { _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
0091 { _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
0092 { _DPRINTK_FLAGS_INCL_LINENO, 'l' },
0093 { _DPRINTK_FLAGS_INCL_TID, 't' },
0094 { _DPRINTK_FLAGS_NONE, '_' },
0095 };
0096
0097 struct flagsbuf { char buf[ARRAY_SIZE(opt_array)+1]; };
0098
0099
0100 static char *ddebug_describe_flags(unsigned int flags, struct flagsbuf *fb)
0101 {
0102 char *p = fb->buf;
0103 int i;
0104
0105 for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
0106 if (flags & opt_array[i].flag)
0107 *p++ = opt_array[i].opt_char;
0108 if (p == fb->buf)
0109 *p++ = '_';
0110 *p = '\0';
0111
0112 return fb->buf;
0113 }
0114
0115 #define vnpr_info(lvl, fmt, ...) \
0116 do { \
0117 if (verbose >= lvl) \
0118 pr_info(fmt, ##__VA_ARGS__); \
0119 } while (0)
0120
0121 #define vpr_info(fmt, ...) vnpr_info(1, fmt, ##__VA_ARGS__)
0122 #define v2pr_info(fmt, ...) vnpr_info(2, fmt, ##__VA_ARGS__)
0123 #define v3pr_info(fmt, ...) vnpr_info(3, fmt, ##__VA_ARGS__)
0124 #define v4pr_info(fmt, ...) vnpr_info(4, fmt, ##__VA_ARGS__)
0125
0126 static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
0127 {
0128
0129 int fmtlen = 0;
0130
0131 if (query->format) {
0132 fmtlen = strlen(query->format);
0133 while (fmtlen && query->format[fmtlen - 1] == '\n')
0134 fmtlen--;
0135 }
0136
0137 v3pr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" lineno=%u-%u\n",
0138 msg,
0139 query->function ?: "",
0140 query->filename ?: "",
0141 query->module ?: "",
0142 fmtlen, query->format ?: "",
0143 query->first_lineno, query->last_lineno);
0144 }
0145
0146
0147
0148
0149
0150
0151
0152 static int ddebug_change(const struct ddebug_query *query,
0153 struct flag_settings *modifiers)
0154 {
0155 int i;
0156 struct ddebug_table *dt;
0157 unsigned int newflags;
0158 unsigned int nfound = 0;
0159 struct flagsbuf fbuf;
0160
0161
0162 mutex_lock(&ddebug_lock);
0163 list_for_each_entry(dt, &ddebug_tables, link) {
0164
0165
0166 if (query->module &&
0167 !match_wildcard(query->module, dt->mod_name))
0168 continue;
0169
0170 for (i = 0; i < dt->num_ddebugs; i++) {
0171 struct _ddebug *dp = &dt->ddebugs[i];
0172
0173
0174 if (query->filename &&
0175 !match_wildcard(query->filename, dp->filename) &&
0176 !match_wildcard(query->filename,
0177 kbasename(dp->filename)) &&
0178 !match_wildcard(query->filename,
0179 trim_prefix(dp->filename)))
0180 continue;
0181
0182
0183 if (query->function &&
0184 !match_wildcard(query->function, dp->function))
0185 continue;
0186
0187
0188 if (query->format) {
0189 if (*query->format == '^') {
0190 char *p;
0191
0192 p = strstr(dp->format, query->format+1);
0193 if (p != dp->format)
0194 continue;
0195 } else if (!strstr(dp->format, query->format))
0196 continue;
0197 }
0198
0199
0200 if (query->first_lineno &&
0201 dp->lineno < query->first_lineno)
0202 continue;
0203 if (query->last_lineno &&
0204 dp->lineno > query->last_lineno)
0205 continue;
0206
0207 nfound++;
0208
0209 newflags = (dp->flags & modifiers->mask) | modifiers->flags;
0210 if (newflags == dp->flags)
0211 continue;
0212 #ifdef CONFIG_JUMP_LABEL
0213 if (dp->flags & _DPRINTK_FLAGS_PRINT) {
0214 if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT))
0215 static_branch_disable(&dp->key.dd_key_true);
0216 } else if (modifiers->flags & _DPRINTK_FLAGS_PRINT)
0217 static_branch_enable(&dp->key.dd_key_true);
0218 #endif
0219 dp->flags = newflags;
0220 v4pr_info("changed %s:%d [%s]%s =%s\n",
0221 trim_prefix(dp->filename), dp->lineno,
0222 dt->mod_name, dp->function,
0223 ddebug_describe_flags(dp->flags, &fbuf));
0224 }
0225 }
0226 mutex_unlock(&ddebug_lock);
0227
0228 if (!nfound && verbose)
0229 pr_info("no matches for query\n");
0230
0231 return nfound;
0232 }
0233
0234
0235
0236
0237
0238
0239
0240 static int ddebug_tokenize(char *buf, char *words[], int maxwords)
0241 {
0242 int nwords = 0;
0243
0244 while (*buf) {
0245 char *end;
0246
0247
0248 buf = skip_spaces(buf);
0249 if (!*buf)
0250 break;
0251 if (*buf == '#')
0252 break;
0253
0254
0255 if (*buf == '"' || *buf == '\'') {
0256 int quote = *buf++;
0257 for (end = buf; *end && *end != quote; end++)
0258 ;
0259 if (!*end) {
0260 pr_err("unclosed quote: %s\n", buf);
0261 return -EINVAL;
0262 }
0263 } else {
0264 for (end = buf; *end && !isspace(*end); end++)
0265 ;
0266 BUG_ON(end == buf);
0267 }
0268
0269
0270 if (nwords == maxwords) {
0271 pr_err("too many words, legal max <=%d\n", maxwords);
0272 return -EINVAL;
0273 }
0274 if (*end)
0275 *end++ = '\0';
0276 words[nwords++] = buf;
0277 buf = end;
0278 }
0279
0280 if (verbose >= 3) {
0281 int i;
0282 pr_info("split into words:");
0283 for (i = 0; i < nwords; i++)
0284 pr_cont(" \"%s\"", words[i]);
0285 pr_cont("\n");
0286 }
0287
0288 return nwords;
0289 }
0290
0291
0292
0293
0294
0295
0296 static inline int parse_lineno(const char *str, unsigned int *val)
0297 {
0298 BUG_ON(str == NULL);
0299 if (*str == '\0') {
0300 *val = 0;
0301 return 0;
0302 }
0303 if (kstrtouint(str, 10, val) < 0) {
0304 pr_err("bad line-number: %s\n", str);
0305 return -EINVAL;
0306 }
0307 return 0;
0308 }
0309
0310 static int parse_linerange(struct ddebug_query *query, const char *first)
0311 {
0312 char *last = strchr(first, '-');
0313
0314 if (query->first_lineno || query->last_lineno) {
0315 pr_err("match-spec: line used 2x\n");
0316 return -EINVAL;
0317 }
0318 if (last)
0319 *last++ = '\0';
0320 if (parse_lineno(first, &query->first_lineno) < 0)
0321 return -EINVAL;
0322 if (last) {
0323
0324 if (parse_lineno(last, &query->last_lineno) < 0)
0325 return -EINVAL;
0326
0327
0328 if (query->last_lineno == 0)
0329 query->last_lineno = UINT_MAX;
0330
0331 if (query->last_lineno < query->first_lineno) {
0332 pr_err("last-line:%d < 1st-line:%d\n",
0333 query->last_lineno,
0334 query->first_lineno);
0335 return -EINVAL;
0336 }
0337 } else {
0338 query->last_lineno = query->first_lineno;
0339 }
0340 v3pr_info("parsed line %d-%d\n", query->first_lineno,
0341 query->last_lineno);
0342 return 0;
0343 }
0344
0345 static int check_set(const char **dest, char *src, char *name)
0346 {
0347 int rc = 0;
0348
0349 if (*dest) {
0350 rc = -EINVAL;
0351 pr_err("match-spec:%s val:%s overridden by %s\n",
0352 name, *dest, src);
0353 }
0354 *dest = src;
0355 return rc;
0356 }
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373 static int ddebug_parse_query(char *words[], int nwords,
0374 struct ddebug_query *query, const char *modname)
0375 {
0376 unsigned int i;
0377 int rc = 0;
0378 char *fline;
0379
0380
0381 if (nwords % 2 != 0) {
0382 pr_err("expecting pairs of match-spec <value>\n");
0383 return -EINVAL;
0384 }
0385
0386 if (modname)
0387
0388 query->module = modname;
0389
0390 for (i = 0; i < nwords; i += 2) {
0391 char *keyword = words[i];
0392 char *arg = words[i+1];
0393
0394 if (!strcmp(keyword, "func")) {
0395 rc = check_set(&query->function, arg, "func");
0396 } else if (!strcmp(keyword, "file")) {
0397 if (check_set(&query->filename, arg, "file"))
0398 return -EINVAL;
0399
0400
0401 fline = strchr(query->filename, ':');
0402 if (!fline)
0403 continue;
0404 *fline++ = '\0';
0405 if (isalpha(*fline) || *fline == '*' || *fline == '?') {
0406
0407 if (check_set(&query->function, fline, "func"))
0408 return -EINVAL;
0409 } else {
0410 if (parse_linerange(query, fline))
0411 return -EINVAL;
0412 }
0413 } else if (!strcmp(keyword, "module")) {
0414 rc = check_set(&query->module, arg, "module");
0415 } else if (!strcmp(keyword, "format")) {
0416 string_unescape_inplace(arg, UNESCAPE_SPACE |
0417 UNESCAPE_OCTAL |
0418 UNESCAPE_SPECIAL);
0419 rc = check_set(&query->format, arg, "format");
0420 } else if (!strcmp(keyword, "line")) {
0421 if (parse_linerange(query, arg))
0422 return -EINVAL;
0423 } else {
0424 pr_err("unknown keyword \"%s\"\n", keyword);
0425 return -EINVAL;
0426 }
0427 if (rc)
0428 return rc;
0429 }
0430 vpr_info_dq(query, "parsed");
0431 return 0;
0432 }
0433
0434
0435
0436
0437
0438
0439
0440 static int ddebug_parse_flags(const char *str, struct flag_settings *modifiers)
0441 {
0442 int op, i;
0443
0444 switch (*str) {
0445 case '+':
0446 case '-':
0447 case '=':
0448 op = *str++;
0449 break;
0450 default:
0451 pr_err("bad flag-op %c, at start of %s\n", *str, str);
0452 return -EINVAL;
0453 }
0454 v3pr_info("op='%c'\n", op);
0455
0456 for (; *str ; ++str) {
0457 for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
0458 if (*str == opt_array[i].opt_char) {
0459 modifiers->flags |= opt_array[i].flag;
0460 break;
0461 }
0462 }
0463 if (i < 0) {
0464 pr_err("unknown flag '%c'\n", *str);
0465 return -EINVAL;
0466 }
0467 }
0468 v3pr_info("flags=0x%x\n", modifiers->flags);
0469
0470
0471 switch (op) {
0472 case '=':
0473
0474 modifiers->mask = 0;
0475 break;
0476 case '+':
0477 modifiers->mask = ~0U;
0478 break;
0479 case '-':
0480 modifiers->mask = ~modifiers->flags;
0481 modifiers->flags = 0;
0482 break;
0483 }
0484 v3pr_info("*flagsp=0x%x *maskp=0x%x\n", modifiers->flags, modifiers->mask);
0485
0486 return 0;
0487 }
0488
0489 static int ddebug_exec_query(char *query_string, const char *modname)
0490 {
0491 struct flag_settings modifiers = {};
0492 struct ddebug_query query = {};
0493 #define MAXWORDS 9
0494 int nwords, nfound;
0495 char *words[MAXWORDS];
0496
0497 nwords = ddebug_tokenize(query_string, words, MAXWORDS);
0498 if (nwords <= 0) {
0499 pr_err("tokenize failed\n");
0500 return -EINVAL;
0501 }
0502
0503 if (ddebug_parse_flags(words[nwords-1], &modifiers)) {
0504 pr_err("flags parse failed\n");
0505 return -EINVAL;
0506 }
0507 if (ddebug_parse_query(words, nwords-1, &query, modname)) {
0508 pr_err("query parse failed\n");
0509 return -EINVAL;
0510 }
0511
0512 nfound = ddebug_change(&query, &modifiers);
0513 vpr_info_dq(&query, nfound ? "applied" : "no-match");
0514
0515 return nfound;
0516 }
0517
0518
0519
0520
0521
0522 static int ddebug_exec_queries(char *query, const char *modname)
0523 {
0524 char *split;
0525 int i, errs = 0, exitcode = 0, rc, nfound = 0;
0526
0527 for (i = 0; query; query = split) {
0528 split = strpbrk(query, ";\n");
0529 if (split)
0530 *split++ = '\0';
0531
0532 query = skip_spaces(query);
0533 if (!query || !*query || *query == '#')
0534 continue;
0535
0536 vpr_info("query %d: \"%s\" mod:%s\n", i, query, modname ?: "*");
0537
0538 rc = ddebug_exec_query(query, modname);
0539 if (rc < 0) {
0540 errs++;
0541 exitcode = rc;
0542 } else {
0543 nfound += rc;
0544 }
0545 i++;
0546 }
0547 if (i)
0548 v2pr_info("processed %d queries, with %d matches, %d errs\n",
0549 i, nfound, errs);
0550
0551 if (exitcode)
0552 return exitcode;
0553 return nfound;
0554 }
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566 int dynamic_debug_exec_queries(const char *query, const char *modname)
0567 {
0568 int rc;
0569 char *qry;
0570
0571 if (!query) {
0572 pr_err("non-null query/command string expected\n");
0573 return -EINVAL;
0574 }
0575 qry = kstrndup(query, PAGE_SIZE, GFP_KERNEL);
0576 if (!qry)
0577 return -ENOMEM;
0578
0579 rc = ddebug_exec_queries(qry, modname);
0580 kfree(qry);
0581 return rc;
0582 }
0583 EXPORT_SYMBOL_GPL(dynamic_debug_exec_queries);
0584
0585 #define PREFIX_SIZE 64
0586
0587 static int remaining(int wrote)
0588 {
0589 if (PREFIX_SIZE - wrote > 0)
0590 return PREFIX_SIZE - wrote;
0591 return 0;
0592 }
0593
0594 static char *__dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
0595 {
0596 int pos_after_tid;
0597 int pos = 0;
0598
0599 if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
0600 if (in_interrupt())
0601 pos += snprintf(buf + pos, remaining(pos), "<intr> ");
0602 else
0603 pos += snprintf(buf + pos, remaining(pos), "[%d] ",
0604 task_pid_vnr(current));
0605 }
0606 pos_after_tid = pos;
0607 if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
0608 pos += snprintf(buf + pos, remaining(pos), "%s:",
0609 desc->modname);
0610 if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
0611 pos += snprintf(buf + pos, remaining(pos), "%s:",
0612 desc->function);
0613 if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
0614 pos += snprintf(buf + pos, remaining(pos), "%d:",
0615 desc->lineno);
0616 if (pos - pos_after_tid)
0617 pos += snprintf(buf + pos, remaining(pos), " ");
0618 if (pos >= PREFIX_SIZE)
0619 buf[PREFIX_SIZE - 1] = '\0';
0620
0621 return buf;
0622 }
0623
0624 static inline char *dynamic_emit_prefix(struct _ddebug *desc, char *buf)
0625 {
0626 if (unlikely(desc->flags & _DPRINTK_FLAGS_INCL_ANY))
0627 return __dynamic_emit_prefix(desc, buf);
0628 return buf;
0629 }
0630
0631 void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
0632 {
0633 va_list args;
0634 struct va_format vaf;
0635 char buf[PREFIX_SIZE] = "";
0636
0637 BUG_ON(!descriptor);
0638 BUG_ON(!fmt);
0639
0640 va_start(args, fmt);
0641
0642 vaf.fmt = fmt;
0643 vaf.va = &args;
0644
0645 printk(KERN_DEBUG "%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
0646
0647 va_end(args);
0648 }
0649 EXPORT_SYMBOL(__dynamic_pr_debug);
0650
0651 void __dynamic_dev_dbg(struct _ddebug *descriptor,
0652 const struct device *dev, const char *fmt, ...)
0653 {
0654 struct va_format vaf;
0655 va_list args;
0656
0657 BUG_ON(!descriptor);
0658 BUG_ON(!fmt);
0659
0660 va_start(args, fmt);
0661
0662 vaf.fmt = fmt;
0663 vaf.va = &args;
0664
0665 if (!dev) {
0666 printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
0667 } else {
0668 char buf[PREFIX_SIZE] = "";
0669
0670 dev_printk_emit(LOGLEVEL_DEBUG, dev, "%s%s %s: %pV",
0671 dynamic_emit_prefix(descriptor, buf),
0672 dev_driver_string(dev), dev_name(dev),
0673 &vaf);
0674 }
0675
0676 va_end(args);
0677 }
0678 EXPORT_SYMBOL(__dynamic_dev_dbg);
0679
0680 #ifdef CONFIG_NET
0681
0682 void __dynamic_netdev_dbg(struct _ddebug *descriptor,
0683 const struct net_device *dev, const char *fmt, ...)
0684 {
0685 struct va_format vaf;
0686 va_list args;
0687
0688 BUG_ON(!descriptor);
0689 BUG_ON(!fmt);
0690
0691 va_start(args, fmt);
0692
0693 vaf.fmt = fmt;
0694 vaf.va = &args;
0695
0696 if (dev && dev->dev.parent) {
0697 char buf[PREFIX_SIZE] = "";
0698
0699 dev_printk_emit(LOGLEVEL_DEBUG, dev->dev.parent,
0700 "%s%s %s %s%s: %pV",
0701 dynamic_emit_prefix(descriptor, buf),
0702 dev_driver_string(dev->dev.parent),
0703 dev_name(dev->dev.parent),
0704 netdev_name(dev), netdev_reg_state(dev),
0705 &vaf);
0706 } else if (dev) {
0707 printk(KERN_DEBUG "%s%s: %pV", netdev_name(dev),
0708 netdev_reg_state(dev), &vaf);
0709 } else {
0710 printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
0711 }
0712
0713 va_end(args);
0714 }
0715 EXPORT_SYMBOL(__dynamic_netdev_dbg);
0716
0717 #endif
0718
0719 #if IS_ENABLED(CONFIG_INFINIBAND)
0720
0721 void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
0722 const struct ib_device *ibdev, const char *fmt, ...)
0723 {
0724 struct va_format vaf;
0725 va_list args;
0726
0727 va_start(args, fmt);
0728
0729 vaf.fmt = fmt;
0730 vaf.va = &args;
0731
0732 if (ibdev && ibdev->dev.parent) {
0733 char buf[PREFIX_SIZE] = "";
0734
0735 dev_printk_emit(LOGLEVEL_DEBUG, ibdev->dev.parent,
0736 "%s%s %s %s: %pV",
0737 dynamic_emit_prefix(descriptor, buf),
0738 dev_driver_string(ibdev->dev.parent),
0739 dev_name(ibdev->dev.parent),
0740 dev_name(&ibdev->dev),
0741 &vaf);
0742 } else if (ibdev) {
0743 printk(KERN_DEBUG "%s: %pV", dev_name(&ibdev->dev), &vaf);
0744 } else {
0745 printk(KERN_DEBUG "(NULL ib_device): %pV", &vaf);
0746 }
0747
0748 va_end(args);
0749 }
0750 EXPORT_SYMBOL(__dynamic_ibdev_dbg);
0751
0752 #endif
0753
0754
0755
0756
0757
0758
0759 static __init int dyndbg_setup(char *str)
0760 {
0761 return 1;
0762 }
0763
0764 __setup("dyndbg=", dyndbg_setup);
0765
0766
0767
0768
0769
0770 #define USER_BUF_PAGE 4096
0771 static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
0772 size_t len, loff_t *offp)
0773 {
0774 char *tmpbuf;
0775 int ret;
0776
0777 if (len == 0)
0778 return 0;
0779 if (len > USER_BUF_PAGE - 1) {
0780 pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
0781 return -E2BIG;
0782 }
0783 tmpbuf = memdup_user_nul(ubuf, len);
0784 if (IS_ERR(tmpbuf))
0785 return PTR_ERR(tmpbuf);
0786 v2pr_info("read %zu bytes from userspace\n", len);
0787
0788 ret = ddebug_exec_queries(tmpbuf, NULL);
0789 kfree(tmpbuf);
0790 if (ret < 0)
0791 return ret;
0792
0793 *offp += len;
0794 return len;
0795 }
0796
0797
0798
0799
0800
0801
0802 static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
0803 {
0804 if (list_empty(&ddebug_tables)) {
0805 iter->table = NULL;
0806 iter->idx = 0;
0807 return NULL;
0808 }
0809 iter->table = list_entry(ddebug_tables.next,
0810 struct ddebug_table, link);
0811 iter->idx = 0;
0812 return &iter->table->ddebugs[iter->idx];
0813 }
0814
0815
0816
0817
0818
0819
0820
0821 static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
0822 {
0823 if (iter->table == NULL)
0824 return NULL;
0825 if (++iter->idx == iter->table->num_ddebugs) {
0826
0827 iter->idx = 0;
0828 if (list_is_last(&iter->table->link, &ddebug_tables)) {
0829 iter->table = NULL;
0830 return NULL;
0831 }
0832 iter->table = list_entry(iter->table->link.next,
0833 struct ddebug_table, link);
0834 }
0835 return &iter->table->ddebugs[iter->idx];
0836 }
0837
0838
0839
0840
0841
0842
0843 static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
0844 {
0845 struct ddebug_iter *iter = m->private;
0846 struct _ddebug *dp;
0847 int n = *pos;
0848
0849 mutex_lock(&ddebug_lock);
0850
0851 if (!n)
0852 return SEQ_START_TOKEN;
0853 if (n < 0)
0854 return NULL;
0855 dp = ddebug_iter_first(iter);
0856 while (dp != NULL && --n > 0)
0857 dp = ddebug_iter_next(iter);
0858 return dp;
0859 }
0860
0861
0862
0863
0864
0865
0866 static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
0867 {
0868 struct ddebug_iter *iter = m->private;
0869 struct _ddebug *dp;
0870
0871 if (p == SEQ_START_TOKEN)
0872 dp = ddebug_iter_first(iter);
0873 else
0874 dp = ddebug_iter_next(iter);
0875 ++*pos;
0876 return dp;
0877 }
0878
0879
0880
0881
0882
0883
0884
0885 static int ddebug_proc_show(struct seq_file *m, void *p)
0886 {
0887 struct ddebug_iter *iter = m->private;
0888 struct _ddebug *dp = p;
0889 struct flagsbuf flags;
0890
0891 if (p == SEQ_START_TOKEN) {
0892 seq_puts(m,
0893 "# filename:lineno [module]function flags format\n");
0894 return 0;
0895 }
0896
0897 seq_printf(m, "%s:%u [%s]%s =%s \"",
0898 trim_prefix(dp->filename), dp->lineno,
0899 iter->table->mod_name, dp->function,
0900 ddebug_describe_flags(dp->flags, &flags));
0901 seq_escape(m, dp->format, "\t\r\n\"");
0902 seq_puts(m, "\"\n");
0903
0904 return 0;
0905 }
0906
0907
0908
0909
0910
0911 static void ddebug_proc_stop(struct seq_file *m, void *p)
0912 {
0913 mutex_unlock(&ddebug_lock);
0914 }
0915
0916 static const struct seq_operations ddebug_proc_seqops = {
0917 .start = ddebug_proc_start,
0918 .next = ddebug_proc_next,
0919 .show = ddebug_proc_show,
0920 .stop = ddebug_proc_stop
0921 };
0922
0923 static int ddebug_proc_open(struct inode *inode, struct file *file)
0924 {
0925 return seq_open_private(file, &ddebug_proc_seqops,
0926 sizeof(struct ddebug_iter));
0927 }
0928
0929 static const struct file_operations ddebug_proc_fops = {
0930 .owner = THIS_MODULE,
0931 .open = ddebug_proc_open,
0932 .read = seq_read,
0933 .llseek = seq_lseek,
0934 .release = seq_release_private,
0935 .write = ddebug_proc_write
0936 };
0937
0938 static const struct proc_ops proc_fops = {
0939 .proc_open = ddebug_proc_open,
0940 .proc_read = seq_read,
0941 .proc_lseek = seq_lseek,
0942 .proc_release = seq_release_private,
0943 .proc_write = ddebug_proc_write
0944 };
0945
0946
0947
0948
0949
0950 int ddebug_add_module(struct _ddebug *tab, unsigned int n,
0951 const char *name)
0952 {
0953 struct ddebug_table *dt;
0954
0955 dt = kzalloc(sizeof(*dt), GFP_KERNEL);
0956 if (dt == NULL) {
0957 pr_err("error adding module: %s\n", name);
0958 return -ENOMEM;
0959 }
0960
0961
0962
0963
0964
0965
0966 dt->mod_name = name;
0967 dt->num_ddebugs = n;
0968 dt->ddebugs = tab;
0969
0970 mutex_lock(&ddebug_lock);
0971 list_add(&dt->link, &ddebug_tables);
0972 mutex_unlock(&ddebug_lock);
0973
0974 vpr_info("%3u debug prints in module %s\n", n, dt->mod_name);
0975 return 0;
0976 }
0977
0978
0979 static int ddebug_dyndbg_param_cb(char *param, char *val,
0980 const char *modname, int on_err)
0981 {
0982 char *sep;
0983
0984 sep = strchr(param, '.');
0985 if (sep) {
0986
0987 *sep = '\0';
0988 modname = param;
0989 param = sep + 1;
0990 }
0991 if (strcmp(param, "dyndbg"))
0992 return on_err;
0993
0994 ddebug_exec_queries((val ? val : "+p"), modname);
0995
0996 return 0;
0997 }
0998
0999
1000 static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
1001 const char *unused, void *arg)
1002 {
1003 vpr_info("%s=\"%s\"\n", param, val);
1004 return ddebug_dyndbg_param_cb(param, val, NULL, 0);
1005 }
1006
1007
1008
1009
1010
1011
1012 int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
1013 {
1014 vpr_info("module: %s %s=\"%s\"\n", module, param, val);
1015 return ddebug_dyndbg_param_cb(param, val, module, -ENOENT);
1016 }
1017
1018 static void ddebug_table_free(struct ddebug_table *dt)
1019 {
1020 list_del_init(&dt->link);
1021 kfree(dt);
1022 }
1023
1024
1025
1026
1027
1028 int ddebug_remove_module(const char *mod_name)
1029 {
1030 struct ddebug_table *dt, *nextdt;
1031 int ret = -ENOENT;
1032
1033 mutex_lock(&ddebug_lock);
1034 list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
1035 if (dt->mod_name == mod_name) {
1036 ddebug_table_free(dt);
1037 ret = 0;
1038 break;
1039 }
1040 }
1041 mutex_unlock(&ddebug_lock);
1042 if (!ret)
1043 v2pr_info("removed module \"%s\"\n", mod_name);
1044 return ret;
1045 }
1046
1047 static void ddebug_remove_all_tables(void)
1048 {
1049 mutex_lock(&ddebug_lock);
1050 while (!list_empty(&ddebug_tables)) {
1051 struct ddebug_table *dt = list_entry(ddebug_tables.next,
1052 struct ddebug_table,
1053 link);
1054 ddebug_table_free(dt);
1055 }
1056 mutex_unlock(&ddebug_lock);
1057 }
1058
1059 static __initdata int ddebug_init_success;
1060
1061 static int __init dynamic_debug_init_control(void)
1062 {
1063 struct proc_dir_entry *procfs_dir;
1064 struct dentry *debugfs_dir;
1065
1066 if (!ddebug_init_success)
1067 return -ENODEV;
1068
1069
1070 if (debugfs_initialized()) {
1071 debugfs_dir = debugfs_create_dir("dynamic_debug", NULL);
1072 debugfs_create_file("control", 0644, debugfs_dir, NULL,
1073 &ddebug_proc_fops);
1074 }
1075
1076
1077 procfs_dir = proc_mkdir("dynamic_debug", NULL);
1078 if (procfs_dir)
1079 proc_create("control", 0644, procfs_dir, &proc_fops);
1080
1081 return 0;
1082 }
1083
1084 static int __init dynamic_debug_init(void)
1085 {
1086 struct _ddebug *iter, *iter_start;
1087 const char *modname = NULL;
1088 char *cmdline;
1089 int ret = 0;
1090 int n = 0, entries = 0, modct = 0;
1091
1092 if (&__start___dyndbg == &__stop___dyndbg) {
1093 if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) {
1094 pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
1095 return 1;
1096 }
1097 pr_info("Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build\n");
1098 ddebug_init_success = 1;
1099 return 0;
1100 }
1101 iter = __start___dyndbg;
1102 modname = iter->modname;
1103 iter_start = iter;
1104 for (; iter < __stop___dyndbg; iter++) {
1105 entries++;
1106 if (strcmp(modname, iter->modname)) {
1107 modct++;
1108 ret = ddebug_add_module(iter_start, n, modname);
1109 if (ret)
1110 goto out_err;
1111 n = 0;
1112 modname = iter->modname;
1113 iter_start = iter;
1114 }
1115 n++;
1116 }
1117 ret = ddebug_add_module(iter_start, n, modname);
1118 if (ret)
1119 goto out_err;
1120
1121 ddebug_init_success = 1;
1122 vpr_info("%d prdebugs in %d modules, %d KiB in ddebug tables, %d kiB in __dyndbg section\n",
1123 entries, modct, (int)((modct * sizeof(struct ddebug_table)) >> 10),
1124 (int)((entries * sizeof(struct _ddebug)) >> 10));
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134 cmdline = kstrdup(saved_command_line, GFP_KERNEL);
1135 parse_args("dyndbg params", cmdline, NULL,
1136 0, 0, 0, NULL, &ddebug_dyndbg_boot_param_cb);
1137 kfree(cmdline);
1138 return 0;
1139
1140 out_err:
1141 ddebug_remove_all_tables();
1142 return 0;
1143 }
1144
1145 early_initcall(dynamic_debug_init);
1146
1147
1148 fs_initcall(dynamic_debug_init_control);