Re: [PATCH v8-RESEND 15/33] dyndbg-API: fix DECLARE_DYNDBG_CLASSMAP

From: jim . cromie
Date: Wed May 22 2024 - 14:52:39 EST


On Tue, May 21, 2024 at 10:31 AM <jim.cromie@xxxxxxxxx> wrote:
>
> On Tue, May 21, 2024 at 5:46 AM Łukasz Bartosik <ukaszb@xxxxxxxxxxxx> wrote:
> >
> > On Thu, May 16, 2024 at 7:44 PM Jim Cromie <jim.cromie@xxxxxxxxx> wrote:
> > >
> > > DECLARE_DYNDBG_CLASSMAP() has a design error; its usage fails a basic
> > > K&R rule: "define once, refer many times".
> > >
> > > It is used across DRM core & drivers, each use re-defines the classmap
> > > understood by that module; and all must match for the modules to
> > > respond together when DRM.debug categories are enabled. This is
> > > brittle; a maintenance foot-gun.
> > >
> > > Worse, it causes the CONFIG_DRM_USE_DYNAMIC_DEBUG=Y regression; 1st
> > > drm.ko loads, and dyndbg initializes its DRM.debug callsites, then a
> > > drm-driver loads, but too late - it missed the DRM.debug enablement.
> > >
> > > So replace it with 2 macros:
> > > DYNDBG_CLASSMAP_DEFINE - invoked once from core - drm.ko
> > > DYNDBG_CLASSMAP_USE - from all drm drivers and helpers.
>
> >
> > Why does DYNDBG_CLASSMAP_DEFINE take "stringified" enum name-vals ?
> >
>
> short version:
>
> real enum vals would be better - misspellings would be compiler errors
> but doing the stringification inside the macro doesnt work,
> __stringify(__VA__ARGS__) produces "DRM_UT_CORE, DRM_UT_DRIVER" etc,
> not 10 separate stringifications
>
> I have a patchset for later that fixes this,
> but I didnt want to complicate this submission any further.
> Its already touching 2 sub-systems, revising and adding API
>
>
> > > - This module registers a tracer callback to count enabled
> > > - pr_debugs in a 'do_debugging' function, then alters their
> > > - enablements, calls the function, and compares counts.
> > > + This module exersizes/demonstrates dyndbg's classmap API, by
> >
> > Typo exersizes -> exercises
> >
>
> yes
>
> > > +static void ddebug_apply_params(const struct ddebug_class_map *cm, const char *modnm)
> > > +{
> > > + const struct kernel_param *kp;
> > > +#if IS_ENABLED(CONFIG_MODULES)
> >
> > Instead of the above maybe use "if (IS_ENABLED(CONFIG_MODULES)) {" ?
> > This will allow to get rid of #if and #endif which make code less readable.
> >
>
> will do.
>
> > > + int i;
> > > +

meh, turns out the #ifdef was doing more work - hiding the use of
struct module in the expression.
and since the cm->mod->kp actually refers thru the struct, it must be defined,
a forward decl looks insufficient


>> lib/dynamic_debug.c:1202:28: error: incomplete definition of type 'struct module'
1202 | for (i = 0, kp = cm->mod->kp; i <
cm->mod->num_kp; i++, kp++)
| ~~~~~~~^
arch/x86/include/asm/alternative.h:108:8: note: forward declaration
of 'struct module'
108 | struct module;
| ^
[jimc:dd-classmap-fix-8d 15/36] lib/dynamic_debug.c:1202:28: error:
incomplete definition of type 'struct module'


I'll probably revert, and stick with the #if block,
anything else feels too subtle by half