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 His patchset's objective is to be able to independently steer some of the drm.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 2 exceedingly well: 1- all work is behind jump-label's NOOP, zero off cost. 2- exact site selectivity, precisely the useful traffic. can tailor enabled set interactively, at shell. Since a tracefs interface is good for drm (the threads suggest so), adding that to dynamic-debug could be useful for everyone. if CONFIG_TRACING: Grab Sean's trace_init/cleanup code, use it to provide tracefs available by default to all pr_debugs. This will likely need some further per-module treatment; perhaps something reflecting hierarchy of module,file,function,line, maybe with a tuned flattening. Add a new +T flag to enable tracing independent of +p. Existing code treats T like other flags. This is not CONFIG_TRACING dependent. RFC. Add ddebug_validate_flags() as last step in ddebug_parse_flags(). Its only job is to fail on +T for non-CONFIG_TRACING builds. RFC. ddebug_change() adjusts the static-key-enable/disable condition to use _DPRINTK_ENABLED, abstracting (+p|+T). dynamic_emit_prefix() now gates on _DPRINTK_ENABLED too, as an optimization but mostly to allow decluttering of its users. __dynamic_pr_debug() etal get minor changes: - call dynamic_emit_prefix() 1st. - if (p) before printk, since T enables too. - if (T) call trace_array_printk - share vaf across p|T WRT <net|ib>_dev, I eschewed all the <T> specific dev_emit_prefix additions for now. tracefs is a fast customer (with different needs), for whom those decorations could be needless bottlenecks. SELFTEST: test_dynamic_debug.ko: Uses the tracer facility to implement a selftest: (that doesn't involve watching syslog) TODO: Earlier code had (tracerfn)() indirection, allowing plugin side-effector we could test the results of. ATM all the tests which count +T'd callsite executions (and which expect >0) are failing. Now it needs a rethink to test from userspace, rather than the current test-once at module-load. It needs a parameters/testme button. So remainder is a bit stale: - 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: (DONE) 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 vlatest: . drop all register_tracer code, and supporting hash code. . copy trace init/cleanup from Seans drm patch use it to provide tracing for all clients, wo needing registration
- Loading branch information