On Tue, Oct 13, 2026 at 8:37 PM <[email protected]> wrote:
>
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) 
> to consider:
> - [Low] test_dynamic_debug: classmap offset mismatch for submodule classes
> - [Low] locking: param_set_do_repeats blocks param_lock for up to 60s
> --
>
> commit adf504f365302c7db4e37850cebef69f82ed353f
> Author: Jim Cromie <[email protected]>
>
> dyndbg-test: add do_bulk testpoint, rename do_prints to do_classes
>
> This patch renames do_prints to do_classes to better align with its purpose
> and introduces do_bulk to generate high-volume workloads. It adds support for
> executing these debug operations multiple times or over a timed duration using
> shared module parameter callbacks.
>
> > diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
> > index 01ce07001d4c7..19e27b5747ac2 100644
> > --- a/lib/test_dynamic_debug.c
> > +++ b/lib/test_dynamic_debug.c
>
> [ ... ]
>
> > @@ -28,25 +28,57 @@
> >  #endif
> >
> >  #include <linux/module.h>
> > +#include <linux/sched.h>
> > +#include <linux/sched/signal.h>
> > +#include <linux/jiffies.h>
> >
> > -/* re-gen output by reading or writing sysfs node: do_prints */
> > +#define TEST_MAX_REPEATS 10000
> > +#define TEST_MAX_SECONDS 60
> >
> > -static void do_prints(void); /* device under test */
> > -static int param_set_do_prints(const char *instr, const struct 
> > kernel_param *kp)
> > +/* re-trigger debug output by reading or writing sysfs nodes: do_classes 
> > or do_bulk */
> > +static void do_classes(int); /* device under test */
> > +static void do_bulk(int);    /* device under test */
> > +
> > +static int param_set_do_repeats(const char *instr, const struct 
> > kernel_param *kp)
> >  {
> > -     do_prints();
> > +     int rc, ct;
> > +     void (*repeat_fn)(int) = kp->arg;
> > +
> > +     rc = kstrtoint(instr, 0, &ct);
> > +     if (rc) {
> > +             pr_err("expecting numeric input, using 1 instead\n");
> > +             ct = 1;
> > +     }
> > +     if (ct > TEST_MAX_REPEATS) {
> > +             pr_warn("%s: clamping %d to %d\n", kp->name, ct, 
> > TEST_MAX_REPEATS);
> > +             ct = TEST_MAX_REPEATS;
> > +     } else if (ct < -TEST_MAX_SECONDS) {
> > +             pr_warn("%s: clamping %d seconds to -%d\n",
> > +                     kp->name, ct, TEST_MAX_SECONDS);
> > +             ct = -TEST_MAX_SECONDS;
> > +     }
> > +
> > +     repeat_fn(ct);
>
> [Severity: Low]
> Does this synchronous loop execution block param_lock system-wide?
>
> When test_dynamic_debug is built-in, writing to its module parameters via
> sysfs triggers param_attr_store() in kernel/params.c, which acquires the
> global param_lock mutex around the .set callback:
>
> kernel/params.c:param_attr_store() {
>     ...
>     kernel_param_lock(mk->mod);
>     if (param_check_unsafe(attribute->param))
>         err = attribute->param->ops->set(buf, attribute->param);
>     ...
> }
>
> Because param_set_do_repeats() invokes the workload synchronously (which
> can run for up to 60 seconds as shown in do_classes() below), this starves
> param_lock, preventing other processes from reading or writing any
> built-in module parameters for the duration.


    In standard usage, test_dynamic_debug is built as a module
(CONFIG_TEST_DYNAMIC_DEBUG=m).
    Under kernel/params.c:KPARAM_MUTEX(mod), modular parameters
acquire the module's
    private &(mod)->param_lock rather than the global param_lock. The
lock-hold is
    strictly local to test_dynamic_debug's own sysfs nodes and has
zero impact on
    core kernel or other module parameters.

    Even in the hypothetical built-in case
(CONFIG_TEST_DYNAMIC_DEBUG=y in a test
    kernel, which I would consider mis-configured),
    test_dynamic_debug is exclusively a test harness whose workloads are
    triggered on demand by explicit sysfs writes. The loops call
cond_resched() and
    check signal_pending(current) on every iteration, keeping the execution
    cooperative and immediately abortable via SIGINT.




>
> > +
> >       return 0;
> >  }
>
> [ ... ]
>
> > @@ -103,7 +135,10 @@ enum cat_disjoint_bits {
> >       D2_DRMRES };
> >
> >  /* numeric verbosity, V2 > V1 related.  V1 is > D2_DRMRES */
> > -enum cat_level_num { V1 = 16, V2, V3, V4, V5, V6, V7 };
> > +enum cat_level_num { V1 = 16, V2, V3, V4, V5, V6, V7, V8 };
> > +
> > +/* test _USE_ w offset */
> > +enum cat_level_offset { Vu1 = V1 + 8, Vu2, Vu3, Vu4, Vu5, Vu6, Vu7, Vu8 };
> >
> >  /* recapitulate DRM's multi-classmap setup */
> >  #if !defined(TEST_DYNAMIC_DEBUG_SUBMOD)
>
> [ ... ]
>
> > @@ -160,6 +183,19 @@ DYNAMIC_DEBUG_CLASSMAP_DEFINE(fail_emptyclass, 0, 0 /* 
> > ,empty */);
> >  DYNAMIC_DEBUG_CLASSMAP_DEFINE(fail_maptype, 3, 10, "no such type");
> >  DYNAMIC_DEBUG_CLASSMAP_DEFINE(fail_base_len, 0, 60,
> >                             "base", "plus", "classes", "length", "too-big");
> > +#endif
> > +
> > +#else /* TEST_DYNAMIC_DEBUG_SUBMOD */
> > +
> > +/*
> > + * in submod/drm-drivers, use the classmaps defined in top/parent
> > + * module above.
> > + */
> > +
> > +DYNAMIC_DEBUG_CLASSMAP_USE(map_disjoint_bits);
> > +DYNAMIC_DEBUG_CLASSMAP_USE_(map_level_num, 7);
>
> [Severity: Low]
> Is this registration macro passing an outdated offset?
>

yes - fixed in v13 (forthcoming)

> The patch adds V8 to map_level_num, increasing its length to 8. While
> cat_level_offset correctly shifts the submodule's class definitions by 8
> (Vu1 = V1 + 8) above, this registration macro still tells dyndbg the
> classes start at offset 7.
>
> This mismatch causes submodule debug callsites to map to the wrong class
> IDs, leaving the last class (Vu8) completely out of bounds and
> uncontrollable.
>
> > +
> > +#if defined(DD_MACRO_ARGCHECK)
> >  DYNAMIC_DEBUG_CLASSMAP_USE_(fail_offset_big, 100);
> >  #endif /* DD_MACRO_ARGCHECK */
>
> [ ... ]
>
> > @@ -210,20 +247,85 @@ static void do_levels(void)
>
> [ ... ]
>
> > -static void do_prints(void)
> > +static void do_classes(int ct)
> > +{
> > +     if (ct < 0) {
> > +             unsigned long timeout = jiffies + (-ct) * HZ;
> > +
> > +             pr_debug("%s for %d seconds:\n", __func__, -ct);
> > +             while (time_before(jiffies, timeout)) {
> > +                     if (signal_pending(current))
> > +                             break;
> > +                     do_cats();
> > +                     do_levels();
> > +                     cond_resched();
> > +             }
> > +             return;
> > +     }
>
> --
> Sashiko AI review · 
> https://sashiko.dev/#/patchset/[email protected]?part=26

Reply via email to