From: Jim Cromie <jim.cromie@gmail.com> To: jbaron@akamai.com, gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org, intel-gvt-dev@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Cc: Jim Cromie <jim.cromie@gmail.com> Subject: [PATCH v7 1/8] dyndbg: add DEFINE_DYNAMIC_DEBUG_CATEGORIES and callbacks Date: Tue, 31 Aug 2021 14:21:26 -0600 [thread overview] Message-ID: <20210831202133.2165222-2-jim.cromie@gmail.com> (raw) In-Reply-To: <20210831202133.2165222-1-jim.cromie@gmail.com> DEFINE_DYNAMIC_DEBUG_CATEGORIES(name, var, bitmap_desc, @bit_descs) allows users to define a drm.debug style (bitmap) sysfs interface, and to specify the desired mapping from bits[0-N] to the format-prefix'd pr_debug()s to be controlled. DEFINE_DYNAMIC_DEBUG_CATEGORIES(debug_gvt, __gvt_debug, "i915/gvt bitmap desc", /** * search-prefixes, passed to dd-exec_queries * defines bits 0-N in order. * leading ^ is tacitly inserted (by callback currently) * trailing space used here excludes subcats. * helper macro needs more work * macro to autogen ++$i, 0x%x$i ? */ _DD_cat_("gvt:cmd: "), _DD_cat_("gvt:core: "), _DD_cat_("gvt:dpy: "), _DD_cat_("gvt:el: "), _DD_cat_("gvt:irq: "), _DD_cat_("gvt:mm: "), _DD_cat_("gvt:mmio: "), _DD_cat_("gvt:render: "), _DD_cat_("gvt:sched: ")); dynamic_debug.c: add 2 new elements: - int param_set_dyndbg() - int param_get_dyndbg() - struct kernel_param_ops param_ops_dyndbg Following the model of kernel/params.c STANDARD_PARAM_DEFS, these are non-static and exported. get/set use an augmented kernel_param; the arg refs a new struct dyndbg_bitmap_param containing: - the map (array, indexed by bitpos) of format-prefix strings, which define the set/category of prdbgs to be changed per each bit. - pointer to the user's ulong holding the bits/state. by sharing state, we coordinate with code that still uses it directly This will allow drm-debug to be converted incrementally, while still using __drm_debug & drm_debug_enabled() in other parts. param_set_dyndbg() compares new vs old bits, and only updates prdbgs on changes. This maximally preserves the underlying state, which may have been customized via later `echo $cmd >control`. So if a user really wants to know that all prdbgs are set precisely, they must pre-clear then set. TLDR: this also doesn't affect the decorator flags "mflt" set per prdbg. dynamic_debug.h: Add DEFINE_DYNAMIC_DEBUG_CATEGORIES() described above, and a stub throwing a BUILD_BUG (RFC) when used without DYNAMIC_DEBUG support. Add structs dyndbg_bitdesc, dyndbg_bitmap_param to support the macro. Note that it also calls MODULE_PARM_DESC for the user, but expects the user to catenate all the bit-descriptions together (as is done in drm.debug), and in the following uses in amdgpu, i915. The intent is to regenerate this output from per-bit help given in VA_ARGS, including a bit_label(); but this can wait. Also externs the struct kernel_param param_ops_dyndbg symbol, as is done in moduleparams.h for all the STANDARD params. USAGE NOTES: Using dyndbg to query on "format ^$prefix" requires that the prefix be present in the compiled-in format string; where run-time prefixing is used, that format would be "%s...", which is not usefully selectable. Using DEFINE_DYNAMIC_DEBUG_CATEGORIES wo support gets a BUILD_BUG. ISTM there is already action at a declarative distance, nobody needs mystery as to why the /sysfs thingy didn't appear. Dyndbg is completely agnostic wrt the categorization scheme used, in order to play well with any prefix convention already in use in the codebase. Ad-hoc categories and sub-categories are implicitly allowed, author discipline and review is expected. Here are some examples: "1","2","3" 2 doesn't imply 1. otherwize, sorta like printk levels "1:","2:","3:" are better, avoiding [1-9]\d+ ambiguity "hi:","mid:","low:" are reasonable, and imply independence "todo:","rfc:","fixme:" might be handy "A:".."Z:" uhm, yeah Hierarchical classes/categories are natural: "drm:<CAT>:" is used in a later commit "drm:<CAT>:<SUB>:" is a natural extension. "drm:atomic:fail:" has been proposed, sounds directly useful NB: in a real sense we abandon enum strictures here, and lose some compiler help, on spelling errs for example. Obviously "drm:" != "DRM:". Some properties of a hierarchical category deserve explication: Trailing spaces matter ! With 1..3-space ("drm: ", "drm:atomic: ", "drm:atomic:fail: "), the ":" doesn't terminate the search-space, the trailing space does. So a "drm:" search spec will match all DRM categories & subcategories, and will not be useful in an interface where all categories are already controlled together. That said, "drm:atomic:" & "drm:atomic: " are different, and both are useful in cases. Ad-Hoc sub-categories: These have a caveat wrt wrapper macros adding prefixes like "drm:atomic: "; the trailing space in the prefix means that drm_dbg_atomic("fail: ...") pastes as "drm:atomic: fail: ", which obviously isn't ideal wrt clear and simple bitmaps. A possible solution is to have a FOO_() version of every FOO() macro which (anti-mnemonically) elides the trailing space, which is normally inserted by a newer FOO(). IE: drm_dbg_atomic_("fail: ..."); // trailing _ means ad-hoc subcat Summarizing: - "drm:kms: " & "drm:kms:" are different - "drm:kms" also different - includes drm:kms2: - "drm:kms:\t" also different - could be troublesome - "drm:kms:*" doesn't work, no wildcard on format atm. Order matters in DEFINE_DYNAMIC_DEBUG_CATEGORIES(... @bit_descs) @bit_descs (array) position determines the bit mapping to the prefix, so to keep a stable map, new categories or 3rd level categories must be added to the end. Since bits are/will-stay applied 0-N, the later bits can countermand the earlier ones, but it's tricky - consider; DD_CATs(... "drm:atomic:", "drm:atomic:fail:" ) // misleading The 1st search-term is misleading, because it includes (modifies) subcategories, but then 2nd overrides it. So don't do that. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> --- v5: . rename to DEFINE_DYNAMIC_DEBUG_CATEGORIES from DEFINE_DYNDBG_BITMAP . in set_dyndbg, replace hardcoded "i915" w kp->mod->name . static inline the stubs . const *str in structs, const array. - Emil . dyndbg: add do-nothing DEFINE_DYNAMIC_DEBUG_CATEGORIES if !DD_CORE . call MOD_PARM_DESC(name, "$desc") for users . simplify callback, remove bit-change detection . config errs reported by <lkp@intel.com> v6: . return rc, bitmap->, snprintf, ws - Andy Shevchenko . s/chgct/matches/ - old varname is misleading . move code off file bottom to a "better" place . change ##fsname to ##var for less generic varname (ie: not "debug") . add KP_MOD_NAME workaround for !CONFIG_MODULES . move forward decl down to where its needed v7: . use kp->arg, dont need kp->data or previous patch-1 - jbaron . use client's ulong for bits, share state . throw BUILD_BUG if DEFINE_DYNAMIC_DEBUG_CATEGORIES used wo support --- include/linux/dynamic_debug.h | 60 ++++++++++++++++++++++++++ lib/dynamic_debug.c | 79 ++++++++++++++++++++++++++++++++++- 2 files changed, 138 insertions(+), 1 deletion(-) diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index dce631e678dd..f51b738668a0 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -181,6 +181,10 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor, KERN_DEBUG, prefix_str, prefix_type, \ rowsize, groupsize, buf, len, ascii) +struct kernel_param; +int param_set_dyndbg(const char *instr, const struct kernel_param *kp); +int param_get_dyndbg(char *buffer, const struct kernel_param *kp); + #else /* !CONFIG_DYNAMIC_DEBUG_CORE */ #include <linux/string.h> @@ -227,6 +231,62 @@ static inline int dynamic_debug_exec_queries(const char *query, const char *modn return 0; } +struct kernel_param; +static inline int param_set_dyndbg(const char *instr, const struct kernel_param *kp) +{ return 0; } +static inline int param_get_dyndbg(char *buffer, const struct kernel_param *kp) +{ return 0; } + #endif /* !CONFIG_DYNAMIC_DEBUG_CORE */ +struct dyndbg_bitdesc { + /* bitpos is inferred from index in containing array */ + const char *prefix; + const char *help; +}; + +struct dyndbg_bitmap_param { + unsigned long *bits; + struct dyndbg_bitdesc map[]; +}; + +#if defined(CONFIG_DYNAMIC_DEBUG) || \ + (defined(CONFIG_DYNAMIC_DEBUG_CORE) && defined(DYNAMIC_DEBUG_MODULE)) +/** + * DEFINE_DYNAMIC_DEBUG_CATEGORIES() - bitmap control of categorized prdbgs + * @fsname: parameter basename under /sys + * @var: C-identifier holding bitmap + * @_desc: string summarizing the controls provided + * @...: list of struct dyndbg_bitdesc initializations + * + * Intended for modules with substantial use of "categorized" prdbgs + * (those with some systematic prefix in the format string), this lets + * modules (using dyndbg) control those prdbg groups according to + * their prefixes, and map them to bits 0-N of a sysfs control point. + * The @bits... identifies the prefixes to be used by dyndbg to + * select and alter those categorized prdbgs, order defines bitpos. + */ +#define DEFINE_DYNAMIC_DEBUG_CATEGORIES(fsname, _var, _desc, ...) \ + MODULE_PARM_DESC(fsname, _desc); \ + static struct dyndbg_bitmap_param ddcats_##_var = \ + { .bits = &_var, .map = { __VA_ARGS__, { .prefix = NULL }}}; \ + module_param_cb(fsname, ¶m_ops_dyndbg, &ddcats_##_var, 0644) + +#define _DD_cat_(pfx) { .prefix = pfx, .help = "help for " pfx } +#define _DD_cat_help_(pfx) "\t " pfx "\t- help for " pfx "\n" + +extern const struct kernel_param_ops param_ops_dyndbg; + +#elif (defined(CONFIG_DYNAMIC_DEBUG_CORE) && !defined(DYNAMIC_DEBUG_MODULE)) + +#define DEFINE_DYNAMIC_DEBUG_CATEGORIES(fsname, var, bitmap_desc, ...) \ + BUILD_BUG_ON_MSG(1, "you need -DDYNAMIC_DEBUG_MODULE in compile") + +#else +#define DEFINE_DYNAMIC_DEBUG_CATEGORIES(fsname, var, bitmap_desc, ...) \ + BUILD_BUG_ON_MSG(1, "DYNAMIC_DEBUG support required to use this macro: " #var) +#define _DD_cat_(pfx) +#define _DD_cat_help_(pfx) +#endif + #endif diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index cb5abb42c16a..9f9e70023aa4 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -529,7 +529,7 @@ static int ddebug_exec_queries(char *query, const char *modname) if (!query || !*query || *query == '#') continue; - vpr_info("query %d: \"%s\"\n", i, query); + vpr_info("query %d: \"%s\" mod:%s\n", i, query, modname ?: "*"); rc = ddebug_exec_query(query, modname); if (rc < 0) { @@ -577,6 +577,83 @@ int dynamic_debug_exec_queries(const char *query, const char *modname) } EXPORT_SYMBOL_GPL(dynamic_debug_exec_queries); +#ifdef CONFIG_MODULES +#define KP_MOD_NAME kp->mod->name +#else +#define KP_MOD_NAME NULL /* wildcard */ +#endif +#define FMT_QUERY_SIZE 128 /* typically need <40 */ +/** + * param_set_dyndbg - bits => categories >control setter + * @instr: string echo>d to sysfs + * @kp: kp->arg has state: bits, map + * + * Enable/disable prdbgs by their "category", as defined in args to + * DEFINE_DYNAMIC_DEBUG_CATEGORIES + * Returns: 0 or <0 if error. + */ +int param_set_dyndbg(const char *instr, const struct kernel_param *kp) +{ + unsigned long inbits; + int rc, i, matches = 0, totct = 0; + char query[FMT_QUERY_SIZE]; + const struct dyndbg_bitmap_param *p = kp->arg; + const struct dyndbg_bitdesc *map = p->map; + + if (!map) { + pr_err("set_dyndbg: no bits=>queries map\n"); + return -EINVAL; + } + rc = kstrtoul(instr, 0, &inbits); + if (rc) { + pr_err("set_dyndbg: failed\n"); + return rc; + } + vpr_info("set_dyndbg: new 0x%lx old 0x%lx\n", inbits, *p->bits); + + for (i = 0; map->prefix && i < BITS_PER_LONG; map++, i++) { + + if (test_bit(i, &inbits) == test_bit(i, p->bits)) + continue; + snprintf(query, FMT_QUERY_SIZE, "format '^%s' %cp", map->prefix, + test_bit(i, &inbits) ? '+' : '-'); + + matches = ddebug_exec_queries(query, KP_MOD_NAME); + + v2pr_info("bit-%d: %d matches on format '^%s'\n", i, + matches, map->prefix); + totct += matches; + } + *p->bits = inbits; + vpr_info("total matches: %d\n", totct); + return 0; +} +EXPORT_SYMBOL(param_set_dyndbg); + +/** + * param_get_dyndbg - bitmap reader + * @buffer: receives string rep of bitmap + * @kp: kp->arg has state: bits, map + * + * Reads last written bits, underlying prdbg state may have changed since. + * Returns: #chars written + */ +int param_get_dyndbg(char *buffer, const struct kernel_param *kp) +{ + const struct dyndbg_bitmap_param *p = kp->arg; + unsigned long val = *p->bits; + + return scnprintf(buffer, PAGE_SIZE, "0x%lx\n", val); +} +EXPORT_SYMBOL(param_get_dyndbg); + +const struct kernel_param_ops param_ops_dyndbg = { + .set = param_set_dyndbg, + .get = param_get_dyndbg, +}; +/* support DEFINE_DYNAMIC_DEBUG_CATEGORIES users */ +EXPORT_SYMBOL(param_ops_dyndbg); + #define PREFIX_SIZE 64 static int remaining(int wrote) -- 2.31.1
WARNING: multiple messages have this Message-ID (diff)
From: Jim Cromie <jim.cromie@gmail.com> To: jbaron@akamai.com, gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org, intel-gvt-dev@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Cc: Jim Cromie <jim.cromie@gmail.com> Subject: [Intel-gfx] [PATCH v7 1/8] dyndbg: add DEFINE_DYNAMIC_DEBUG_CATEGORIES and callbacks Date: Tue, 31 Aug 2021 14:21:26 -0600 [thread overview] Message-ID: <20210831202133.2165222-2-jim.cromie@gmail.com> (raw) In-Reply-To: <20210831202133.2165222-1-jim.cromie@gmail.com> DEFINE_DYNAMIC_DEBUG_CATEGORIES(name, var, bitmap_desc, @bit_descs) allows users to define a drm.debug style (bitmap) sysfs interface, and to specify the desired mapping from bits[0-N] to the format-prefix'd pr_debug()s to be controlled. DEFINE_DYNAMIC_DEBUG_CATEGORIES(debug_gvt, __gvt_debug, "i915/gvt bitmap desc", /** * search-prefixes, passed to dd-exec_queries * defines bits 0-N in order. * leading ^ is tacitly inserted (by callback currently) * trailing space used here excludes subcats. * helper macro needs more work * macro to autogen ++$i, 0x%x$i ? */ _DD_cat_("gvt:cmd: "), _DD_cat_("gvt:core: "), _DD_cat_("gvt:dpy: "), _DD_cat_("gvt:el: "), _DD_cat_("gvt:irq: "), _DD_cat_("gvt:mm: "), _DD_cat_("gvt:mmio: "), _DD_cat_("gvt:render: "), _DD_cat_("gvt:sched: ")); dynamic_debug.c: add 2 new elements: - int param_set_dyndbg() - int param_get_dyndbg() - struct kernel_param_ops param_ops_dyndbg Following the model of kernel/params.c STANDARD_PARAM_DEFS, these are non-static and exported. get/set use an augmented kernel_param; the arg refs a new struct dyndbg_bitmap_param containing: - the map (array, indexed by bitpos) of format-prefix strings, which define the set/category of prdbgs to be changed per each bit. - pointer to the user's ulong holding the bits/state. by sharing state, we coordinate with code that still uses it directly This will allow drm-debug to be converted incrementally, while still using __drm_debug & drm_debug_enabled() in other parts. param_set_dyndbg() compares new vs old bits, and only updates prdbgs on changes. This maximally preserves the underlying state, which may have been customized via later `echo $cmd >control`. So if a user really wants to know that all prdbgs are set precisely, they must pre-clear then set. TLDR: this also doesn't affect the decorator flags "mflt" set per prdbg. dynamic_debug.h: Add DEFINE_DYNAMIC_DEBUG_CATEGORIES() described above, and a stub throwing a BUILD_BUG (RFC) when used without DYNAMIC_DEBUG support. Add structs dyndbg_bitdesc, dyndbg_bitmap_param to support the macro. Note that it also calls MODULE_PARM_DESC for the user, but expects the user to catenate all the bit-descriptions together (as is done in drm.debug), and in the following uses in amdgpu, i915. The intent is to regenerate this output from per-bit help given in VA_ARGS, including a bit_label(); but this can wait. Also externs the struct kernel_param param_ops_dyndbg symbol, as is done in moduleparams.h for all the STANDARD params. USAGE NOTES: Using dyndbg to query on "format ^$prefix" requires that the prefix be present in the compiled-in format string; where run-time prefixing is used, that format would be "%s...", which is not usefully selectable. Using DEFINE_DYNAMIC_DEBUG_CATEGORIES wo support gets a BUILD_BUG. ISTM there is already action at a declarative distance, nobody needs mystery as to why the /sysfs thingy didn't appear. Dyndbg is completely agnostic wrt the categorization scheme used, in order to play well with any prefix convention already in use in the codebase. Ad-hoc categories and sub-categories are implicitly allowed, author discipline and review is expected. Here are some examples: "1","2","3" 2 doesn't imply 1. otherwize, sorta like printk levels "1:","2:","3:" are better, avoiding [1-9]\d+ ambiguity "hi:","mid:","low:" are reasonable, and imply independence "todo:","rfc:","fixme:" might be handy "A:".."Z:" uhm, yeah Hierarchical classes/categories are natural: "drm:<CAT>:" is used in a later commit "drm:<CAT>:<SUB>:" is a natural extension. "drm:atomic:fail:" has been proposed, sounds directly useful NB: in a real sense we abandon enum strictures here, and lose some compiler help, on spelling errs for example. Obviously "drm:" != "DRM:". Some properties of a hierarchical category deserve explication: Trailing spaces matter ! With 1..3-space ("drm: ", "drm:atomic: ", "drm:atomic:fail: "), the ":" doesn't terminate the search-space, the trailing space does. So a "drm:" search spec will match all DRM categories & subcategories, and will not be useful in an interface where all categories are already controlled together. That said, "drm:atomic:" & "drm:atomic: " are different, and both are useful in cases. Ad-Hoc sub-categories: These have a caveat wrt wrapper macros adding prefixes like "drm:atomic: "; the trailing space in the prefix means that drm_dbg_atomic("fail: ...") pastes as "drm:atomic: fail: ", which obviously isn't ideal wrt clear and simple bitmaps. A possible solution is to have a FOO_() version of every FOO() macro which (anti-mnemonically) elides the trailing space, which is normally inserted by a newer FOO(). IE: drm_dbg_atomic_("fail: ..."); // trailing _ means ad-hoc subcat Summarizing: - "drm:kms: " & "drm:kms:" are different - "drm:kms" also different - includes drm:kms2: - "drm:kms:\t" also different - could be troublesome - "drm:kms:*" doesn't work, no wildcard on format atm. Order matters in DEFINE_DYNAMIC_DEBUG_CATEGORIES(... @bit_descs) @bit_descs (array) position determines the bit mapping to the prefix, so to keep a stable map, new categories or 3rd level categories must be added to the end. Since bits are/will-stay applied 0-N, the later bits can countermand the earlier ones, but it's tricky - consider; DD_CATs(... "drm:atomic:", "drm:atomic:fail:" ) // misleading The 1st search-term is misleading, because it includes (modifies) subcategories, but then 2nd overrides it. So don't do that. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> --- v5: . rename to DEFINE_DYNAMIC_DEBUG_CATEGORIES from DEFINE_DYNDBG_BITMAP . in set_dyndbg, replace hardcoded "i915" w kp->mod->name . static inline the stubs . const *str in structs, const array. - Emil . dyndbg: add do-nothing DEFINE_DYNAMIC_DEBUG_CATEGORIES if !DD_CORE . call MOD_PARM_DESC(name, "$desc") for users . simplify callback, remove bit-change detection . config errs reported by <lkp@intel.com> v6: . return rc, bitmap->, snprintf, ws - Andy Shevchenko . s/chgct/matches/ - old varname is misleading . move code off file bottom to a "better" place . change ##fsname to ##var for less generic varname (ie: not "debug") . add KP_MOD_NAME workaround for !CONFIG_MODULES . move forward decl down to where its needed v7: . use kp->arg, dont need kp->data or previous patch-1 - jbaron . use client's ulong for bits, share state . throw BUILD_BUG if DEFINE_DYNAMIC_DEBUG_CATEGORIES used wo support --- include/linux/dynamic_debug.h | 60 ++++++++++++++++++++++++++ lib/dynamic_debug.c | 79 ++++++++++++++++++++++++++++++++++- 2 files changed, 138 insertions(+), 1 deletion(-) diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index dce631e678dd..f51b738668a0 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -181,6 +181,10 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor, KERN_DEBUG, prefix_str, prefix_type, \ rowsize, groupsize, buf, len, ascii) +struct kernel_param; +int param_set_dyndbg(const char *instr, const struct kernel_param *kp); +int param_get_dyndbg(char *buffer, const struct kernel_param *kp); + #else /* !CONFIG_DYNAMIC_DEBUG_CORE */ #include <linux/string.h> @@ -227,6 +231,62 @@ static inline int dynamic_debug_exec_queries(const char *query, const char *modn return 0; } +struct kernel_param; +static inline int param_set_dyndbg(const char *instr, const struct kernel_param *kp) +{ return 0; } +static inline int param_get_dyndbg(char *buffer, const struct kernel_param *kp) +{ return 0; } + #endif /* !CONFIG_DYNAMIC_DEBUG_CORE */ +struct dyndbg_bitdesc { + /* bitpos is inferred from index in containing array */ + const char *prefix; + const char *help; +}; + +struct dyndbg_bitmap_param { + unsigned long *bits; + struct dyndbg_bitdesc map[]; +}; + +#if defined(CONFIG_DYNAMIC_DEBUG) || \ + (defined(CONFIG_DYNAMIC_DEBUG_CORE) && defined(DYNAMIC_DEBUG_MODULE)) +/** + * DEFINE_DYNAMIC_DEBUG_CATEGORIES() - bitmap control of categorized prdbgs + * @fsname: parameter basename under /sys + * @var: C-identifier holding bitmap + * @_desc: string summarizing the controls provided + * @...: list of struct dyndbg_bitdesc initializations + * + * Intended for modules with substantial use of "categorized" prdbgs + * (those with some systematic prefix in the format string), this lets + * modules (using dyndbg) control those prdbg groups according to + * their prefixes, and map them to bits 0-N of a sysfs control point. + * The @bits... identifies the prefixes to be used by dyndbg to + * select and alter those categorized prdbgs, order defines bitpos. + */ +#define DEFINE_DYNAMIC_DEBUG_CATEGORIES(fsname, _var, _desc, ...) \ + MODULE_PARM_DESC(fsname, _desc); \ + static struct dyndbg_bitmap_param ddcats_##_var = \ + { .bits = &_var, .map = { __VA_ARGS__, { .prefix = NULL }}}; \ + module_param_cb(fsname, ¶m_ops_dyndbg, &ddcats_##_var, 0644) + +#define _DD_cat_(pfx) { .prefix = pfx, .help = "help for " pfx } +#define _DD_cat_help_(pfx) "\t " pfx "\t- help for " pfx "\n" + +extern const struct kernel_param_ops param_ops_dyndbg; + +#elif (defined(CONFIG_DYNAMIC_DEBUG_CORE) && !defined(DYNAMIC_DEBUG_MODULE)) + +#define DEFINE_DYNAMIC_DEBUG_CATEGORIES(fsname, var, bitmap_desc, ...) \ + BUILD_BUG_ON_MSG(1, "you need -DDYNAMIC_DEBUG_MODULE in compile") + +#else +#define DEFINE_DYNAMIC_DEBUG_CATEGORIES(fsname, var, bitmap_desc, ...) \ + BUILD_BUG_ON_MSG(1, "DYNAMIC_DEBUG support required to use this macro: " #var) +#define _DD_cat_(pfx) +#define _DD_cat_help_(pfx) +#endif + #endif diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index cb5abb42c16a..9f9e70023aa4 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -529,7 +529,7 @@ static int ddebug_exec_queries(char *query, const char *modname) if (!query || !*query || *query == '#') continue; - vpr_info("query %d: \"%s\"\n", i, query); + vpr_info("query %d: \"%s\" mod:%s\n", i, query, modname ?: "*"); rc = ddebug_exec_query(query, modname); if (rc < 0) { @@ -577,6 +577,83 @@ int dynamic_debug_exec_queries(const char *query, const char *modname) } EXPORT_SYMBOL_GPL(dynamic_debug_exec_queries); +#ifdef CONFIG_MODULES +#define KP_MOD_NAME kp->mod->name +#else +#define KP_MOD_NAME NULL /* wildcard */ +#endif +#define FMT_QUERY_SIZE 128 /* typically need <40 */ +/** + * param_set_dyndbg - bits => categories >control setter + * @instr: string echo>d to sysfs + * @kp: kp->arg has state: bits, map + * + * Enable/disable prdbgs by their "category", as defined in args to + * DEFINE_DYNAMIC_DEBUG_CATEGORIES + * Returns: 0 or <0 if error. + */ +int param_set_dyndbg(const char *instr, const struct kernel_param *kp) +{ + unsigned long inbits; + int rc, i, matches = 0, totct = 0; + char query[FMT_QUERY_SIZE]; + const struct dyndbg_bitmap_param *p = kp->arg; + const struct dyndbg_bitdesc *map = p->map; + + if (!map) { + pr_err("set_dyndbg: no bits=>queries map\n"); + return -EINVAL; + } + rc = kstrtoul(instr, 0, &inbits); + if (rc) { + pr_err("set_dyndbg: failed\n"); + return rc; + } + vpr_info("set_dyndbg: new 0x%lx old 0x%lx\n", inbits, *p->bits); + + for (i = 0; map->prefix && i < BITS_PER_LONG; map++, i++) { + + if (test_bit(i, &inbits) == test_bit(i, p->bits)) + continue; + snprintf(query, FMT_QUERY_SIZE, "format '^%s' %cp", map->prefix, + test_bit(i, &inbits) ? '+' : '-'); + + matches = ddebug_exec_queries(query, KP_MOD_NAME); + + v2pr_info("bit-%d: %d matches on format '^%s'\n", i, + matches, map->prefix); + totct += matches; + } + *p->bits = inbits; + vpr_info("total matches: %d\n", totct); + return 0; +} +EXPORT_SYMBOL(param_set_dyndbg); + +/** + * param_get_dyndbg - bitmap reader + * @buffer: receives string rep of bitmap + * @kp: kp->arg has state: bits, map + * + * Reads last written bits, underlying prdbg state may have changed since. + * Returns: #chars written + */ +int param_get_dyndbg(char *buffer, const struct kernel_param *kp) +{ + const struct dyndbg_bitmap_param *p = kp->arg; + unsigned long val = *p->bits; + + return scnprintf(buffer, PAGE_SIZE, "0x%lx\n", val); +} +EXPORT_SYMBOL(param_get_dyndbg); + +const struct kernel_param_ops param_ops_dyndbg = { + .set = param_set_dyndbg, + .get = param_get_dyndbg, +}; +/* support DEFINE_DYNAMIC_DEBUG_CATEGORIES users */ +EXPORT_SYMBOL(param_ops_dyndbg); + #define PREFIX_SIZE 64 static int remaining(int wrote) -- 2.31.1
next prev parent reply other threads:[~2021-08-31 20:21 UTC|newest] Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-08-31 20:21 [PATCH v7 0/8] use DYNAMIC_DEBUG to implement DRM.debug Jim Cromie 2021-08-31 20:21 ` [Intel-gfx] " Jim Cromie 2021-08-31 20:21 ` Jim Cromie [this message] 2021-08-31 20:21 ` [Intel-gfx] [PATCH v7 1/8] dyndbg: add DEFINE_DYNAMIC_DEBUG_CATEGORIES and callbacks Jim Cromie 2021-08-31 20:21 ` [PATCH v7 2/8] dyndbg: remove spaces in pr_debug "gvt: core:" etc prefixes Jim Cromie 2021-08-31 20:21 ` [Intel-gfx] " Jim Cromie 2021-08-31 20:21 ` [PATCH v7 3/8] i915/gvt: use DEFINE_DYNAMIC_DEBUG_CATEGORIES to create "gvt:core:" etc categories Jim Cromie 2021-08-31 20:21 ` [Intel-gfx] " Jim Cromie 2021-09-03 11:07 ` Tvrtko Ursulin 2021-09-03 19:22 ` jim.cromie 2021-09-03 19:22 ` jim.cromie 2021-09-06 12:26 ` Tvrtko Ursulin 2021-09-06 17:41 ` jim.cromie 2021-09-07 15:14 ` Tvrtko Ursulin 2021-09-07 17:26 ` jim.cromie 2021-09-07 17:26 ` jim.cromie 2021-08-31 20:21 ` [PATCH v7 4/8] amdgpu: use DEFINE_DYNAMIC_DEBUG_CATEGORIES Jim Cromie 2021-08-31 20:21 ` [Intel-gfx] " Jim Cromie 2021-08-31 20:21 ` [PATCH v7 5/8] drm_print: add choice to use dynamic debug in drm-debug Jim Cromie 2021-08-31 20:21 ` [Intel-gfx] " Jim Cromie 2021-09-03 11:15 ` Tvrtko Ursulin 2021-09-03 21:57 ` jim.cromie 2021-09-03 21:57 ` jim.cromie 2021-09-06 10:20 ` Tvrtko Ursulin 2021-09-06 18:24 ` jim.cromie 2021-09-06 18:24 ` jim.cromie 2021-08-31 20:21 ` [PATCH v7 6/8] drm_print: instrument drm_debug_enabled Jim Cromie 2021-08-31 20:21 ` [Intel-gfx] " Jim Cromie 2021-09-05 18:50 ` jim.cromie 2021-09-05 18:50 ` [Intel-gfx] " jim.cromie 2021-09-05 18:50 ` jim.cromie 2021-08-31 20:21 ` [PATCH v7 7/8] amdgpu_ucode: reduce number of pr_debug calls Jim Cromie 2021-08-31 20:21 ` [Intel-gfx] " Jim Cromie 2021-08-31 20:21 ` [PATCH v7 8/8] nouveau: fold multiple DRM_DEBUG_DRIVERs together Jim Cromie 2021-08-31 20:21 ` [Intel-gfx] " Jim Cromie 2021-08-31 21:33 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for use DYNAMIC_DEBUG to implement DRM.debug (rev2) Patchwork 2021-08-31 21:37 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork 2021-08-31 22:01 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork 2021-08-31 23:38 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork 2021-09-03 0:31 ` jim.cromie 2021-09-03 11:29 ` Tvrtko Ursulin 2021-09-03 13:01 ` Petri Latvala 2021-09-05 17:35 ` jim.cromie 2021-09-06 10:14 ` Tvrtko Ursulin 2021-09-06 10:04 ` Tvrtko Ursulin 2021-09-06 11:25 ` Petri Latvala 2021-09-07 4:13 ` Gupta, Anshuman
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210831202133.2165222-2-jim.cromie@gmail.com \ --to=jim.cromie@gmail.com \ --cc=amd-gfx@lists.freedesktop.org \ --cc=dri-devel@lists.freedesktop.org \ --cc=gregkh@linuxfoundation.org \ --cc=intel-gfx@lists.freedesktop.org \ --cc=intel-gvt-dev@lists.freedesktop.org \ --cc=jbaron@akamai.com \ --cc=linux-kernel@vger.kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.