Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
dyndbg: add print-to-tracefs, selftest with it - RFC
Sean Paul proposed, in: https://patchwork.freedesktop.org/series/78133/ drm/trace: Mirror DRM debug logs to tracefs That patchset's objective is to be able to independently steer some of the debug stream to an alternate tracing destination, by splitting drm_debug_enabled() into syslog & trace flavors, and enabling them separately. 2 advantages were identified: 1- syslog is heavyweight, tracefs is much lighter 2- separate selection of enabled categories means less traffic Dynamic-Debug can do this exceedingly well: 1- all work is behind jump-label's NOOP, zero off cost. 2- exact site selectivity, precisely the useful traffic. can do this interactively, at shell. The basic elements: per-callsite: - add a new +T flag to enable tracing independent of +p - adjust the static-key-enable/disable condition for (+p|+T) - if (p) before printk, since T enables too. - if (T) call tracer, if one is found for module. per-module calls to: = int dynamic_debug_register_tracer(module, tracer); = int dynamic_debug_unregister_tracer(module, tracer); private new hash: dyndbg_tracers_by_module The calls manage the hash of module => tracer_fn, allowing client modules to provide a callback function to handle any +T'd pr_debugs. __dynamic_pr_debug etal get print-to-trace code. If drm registers a callback, one could then do: echo module drm* format ^drm:atomic:fail: +T > /proc/dynamic_debug/control to enable tracing on arbitrary groups of prdbgs, or categorized ones. A client module must connect to tracefs, and provide a printk-ish function to write to it, and register that function. It should unregister the same callback it registered, to allow adding modest protection against tracefn 'pirating' (unregistering yours, registering theirs) SELFTEST: test_dynamic_debug.ko: Uses the tracer facility to implement a selftest: (that doesn't involve watching syslog) - A custom tracer counts the number of calls (of T-enabled pr_debugs), - do_debugging(x) calls a set of categorized pr_debugs x times - test registers the tracer on the module then iteratively: manipulates dyndbg states via query-cmds, mostly format ^prefix runs do_debugging() counts enabled callsite executions reports mismatches - modprobe test_dynamic_debug use_bad_tracer=1 attaches a bad/recursive tracer Bad Things (did) Happen. has thrown me interesting panics. cannot replicate atm. RFC: The "tracer" interface probably needs work and a new name. It is only 1/2 way towards a real tracefs interface; and the code I lifted from Sean Paul in the next patch could be implemented in dynamic_debug.c instead, and made available for all pr_debug users. This would also eliminate need for dynamic_debug_(un)register_tracer(), since dyndbg could just provide it when TRACING is on. NOTES: I'm not crazy about dyndbg_register_tracer()s THIS_MODULE arg, but I need &mod->name to use as the hashkey; this value is known ptr-equal to the modname ptr embedded in ddebug_tables, as guaranteed (in part) by: 4573fe1 dynamic_debug: use pointer comparison in ddebug_remove_module cdf6d00 dynamic_debug: don't duplicate modname in ddebug_add_module For pr_debug(), that key is available via (struct _ddebug *)desc->modname. $> modprobe test_dynamic_debug dyndbg=+p it fails 3/29 tests. havent looked at why. $> modprobe test_dynamic_debug use_bad_tracer=1 Earlier in dev, bad_tracer() exploded in recursion, I havent been able to replicate that lately. __dynamic_pr_debug() pr_warns if +T w/o a registered tracer, I tried a WARN_ONCE, got a -cut-here- panic-once, so backed off that. This probably should be done with some validation on +T ops instead, but the bikeshed awaits; - only allowed on queries with a module specified ? - enable +T on any registrant module ? - ignore +T if no registrant on module ? this is probably simplest, to do and to explain. - should unregister also do "module foo -T" automatically ? Signed-off-by: Jim Cromie <jim.cromie@gmail.com> --- v4: (rfc) . fix printk (to syslog) needs if (+p), since +T also enables . add prototypes for un/register_aux_print . change iface names: s/aux_print/tracer/ . also s/trace_print/tracer/ . struct va_format *vaf - tighten further ? v5: (rfc) . fix "too many arguments to function", and name the args: int (*aux_print)(const char *fmt, char *prefix, char *label, void *); prefix : is a slot for dynamic_emit_prefix, or for custom buffer insert label : for builtin-caller used by drm-trace-print void* : vaf, add type constraint later. v6: (rfc) . more test in test module . add mod arg to *register, following exec_queries pattern . move code . move kdoc to c from h v7: (rfc) . simplify tracer prototype (probably needs more tailoring) . separate from dd-exec-queries . drop struct _ddebug.tracer field . 1 per module registration, into hash . rework test_dynamic_debug v10: . change rc s/void/int/ dynamic_debug_register_tracer
- Loading branch information