1
2
3
4
5
6
7
8
9
10
11
12
13
14#define pr_fmt(fmt) "dyndbg: " fmt
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#include <rdma/ib_verbs.h>
41
42extern struct _ddebug __start___dyndbg[];
43extern struct _ddebug __stop___dyndbg[];
44
45struct ddebug_table {
46 struct list_head link;
47 const char *mod_name;
48 unsigned int num_ddebugs;
49 struct _ddebug *ddebugs;
50};
51
52struct ddebug_query {
53 const char *filename;
54 const char *module;
55 const char *function;
56 const char *format;
57 unsigned int first_lineno, last_lineno;
58};
59
60struct ddebug_iter {
61 struct ddebug_table *table;
62 unsigned int idx;
63};
64
65struct flag_settings {
66 unsigned int flags;
67 unsigned int mask;
68};
69
70static DEFINE_MUTEX(ddebug_lock);
71static LIST_HEAD(ddebug_tables);
72static int verbose;
73module_param(verbose, int, 0644);
74MODULE_PARM_DESC(verbose, " dynamic_debug/control processing "
75 "( 0 = off (default), 1 = module add/rm, 2 = >control summary, 3 = parsing, 4 = per-site changes)");
76
77
78static inline const char *trim_prefix(const char *path)
79{
80 int skip = strlen(__FILE__) - strlen("lib/dynamic_debug.c");
81
82 if (strncmp(path, __FILE__, skip))
83 skip = 0;
84
85 return path + skip;
86}
87
88static struct { unsigned flag:8; char opt_char; } opt_array[] = {
89 { _DPRINTK_FLAGS_PRINT, 'p' },
90 { _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
91 { _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
92 { _DPRINTK_FLAGS_INCL_LINENO, 'l' },
93 { _DPRINTK_FLAGS_INCL_TID, 't' },
94 { _DPRINTK_FLAGS_NONE, '_' },
95};
96
97struct flagsbuf { char buf[ARRAY_SIZE(opt_array)+1]; };
98
99
100static char *ddebug_describe_flags(unsigned int flags, struct flagsbuf *fb)
101{
102 char *p = fb->buf;
103 int i;
104
105 for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
106 if (flags & opt_array[i].flag)
107 *p++ = opt_array[i].opt_char;
108 if (p == fb->buf)
109 *p++ = '_';
110 *p = '\0';
111
112 return fb->buf;
113}
114
115#define vnpr_info(lvl, fmt, ...) \
116do { \
117 if (verbose >= lvl) \
118 pr_info(fmt, ##__VA_ARGS__); \
119} while (0)
120
121#define vpr_info(fmt, ...) vnpr_info(1, fmt, ##__VA_ARGS__)
122#define v2pr_info(fmt, ...) vnpr_info(2, fmt, ##__VA_ARGS__)
123#define v3pr_info(fmt, ...) vnpr_info(3, fmt, ##__VA_ARGS__)
124#define v4pr_info(fmt, ...) vnpr_info(4, fmt, ##__VA_ARGS__)
125
126static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
127{
128
129 int fmtlen = 0;
130
131 if (query->format) {
132 fmtlen = strlen(query->format);
133 while (fmtlen && query->format[fmtlen - 1] == '\n')
134 fmtlen--;
135 }
136
137 v3pr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" lineno=%u-%u\n",
138 msg,
139 query->function ?: "",
140 query->filename ?: "",
141 query->module ?: "",
142 fmtlen, query->format ?: "",
143 query->first_lineno, query->last_lineno);
144}
145
146
147
148
149
150
151
152static int ddebug_change(const struct ddebug_query *query,
153 struct flag_settings *modifiers)
154{
155 int i;
156 struct ddebug_table *dt;
157 unsigned int newflags;
158 unsigned int nfound = 0;
159 struct flagsbuf fbuf;
160
161
162 mutex_lock(&ddebug_lock);
163 list_for_each_entry(dt, &ddebug_tables, link) {
164
165
166 if (query->module &&
167 !match_wildcard(query->module, dt->mod_name))
168 continue;
169
170 for (i = 0; i < dt->num_ddebugs; i++) {
171 struct _ddebug *dp = &dt->ddebugs[i];
172
173
174 if (query->filename &&
175 !match_wildcard(query->filename, dp->filename) &&
176 !match_wildcard(query->filename,
177 kbasename(dp->filename)) &&
178 !match_wildcard(query->filename,
179 trim_prefix(dp->filename)))
180 continue;
181
182
183 if (query->function &&
184 !match_wildcard(query->function, dp->function))
185 continue;
186
187
188 if (query->format) {
189 if (*query->format == '^') {
190 char *p;
191
192 p = strstr(dp->format, query->format+1);
193 if (p != dp->format)
194 continue;
195 } else if (!strstr(dp->format, query->format))
196 continue;
197 }
198
199
200 if (query->first_lineno &&
201 dp->lineno < query->first_lineno)
202 continue;
203 if (query->last_lineno &&
204 dp->lineno > query->last_lineno)
205 continue;
206
207 nfound++;
208
209 newflags = (dp->flags & modifiers->mask) | modifiers->flags;
210 if (newflags == dp->flags)
211 continue;
212#ifdef CONFIG_JUMP_LABEL
213 if (dp->flags & _DPRINTK_FLAGS_PRINT) {
214 if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT))
215 static_branch_disable(&dp->key.dd_key_true);
216 } else if (modifiers->flags & _DPRINTK_FLAGS_PRINT)
217 static_branch_enable(&dp->key.dd_key_true);
218#endif
219 dp->flags = newflags;
220 v4pr_info("changed %s:%d [%s]%s =%s\n",
221 trim_prefix(dp->filename), dp->lineno,
222 dt->mod_name, dp->function,
223 ddebug_describe_flags(dp->flags, &fbuf));
224 }
225 }
226 mutex_unlock(&ddebug_lock);
227
228 if (!nfound && verbose)
229 pr_info("no matches for query\n");
230
231 return nfound;
232}
233
234
235
236
237
238
239
240static int ddebug_tokenize(char *buf, char *words[], int maxwords)
241{
242 int nwords = 0;
243
244 while (*buf) {
245 char *end;
246
247
248 buf = skip_spaces(buf);
249 if (!*buf)
250 break;
251 if (*buf == '#')
252 break;
253
254
255 if (*buf == '"' || *buf == '\'') {
256 int quote = *buf++;
257 for (end = buf; *end && *end != quote; end++)
258 ;
259 if (!*end) {
260 pr_err("unclosed quote: %s\n", buf);
261 return -EINVAL;
262 }
263 } else {
264 for (end = buf; *end && !isspace(*end); end++)
265 ;
266 BUG_ON(end == buf);
267 }
268
269
270 if (nwords == maxwords) {
271 pr_err("too many words, legal max <=%d\n", maxwords);
272 return -EINVAL;
273 }
274 if (*end)
275 *end++ = '\0';
276 words[nwords++] = buf;
277 buf = end;
278 }
279
280 if (verbose >= 3) {
281 int i;
282 pr_info("split into words:");
283 for (i = 0; i < nwords; i++)
284 pr_cont(" \"%s\"", words[i]);
285 pr_cont("\n");
286 }
287
288 return nwords;
289}
290
291
292
293
294
295
296static inline int parse_lineno(const char *str, unsigned int *val)
297{
298 BUG_ON(str == NULL);
299 if (*str == '\0') {
300 *val = 0;
301 return 0;
302 }
303 if (kstrtouint(str, 10, val) < 0) {
304 pr_err("bad line-number: %s\n", str);
305 return -EINVAL;
306 }
307 return 0;
308}
309
310static int parse_linerange(struct ddebug_query *query, const char *first)
311{
312 char *last = strchr(first, '-');
313
314 if (query->first_lineno || query->last_lineno) {
315 pr_err("match-spec: line used 2x\n");
316 return -EINVAL;
317 }
318 if (last)
319 *last++ = '\0';
320 if (parse_lineno(first, &query->first_lineno) < 0)
321 return -EINVAL;
322 if (last) {
323
324 if (parse_lineno(last, &query->last_lineno) < 0)
325 return -EINVAL;
326
327
328 if (query->last_lineno == 0)
329 query->last_lineno = UINT_MAX;
330
331 if (query->last_lineno < query->first_lineno) {
332 pr_err("last-line:%d < 1st-line:%d\n",
333 query->last_lineno,
334 query->first_lineno);
335 return -EINVAL;
336 }
337 } else {
338 query->last_lineno = query->first_lineno;
339 }
340 v3pr_info("parsed line %d-%d\n", query->first_lineno,
341 query->last_lineno);
342 return 0;
343}
344
345static int check_set(const char **dest, char *src, char *name)
346{
347 int rc = 0;
348
349 if (*dest) {
350 rc = -EINVAL;
351 pr_err("match-spec:%s val:%s overridden by %s\n",
352 name, *dest, src);
353 }
354 *dest = src;
355 return rc;
356}
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373static int ddebug_parse_query(char *words[], int nwords,
374 struct ddebug_query *query, const char *modname)
375{
376 unsigned int i;
377 int rc = 0;
378 char *fline;
379
380
381 if (nwords % 2 != 0) {
382 pr_err("expecting pairs of match-spec <value>\n");
383 return -EINVAL;
384 }
385
386 if (modname)
387
388 query->module = modname;
389
390 for (i = 0; i < nwords; i += 2) {
391 char *keyword = words[i];
392 char *arg = words[i+1];
393
394 if (!strcmp(keyword, "func")) {
395 rc = check_set(&query->function, arg, "func");
396 } else if (!strcmp(keyword, "file")) {
397 if (check_set(&query->filename, arg, "file"))
398 return -EINVAL;
399
400
401 fline = strchr(query->filename, ':');
402 if (!fline)
403 continue;
404 *fline++ = '\0';
405 if (isalpha(*fline) || *fline == '*' || *fline == '?') {
406
407 if (check_set(&query->function, fline, "func"))
408 return -EINVAL;
409 } else {
410 if (parse_linerange(query, fline))
411 return -EINVAL;
412 }
413 } else if (!strcmp(keyword, "module")) {
414 rc = check_set(&query->module, arg, "module");
415 } else if (!strcmp(keyword, "format")) {
416 string_unescape_inplace(arg, UNESCAPE_SPACE |
417 UNESCAPE_OCTAL |
418 UNESCAPE_SPECIAL);
419 rc = check_set(&query->format, arg, "format");
420 } else if (!strcmp(keyword, "line")) {
421 if (parse_linerange(query, arg))
422 return -EINVAL;
423 } else {
424 pr_err("unknown keyword \"%s\"\n", keyword);
425 return -EINVAL;
426 }
427 if (rc)
428 return rc;
429 }
430 vpr_info_dq(query, "parsed");
431 return 0;
432}
433
434
435
436
437
438
439
440static int ddebug_parse_flags(const char *str, struct flag_settings *modifiers)
441{
442 int op, i;
443
444 switch (*str) {
445 case '+':
446 case '-':
447 case '=':
448 op = *str++;
449 break;
450 default:
451 pr_err("bad flag-op %c, at start of %s\n", *str, str);
452 return -EINVAL;
453 }
454 v3pr_info("op='%c'\n", op);
455
456 for (; *str ; ++str) {
457 for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
458 if (*str == opt_array[i].opt_char) {
459 modifiers->flags |= opt_array[i].flag;
460 break;
461 }
462 }
463 if (i < 0) {
464 pr_err("unknown flag '%c'\n", *str);
465 return -EINVAL;
466 }
467 }
468 v3pr_info("flags=0x%x\n", modifiers->flags);
469
470
471 switch (op) {
472 case '=':
473
474 modifiers->mask = 0;
475 break;
476 case '+':
477 modifiers->mask = ~0U;
478 break;
479 case '-':
480 modifiers->mask = ~modifiers->flags;
481 modifiers->flags = 0;
482 break;
483 }
484 v3pr_info("*flagsp=0x%x *maskp=0x%x\n", modifiers->flags, modifiers->mask);
485
486 return 0;
487}
488
489static int ddebug_exec_query(char *query_string, const char *modname)
490{
491 struct flag_settings modifiers = {};
492 struct ddebug_query query = {};
493#define MAXWORDS 9
494 int nwords, nfound;
495 char *words[MAXWORDS];
496
497 nwords = ddebug_tokenize(query_string, words, MAXWORDS);
498 if (nwords <= 0) {
499 pr_err("tokenize failed\n");
500 return -EINVAL;
501 }
502
503 if (ddebug_parse_flags(words[nwords-1], &modifiers)) {
504 pr_err("flags parse failed\n");
505 return -EINVAL;
506 }
507 if (ddebug_parse_query(words, nwords-1, &query, modname)) {
508 pr_err("query parse failed\n");
509 return -EINVAL;
510 }
511
512 nfound = ddebug_change(&query, &modifiers);
513 vpr_info_dq(&query, nfound ? "applied" : "no-match");
514
515 return nfound;
516}
517
518
519
520
521
522static int ddebug_exec_queries(char *query, const char *modname)
523{
524 char *split;
525 int i, errs = 0, exitcode = 0, rc, nfound = 0;
526
527 for (i = 0; query; query = split) {
528 split = strpbrk(query, ";\n");
529 if (split)
530 *split++ = '\0';
531
532 query = skip_spaces(query);
533 if (!query || !*query || *query == '#')
534 continue;
535
536 vpr_info("query %d: \"%s\" mod:%s\n", i, query, modname ?: "*");
537
538 rc = ddebug_exec_query(query, modname);
539 if (rc < 0) {
540 errs++;
541 exitcode = rc;
542 } else {
543 nfound += rc;
544 }
545 i++;
546 }
547 if (i)
548 v2pr_info("processed %d queries, with %d matches, %d errs\n",
549 i, nfound, errs);
550
551 if (exitcode)
552 return exitcode;
553 return nfound;
554}
555
556
557
558
559
560
561
562
563
564
565
566int dynamic_debug_exec_queries(const char *query, const char *modname)
567{
568 int rc;
569 char *qry;
570
571 if (!query) {
572 pr_err("non-null query/command string expected\n");
573 return -EINVAL;
574 }
575 qry = kstrndup(query, PAGE_SIZE, GFP_KERNEL);
576 if (!qry)
577 return -ENOMEM;
578
579 rc = ddebug_exec_queries(qry, modname);
580 kfree(qry);
581 return rc;
582}
583EXPORT_SYMBOL_GPL(dynamic_debug_exec_queries);
584
585#define PREFIX_SIZE 64
586
587static int remaining(int wrote)
588{
589 if (PREFIX_SIZE - wrote > 0)
590 return PREFIX_SIZE - wrote;
591 return 0;
592}
593
594static char *__dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
595{
596 int pos_after_tid;
597 int pos = 0;
598
599 if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
600 if (in_interrupt())
601 pos += snprintf(buf + pos, remaining(pos), "<intr> ");
602 else
603 pos += snprintf(buf + pos, remaining(pos), "[%d] ",
604 task_pid_vnr(current));
605 }
606 pos_after_tid = pos;
607 if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
608 pos += snprintf(buf + pos, remaining(pos), "%s:",
609 desc->modname);
610 if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
611 pos += snprintf(buf + pos, remaining(pos), "%s:",
612 desc->function);
613 if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
614 pos += snprintf(buf + pos, remaining(pos), "%d:",
615 desc->lineno);
616 if (pos - pos_after_tid)
617 pos += snprintf(buf + pos, remaining(pos), " ");
618 if (pos >= PREFIX_SIZE)
619 buf[PREFIX_SIZE - 1] = '\0';
620
621 return buf;
622}
623
624static inline char *dynamic_emit_prefix(struct _ddebug *desc, char *buf)
625{
626 if (unlikely(desc->flags & _DPRINTK_FLAGS_INCL_ANY))
627 return __dynamic_emit_prefix(desc, buf);
628 return buf;
629}
630
631void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
632{
633 va_list args;
634 struct va_format vaf;
635 char buf[PREFIX_SIZE] = "";
636
637 BUG_ON(!descriptor);
638 BUG_ON(!fmt);
639
640 va_start(args, fmt);
641
642 vaf.fmt = fmt;
643 vaf.va = &args;
644
645 printk(KERN_DEBUG "%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
646
647 va_end(args);
648}
649EXPORT_SYMBOL(__dynamic_pr_debug);
650
651void __dynamic_dev_dbg(struct _ddebug *descriptor,
652 const struct device *dev, const char *fmt, ...)
653{
654 struct va_format vaf;
655 va_list args;
656
657 BUG_ON(!descriptor);
658 BUG_ON(!fmt);
659
660 va_start(args, fmt);
661
662 vaf.fmt = fmt;
663 vaf.va = &args;
664
665 if (!dev) {
666 printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
667 } else {
668 char buf[PREFIX_SIZE] = "";
669
670 dev_printk_emit(LOGLEVEL_DEBUG, dev, "%s%s %s: %pV",
671 dynamic_emit_prefix(descriptor, buf),
672 dev_driver_string(dev), dev_name(dev),
673 &vaf);
674 }
675
676 va_end(args);
677}
678EXPORT_SYMBOL(__dynamic_dev_dbg);
679
680#ifdef CONFIG_NET
681
682void __dynamic_netdev_dbg(struct _ddebug *descriptor,
683 const struct net_device *dev, const char *fmt, ...)
684{
685 struct va_format vaf;
686 va_list args;
687
688 BUG_ON(!descriptor);
689 BUG_ON(!fmt);
690
691 va_start(args, fmt);
692
693 vaf.fmt = fmt;
694 vaf.va = &args;
695
696 if (dev && dev->dev.parent) {
697 char buf[PREFIX_SIZE] = "";
698
699 dev_printk_emit(LOGLEVEL_DEBUG, dev->dev.parent,
700 "%s%s %s %s%s: %pV",
701 dynamic_emit_prefix(descriptor, buf),
702 dev_driver_string(dev->dev.parent),
703 dev_name(dev->dev.parent),
704 netdev_name(dev), netdev_reg_state(dev),
705 &vaf);
706 } else if (dev) {
707 printk(KERN_DEBUG "%s%s: %pV", netdev_name(dev),
708 netdev_reg_state(dev), &vaf);
709 } else {
710 printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
711 }
712
713 va_end(args);
714}
715EXPORT_SYMBOL(__dynamic_netdev_dbg);
716
717#endif
718
719#if IS_ENABLED(CONFIG_INFINIBAND)
720
721void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
722 const struct ib_device *ibdev, const char *fmt, ...)
723{
724 struct va_format vaf;
725 va_list args;
726
727 va_start(args, fmt);
728
729 vaf.fmt = fmt;
730 vaf.va = &args;
731
732 if (ibdev && ibdev->dev.parent) {
733 char buf[PREFIX_SIZE] = "";
734
735 dev_printk_emit(LOGLEVEL_DEBUG, ibdev->dev.parent,
736 "%s%s %s %s: %pV",
737 dynamic_emit_prefix(descriptor, buf),
738 dev_driver_string(ibdev->dev.parent),
739 dev_name(ibdev->dev.parent),
740 dev_name(&ibdev->dev),
741 &vaf);
742 } else if (ibdev) {
743 printk(KERN_DEBUG "%s: %pV", dev_name(&ibdev->dev), &vaf);
744 } else {
745 printk(KERN_DEBUG "(NULL ib_device): %pV", &vaf);
746 }
747
748 va_end(args);
749}
750EXPORT_SYMBOL(__dynamic_ibdev_dbg);
751
752#endif
753
754
755
756
757
758
759static __init int dyndbg_setup(char *str)
760{
761 return 1;
762}
763
764__setup("dyndbg=", dyndbg_setup);
765
766
767
768
769
770#define USER_BUF_PAGE 4096
771static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
772 size_t len, loff_t *offp)
773{
774 char *tmpbuf;
775 int ret;
776
777 if (len == 0)
778 return 0;
779 if (len > USER_BUF_PAGE - 1) {
780 pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
781 return -E2BIG;
782 }
783 tmpbuf = memdup_user_nul(ubuf, len);
784 if (IS_ERR(tmpbuf))
785 return PTR_ERR(tmpbuf);
786 v2pr_info("read %zu bytes from userspace\n", len);
787
788 ret = ddebug_exec_queries(tmpbuf, NULL);
789 kfree(tmpbuf);
790 if (ret < 0)
791 return ret;
792
793 *offp += len;
794 return len;
795}
796
797
798
799
800
801
802static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
803{
804 if (list_empty(&ddebug_tables)) {
805 iter->table = NULL;
806 iter->idx = 0;
807 return NULL;
808 }
809 iter->table = list_entry(ddebug_tables.next,
810 struct ddebug_table, link);
811 iter->idx = 0;
812 return &iter->table->ddebugs[iter->idx];
813}
814
815
816
817
818
819
820
821static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
822{
823 if (iter->table == NULL)
824 return NULL;
825 if (++iter->idx == iter->table->num_ddebugs) {
826
827 iter->idx = 0;
828 if (list_is_last(&iter->table->link, &ddebug_tables)) {
829 iter->table = NULL;
830 return NULL;
831 }
832 iter->table = list_entry(iter->table->link.next,
833 struct ddebug_table, link);
834 }
835 return &iter->table->ddebugs[iter->idx];
836}
837
838
839
840
841
842
843static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
844{
845 struct ddebug_iter *iter = m->private;
846 struct _ddebug *dp;
847 int n = *pos;
848
849 mutex_lock(&ddebug_lock);
850
851 if (!n)
852 return SEQ_START_TOKEN;
853 if (n < 0)
854 return NULL;
855 dp = ddebug_iter_first(iter);
856 while (dp != NULL && --n > 0)
857 dp = ddebug_iter_next(iter);
858 return dp;
859}
860
861
862
863
864
865
866static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
867{
868 struct ddebug_iter *iter = m->private;
869 struct _ddebug *dp;
870
871 if (p == SEQ_START_TOKEN)
872 dp = ddebug_iter_first(iter);
873 else
874 dp = ddebug_iter_next(iter);
875 ++*pos;
876 return dp;
877}
878
879
880
881
882
883
884
885static int ddebug_proc_show(struct seq_file *m, void *p)
886{
887 struct ddebug_iter *iter = m->private;
888 struct _ddebug *dp = p;
889 struct flagsbuf flags;
890
891 if (p == SEQ_START_TOKEN) {
892 seq_puts(m,
893 "# filename:lineno [module]function flags format\n");
894 return 0;
895 }
896
897 seq_printf(m, "%s:%u [%s]%s =%s \"",
898 trim_prefix(dp->filename), dp->lineno,
899 iter->table->mod_name, dp->function,
900 ddebug_describe_flags(dp->flags, &flags));
901 seq_escape(m, dp->format, "\t\r\n\"");
902 seq_puts(m, "\"\n");
903
904 return 0;
905}
906
907
908
909
910
911static void ddebug_proc_stop(struct seq_file *m, void *p)
912{
913 mutex_unlock(&ddebug_lock);
914}
915
916static const struct seq_operations ddebug_proc_seqops = {
917 .start = ddebug_proc_start,
918 .next = ddebug_proc_next,
919 .show = ddebug_proc_show,
920 .stop = ddebug_proc_stop
921};
922
923static int ddebug_proc_open(struct inode *inode, struct file *file)
924{
925 return seq_open_private(file, &ddebug_proc_seqops,
926 sizeof(struct ddebug_iter));
927}
928
929static const struct file_operations ddebug_proc_fops = {
930 .owner = THIS_MODULE,
931 .open = ddebug_proc_open,
932 .read = seq_read,
933 .llseek = seq_lseek,
934 .release = seq_release_private,
935 .write = ddebug_proc_write
936};
937
938static const struct proc_ops proc_fops = {
939 .proc_open = ddebug_proc_open,
940 .proc_read = seq_read,
941 .proc_lseek = seq_lseek,
942 .proc_release = seq_release_private,
943 .proc_write = ddebug_proc_write
944};
945
946
947
948
949
950int ddebug_add_module(struct _ddebug *tab, unsigned int n,
951 const char *name)
952{
953 struct ddebug_table *dt;
954
955 dt = kzalloc(sizeof(*dt), GFP_KERNEL);
956 if (dt == NULL) {
957 pr_err("error adding module: %s\n", name);
958 return -ENOMEM;
959 }
960
961
962
963
964
965
966 dt->mod_name = name;
967 dt->num_ddebugs = n;
968 dt->ddebugs = tab;
969
970 mutex_lock(&ddebug_lock);
971 list_add(&dt->link, &ddebug_tables);
972 mutex_unlock(&ddebug_lock);
973
974 vpr_info("%3u debug prints in module %s\n", n, dt->mod_name);
975 return 0;
976}
977
978
979static int ddebug_dyndbg_param_cb(char *param, char *val,
980 const char *modname, int on_err)
981{
982 char *sep;
983
984 sep = strchr(param, '.');
985 if (sep) {
986
987 *sep = '\0';
988 modname = param;
989 param = sep + 1;
990 }
991 if (strcmp(param, "dyndbg"))
992 return on_err;
993
994 ddebug_exec_queries((val ? val : "+p"), modname);
995
996 return 0;
997}
998
999
1000static 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
1012int 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
1018static void ddebug_table_free(struct ddebug_table *dt)
1019{
1020 list_del_init(&dt->link);
1021 kfree(dt);
1022}
1023
1024
1025
1026
1027
1028int 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
1047static 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
1059static __initdata int ddebug_init_success;
1060
1061static 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
1084static 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
1140out_err:
1141 ddebug_remove_all_tables();
1142 return 0;
1143}
1144
1145early_initcall(dynamic_debug_init);
1146
1147
1148fs_initcall(dynamic_debug_init_control);
1149