xref: /linux/lib/test_dynamic_debug.c (revision 5ad30c5fc0a72c2aaa1d26f9e4061d8646231adb)
1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   * Kernel module for testing dynamic_debug
4   *
5   * Authors:
6   *      Jim Cromie	<jim.cromie@gmail.com>
7   */
8  
9  #define pr_fmt(fmt) "test_dd: " fmt
10  
11  #include <linux/module.h>
12  
13  /* run tests by reading or writing sysfs node: do_prints */
14  
15  static void do_prints(void); /* device under test */
16  static int param_set_do_prints(const char *instr, const struct kernel_param *kp)
17  {
18  	do_prints();
19  	return 0;
20  }
21  static int param_get_do_prints(char *buffer, const struct kernel_param *kp)
22  {
23  	do_prints();
24  	return scnprintf(buffer, PAGE_SIZE, "did do_prints\n");
25  }
26  static const struct kernel_param_ops param_ops_do_prints = {
27  	.set = param_set_do_prints,
28  	.get = param_get_do_prints,
29  };
30  module_param_cb(do_prints, &param_ops_do_prints, NULL, 0600);
31  
32  /*
33   * Using the CLASSMAP api:
34   * - classmaps must have corresponding enum
35   * - enum symbols must match/correlate with class-name strings in the map.
36   * - base must equal enum's 1st value
37   * - multiple maps must set their base to share the 0-30 class_id space !!
38   *   (build-bug-on tips welcome)
39   * Additionally, here:
40   * - tie together sysname, mapname, bitsname, flagsname
41   */
42  #define DD_SYS_WRAP(_model, _flags)					\
43  	static unsigned long bits_##_model;				\
44  	static struct ddebug_class_param _flags##_model = {		\
45  		.bits = &bits_##_model,					\
46  		.flags = #_flags,					\
47  		.map = &map_##_model,					\
48  	};								\
49  	module_param_cb(_flags##_##_model, &param_ops_dyndbg_classes, &_flags##_model, 0600)
50  
51  /* numeric input, independent bits */
52  enum cat_disjoint_bits {
53  	D2_CORE = 0,
54  	D2_DRIVER,
55  	D2_KMS,
56  	D2_PRIME,
57  	D2_ATOMIC,
58  	D2_VBL,
59  	D2_STATE,
60  	D2_LEASE,
61  	D2_DP,
62  	D2_DRMRES };
63  DECLARE_DYNDBG_CLASSMAP(map_disjoint_bits, DD_CLASS_TYPE_DISJOINT_BITS, 0,
64  			"D2_CORE",
65  			"D2_DRIVER",
66  			"D2_KMS",
67  			"D2_PRIME",
68  			"D2_ATOMIC",
69  			"D2_VBL",
70  			"D2_STATE",
71  			"D2_LEASE",
72  			"D2_DP",
73  			"D2_DRMRES");
74  DD_SYS_WRAP(disjoint_bits, p);
75  DD_SYS_WRAP(disjoint_bits, T);
76  
77  /* symbolic input, independent bits */
78  enum cat_disjoint_names { LOW = 11, MID, HI };
79  DECLARE_DYNDBG_CLASSMAP(map_disjoint_names, DD_CLASS_TYPE_DISJOINT_NAMES, 10,
80  			"LOW", "MID", "HI");
81  DD_SYS_WRAP(disjoint_names, p);
82  DD_SYS_WRAP(disjoint_names, T);
83  
84  /* numeric verbosity, V2 > V1 related */
85  enum cat_level_num { V0 = 14, V1, V2, V3, V4, V5, V6, V7 };
86  DECLARE_DYNDBG_CLASSMAP(map_level_num, DD_CLASS_TYPE_LEVEL_NUM, 14,
87  		       "V0", "V1", "V2", "V3", "V4", "V5", "V6", "V7");
88  DD_SYS_WRAP(level_num, p);
89  DD_SYS_WRAP(level_num, T);
90  
91  /* symbolic verbosity */
92  enum cat_level_names { L0 = 22, L1, L2, L3, L4, L5, L6, L7 };
93  DECLARE_DYNDBG_CLASSMAP(map_level_names, DD_CLASS_TYPE_LEVEL_NAMES, 22,
94  			"L0", "L1", "L2", "L3", "L4", "L5", "L6", "L7");
95  DD_SYS_WRAP(level_names, p);
96  DD_SYS_WRAP(level_names, T);
97  
98  /* stand-in for all pr_debug etc */
99  #define prdbg(SYM) __pr_debug_cls(SYM, #SYM " msg\n")
100  
101  static void do_cats(void)
102  {
103  	pr_debug("doing categories\n");
104  
105  	prdbg(LOW);
106  	prdbg(MID);
107  	prdbg(HI);
108  
109  	prdbg(D2_CORE);
110  	prdbg(D2_DRIVER);
111  	prdbg(D2_KMS);
112  	prdbg(D2_PRIME);
113  	prdbg(D2_ATOMIC);
114  	prdbg(D2_VBL);
115  	prdbg(D2_STATE);
116  	prdbg(D2_LEASE);
117  	prdbg(D2_DP);
118  	prdbg(D2_DRMRES);
119  }
120  
121  static void do_levels(void)
122  {
123  	pr_debug("doing levels\n");
124  
125  	prdbg(V1);
126  	prdbg(V2);
127  	prdbg(V3);
128  	prdbg(V4);
129  	prdbg(V5);
130  	prdbg(V6);
131  	prdbg(V7);
132  
133  	prdbg(L1);
134  	prdbg(L2);
135  	prdbg(L3);
136  	prdbg(L4);
137  	prdbg(L5);
138  	prdbg(L6);
139  	prdbg(L7);
140  }
141  
142  static void do_prints(void)
143  {
144  	do_cats();
145  	do_levels();
146  }
147  
148  static int __init test_dynamic_debug_init(void)
149  {
150  	pr_debug("init start\n");
151  	do_prints();
152  	pr_debug("init done\n");
153  	return 0;
154  }
155  
156  static void __exit test_dynamic_debug_exit(void)
157  {
158  	pr_debug("exited\n");
159  }
160  
161  module_init(test_dynamic_debug_init);
162  module_exit(test_dynamic_debug_exit);
163  
164  MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>");
165  MODULE_LICENSE("GPL");
166