@@ -78,7 +78,7 @@ obj-$(CONFIG_TEST_SORT) += test_sort.o
obj-$(CONFIG_TEST_USER_COPY) += test_user_copy.o
obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_keys.o
obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o
-obj-$(CONFIG_TEST_DYNAMIC_DEBUG) += test_dynamic_debug.o
+obj-$(CONFIG_TEST_DYNAMIC_DEBUG) += test_dynamic_debug.o test_dynamic_debug_submod.o
obj-$(CONFIG_TEST_PRINTF) += test_printf.o
obj-$(CONFIG_TEST_SCANF) += test_scanf.o
obj-$(CONFIG_TEST_BITMAP) += test_bitmap.o
@@ -100,6 +100,7 @@ obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o
obj-$(CONFIG_TEST_REF_TRACKER) += test_ref_tracker.o
CFLAGS_test_fprobe.o += $(CC_FLAGS_FTRACE)
obj-$(CONFIG_FPROBE_SANITY_TEST) += test_fprobe.o
+
#
# CFLAGS for compiling floating point code inside the kernel. x86/Makefile turns
# off the generation of FPU/SSE* instructions for kernel proper but FPU_FLAGS
@@ -6,7 +6,11 @@
* Jim Cromie <jim.cromie@gmail.com>
*/
-#define pr_fmt(fmt) "test_dd: " fmt
+#if defined(TEST_DYNAMIC_DEBUG_SUBMOD)
+ #define pr_fmt(fmt) "test_dd_submod: " fmt
+#else
+ #define pr_fmt(fmt) "test_dd: " fmt
+#endif
#define DEBUG /* enable all prdbgs (plain & class'd) at compiletime */
@@ -49,6 +53,13 @@ module_param_cb(do_prints, ¶m_ops_do_prints, NULL, 0600);
}; \
module_param_cb(_flags##_##_model, ¶m_ops_dyndbg_classes, &_flags##_model, 0600)
+/*
+ * dynamic-debug imitates drm.debug model's use of enums (DRM_UT_CORE
+ * etc) to define it's classes/categories. dyndbg allows class-id's
+ * 0..62, reserving 63 for plain old (non-class'd) prdbgs. A module
+ * can define multiple classmaps, as long as they share the range.
+ */
+
/* numeric input, independent bits */
enum cat_disjoint_bits {
D2_CORE = 0,
@@ -61,7 +72,36 @@ enum cat_disjoint_bits {
D2_LEASE,
D2_DP,
D2_DRMRES };
+
+/* symbolic input, independent bits */
+enum cat_disjoint_names { LOW = 10, MID, HI };
+
+/* numeric verbosity, V2 > V1 related */
+enum cat_level_num { V0 = 14, V1, V2, V3, V4, V5, V6, V7 };
+
+/* symbolic verbosity */
+enum cat_level_names { L0 = 22, L1, L2, L3, L4, L5, L6, L7 };
+
+#if defined(TEST_DYNAMIC_DEBUG_SUBMOD)
+
+/* use the classmaps defined in 'parent' module below */
+DYNDBG_CLASSMAP_USE(map_disjoint_bits);
+DYNDBG_CLASSMAP_USE(map_disjoint_names);
+DYNDBG_CLASSMAP_USE(map_level_num);
+DYNDBG_CLASSMAP_USE(map_level_names);
+
+#else
+
+/*
+ * parent module, define a classmap of each of 4 types.
+ * enum values are class-ids
+ * enum symbols are stringified, used as classnames
+ * param bits are mapped in order: 0..N
+ * (a straight, obvious, linear map is encouraged)
+ */
+
DYNDBG_CLASSMAP_DEFINE(map_disjoint_bits, DD_CLASS_TYPE_DISJOINT_BITS,
+ /* bits 0..N of param are mapped to these class-ids */
D2_CORE,
D2_DRIVER,
D2_KMS,
@@ -75,27 +115,23 @@ DYNDBG_CLASSMAP_DEFINE(map_disjoint_bits, DD_CLASS_TYPE_DISJOINT_BITS,
DD_SYS_WRAP(disjoint_bits, p);
DD_SYS_WRAP(disjoint_bits, T);
-/* symbolic input, independent bits */
-enum cat_disjoint_names { LOW = 10, MID, HI };
DYNDBG_CLASSMAP_DEFINE(map_disjoint_names, DD_CLASS_TYPE_DISJOINT_NAMES,
LOW, MID, HI);
DD_SYS_WRAP(disjoint_names, p);
DD_SYS_WRAP(disjoint_names, T);
-/* numeric verbosity, V2 > V1 related */
-enum cat_level_num { V0 = 14, V1, V2, V3, V4, V5, V6, V7 };
DYNDBG_CLASSMAP_DEFINE(map_level_num, DD_CLASS_TYPE_LEVEL_NUM,
V0, V1, V2, V3, V4, V5, V6, V7);
DD_SYS_WRAP(level_num, p);
DD_SYS_WRAP(level_num, T);
-/* symbolic verbosity */
-enum cat_level_names { L0 = 22, L1, L2, L3, L4, L5, L6, L7 };
DYNDBG_CLASSMAP_DEFINE(map_level_names, DD_CLASS_TYPE_LEVEL_NAMES,
L0, L1, L2, L3, L4, L5, L6, L7);
DD_SYS_WRAP(level_names, p);
DD_SYS_WRAP(level_names, T);
+#endif /* TEST_DYNAMIC_DEBUG_SUBMOD */
+
/* stand-in for all pr_debug etc */
#define prdbg(SYM) __pr_debug_cls(SYM, #SYM " msg\n")
new file mode 100644
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Kernel module for testing dynamic_debug
+ *
+ * Authors:
+ * Jim Cromie <jim.cromie@gmail.com>
+ */
+
+#define TEST_DYNAMIC_DEBUG_SUBMOD
+#include "test_dynamic_debug.c"
CONFIG_DRM_USE_DYNAMIC_DEBUG=y has a regression; drm subsystem modules, which depend upon drm.ko and use the drm.debug API, do not get enabled when __drm_debug is set by `modprobe drm debug=0x1f`. With =N, __drm_debug is checked before logging the msg, so the end-of-modprobe debug=$init affected all later checks. But with =y, each run-time check is replaced by a static-key that is set at end-of-modprobe. This creates a chicken-egg dependency; i915 must be modprobed before its drm.debugs are enabled, but drm.ko (and __drm_debug=$init) must be done before modprobe i915, so its callsites arent there yet to be enabled. The WIP-fix is to split DECLARE_DYNDBG_CLASSMAP to: DYNDBG_CLASSMAP_DEFINE - invoked in 'parent' DYNDBG_CLASSMAP_USE - invoked in dependent, to USE the exported definition To prove the fix w/o involving DRM, we need 2 modules, one dependent on the other. Add test_dynamic_debug_submod.ko, which _USEs the classmaps _exported by test_dynamic_debug.ko To keep code to a minimum, test_dynamic_debug.c ifdefs on TEST_DYNAMIC_DEBUG_SUBMOD to build either parent or dependent, with either DYNDBG_CLASSMAP_DEFINE or DYNDBG_CLASSMAP_USE blocks. So test_dynamic_debug_submod.c is just 2 lines: include parent after defining SUBMOD. This also gives the 2 modules identical logging behavior as a baseline. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> --- lib/Makefile | 3 +- lib/test_dynamic_debug.c | 50 ++++++++++++++++++++++++++++----- lib/test_dynamic_debug_submod.c | 10 +++++++ 3 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 lib/test_dynamic_debug_submod.c