summaryrefslogtreecommitdiffstats
path: root/lib/dynamic_debug.c
Commit message (Collapse)AuthorAgeFilesLines
* dyndbg: add source filename to prefixThomas Weißschuh2023-08-041-0/+4
| | | | | | | | | | | | | | | | | | | | | | | Printing the line number without the file is of limited usefulness. Knowing the filename also makes it also easier to relate the logged information to the controlfile. Example: # modprobe test_dynamic_debug # echo 'file test_dynamic_debug.c =pfsl' > /proc/dynamic_debug/control # echo 1 > /sys/module/test_dynamic_debug/parameters/do_prints # dmesg | tail -2 [ 71.802212] do_cats:lib/test_dynamic_debug.c:103: test_dd: doing categories [ 71.802227] do_levels:lib/test_dynamic_debug.c:123: test_dd: doing levels Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> Acked-by: Jim Cromie <jim.cromie@gmail.com> Acked-by: Jason Baron <jbaron@akamai.com> Reviewed-by: Luis Chamberlain <mcgrof@kernel.org> Link: https://lore.kernel.org/r/20230709-dyndbg-filename-v2-3-fd83beef0925@weissschuh.net Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: increase PREFIX_SIZE to 128Thomas Weißschuh2023-08-041-1/+1
| | | | | | | | | | | A follow-up patch will add the possibility to print the filename as part of the prefix. Increase the maximum prefix size to accommodate this. Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> Reviewed-by: Luis Chamberlain <mcgrof@kernel.org> Link: https://lore.kernel.org/r/20230709-dyndbg-filename-v2-2-fd83beef0925@weissschuh.net Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: constify opt_arrayThomas Weißschuh2023-08-041-1/+1
| | | | | | | | | It is never modified, so mark it const. Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> Reviewed-by: Luis Chamberlain <mcgrof@kernel.org> Link: https://lore.kernel.org/r/20230709-dyndbg-filename-v2-1-fd83beef0925@weissschuh.net Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: use the module notifier callbacksJason Baron2023-03-091-9/+41
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Bring dynamic debug in line with other subsystems by using the module notifier callbacks. This results in a net decrease in core module code. Additionally, Jim Cromie has a new dynamic debug classmap feature, which requires that jump labels be initialized prior to dynamic debug. Specifically, the new feature toggles a jump label from the existing dynamic_debug_setup() function. However, this does not currently work properly, because jump labels are initialized via the 'module_notify_list' notifier chain, which is invoked after the current call to dynamic_debug_setup(). Thus, this patch ensures that jump labels are initialized prior to dynamic debug by setting the dynamic debug notifier priority to 0, while jump labels have the higher priority of 1. Tested by Jim using his new test case, and I've verfied the correct printing via: # modprobe test_dynamic_debug dyndbg. Link: https://lore.kernel.org/lkml/20230113193016.749791-21-jim.cromie@gmail.com/ Reported-by: kernel test robot <lkp@intel.com> Link: https://lore.kernel.org/oe-kbuild-all/202302190427.9iIK2NfJ-lkp@intel.com/ Tested-by: Jim Cromie <jim.cromie@gmail.com> Reviewed-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> CC: Jim Cromie <jim.cromie@gmail.com> Cc: Luis Chamberlain <mcgrof@kernel.org> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Jason Baron <jbaron@akamai.com> Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
* dyndbg: remove unused 'base' arg from __ddebug_add_module()Jason Baron2023-03-091-5/+4
| | | | | | | | | | | | | The 'base' parameter to __ddebug_add_module() is no longer in use after: Commit b7b4eebdba7b ("dyndbg: gather __dyndbg[] state into struct _ddebug_info"). Cc: Jim Cromie <jim.cromie@gmail.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Tested-by: Jim Cromie <jim.cromie@gmail.com> Reviewed-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com> Signed-off-by: Jason Baron <jbaron@akamai.com> Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
* dyndbg: add drm.debug style (drm/parameters/debug) bitmap supportJim Cromie2022-09-071-0/+212
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add kernel_param_ops and callbacks to use a class-map to validate and apply input to a sysfs-node, which allows users to control classes defined in that class-map. This supports uses like: echo 0x3 > /sys/module/drm/parameters/debug IE add these: - int param_set_dyndbg_classes() - int param_get_dyndbg_classes() - struct kernel_param_ops param_ops_dyndbg_classes Following the model of kernel/params.c STANDARD_PARAM_DEFS, these are non-static and exported. This might be unnecessary here. get/set use an augmented kernel_param; the arg refs a new struct ddebug_class_param, which contains: - A ptr to user's state-store; a union of &ulong for drm.debug, &int for nouveau level debug. By ref'g the client's bit-state _var, code coordinates with existing code (like drm_debug_enabled) which uses it, so existing/remaining calls can work unchanged. Changing drm.debug to a ulong allows use of BIT() etc. - FLAGS: dyndbg.flags toggled by changes to bitmap. Usually just "p". - MAP: a pointer to struct ddebug_classes_map, which maps those class-names to .class_ids 0..N that the module is using. This class-map is declared & initialized by DECLARE_DYNDBG_CLASSMAP. - map-type: 4 enums DD_CLASS_TYPE_* select 2 input forms and 2 meanings. numeric input: DD_CLASS_TYPE_DISJOINT_BITS integer input, independent bits. ie: drm.debug DD_CLASS_TYPE_LEVEL_NUM integer input, 0..N levels classnames-list (comma separated) input: DD_CLASS_TYPE_DISJOINT_NAMES each name affects a bit, others preserved DD_CLASS_TYPE_LEVEL_NAMES names have level meanings, like kern_levels.h _NAMES - comma-separated classnames (with optional +-) _NUM - numeric input, 0-N expected _BITS - numeric input, 0x1F bitmap form expected _DISJOINT - bits are independent _LEVEL - (x<y) on bit-pos. _DISJOINT treats input like a bit-vector (ala drm.debug), and sets each bit accordingly. LEVEL is layered on top of this. _LEVEL treats input like a bit-pos:N, then sets bits(0..N)=1, and bits(N+1..max)=0. This applies (bit<N) semantics on top of disjoint bits. USAGES: A potentially typical _DISJOINT_NAMES use: echo +DRM_UT_CORE,+DRM_UT_KMS,-DRM_UT_DRIVER,-DRM_UT_ATOMIC \ > /sys/module/drm/parameters/debug_catnames A naive _LEVEL_NAMES use, with one class, that sets all in the class-map according to (x<y): : problem seen echo +L7 > /sys/module/test_dynamic_debug/parameters/p_level_names : problem solved echo -L1 > /sys/module/test_dynamic_debug/parameters/p_level_names Note this artifact: : this is same as prev cmd (due to +/-) echo L0 > /sys/module/test_dynamic_debug/parameters/p_level_names : this is "even-more" off, but same wo __pr_debug_class(L0, ".."). echo -L0 > /sys/module/test_dynamic_debug/parameters/p_level_names A stress-test/make-work usage (kid toggling a light switch): echo +L7,L0,L7,L0,L7,L0,L7,L0,L7,L0,L7,L0,L7 \ > /sys/module/test_dynamic_debug/parameters/p_level_names ddebug_apply_class_bitmap(): inside-fn, works on bitmaps, receives new-bits, finds diffs vs client-bitvector holding "current" state, and issues exec_query to commit the adjustment. param_set_dyndbg_classes(): interface fn, sends _NAMES to param_set_dyndbg_classnames() and returns, falls thru to handle _BITS, _NUM internally, and calls ddebug_apply_class_bitmap(). Finishes by updating state. param_set_dyndbg_classnames(): handles classnames-list in loop, calls ddebug_apply_class_bitmap for each, then updates state. NOTES: _LEVEL_ is overlay on _DISJOINT_; inputs are converted to a bitmask, by the callbacks. IOW this is possible, and possibly confusing: echo class V3 +p > control echo class V1 -p > control IMO thats ok, relative verbosity is an interface property. _LEVEL_NUM maps still need class-names, even though the names are not usable at the sysfs interface (unlike with _NAMES style). The names are the only way to >control the classes. - It must have a "V0" name, something below "V1" to turn "V1" off. __pr_debug_cls(V0,..) is printk, don't do that. - "class names" is required at the >control interface. - relative levels are not enforced at >control _LEVEL_NAMES bear +/- signs, which alters the on-bit-pos by 1. IOW, +L2 means L0,L1,L2, and -L2 means just L0,L1. This kinda spoils the readback fidelity, since the L0 bit gets turned on by any use of any L*, except "-L0". All the interface uncertainty here pertains to the _NAMES features. Nobody has actually asked for this, so its practical (if a little tedious) to split it out. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20220904214134.408619-21-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: validate class FOO by checking with moduleJim Cromie2022-09-071-8/+68
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add module-to-class validation: #> echo class DRM_UT_KMS +p > /proc/dynamic_debug/control If a query has "class FOO", then ddebug_find_valid_class(), called from ddebug_change(), requires that FOO is known to module X, otherwize the query is skipped entirely for X. This protects each module's class-space, other than the default:31. The authors' choice of FOO is highly selective, giving isolation and/or coordinated sharing of FOOs. For example, only DRM modules should know and respond to DRM_UT_KMS. So this, combined with module's opt-in declaration of known classes, effectively privatizes the .class_id space for each module (or coordinated set of modules). Notes: For all "class FOO" queries, ddebug_find_valid_class() is called, it returns the map matching the query, and sets valid_class via an *outvar). If no "class FOO" is supplied, valid_class = _CLASS_DFLT. This insures that legacy queries do not trample on new class'd callsites, as they get added. Also add a new column to control-file output, displaying non-default class-name (when found) or the "unknown _id:", if it has not been (correctly) declared with one of the declarator macros. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20220904214134.408619-18-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: add ddebug_attach_module_classesJim Cromie2022-09-071-1/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add ddebug_attach_module_classes(), call it from ddebug_add_module(). It scans the classes/section its given, finds records where the module-name matches the module being added, and adds them to the module's maps list. No locking here, since the record isn't yet linked into the ddebug_tables list. It is called indirectly from 2 sources: - from load_module(), where it scans the module's __dyndbg_classes section, which contains DYNAMIC_DEBUG_CLASSES definitions from just the module. - from dynamic_debug_init(), where all DYNAMIC_DEBUG_CLASSES definitions of each builtin module have been packed together. This is why ddebug_attach_module_classes() checks module-name. NOTES Its (highly) likely that builtin classes will be ordered by module name (just like prdbg descriptors are in the __dyndbg section). So the list can be replaced by a vector (ptr + length), which will work for loaded modules too. This would imitate whats currently done for the _ddebug descriptors. That said, converting to vector,len is close to pointless; a small minority of modules will ever define a class-map, and almost all of them will have only 1 or 2 class-maps, so theres only a couple dozen pointers to save. TODO: re-evaluate for lines removable. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20220904214134.408619-17-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* kernel/module: add __dyndbg_classes sectionJim Cromie2022-09-071-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add __dyndbg_classes section, using __dyndbg as a model. Use it: vmlinux.lds.h: KEEP the new section, which also silences orphan section warning on loadable modules. Add (__start_/__stop_)__dyndbg_classes linker symbols for the c externs (below). kernel/module/main.c: - fill new fields in find_module_sections(), using section_objs() - extend callchain prototypes to pass classes, length load_module(): pass new info to dynamic_debug_setup() dynamic_debug_setup(): new params, pass through to ddebug_add_module() dynamic_debug.c: - add externs to the linker symbols. ddebug_add_module(): - It currently builds a debug_table, and *will* find and attach classes. dynamic_debug_init(): - add class fields to the _ddebug_info cursor var: di. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20220904214134.408619-16-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: gather __dyndbg[] state into struct _ddebug_infoJim Cromie2022-09-071-9/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This new struct composes the linker provided (vector,len) section, and provides a place to add other __dyndbg[] state-data later: descs - the vector of descriptors in __dyndbg section. num_descs - length of the data/section. Use it, in several different ways, as follows: In lib/dynamic_debug.c: ddebug_add_module(): Alter params-list, replacing 2 args (array,index) with a struct _ddebug_info * containing them both, with room for expansion. This helps future-proof the function prototype against the looming addition of class-map info into the dyndbg-state, by providing a place to add more member fields later. NB: later add static struct _ddebug_info builtins_state declaration, not needed yet. ddebug_add_module() is called in 2 contexts: In dynamic_debug_init(), declare, init a struct _ddebug_info di auto-var to use as a cursor. Then iterate over the prdbg blocks of the builtin modules, and update the di cursor before calling _add_module for each. Its called from kernel/module/main.c:load_info() for each loaded module: In internal.h, alter struct load_info, replacing the dyndbg array,len fields with an embedded _ddebug_info containing them both; and populate its members in find_module_sections(). The 2 calling contexts differ in that _init deals with contiguous subranges of __dyndbgs[] section, packed together, while loadable modules are added one at a time. So rename ddebug_add_module() into outer/__inner fns, call __inner from _init, and provide the offset into the builtin __dyndbgs[] where the module's prdbgs reside. The cursor provides start, len of the subrange for each. The offset will be used later to pack the results of builtin __dyndbg_sites[] de-duplication, and is 0 and unneeded for loadable modules, Note: kernel/module/main.c includes <dynamic_debug.h> for struct _ddeubg_info. This might be prone to include loops, since its also included by printk.h. Nothing has broken in robot-land on this. cc: Luis Chamberlain <mcgrof@kernel.org> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20220904214134.408619-12-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: cleanup auto vars in dynamic_debug_initJim Cromie2022-09-071-16/+17
| | | | | | | | | | | | | | | | | | | | | | rework var-names for clarity, regularity rename variables - n to mod_sites - it counts sites-per-module - entries to i - display only - iter_start to iter_mod_start - marks start of each module's subrange - modct to mod_ct - stylistic new iterator var: - site - cursor parallel to iter 1st step towards 'demotion' of iter->site, for removal later treat vars as iters: - drop init at top init just above for-loop, in a textual block Acked-by: Jason Baron <jbaron@akamai.com> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20220904214134.408619-11-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: drop EXPORTed dynamic_debug_exec_queriesJim Cromie2022-09-071-29/+0
| | | | | | | | | | | | | | | | | This exported fn is unused, and will not be needed. Lets dump it. The export was added to let drm control pr_debugs, as part of using them to avoid drm_debug_enabled overheads. But its better to just implement the drm.debug bitmap interface, then its available for everyone. Fixes: a2d375eda771 ("dyndbg: refine export, rename to dynamic_debug_exec_queries()") Fixes: 4c0d77828d4f ("dyndbg: export ddebug_exec_queries") Acked-by: Jason Baron <jbaron@akamai.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20220904214134.408619-10-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: let query-modname override actual module nameJim Cromie2022-09-071-4/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | dyndbg's control-parser: ddebug_parse_query(), requires that search terms: module, func, file, lineno, are used only once in a query; a thing cannot be named both foo and bar. The cited commit added an overriding module modname, taken from the module loader, which is authoritative. So it set query.module 1st, which disallowed its use in the query-string. But now, its useful to allow a module-load to enable classes across a whole (or part of) a subsystem at once. # enable (dynamic-debug in) drm only modprobe drm dyndbg="class DRM_UT_CORE +p" # get drm_helper too modprobe drm dyndbg="class DRM_UT_CORE module drm* +p" # get everything that knows DRM_UT_CORE modprobe drm dyndbg="class DRM_UT_CORE module * +p" # also for boot-args: drm.dyndbg="class DRM_UT_CORE module * +p" So convert the override into a default, by filling it only when/after the query-string omitted the module. NB: the query class FOO handling is forthcoming. Fixes: 8e59b5cfb9a6 dynamic_debug: add modname arg to exec_query callchain Acked-by: Jason Baron <jbaron@akamai.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20220904214134.408619-8-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: use ESCAPE_SPACE for cat controlJim Cromie2022-09-071-1/+1
| | | | | | | | | | | | | | | | | | | | `cat control` currently does octal escape, so '\n' becomes "\012". Change this to display as "\n" instead, which reads much cleaner. :#> head -n7 /proc/dynamic_debug/control # filename:lineno [module]function flags format init/main.c:1179 [main]initcall_blacklist =_ "blacklisting initcall %s\n" init/main.c:1218 [main]initcall_blacklisted =_ "initcall %s blacklisted\n" init/main.c:1424 [main]run_init_process =_ " with arguments:\n" init/main.c:1426 [main]run_init_process =_ " %s\n" init/main.c:1427 [main]run_init_process =_ " with environment:\n" init/main.c:1429 [main]run_init_process =_ " %s\n" Acked-by: Jason Baron <jbaron@akamai.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20220904214134.408619-7-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: reverse module.callsite walk in cat controlJim Cromie2022-09-071-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | Walk the module's vector of callsites backwards; ie N..0. This "corrects" the backwards appearance of a module's prdbg vector when walked 0..N. I think this is due to linker mechanics, which I'm inclined to treat as immutable, and the order is fixable in display. No functional changes. Combined with previous commit, which reversed tables-list, we get: :#> head -n7 /proc/dynamic_debug/control # filename:lineno [module]function flags format init/main.c:1179 [main]initcall_blacklist =_ "blacklisting initcall %s\012" init/main.c:1218 [main]initcall_blacklisted =_ "initcall %s blacklisted\012" init/main.c:1424 [main]run_init_process =_ " with arguments:\012" init/main.c:1426 [main]run_init_process =_ " %s\012" init/main.c:1427 [main]run_init_process =_ " with environment:\012" init/main.c:1429 [main]run_init_process =_ " %s\012" Acked-by: Jason Baron <jbaron@akamai.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20220904214134.408619-6-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: reverse module walk in cat controlJim Cromie2022-09-071-1/+1
| | | | | | | | | | | | | | | /proc/dynamic_debug/control walks the prdbg catalog in "reverse", fix this by adding new ddebug_tables to tail of list. This puts init/main.c entries 1st, which looks more than coincidental. no functional changes. Acked-by: Jason Baron <jbaron@akamai.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20220904214134.408619-5-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: show both old and new in change-infoJim Cromie2022-09-071-5/+6
| | | | | | | | | | | | print "old => new" flag values to the info("change") message. no functional change. Acked-by: Jason Baron <jbaron@akamai.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20220904214134.408619-4-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: fix static_branch manipulationJim Cromie2022-09-071-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In https://lore.kernel.org/lkml/20211209150910.GA23668@axis.com/ Vincent's patch commented on, and worked around, a bug toggling static_branch's, when a 2nd PRINTK-ish flag was added. The bug results in a premature static_branch_disable when the 1st of 2 flags was disabled. The cited commit computed newflags, but then in the JUMP_LABEL block, failed to use that result, instead using just one of the terms in it. Using newflags instead made the code work properly. This is Vincents test-case, reduced. It needs the 2nd flag to demonstrate the bug, but it's explanatory here. pt_test() { echo 5 > /sys/module/dynamic_debug/verbose site="module tcp" # just one callsite echo " $site =_ " > /proc/dynamic_debug/control # clear it # A B ~A ~B for flg in +T +p "-T #broke here" -p; do echo " $site $flg " > /proc/dynamic_debug/control done; # A B ~B ~A for flg in +T +p "-p #broke here" -T; do echo " $site $flg " > /proc/dynamic_debug/control done } pt_test Fixes: 84da83a6ffc0 dyndbg: combine flags & mask into a struct, simplify with it CC: vincent.whitchurch@axis.com Acked-by: Jason Baron <jbaron@akamai.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20220904214134.408619-2-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: refine verbosity 1-4 summary-detailJim Cromie2021-10-211-11/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | adjust current v*pr_info() calls to fit an overview..detail scheme: 1- module level activity: add/remove, etc 2- command ingest, splitting, summary of effects. per >control write 3- command parsing: op, flags, search terms 4- per-site change msg can yield ~3k x 2 logs per echo "+p;-p" > command. Summarize these 4 levels in MODULE_PARM_DESC, and update verbose=3 in Doc. 2- is new, to isolate a problem where a stress-test script (which feeds ~4kb multi-command strings) would produce short writes, truncating last command and causing parsing errors, which confused test results. The script fix was to use syswrite, to deliver full proper commands. 4- gets per-callsite "changed:" pr-infos, which are very noisy during stress tests, and formerly obscured v1-3 messages, and overwhelmed the static-key workload being tested. The verbose parameter has previously seen adjustment: commit 481c0e33f1e7 ("dyndbg: refine debug verbosity; 1 is basic, 2 more chatty") The script driving these adjustments is: !/usr/bin/perl -w =for Doc 1st purpose was to benchmark the effect of wildcard queries on query performance; if wildcards are risk free cheap enough, we can deploy them in the (floating) format search. 1st finding: wildcards take 2x as long to process. 2nd purpose was to benchmark real static-key changes VS simple flag changes. Found ~100x decrease for the hard work. The script maximizes workload per >control by packing it a ~4kb string of "+p; -p;" commands; this uncovered some broken stuff. The 85th query failed, and appears to be truncated, so is gramatically incorrect. Its either an error here, or in the kernel. Its not happening atm, retest. Plot thickens: fail only happens doing +-p, not +-mf, likely load dependent. Error remains consistent. Looks like a short write, longer on writer than kernel-reader. Try syswrite on handle to control this. That fixed short write. =cut use Getopt::Std; getopts('vN:k:', \my %opts) or die <<EOH; $0 options: -v verbose -k=n kernel dyndbg verbosity -N=n number of loops.. tbrc EOH $opts{N} //= 10; # !undef, 0 tests too long. my $ctrl = '/proc/dynamic_debug/control'; vx($opts{k}) if defined $opts{k}; # works on -k0 open(my $CTL, '>', $ctrl) or die "cant open $ctrl for writing: $!\n"; sub vx { my $arg = shift; my $cmd = "echo $arg > /sys/module/dynamic_debug/parameters/verbose"; system($cmd); warn("vx problem: rc:$? err:$! qry: $cmd\n") if ($?); } sub qryOK { my $qry = shift; print "syntax test: <\n$qry>\n" if $opts{v}; my $bytes = syswrite $CTL, $qry; printf "short read: $bytes / %d\n", length $qry if $bytes < length $qry; if ($?) { warn "rc:$? err:$! qry: $qry\n"; return 0; } return 1; } sub build_queries { my ($cmd, $flags, $ct) = @_; # build experiment and reference queries my $cycle = " $cmd +$flags # on ; $cmd -$flags # off \n"; my $ref = " +$flags ; -$flags \n"; my $len = length $cycle; my $max = int(4096 / $len); # break/fit to buffer size $ct |= $max; print "qry: ct:$max x << \n$cycle >>\n"; return unless qryOK($ref); return unless qryOK($cycle); my $wild = $cycle x $ct; my $empty = $ref x $ct; printf "len: %d, %d\n", length $wild, length $empty; return { trial => $wild, ref => $empty, probe => $cycle, zero => $ref, count => $ct, max => $max }; } my $query_set = build_queries(' file "*" module "*" func "*" ', "mf"); qryOK($query_set->{zero}); qryOK($query_set->{probe}); qryOK($query_set->{ref}); qryOK($query_set->{trial}); use Benchmark; sub dobatch { my ($cmd, $flags, $reps, $ct) = @_; $reps ||= $opts{N}; my $qs = build_queries($cmd, $flags, $ct); timethese($reps, { wildcards => sub { syswrite $CTL, $qs->{trial}; }, no_search => sub { syswrite $CTL, $qs->{ref}; } } ); } sub bench_static_key_toggle { vx 0; dobatch(' file "*" module "*" func "*" ', "mf"); dobatch(' file "*" module "*" func "*" ', "p"); } sub bench_verbose_levels { for my $i (0..4) { vx $i; dobatch(' file "*" module "*" func "*" ', "mf"); } } bench_static_key_toggle(); __END__ Heres how the test-script runs: :: verbose=3 parsing info [ 48.401646] dyndbg: query 95: "file "*" module "*" func "*" -mf # off " mod:* [ 48.402040] dyndbg: split into words: "file" "*" "module" "*" "func" "*" "-mf" [ 48.402456] dyndbg: op='-' [ 48.402615] dyndbg: flags=0x6 [ 48.402779] dyndbg: *flagsp=0x0 *maskp=0xfffffff9 [ 48.403033] dyndbg: parsed: func="*" file="*" module="*" format="" lineno=0-0 [ 48.403674] dyndbg: applied: func="*" file="*" module="*" format="" lineno=0-0 :: verbose=2 >control summary. ~300k site matches/changes per 4kb command [ 48.404063] dyndbg: processed 96 queries, with 296160 matches, 0 errs :: 2 queries against each other, no-search vs all-wildcard-search qry: ct:48 x << file "*" module "*" func "*" +mf # on ; file "*" module "*" func "*" -mf # off >> len: 4080, 576 Benchmark: timing 10 iterations of no_search, wildcards... no_search: 0 wallclock secs ( 0.00 usr + 0.03 sys = 0.03 CPU) @ 333.33/s (n=10) (warning: too few iterations for a reliable count) wildcards: 0 wallclock secs ( 0.00 usr + 0.09 sys = 0.09 CPU) @ 111.11/s (n=10) (warning: too few iterations for a reliable count) :: 2 queries, both doing real work / changing stati-key states. qry: ct:49 x << file "*" module "*" func "*" +p # on ; file "*" module "*" func "*" -p # off >> len: 4067, 490 Benchmark: timing 10 iterations of no_search, wildcards... no_search: 20 wallclock secs ( 0.00 usr + 20.36 sys = 20.36 CPU) @ 0.49/s (n=10) wildcards: 21 wallclock secs ( 0.00 usr + 21.08 sys = 21.08 CPU) @ 0.47/s (n=10) bash-5.1# Thats 150k static-key-toggles / sec ~600x slower than simple flags on qemu --smp 3 run Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20211019210746.185307-1-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: fix spurious vNpr_info changeJim Cromie2021-10-151-1/+1
| | | | | | | | | | The cited commit inadvertently altered the verbose level of a vpr_info, restore it to original. Fixes: 216a0fc40897 ("dyndbg: show module in vpr-info in dd-exec-queries") Signed-off-By: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20211014223614.1952171-1-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: no vpr-info on empty queriesJim Cromie2021-10-141-2/+4
| | | | | | | | | | when `echo $cmd > control` contains multiple queries, extra query separators (;\n) can parse as empty statements. This is normal, and a vpr-info on an empty command is just noise. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20211013220726.1280565-4-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: vpr-info on remove-module complete, not startingJim Cromie2021-10-141-2/+2
| | | | | | | | | | On qemu --smp 3 runs, remove-module can get called 3 times. So don't print on entry; instead print "removed" after entry is found and removed, so just once. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20211013220726.1280565-3-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: Remove support for ddebug_query paramAndrew Halaney2021-10-141-25/+0
| | | | | | | | | | This param has been deprecated for a very long time now, let's rip it out. Signed-off-by: Andrew Halaney <ahalaney@redhat.com> Signed-off-by: Jason Baron <jbaron@akamai.com> Link: https://lore.kernel.org/r/1634139622-20667-3-git-send-email-jbaron@akamai.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: make dyndbg a known cli paramAndrew Halaney2021-10-141-0/+12
| | | | | | | | | | | | | | | | | | | | | Right now dyndbg shows up as an unknown parameter if used on boot: Unknown command line parameters: dyndbg=+p That's because it is unknown, it doesn't sit in the __param section, so the processing done to warn users supplying an unknown parameter doesn't think it is legitimate. Install a dummy handler to register it. dynamic debug needs to search the whole command line for modules listed that are currently builtin, so there's no real work to be done in this callback. Fixes: 86d1919a4fb0 ("init: print out unknown kernel parameters") Tested-by: Jim Cromie <jim.cromie@gmail.com> Signed-off-by: Andrew Halaney <ahalaney@redhat.com> Signed-off-by: Jason Baron <jbaron@akamai.com> Link: https://lore.kernel.org/r/1634139622-20667-2-git-send-email-jbaron@akamai.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: show module in vpr-info in dd-exec-queriesJim Cromie2021-10-131-1/+1
| | | | | | | | | | dynamic_debug_exec_queries() accepts a separate module arg (so it can support $module.dyndbg boot arg), display that in the vpr-info for a more useful user-debug context. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20211012183310.1016678-2-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* lib: fix spelling mistakesZhen Lei2021-07-081-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fix some spelling mistakes in comments: permanentely ==> permanently wont ==> won't remaning ==> remaining succed ==> succeed shouldnt ==> shouldn't alpha-numeric ==> alphanumeric storeing ==> storing funtion ==> function documenation ==> documentation Determin ==> Determine intepreted ==> interpreted ammount ==> amount obious ==> obvious interupts ==> interrupts occured ==> occurred asssociated ==> associated taking into acount ==> taking into account squence ==> sequence stil ==> still contiguos ==> contiguous matchs ==> matches Link: https://lkml.kernel.org/r/20210607072555.12416-1-thunder.leizhen@huawei.com Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com> Reviewed-by: Jacob Keller <jacob.e.keller@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* dyndbg: display KiB of data memory used.Jim Cromie2021-05-271-3/+3
| | | | | | | | | | | If booted with verbose>=1, dyndbg prints the memory usage in bytes, of builtin modules' prdebugs. KiB reads better. no functional changes. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20210525033240.35260-1-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: drop uninformative vpr_infoJim Cromie2021-05-131-1/+0
| | | | | | | | | | | Remove a vpr_info which I added in 2012, when I knew even less than now. In 2020, a simpler pr_fmt stripped it of context, and any remaining value. no functional change. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20210504222235.1033685-3-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: avoid calling dyndbg_emit_prefix when it has no workJim Cromie2021-05-131-7/+12
| | | | | | | | | | | | | Wrap function in a static-inline one, which checks flags to avoid calling the function unnecessarily. And hoist its output-buffer initialization to the grand-caller, which is already allocating the buffer on the stack, and can trivially initialize it too. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20210504222235.1033685-2-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: fix parsing file query without a line-range suffixShuo Chen2021-04-301-1/+1
| | | | | | | | | | | | | | | | | Query like 'file tcp_input.c line 1234 +p' was broken by commit aaebe329bff0 ("dyndbg: accept 'file foo.c:func1' and 'file foo.c:10-100'") because a file name without a ':' now makes the loop in ddebug_parse_query() exits early before parsing the 'line 1234' part. As a result, all pr_debug() in tcp_input.c will be enabled, instead of only the one on line 1234. Changing 'break' to 'continue' fixes this. Fixes: aaebe329bff0 ("dyndbg: accept 'file foo.c:func1' and 'file foo.c:10-100'") Cc: stable <stable@vger.kernel.org> Reviewed-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Shuo Chen <shuochen@google.com> Acked-by: Jason Baron <jbaron@akamai.com> Link: https://lore.kernel.org/r/20210414212400.2927281-1-giantchen@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: fix use before null checkJim Cromie2020-12-091-2/+7
| | | | | | | | | | | | | | | | In commit a2d375eda771 ("dyndbg: refine export, rename to dynamic_debug_exec_queries()"), a string is copied before checking it isn't NULL. Fix this, report a usage/interface error, and return the proper error code. Fixes: a2d375eda771 ("dyndbg: refine export, rename to dynamic_debug_exec_queries()") Cc: stable@vger.kernel.org -- -v2 drop comment tweak, improve commit message Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20201209183625.2432329-1-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: use keyword, arg varnames for query term pairsJim Cromie2020-09-271-12/+15
| | | | | | | | | optimize for clarity by replacing word[i,i+1] refs with temps. no functional changes. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200921190433.1149521-3-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* Revert "dyndbg: accept query terms like file=bar and module=foo"Greg Kroah-Hartman2020-09-101-33/+20
| | | | | | | | | | | | | | | This reverts commit 14775b04964264189caa4a0862eac05dab8c0502 as there were still some parsing problems with it, and the follow-on patch for it. Let's revisit it later, just drop it for now. Cc: <jbaron@akamai.com> Cc: Jim Cromie <jim.cromie@gmail.com> Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org> Cc: Stephen Rothwell <sfr@canb.auug.org.au> Fixes: 14775b049642 ("dyndbg: accept query terms like file=bar and module=foo") Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* Revert "dyndbg: fix problem parsing format="foo bar""Greg Kroah-Hartman2020-09-101-17/+21
| | | | | | | | | | | | This reverts commit 42f07816ac0cc797928119cc039c414ae2b95d34 as it still causes problems. It will be resolved later, let's revert it so we can also revert the original patch this was supposed to be helping with. Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org> Fixes: 42f07816ac0c ("dyndbg: fix problem parsing format="foo bar"") Cc: Jim Cromie <jim.cromie@gmail.com> Cc: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: fix problem parsing format="foo bar"Jim Cromie2020-09-041-21/+17
| | | | | | | | | | | | | | | | | | commit 14775b049642 ("dyndbg: accept query terms like file=bar and module=foo") added the combined keyword=value parsing poorly; revert most of it, keeping the keyword & arg change. Instead, fix the tokenizer for the new input, by terminating the keyword (an unquoted word) on '=' as well as space, thus letting the tokenizer work on the quoted argument, like it would have previously. Also add a few debug-prints to show more parsing context, into tokenizer and parse-query, and use "keyword, value" in others. Fixes: 14775b049642 ("dyndbg: accept query terms like file=bar and module=foo") Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200831182210.850852-4-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: refine export, rename to dynamic_debug_exec_queries()Jim Cromie2020-09-041-2/+25
| | | | | | | | | | | | | | | | | | | | | | commit 4c0d77828d4f ("dyndbg: export ddebug_exec_queries") had a few problems: - broken non DYNAMIC_DEBUG_CORE configs, sparse warning - the exported function modifies query string, breaks on RO strings. - func name follows internal convention, shouldn't be exposed as is. 1st is fixed in header with ifdefd function prototype or stub defn. Also remove an obsolete HAVE-symbol ifdef-comment, and add others. Fix others by wrapping existing internal function with a new one, named in accordance with module-prefix naming convention, before export hits v5.9.0. In new function, copy query string to a local buffer, so users can pass hard-coded/RO queries, and internal function can be used unchanged. Fixes: 4c0d77828d4f ("dyndbg: export ddebug_exec_queries") Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200831182210.850852-3-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: give %3u width in pr-format, cosmetic onlyJim Cromie2020-09-041-1/+1
| | | | | | | | | | Specify the print-width so log entries line up nicely. no functional changes. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200831182210.850852-2-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: export ddebug_exec_queriesJim Cromie2020-07-241-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Export ddebug_exec_queries() for use by modules. This will allow module authors to control all their *pr_debug*s dynamically. And since ddebug_exec_queries() is what implements "echo $query >control", it gives the same per-callsite control. Virtues of this: - simplicity. just an export. - full control over any/all subsets of callsites. - same "query/command-string" in code and console - full callsite selectivity with module file line format Format in particular deserves special attention; it is where low-hanging fruit will be found. Consider: drivers/gpu/drm/amd/display/include/logger_types.h: #define DC_LOG_SURFACE(...) pr_debug("[SURFACE]:"__VA_ARGS__) #define DC_LOG_HW_LINK_TRAINING(...) pr_debug("[HW_LINK_TRAINING]:"__VA_ARGS__) .. 9 more .. Thats 11 string prefixes, used in 804 places in drivers/gpu/** Clearly this is a systematized classification of those callsites. And one I'd expect to see repeated often. Using ddebug_exec_queries(), authors can select on those prefixes as a unitary set, equivalent to: echo "module=MODULE_NAME format=^[SURFACE]: +p" >control Trivially, those sets can be subsected with the other query terms too, say file=foo, should the author see fit. Perhaps as important, users can modify the set of enabled callsites, presumably to aid debugging by enabling helpful debug callsites, and disabling those that just clutter the info. Authors could even alter [fmlt] flags, though I dont see a good reason why they would. Perhaps harnessed by bug-logging automation to get fuller, or more minimal bug-reports. DRM drm has both drm.debug, which defines 32 categories of drm_printk logging, and entirely separate uses of pr_debug, which are dynamic on this i915 laptop, running mainline. So I can observe and report on both. The i915 driver has 118 dyndbg callsites, with following "classifications" defined in drivers/gpu/drm/i915/gvt/** $ grep 915 /proc/dynamic_debug/control | cut -d= -f2 | cut -d: -f1,2 | sort -u _ "gvt: cmd _ "gvt: core _ "gvt: dpy _ "gvt: el _ "gvt: irq _ "gvt: mm _ "gvt: mmio _ "gvt: render _ "gvt: sched _ "%s for root hub!\012" _ "Vendor defined info completion code %u\012" This classification is entirely out-of-band for control by drm.debug, and is only available to root user at the console. But module authors can activate them with ddebug_exec_queries(sprintf("format=^%s +p")), and then decide how to expose the groups to the user for max utility. drm.debug drm.debug has 32 bit-flags, and matching enum drm_debug_category values to classify the ~2943 DRM_DEBUG*() callsites in drivers/gpu The drm.debug callback could invoke ddebug_exec_queries() with 32 different hardcoded query strings, needing only (bit) ? " +p" : " -p" added. I briefly enabled drm.debug=0xff on my i915 laptop, which yielded these unique prefixes: (dmesg | cut -c17- | cut -d\] -f1 | sort -u) [drm:drm_atomic_check_only [drm [drm:drm_atomic_get_crtc_state [drm [drm:drm_atomic_get_plane_state [drm [drm:drm_atomic_nonblocking_commit [drm [drm:drm_atomic_set_fb_for_plane [drm [drm:drm_atomic_state_default_clear [drm [drm:__drm_atomic_state_free [drm [drm:drm_atomic_state_init [drm [drm:drm_crtc_vblank_helper_get_vblank_timestamp_internal [drm [drm:drm_handle_vblank [drm [drm:drm_ioctl [drm [drm:drm_mode_addfb2 [drm [drm:drm_mode_object_get [drm [drm:drm_mode_object_put.part.0 [drm [drm:drm_update_vblank_count [drm [drm:drm_vblank_enable [drm [drm:drm_vblank_restore [drm [drm:vblank_disable_fn [drm i915 0000:00:02.0: [drm:gen9_set_dc_state [i915 i915 0000:00:02.0: [drm:intel_atomic_get_global_obj_state [i915 i915 0000:00:02.0: [drm:__intel_display_power_get_domain.part.0 [i915 i915 0000:00:02.0: [drm:__intel_display_power_put_domain [i915 i915 0000:00:02.0: [drm:intel_plane_atomic_calc_changes [i915 i915 0000:00:02.0: [drm:skl_enable_dc6 [i915 Several good format=^prefixes are apparent there, and some misses. ^[drm:drm_atomic_ # misses: [drm:__drm_atomic_state_free [drm ^[drm:drm_ioctl ^[drm:drm_mode ^[drm:drm_vblank_ # misses: [drm:drm_update_vblank_count & [drm:vblank_disable_fn Its not a perfect 1:1 single format-match per class, but the misses above can be covered with 1 & 2 additional queries, which can be concatenated together with ";" separators and submitted with 1 call. Benefits: For drm, adapting DRM_DEBUG to use dynamic-debug inside could replicate (and thereby obsolete) lots of bit-checking in current DRM_DEBUG callsites, at least with JUMP_LABEL optimized code. ddebug_exec_queries() and a handful of fixed query-strings can select and thereby control the already classified callsites. With the classes mapped to queries, the enum type and parameter can be eliminated (folded away with macro magic), at least for DYNAMIC_DEBUG & JUMP_LABEL builds. Is it safe ? ddebug_exec_queries() is currently exposed to user space in several limited ways; 1 it is called from module-load callback, where it implements the $modname.dyndbg=+p "fake" parameter provided to all modules. 2 it handles query input via >control directly IOW, it is "fully" exposed to local root user; exposing the same functionality to other kernel modules is no additional risk. The other standard issue to check is locking: dyndbg has a single mutex, taken by ddebug_change to handle >control, and by ddebug_proc_(start|stop) to span `cat control`. Queries submitted via export will typically have module specified, which dramatically cuts the scan by ddebug_change vs "module=* +p". ISTM this proposed export presents no locking problems. TLDR; It would be interesting to see how drm.dyndbg=$QUERY and drm.debug=$HEXY would interact; it might be order dependent, as if given as modprobe args or in /etc/modprobe.d/ Acked-by: <jbaron@akamai.com> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200719231058.1586423-19-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: shorten our logging prefix, drop __func__Jim Cromie2020-07-241-1/+1
| | | | | | | | | | | | For log-message output, reduce column space consumed by current pr_fmt by dropping __func__ and shortening "dynamic_debug" to "dyndbg". This improves readability on narrow consoles, and better matches other kernel boot info messages. Acked-by: <jbaron@akamai.com> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200719231058.1586423-18-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: allow anchored match on format query termJim Cromie2020-07-241-3/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This should work: echo module=amd* format=^[IF_TRACE]: +p >/proc/dynamic_debug/control consider drivers/gpu/drm/amd/display/include/logger_types.h: It has 11 defines like: #define DC_LOG_IF_TRACE(...) pr_debug("[IF_TRACE]:"__VA_ARGS__) These defines are used 804 times at recent count; they are a good use case to evaluate existing format-message based classifications of *pr_debug*. Those macros prefix the supplied format with a fixed string, I'd expect most existing message classification schemes to do something similar. Hence we want to be able to anchor our match to the beginning of the format string, allowing easy construction of clear and precise queries, leveraging the existing classification scheme to enable and disable those callsites. Note that unlike other search terms, formats are implicitly floating substring matches, without the need for explicit wildcards. This makes no attempt at wider regex features, just the one we need. TLDR: Using the anchor also means the []s are less helpful for disamiguating the prefix from a random in-message occurrence, allowing shorter prefixes. Acked-by: <jbaron@akamai.com> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200719231058.1586423-17-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: combine flags & mask into a struct, simplify with itJim Cromie2020-07-241-21/+24
| | | | | | | | | | | | | | | | | | | | | | | | | flags & mask are used together everywhere, and are passed around together between multiple functions; they belong together in a struct, call that struct flag_settings. Use struct flag_settings to rework 3 functions: - ddebug_exec_query - declares query and flag-settings, calls other 2, passing flags - ddebug_parse_flags - fills flag_settings and returns - ddebug_change - test all callsites against query, modify passing sites. benefits: - bit-banging always needs flags & mask, best together. - simpler function signatures - 1 less parameter, less stack overhead no functional changes Acked-by: <jbaron@akamai.com> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200719231058.1586423-16-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: accept query terms like file=bar and module=fooJim Cromie2020-07-241-20/+33
| | | | | | | | | | | | Current code expects "keyword" "arg" as 2 words, space separated. Change to also accept "keyword=arg" form as well, and drop !(nwords%2) requirement. Then in rest of function, use new keyword, arg variables instead of word[i], word[i+1] Acked-by: <jbaron@akamai.com> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200719231058.1586423-15-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: accept 'file foo.c:func1' and 'file foo.c:10-100'Jim Cromie2020-07-241-1/+17
| | | | | | | | | | | | | | | | | | | | | | Accept these additional query forms: echo "file $filestr +_" > control path/to/file.c:100 # as from control, column 1 path/to/file.c:1-100 # or any legal line-range path/to/file.c:func_A # as from an editor/browser path/to/file.c:drm_* # wildcards still work path/to/file.c:*_foo # lead wildcard too 1st 2 examples are treated as line-ranges, 3-5 are treated as func's Doc these changes, and sprinkle in a few extra wild-card examples and trailing # explanation texts. Acked-by: <jbaron@akamai.com> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200719231058.1586423-14-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: refactor parse_linerange out of ddebug_parse_queryJim Cromie2020-07-241-27/+36
| | | | | | | | | | | | Make the code-block reusable to later handle "file foo.c:101-200" etc. This is a 99% code move, with reindent, function wrap&call, +pr_debug. no functional changes. Acked-by: <jbaron@akamai.com> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200719231058.1586423-13-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: use gcc ?: to reduce word countJim Cromie2020-07-241-4/+4
| | | | | | | | | reduce word count via gcc ?: extension, no actual code change. Acked-by: <jbaron@akamai.com> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200719231058.1586423-12-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: make ddebug_tables list LIFO for add/remove_moduleJim Cromie2020-07-241-1/+1
| | | | | | | | | | | | loadable modules are the last in on this list, and are the only modules that could be removed. ddebug_remove_module() searches from head, but ddebug_add_module() uses list_add_tail(). Change it to list_add() for a micro-optimization. Acked-by: <jbaron@akamai.com> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200719231058.1586423-11-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: prefer declarative init in caller, to memset in calleeJim Cromie2020-07-241-2/+1
| | | | | | | | | | | | ddebug_exec_query declares an auto var, and passes it to ddebug_parse_query, which memsets it before using it. Drop that memset, instead initialize the variable in the caller; let the compiler decide how to do it. Acked-by: <jbaron@akamai.com> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200719231058.1586423-10-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: fix pr_err with empty stringJim Cromie2020-07-241-1/+1
| | | | | | | | | | this pr_err attempts to print the string after the OP, but the string has been parsed and chopped up, so looks empty. Acked-by: <jbaron@akamai.com> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200719231058.1586423-9-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: fix a BUG_ON in ddebug_describe_flagsJim Cromie2020-07-241-12/+11
| | | | | | | | | | | | | | | | ddebug_describe_flags() currently fills a caller provided string buffer, after testing its size (also passed) in a BUG_ON. Fix this by replacing them with a known-big-enough string buffer wrapped in a struct, and passing that instead. Also simplify ddebug_describe_flags() flags parameter from a struct to a member in that struct, and hoist the member deref up to the caller. This makes the function reusable (soon) where flags are unpacked. Acked-by: <jbaron@akamai.com> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200719231058.1586423-8-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* dyndbg: fix overcounting of ram used by dyndbgJim Cromie2020-07-241-6/+2
| | | | | | | | | | | | | | | | | | | | | | | | during dyndbg init, verbose logging prints its ram overhead. It counted strlens of struct _ddebug's 4 string members, in all callsite entries, which would be approximately correct if each had been mallocd. But they are pointers into shared .rodata; for example, all 10 kobject callsites have identical filename, module values. Its best not to count that memory at all, since we cannot know they were linked in because of CONFIG_DYNAMIC_DEBUG=y, and we want to report a number that reflects what ram is saved by deconfiguring it. Also fix wording and size under-reporting of the __dyndbg section. Heres my overhead, on a virtme-run VM on a fedora-31 laptop: dynamic_debug:dynamic_debug_init: 260 modules, 2479 entries \ and 10400 bytes in ddebug tables, 138824 bytes in __dyndbg section Acked-by: <jbaron@akamai.com> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Link: https://lore.kernel.org/r/20200719231058.1586423-7-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>