hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/lib/dynamic_debug.c
....@@ -11,7 +11,7 @@
1111 * Copyright (C) 2013 Du, Changbin <changbin.du@gmail.com>
1212 */
1313
14
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
14
+#define pr_fmt(fmt) "dyndbg: " fmt
1515
1616 #include <linux/kernel.h>
1717 #include <linux/module.h>
....@@ -37,8 +37,10 @@
3737 #include <linux/device.h>
3838 #include <linux/netdevice.h>
3939
40
-extern struct _ddebug __start___verbose[];
41
-extern struct _ddebug __stop___verbose[];
40
+#include <rdma/ib_verbs.h>
41
+
42
+extern struct _ddebug __start___dyndbg[];
43
+extern struct _ddebug __stop___dyndbg[];
4244
4345 struct ddebug_table {
4446 struct list_head link;
....@@ -58,6 +60,11 @@
5860 struct ddebug_iter {
5961 struct ddebug_table *table;
6062 unsigned int idx;
63
+};
64
+
65
+struct flag_settings {
66
+ unsigned int flags;
67
+ unsigned int mask;
6168 };
6269
6370 static DEFINE_MUTEX(ddebug_lock);
....@@ -103,11 +110,14 @@
103110 return fb->buf;
104111 }
105112
106
-#define vpr_info(fmt, ...) \
113
+#define vnpr_info(lvl, fmt, ...) \
107114 do { \
108
- if (verbose) \
115
+ if (verbose >= lvl) \
109116 pr_info(fmt, ##__VA_ARGS__); \
110117 } while (0)
118
+
119
+#define vpr_info(fmt, ...) vnpr_info(1, fmt, ##__VA_ARGS__)
120
+#define v2pr_info(fmt, ...) vnpr_info(2, fmt, ##__VA_ARGS__)
111121
112122 static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
113123 {
....@@ -122,10 +132,10 @@
122132
123133 vpr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" lineno=%u-%u\n",
124134 msg,
125
- query->function ? query->function : "",
126
- query->filename ? query->filename : "",
127
- query->module ? query->module : "",
128
- fmtlen, query->format ? query->format : "",
135
+ query->function ?: "",
136
+ query->filename ?: "",
137
+ query->module ?: "",
138
+ fmtlen, query->format ?: "",
129139 query->first_lineno, query->last_lineno);
130140 }
131141
....@@ -136,7 +146,7 @@
136146 * logs the changes. Takes ddebug_lock.
137147 */
138148 static int ddebug_change(const struct ddebug_query *query,
139
- unsigned int flags, unsigned int mask)
149
+ struct flag_settings *modifiers)
140150 {
141151 int i;
142152 struct ddebug_table *dt;
....@@ -171,9 +181,16 @@
171181 continue;
172182
173183 /* match against the format */
174
- if (query->format &&
175
- !strstr(dp->format, query->format))
176
- continue;
184
+ if (query->format) {
185
+ if (*query->format == '^') {
186
+ char *p;
187
+ /* anchored search. match must be at beginning */
188
+ p = strstr(dp->format, query->format+1);
189
+ if (p != dp->format)
190
+ continue;
191
+ } else if (!strstr(dp->format, query->format))
192
+ continue;
193
+ }
177194
178195 /* match against the line number range */
179196 if (query->first_lineno &&
....@@ -185,18 +202,19 @@
185202
186203 nfound++;
187204
188
- newflags = (dp->flags & mask) | flags;
205
+ newflags = (dp->flags & modifiers->mask) | modifiers->flags;
189206 if (newflags == dp->flags)
190207 continue;
191208 #ifdef CONFIG_JUMP_LABEL
192209 if (dp->flags & _DPRINTK_FLAGS_PRINT) {
193
- if (!(flags & _DPRINTK_FLAGS_PRINT))
210
+ if (!(newflags & _DPRINTK_FLAGS_PRINT))
194211 static_branch_disable(&dp->key.dd_key_true);
195
- } else if (flags & _DPRINTK_FLAGS_PRINT)
212
+ } else if (newflags & _DPRINTK_FLAGS_PRINT) {
196213 static_branch_enable(&dp->key.dd_key_true);
214
+ }
197215 #endif
198216 dp->flags = newflags;
199
- vpr_info("changed %s:%d [%s]%s =%s\n",
217
+ v2pr_info("changed %s:%d [%s]%s =%s\n",
200218 trim_prefix(dp->filename), dp->lineno,
201219 dt->mod_name, dp->function,
202220 ddebug_describe_flags(dp->flags, &fbuf));
....@@ -286,6 +304,41 @@
286304 return 0;
287305 }
288306
307
+static int parse_linerange(struct ddebug_query *query, const char *first)
308
+{
309
+ char *last = strchr(first, '-');
310
+
311
+ if (query->first_lineno || query->last_lineno) {
312
+ pr_err("match-spec: line used 2x\n");
313
+ return -EINVAL;
314
+ }
315
+ if (last)
316
+ *last++ = '\0';
317
+ if (parse_lineno(first, &query->first_lineno) < 0)
318
+ return -EINVAL;
319
+ if (last) {
320
+ /* range <first>-<last> */
321
+ if (parse_lineno(last, &query->last_lineno) < 0)
322
+ return -EINVAL;
323
+
324
+ /* special case for last lineno not specified */
325
+ if (query->last_lineno == 0)
326
+ query->last_lineno = UINT_MAX;
327
+
328
+ if (query->last_lineno < query->first_lineno) {
329
+ pr_err("last-line:%d < 1st-line:%d\n",
330
+ query->last_lineno,
331
+ query->first_lineno);
332
+ return -EINVAL;
333
+ }
334
+ } else {
335
+ query->last_lineno = query->first_lineno;
336
+ }
337
+ vpr_info("parsed line %d-%d\n", query->first_lineno,
338
+ query->last_lineno);
339
+ return 0;
340
+}
341
+
289342 static int check_set(const char **dest, char *src, char *name)
290343 {
291344 int rc = 0;
....@@ -319,66 +372,61 @@
319372 {
320373 unsigned int i;
321374 int rc = 0;
375
+ char *fline;
322376
323377 /* check we have an even number of words */
324378 if (nwords % 2 != 0) {
325379 pr_err("expecting pairs of match-spec <value>\n");
326380 return -EINVAL;
327381 }
328
- memset(query, 0, sizeof(*query));
329
-
330
- if (modname)
331
- /* support $modname.dyndbg=<multiple queries> */
332
- query->module = modname;
333382
334383 for (i = 0; i < nwords; i += 2) {
335
- if (!strcmp(words[i], "func")) {
336
- rc = check_set(&query->function, words[i+1], "func");
337
- } else if (!strcmp(words[i], "file")) {
338
- rc = check_set(&query->filename, words[i+1], "file");
339
- } else if (!strcmp(words[i], "module")) {
340
- rc = check_set(&query->module, words[i+1], "module");
341
- } else if (!strcmp(words[i], "format")) {
342
- string_unescape_inplace(words[i+1], UNESCAPE_SPACE |
384
+ char *keyword = words[i];
385
+ char *arg = words[i+1];
386
+
387
+ if (!strcmp(keyword, "func")) {
388
+ rc = check_set(&query->function, arg, "func");
389
+ } else if (!strcmp(keyword, "file")) {
390
+ if (check_set(&query->filename, arg, "file"))
391
+ return -EINVAL;
392
+
393
+ /* tail :$info is function or line-range */
394
+ fline = strchr(query->filename, ':');
395
+ if (!fline)
396
+ continue;
397
+ *fline++ = '\0';
398
+ if (isalpha(*fline) || *fline == '*' || *fline == '?') {
399
+ /* take as function name */
400
+ if (check_set(&query->function, fline, "func"))
401
+ return -EINVAL;
402
+ } else {
403
+ if (parse_linerange(query, fline))
404
+ return -EINVAL;
405
+ }
406
+ } else if (!strcmp(keyword, "module")) {
407
+ rc = check_set(&query->module, arg, "module");
408
+ } else if (!strcmp(keyword, "format")) {
409
+ string_unescape_inplace(arg, UNESCAPE_SPACE |
343410 UNESCAPE_OCTAL |
344411 UNESCAPE_SPECIAL);
345
- rc = check_set(&query->format, words[i+1], "format");
346
- } else if (!strcmp(words[i], "line")) {
347
- char *first = words[i+1];
348
- char *last = strchr(first, '-');
349
- if (query->first_lineno || query->last_lineno) {
350
- pr_err("match-spec: line used 2x\n");
412
+ rc = check_set(&query->format, arg, "format");
413
+ } else if (!strcmp(keyword, "line")) {
414
+ if (parse_linerange(query, arg))
351415 return -EINVAL;
352
- }
353
- if (last)
354
- *last++ = '\0';
355
- if (parse_lineno(first, &query->first_lineno) < 0)
356
- return -EINVAL;
357
- if (last) {
358
- /* range <first>-<last> */
359
- if (parse_lineno(last, &query->last_lineno) < 0)
360
- return -EINVAL;
361
-
362
- /* special case for last lineno not specified */
363
- if (query->last_lineno == 0)
364
- query->last_lineno = UINT_MAX;
365
-
366
- if (query->last_lineno < query->first_lineno) {
367
- pr_err("last-line:%d < 1st-line:%d\n",
368
- query->last_lineno,
369
- query->first_lineno);
370
- return -EINVAL;
371
- }
372
- } else {
373
- query->last_lineno = query->first_lineno;
374
- }
375416 } else {
376
- pr_err("unknown keyword \"%s\"\n", words[i]);
417
+ pr_err("unknown keyword \"%s\"\n", keyword);
377418 return -EINVAL;
378419 }
379420 if (rc)
380421 return rc;
381422 }
423
+ if (!query->module && modname)
424
+ /*
425
+ * support $modname.dyndbg=<multiple queries>, when
426
+ * not given in the query itself
427
+ */
428
+ query->module = modname;
429
+
382430 vpr_info_dq(query, "parsed");
383431 return 0;
384432 }
....@@ -389,11 +437,9 @@
389437 * flags fields of matched _ddebug's. Returns 0 on success
390438 * or <0 on error.
391439 */
392
-static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
393
- unsigned int *maskp)
440
+static int ddebug_parse_flags(const char *str, struct flag_settings *modifiers)
394441 {
395
- unsigned flags = 0;
396
- int op = '=', i;
442
+ int op, i;
397443
398444 switch (*str) {
399445 case '+':
....@@ -410,40 +456,40 @@
410456 for (; *str ; ++str) {
411457 for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
412458 if (*str == opt_array[i].opt_char) {
413
- flags |= opt_array[i].flag;
459
+ modifiers->flags |= opt_array[i].flag;
414460 break;
415461 }
416462 }
417463 if (i < 0) {
418
- pr_err("unknown flag '%c' in \"%s\"\n", *str, str);
464
+ pr_err("unknown flag '%c'\n", *str);
419465 return -EINVAL;
420466 }
421467 }
422
- vpr_info("flags=0x%x\n", flags);
468
+ vpr_info("flags=0x%x\n", modifiers->flags);
423469
424
- /* calculate final *flagsp, *maskp according to mask and op */
470
+ /* calculate final flags, mask based upon op */
425471 switch (op) {
426472 case '=':
427
- *maskp = 0;
428
- *flagsp = flags;
473
+ /* modifiers->flags already set */
474
+ modifiers->mask = 0;
429475 break;
430476 case '+':
431
- *maskp = ~0U;
432
- *flagsp = flags;
477
+ modifiers->mask = ~0U;
433478 break;
434479 case '-':
435
- *maskp = ~flags;
436
- *flagsp = 0;
480
+ modifiers->mask = ~modifiers->flags;
481
+ modifiers->flags = 0;
437482 break;
438483 }
439
- vpr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp);
484
+ vpr_info("*flagsp=0x%x *maskp=0x%x\n", modifiers->flags, modifiers->mask);
485
+
440486 return 0;
441487 }
442488
443489 static int ddebug_exec_query(char *query_string, const char *modname)
444490 {
445
- unsigned int flags = 0, mask = 0;
446
- struct ddebug_query query;
491
+ struct flag_settings modifiers = {};
492
+ struct ddebug_query query = {};
447493 #define MAXWORDS 9
448494 int nwords, nfound;
449495 char *words[MAXWORDS];
....@@ -454,7 +500,7 @@
454500 return -EINVAL;
455501 }
456502 /* check flags 1st (last arg) so query is pairs of spec,val */
457
- if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) {
503
+ if (ddebug_parse_flags(words[nwords-1], &modifiers)) {
458504 pr_err("flags parse failed\n");
459505 return -EINVAL;
460506 }
....@@ -463,7 +509,7 @@
463509 return -EINVAL;
464510 }
465511 /* actually go and implement the change */
466
- nfound = ddebug_change(&query, flags, mask);
512
+ nfound = ddebug_change(&query, &modifiers);
467513 vpr_info_dq(&query, nfound ? "applied" : "no-match");
468514
469515 return nfound;
....@@ -635,6 +681,41 @@
635681
636682 #endif
637683
684
+#if IS_ENABLED(CONFIG_INFINIBAND)
685
+
686
+void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
687
+ const struct ib_device *ibdev, const char *fmt, ...)
688
+{
689
+ struct va_format vaf;
690
+ va_list args;
691
+
692
+ va_start(args, fmt);
693
+
694
+ vaf.fmt = fmt;
695
+ vaf.va = &args;
696
+
697
+ if (ibdev && ibdev->dev.parent) {
698
+ char buf[PREFIX_SIZE];
699
+
700
+ dev_printk_emit(LOGLEVEL_DEBUG, ibdev->dev.parent,
701
+ "%s%s %s %s: %pV",
702
+ dynamic_emit_prefix(descriptor, buf),
703
+ dev_driver_string(ibdev->dev.parent),
704
+ dev_name(ibdev->dev.parent),
705
+ dev_name(&ibdev->dev),
706
+ &vaf);
707
+ } else if (ibdev) {
708
+ printk(KERN_DEBUG "%s: %pV", dev_name(&ibdev->dev), &vaf);
709
+ } else {
710
+ printk(KERN_DEBUG "(NULL ib_device): %pV", &vaf);
711
+ }
712
+
713
+ va_end(args);
714
+}
715
+EXPORT_SYMBOL(__dynamic_ibdev_dbg);
716
+
717
+#endif
718
+
638719 #define DDEBUG_STRING_SIZE 1024
639720 static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE];
640721
....@@ -733,8 +814,6 @@
733814 struct _ddebug *dp;
734815 int n = *pos;
735816
736
- vpr_info("called m=%p *pos=%lld\n", m, (unsigned long long)*pos);
737
-
738817 mutex_lock(&ddebug_lock);
739818
740819 if (!n)
....@@ -757,9 +836,6 @@
757836 struct ddebug_iter *iter = m->private;
758837 struct _ddebug *dp;
759838
760
- vpr_info("called m=%p p=%p *pos=%lld\n",
761
- m, p, (unsigned long long)*pos);
762
-
763839 if (p == SEQ_START_TOKEN)
764840 dp = ddebug_iter_first(iter);
765841 else
....@@ -779,8 +855,6 @@
779855 struct ddebug_iter *iter = m->private;
780856 struct _ddebug *dp = p;
781857 struct flagsbuf flags;
782
-
783
- vpr_info("called m=%p p=%p\n", m, p);
784858
785859 if (p == SEQ_START_TOKEN) {
786860 seq_puts(m,
....@@ -804,7 +878,6 @@
804878 */
805879 static void ddebug_proc_stop(struct seq_file *m, void *p)
806880 {
807
- vpr_info("called m=%p p=%p\n", m, p);
808881 mutex_unlock(&ddebug_lock);
809882 }
810883
....@@ -815,13 +888,6 @@
815888 .stop = ddebug_proc_stop
816889 };
817890
818
-/*
819
- * File_ops->open method for <debugfs>/dynamic_debug/control. Does
820
- * the seq_file setup dance, and also creates an iterator to walk the
821
- * _ddebugs. Note that we create a seq_file always, even for O_WRONLY
822
- * files where it's not needed, as doing so simplifies the ->release
823
- * method.
824
- */
825891 static int ddebug_proc_open(struct inode *inode, struct file *file)
826892 {
827893 vpr_info("called\n");
....@@ -838,6 +904,14 @@
838904 .write = ddebug_proc_write
839905 };
840906
907
+static const struct proc_ops proc_fops = {
908
+ .proc_open = ddebug_proc_open,
909
+ .proc_read = seq_read,
910
+ .proc_lseek = seq_lseek,
911
+ .proc_release = seq_release_private,
912
+ .proc_write = ddebug_proc_write
913
+};
914
+
841915 /*
842916 * Allocate a new ddebug_table for the given module
843917 * and add it to the global list.
....@@ -846,28 +920,29 @@
846920 const char *name)
847921 {
848922 struct ddebug_table *dt;
849
- const char *new_name;
850923
851924 dt = kzalloc(sizeof(*dt), GFP_KERNEL);
852
- if (dt == NULL)
853
- return -ENOMEM;
854
- new_name = kstrdup_const(name, GFP_KERNEL);
855
- if (new_name == NULL) {
856
- kfree(dt);
925
+ if (dt == NULL) {
926
+ pr_err("error adding module: %s\n", name);
857927 return -ENOMEM;
858928 }
859
- dt->mod_name = new_name;
929
+ /*
930
+ * For built-in modules, name lives in .rodata and is
931
+ * immortal. For loaded modules, name points at the name[]
932
+ * member of struct module, which lives at least as long as
933
+ * this struct ddebug_table.
934
+ */
935
+ dt->mod_name = name;
860936 dt->num_ddebugs = n;
861937 dt->ddebugs = tab;
862938
863939 mutex_lock(&ddebug_lock);
864
- list_add_tail(&dt->link, &ddebug_tables);
940
+ list_add(&dt->link, &ddebug_tables);
865941 mutex_unlock(&ddebug_lock);
866942
867
- vpr_info("%u debug prints in module %s\n", n, dt->mod_name);
943
+ v2pr_info("%3u debug prints in module %s\n", n, dt->mod_name);
868944 return 0;
869945 }
870
-EXPORT_SYMBOL_GPL(ddebug_add_module);
871946
872947 /* helper for ddebug_dyndbg_(boot|module)_param_cb */
873948 static int ddebug_dyndbg_param_cb(char *param, char *val,
....@@ -912,7 +987,6 @@
912987 static void ddebug_table_free(struct ddebug_table *dt)
913988 {
914989 list_del_init(&dt->link);
915
- kfree_const(dt->mod_name);
916990 kfree(dt);
917991 }
918992
....@@ -925,19 +999,19 @@
925999 struct ddebug_table *dt, *nextdt;
9261000 int ret = -ENOENT;
9271001
928
- vpr_info("removing module \"%s\"\n", mod_name);
1002
+ v2pr_info("removing module \"%s\"\n", mod_name);
9291003
9301004 mutex_lock(&ddebug_lock);
9311005 list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
932
- if (!strcmp(dt->mod_name, mod_name)) {
1006
+ if (dt->mod_name == mod_name) {
9331007 ddebug_table_free(dt);
9341008 ret = 0;
1009
+ break;
9351010 }
9361011 }
9371012 mutex_unlock(&ddebug_lock);
9381013 return ret;
9391014 }
940
-EXPORT_SYMBOL_GPL(ddebug_remove_module);
9411015
9421016 static void ddebug_remove_all_tables(void)
9431017 {
....@@ -971,7 +1045,7 @@
9711045 /* Also create the control file in procfs */
9721046 procfs_dir = proc_mkdir("dynamic_debug", NULL);
9731047 if (procfs_dir)
974
- proc_create("control", 0644, procfs_dir, &ddebug_proc_fops);
1048
+ proc_create("control", 0644, procfs_dir, &proc_fops);
9751049
9761050 return 0;
9771051 }
....@@ -983,20 +1057,21 @@
9831057 char *cmdline;
9841058 int ret = 0;
9851059 int n = 0, entries = 0, modct = 0;
986
- int verbose_bytes = 0;
9871060
988
- if (__start___verbose == __stop___verbose) {
989
- pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
990
- return 1;
1061
+ if (&__start___dyndbg == &__stop___dyndbg) {
1062
+ if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) {
1063
+ pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
1064
+ return 1;
1065
+ }
1066
+ pr_info("Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build\n");
1067
+ ddebug_init_success = 1;
1068
+ return 0;
9911069 }
992
- iter = __start___verbose;
1070
+ iter = __start___dyndbg;
9931071 modname = iter->modname;
9941072 iter_start = iter;
995
- for (; iter < __stop___verbose; iter++) {
1073
+ for (; iter < __stop___dyndbg; iter++) {
9961074 entries++;
997
- verbose_bytes += strlen(iter->modname) + strlen(iter->function)
998
- + strlen(iter->filename) + strlen(iter->format);
999
-
10001075 if (strcmp(modname, iter->modname)) {
10011076 modct++;
10021077 ret = ddebug_add_module(iter_start, n, modname);
....@@ -1013,9 +1088,9 @@
10131088 goto out_err;
10141089
10151090 ddebug_init_success = 1;
1016
- vpr_info("%d modules, %d entries and %d bytes in ddebug tables, %d bytes in (readonly) verbose section\n",
1091
+ vpr_info("%d modules, %d entries and %d bytes in ddebug tables, %d bytes in __dyndbg section\n",
10171092 modct, entries, (int)(modct * sizeof(struct ddebug_table)),
1018
- verbose_bytes + (int)(__stop___verbose - __start___verbose));
1093
+ (int)(entries * sizeof(struct _ddebug)));
10191094
10201095 /* apply ddebug_query boot param, dont unload tables on err */
10211096 if (ddebug_setup_string[0] != '\0') {