Message ID | 20240716185806.1572048-1-jim.cromie@gmail.com (mailing list archive) |
---|---|
Headers | show |
Series | fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y | expand |
On Tue, Jul 16, 2024 at 8:58 PM Jim Cromie <jim.cromie@gmail.com> wrote: > > resending to fix double-copies of a dozen patches. > added 2 squash-ins to address Ville's designated-initializer comment. > > This fixes dynamic-debug support for DRM.debug, added via classmaps. > commit bb2ff6c27bc9 (drm: Disable dynamic debug as broken) > > CONFIG_DRM_USE_DYNAMIC_DEBUG=y was marked broken because drm.debug=val > was applied when drm.ko was modprobed; too early for the yet-to-load > drivers, which thus missed the enablement. My testing with > /etc/modprobe.d/ entries and modprobes with dyndbg=$querycmd options > obscured this omission. > > The fix is to replace invocations of DECLARE_DYNDBG_CLASSMAP with > DYNDBG_CLASSMAP_DEFINE for core, and DYNDBG_CLASSMAP_USE for drivers. > The distinction allows dyndbg to also handle the users properly. > > DRM is the only current classmaps user, and is not actually using it, > so if you think DRM could benefit from zero-off-cost debugs based on > static-keys, please test. > > There is also a no-DRM-involved selftest script: > > [root@v6 b0-dd]# V=0 ./tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh > # consulting KCONFIG_CONFIG: .config > # BASIC_TESTS > : 0 matches on =p > : 14 matches on =p > : 0 matches on =p > : 21 matches on =mf > : 0 matches on =ml > : 6 matches on =mfl > ... > # Done on: Sun Jun 30 10:34:24 PM MDT 2024 > > HISTORY > > 9/4/22 - ee879be38bc8..ace7c4bbb240 commited - classmaps-v1 dyndbg parts > 9/11/22 - 0406faf25fb1..16deeb8e18ca commited - classmaps-v1 drm parts > > https://lore.kernel.org/lkml/Y3XUrOGAV4I7bB3M@kroah.com/ > greg k-h says: > This should go through the drm tree now. The rest probably should also > go that way and not through my tree as well. > > https://lore.kernel.org/lkml/20221206003424.592078-1-jim.cromie@gmail.com/ > v1- RFC adds DYNDBG_CLASSMAP_DEFINE + test-submod to recap DRM failure > > https://lore.kernel.org/lkml/20230113193016.749791-1-jim.cromie@gmail.com/ > v2- w RFC on "tolerate toggled state" > > https://lore.kernel.org/lkml/Y8aNMxHpvZ8qecSc@hirez.programming.kicks-ass.net/ > - PeterZ - nacks tolerance of insane/uninit static-key state > > https://lore.kernel.org/lkml/8ca08fba-1120-ca86-6129-0b33afb4a1da@akamai.com/ > - JasonB diagnoses prob - set jump-label b4 init > > 7deabd674988 dyndbg: use the module notifier callbacks > - JasonB lands fix for my problem > he moves dyndbg to use notifiers to do init, like & after jump-labels > > https://lore.kernel.org/lkml/20230125203743.564009-20-jim.cromie@gmail.com/ > v3- probing, workaround-ish > > https://lore.kernel.org/lkml/20230713163626.31338-1-jim.cromie@gmail.com/ > v4 - 7/13/23 > - had extra/unused __UNIQUE_ID warnings/errs on lkp-tested arches > due to unmatched __used marks > - RandyD doc fixes, thx. > > https://lore.kernel.org/lkml/20230801170255.163237-1-jim.cromie@gmail.com/ > v5 - 8/1/23 > - lkp-test reported panics-on-boot > https://lore.kernel.org/lkml/202308031432.fcb4197-oliver.sang@intel.com/ > - DRM=y in apply-params > - missing align(8) in init-macro, failed only for builtin modules > > https://lore.kernel.org/lkml/20230911230838.14461-1-jim.cromie@gmail.com/ > v6 - 9/11/23 - no feedback > > v7[a-d] - attempts to get into/thru DRM patchwork CI.. > - "jenius" struck, I preserved DECLARE_DYNDBG_CLASSMAP til later > > v8[a-i] - added tools/testing/selftests/dynamic_debug/* > - now turnkey testable without DRM > > > CLASSMAPS FROM THE TOP > > dynamic-debug classmap's primary goal was to bring zero-off-cost > debugs, via static-keys, to DRM. > > drm.debug: > > is ~5000 invocations of debug-macros across core, drivers, helpers; > each in 1 of 10 exclusive categories: DRM_UT_*, kept in an enum/int, > and passed in 1st macro-arg, as a builtin-constant. > > The 10 categories are all controlled together, by bits 0..9 in a sysfs > knob. > > drm.debug=0x1ff # bootarg > echo 0x4 > /sys/module/drm/parameters/debug # run-time setting > > Keeping all that unchanged was a firm design requirement for classmaps. > > Below the sysfs interface, classmaps are exposed in the >control > grammar with a new "class" keyword. This is mostly like the other > selector keywords, differing by: > > a- classnames are client/subsystem/domain defined, not code-name-structural. > the classnames are global, across system > IOW: "class DRM_UT_CORE" selects on any module which knows the class > > b- classes are protected from unqualified modification. > > # cannot disable any DRM (or other) classes without saying so > echo -p > /proc/dynamic_debug/control > > c- because b, modules must opt-in so dyndbg knows their classnames. > without names, dyndbg cannot lookup the classid & change the class. > > d- classes don't have wildcards - add if needed. > DRM uses "${SUBSYS}_${CATNAME}" > probably more useful with "${TOP}_${MID}_${LOW}" classnames > nobody's sure what _UT_ is. > > API in use: > > DYNDBG_CLASSMAP_* macros are all file-scope declarators. > > 1. DYNDBG_CLASSMAP_DEFINE(drm_debug_classes, ...); > 2. DYNDBG_CLASSMAP_USE(drm_debug_classes); > > Classmaps get DEFINEd once (in drm.ko for core) and USEd (in drivers > and helpers), these declarations 1. define and export a classmap (in > core module), and 2. refer to the exported class-struct from the other > modules. > > They both tell dynamic-debug that the module has some of these class'd > pr_debugs, so dyndbg can use the classmap's names to validate >control > inputs and change the callsites. This is the opt-in. > > The distinction allows USErs to act differently than the DEFINEr; they > have to follow the ref back to the DEFINEing module, find the kparam > connected to the classmap, and lookup and apply its modprobed value. > (this is the bug-fix). > > Dyndbg uses the classnames to validate "class FOO" >control inputs, > and apply the changes to each module that has DEFINEd or USEd the > classmap. > > This makes classmaps opt-in: modules must _DEFINE or _USE a classmap > for their class'd pr_debug()s to be >control'd. > > NOTE: __pr_dbg_class(1, "const-int unreachable class 1"); is legal, > but not controllable unless the const 1 has been mapped to a _DEFINE'd > classname. > > NB: and __pr_dbg_class(i++, "undeclared class") is illegal. > > In drm_print.c we have: (theres room for better words...) > > /* classnames must match value-symbols of enum drm_debug_category */ > DRM_CLASSMAP_DEFINE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, > DRM_UT_CORE, // _base > /* this effectively names the bits in drm.debug */ > "DRM_UT_CORE", > "DRM_UT_DRIVER", > "DRM_UT_KMS", > "DRM_UT_PRIME", > "DRM_UT_ATOMIC", > "DRM_UT_VBL", > "DRM_UT_STATE", > "DRM_UT_LEASE", > "DRM_UT_DP", > "DRM_UT_DRMRES"); > > This maps the sequence of "classnames" to ints starting with DRM_UT_CORE. > other _bases allow sharing the per-module 0..62 class-id space. > (63 is default/unclassed/common prdbg). > > Only complete, linear maps are recommended. This suits DRM. > > DYNDBG_CLASSMAP_PARAM_REF() creates the sysfs-kparam classbits knob, > binding the extern'd long-int/bitvec to the classmap. The extern > insures that old users of __drm_debug can still check its value. > > DRM's categories are independent of each other. The other possible > classmap-type/behavior is "related", ie somehow "ordered": V3>V2. The > relatedness of classes in a classmap is enforced at the kparam, where > they are all set together, not at the >control interface. > > THE PATCHSET has 2 halves: > > 1- dynamic-debug fix - API change > > The root cause was DECLARE_DYNDBG_CLASSMAP tried to do too much, and > its use in both core and drivers, helpers couldnt sort the difference. > > The fix is to replace it with DYNDBG_CLASSMAP_DEFINE in core, and > DYNDBG_CLASSMAP_USE in drivers,helpers. The 1st differs from -v1 by > exporting the classmap, allowing 2nd to ref it. They respectively add > records to 2 ELF sections in the module. > > Now, dyndbg's on-modprobe handler follows the _USE/refs to the owning > module, finds the controlling kparam: drm.debug, and applies its value > thru the classmap, to the module's pr_debugs. > > A selftest script is included: > :#> ./tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh > > It recapitulates the DRM regression scenario using the 2 test modules. > The test verifies that the dependent module is initialized properly > from the parent's classmap kparam, and the classed prdbgs get enabled. > > This latest rev fixes the test for the various CONFIG_DYNAMIC_DEBUG* > build combos, by skipping some subtests where the expected counts are > wrong. Lukasz Bartosik caught this - thanks. > CC: ukaszb@chromium.org > > And 2 tweaks to kdoc & howto, to steer api users away from using > designated initializers to _DEFINE the classmap. > > > 2- DRM fixes - use new api. > > a. update core/drivers to invoke DRM_CLASSMAP_DEFINE/_USE > b. wrap DYNDBG_CLASSMAP_* with DRM_CLASSMAP_* - hide ifdef > > c. now with separate +DRM_CLASSMAP_USE patches for each driver/helper: > d. and defer dropping DECLARE_DYNDBG_CLASSMAP til later > > Maybe theres a single place to invoke DRM_CLASSMAP_USE just once, > perhaps from a client library c-file. I poked a little, didn't find it. > It would be a bit obscured for an opt-in style declaration. > > Patches are against v6.10 > theyre also at: > tree/branch: https://github.com/jimc/linux.git dd-fix-9d > and lkp-robot told me: > [jimc:dd-fix-9d] BUILD SUCCESS 7c38f1d94f9919fec887113b620b83d60061c035 > > > Finally, classmaps are in a meta-stable state right now; some governor > might yet walk it over to the gravel pit out back. > > Tested-bys would help greatly, help get it off the fence it straddles. > Please specify your test method: selftest or drm.debug=0x1ff boot. > > Next Im gonna try to haul this over to the freedesktop DRM-CI river, > presuming I can find the way (accts,etc) > > Also entertaining Reviewed-bys :-} > > Jim Cromie (54): > > DYNAMIC-DEBUG parts: > > cleanup: > docs/dyndbg: update examples \012 to \n > test-dyndbg: fixup CLASSMAP usage error > dyndbg: reword "class unknown," to "class:_UNKNOWN_" > dyndbg: make ddebug_class_param union members same size > dyndbg: replace classmap list with a vector > > prep: > dyndbg: ddebug_apply_class_bitmap - add module arg, select on it > dyndbg: split param_set_dyndbg_classes to _module & wrapper fns > dyndbg: drop NUM_TYPE_ARRAY > dyndbg: reduce verbose/debug clutter > dyndbg: silence debugs with no-change updates > dyndbg: tighten ddebug_class_name() 1st arg type > dyndbg: tighten fn-sig of ddebug_apply_class_bitmap > dyndbg: reduce verbose=3 messages in ddebug_add_module > > API changes & selftest: > dyndbg-API: remove DD_CLASS_TYPE_(DISJOINT|LEVEL)_NAMES and code > dyndbg-API: fix DECLARE_DYNDBG_CLASSMAP > selftests-dyndbg: add tools/testing/selftests/dynamic_debug/* > dyndbg-API: promote DYNDBG_CLASSMAP_PARAM to API > dyndbg-doc: add classmap info to howto > dyndbg: treat comma as a token separator > selftests-dyndbg: add comma_terminator_tests > dyndbg: split multi-query strings with % > selftests-dyndbg: test_percent_splitting > docs/dyndbg: explain new delimiters: comma, percent > selftests-dyndbg: add test_mod_submod > dyndbg-doc: explain flags parse 1st > dyndbg: change __dynamic_func_call_cls* macros into expressions > selftests-dyndbg: check KCONFIG_CONFIG to avoid silly fails > dyndbg-selftest: reduce default verbosity > > DRM-parts: > > drm: use correct ccflags-y spelling > drm-dyndbg: adapt drm core to use dyndbg classmaps-v2 > drm-dyndbg: adapt DRM to invoke DYNDBG_CLASSMAP_PARAM > drm-dyndbg: DRM_CLASSMAP_USE in amdgpu driver > drm-dyndbg: DRM_CLASSMAP_USE in i915 driver > drm-dyndbg: DRM_CLASSMAP_USE in drm_crtc_helper > drm-dyndbg: DRM_CLASSMAP_USE in drm_dp_helper > drm-dyndbg: DRM_CLASSMAP_USE in nouveau > drm-print: workaround unused variable compiler meh > drm-dyndbg: add DRM_CLASSMAP_USE to Xe driver > drm-dyndbg: add DRM_CLASSMAP_USE to virtio_gpu > drm-dyndbg: add DRM_CLASSMAP_USE to simpledrm > drm-dyndbg: add DRM_CLASSMAP_USE to bochs > drm-dyndbg: add DRM_CLASSMAP_USE to etnaviv > drm-dyndbg: add DRM_CLASSMAP_USE to gma500 driver > drm-dyndbg: add DRM_CLASSMAP_USE to radeon > drm-dyndbg: add DRM_CLASSMAP_USE to vmwgfx driver > drm-dyndbg: add DRM_CLASSMAP_USE to vkms driver > drm-dyndbg: add DRM_CLASSMAP_USE to udl driver > drm-dyndbg: add DRM_CLASSMAP_USE to mgag200 driver > drm-dyndbg: add DRM_CLASSMAP_USE to the gud driver > drm-dyndbg: add DRM_CLASSMAP_USE to the qxl driver > drm-dyndbg: add DRM_CLASSMAP_USE to the drm_gem_shmem_helper driver > drm: restore CONFIG_DRM_USE_DYNAMIC_DEBUG un-BROKEN > > added in -resend (will squash back in): > > dyndbg: tighten up kdoc about DYNDBG_CLASSMAP_* macros > docs-dyndbg: improve howto classmaps api section > > .../admin-guide/dynamic-debug-howto.rst | 113 ++++- > MAINTAINERS | 3 +- > drivers/gpu/drm/Kconfig | 3 +- > drivers/gpu/drm/Makefile | 3 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 12 +- > drivers/gpu/drm/display/drm_dp_helper.c | 12 +- > drivers/gpu/drm/drm_crtc_helper.c | 12 +- > drivers/gpu/drm/drm_gem_shmem_helper.c | 2 + > drivers/gpu/drm/drm_print.c | 38 +- > drivers/gpu/drm/etnaviv/etnaviv_drv.c | 2 + > drivers/gpu/drm/gma500/psb_drv.c | 2 + > drivers/gpu/drm/gud/gud_drv.c | 2 + > drivers/gpu/drm/i915/i915_params.c | 12 +- > drivers/gpu/drm/mgag200/mgag200_drv.c | 2 + > drivers/gpu/drm/nouveau/nouveau_drm.c | 12 +- > drivers/gpu/drm/qxl/qxl_drv.c | 2 + > drivers/gpu/drm/radeon/radeon_drv.c | 2 + > drivers/gpu/drm/tiny/bochs.c | 2 + > drivers/gpu/drm/tiny/simpledrm.c | 2 + > drivers/gpu/drm/udl/udl_main.c | 2 + > drivers/gpu/drm/virtio/virtgpu_drv.c | 2 + > drivers/gpu/drm/vkms/vkms_drv.c | 2 + > drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 + > drivers/gpu/drm/xe/xe_drm_client.c | 2 + > include/asm-generic/vmlinux.lds.h | 1 + > include/drm/drm_print.h | 10 + > include/linux/dynamic_debug.h | 145 ++++-- > kernel/module/main.c | 3 + > lib/Kconfig.debug | 24 +- > lib/Makefile | 3 + > lib/dynamic_debug.c | 436 +++++++++++------- > lib/test_dynamic_debug.c | 131 +++--- > lib/test_dynamic_debug_submod.c | 17 + > tools/testing/selftests/Makefile | 1 + > .../testing/selftests/dynamic_debug/Makefile | 9 + > tools/testing/selftests/dynamic_debug/config | 2 + > .../dynamic_debug/dyndbg_selftest.sh | 375 +++++++++++++++ > 37 files changed, 1042 insertions(+), 363 deletions(-) > create mode 100644 lib/test_dynamic_debug_submod.c > create mode 100644 tools/testing/selftests/dynamic_debug/Makefile > create mode 100644 tools/testing/selftests/dynamic_debug/config > create mode 100755 tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh > > -- > 2.45.2 > Tested-by: Łukasz Bartosik <ukaszb@chromium.org> Here is what I tested in virtme-ng: TEST_DYNAMIC_DEBUG=M and TEST_DYNAMIC_DEBUG_SUBMOD=M BASIC_TESTS, COMMA_TERMINATOR_TESTS, TEST_PERCENT_SPLITTING and TEST_MOD_SUBMOD selftests passed TEST_DYNAMIC_DEBUG=Y and TEST_DYNAMIC_DEBUG_SUBMOD=M BASIC_TESTS and COMMA_TERMINATOR_TESTS selftests passed, TEST_PERCENT_SPLITTING and TEST_PERCENT_SPLITTING selftests were skipped TEST_DYNAMIC_DEBUG=Y and TEST_DYNAMIC_DEBUG_SUBMOD=Y BASIC_TESTS and COMMA_TERMINATOR_TESTS selftests passed, TEST_PERCENT_SPLITTING and TEST_PERCENT_SPLITTING selftests were skipped I also did manual testing by enabling/disabling different classes from the kernel command line with drm.debug param and verified they are correctly reflected in cat /proc/dynamic_debug/control. All the above LGTM.