2018-09-19 22:08:08

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 00/22] various dynamic_debug patches

This started as an experiment to see how hard it would be to change
the four pointers in struct _ddebug into relative offsets, a la
CONFIG_GENERIC_BUG_RELATIVE_POINTERS, thus saving 16 bytes per
pr_debug site (and thus exactly making up for the extra space used by
the introduction of jump labels in 9049fc74). I stumbled on a few
things that are probably worth fixing regardless of whether the latter
half of this series is deemed worthwhile.

Patch relationships: 1-2, 3-4, 5-6 and 15-16 can be applied
individually, though 2, 4 and 6 probably makes most sense in the
context of the final goal of the series.

7-12 I believe make sense on their own. Patch 13 again only makes
sense if we go all the way, and 14 and 17 depend on 13.

18-21 are more preparatory patches, and finally 22 switch over x86-64
to use CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS. I've tested that the
end result boots under virtme and that the dynamic_debug control file
has the expected contents.

Rasmus Villemoes (22):
linux/device.h: use DYNAMIC_DEBUG_BRANCH in dev_dbg_ratelimited
linux/device.h: use unique identifier for each struct _ddebug
linux/net.h: use DYNAMIC_DEBUG_BRANCH in net_dbg_ratelimited
linux/net.h: use unique identifier for each struct _ddebug
linux/printk.h: use DYNAMIC_DEBUG_BRANCH in pr_debug_ratelimited
linux/printk.h: use unique identifier for each struct _ddebug
dynamic_debug: consolidate DEFINE_DYNAMIC_DEBUG_METADATA definitions
dynamic_debug: don't duplicate modname in ddebug_add_module
dynamic_debug: use pointer comparison in ddebug_remove_module
dynamic_debug: remove unused EXPORT_SYMBOLs
dynamic_debug: move pr_err from module.c to ddebug_add_module
dynamic_debug: add static inline stub for ddebug_add_module
dynamic_debug: refactor dynamic_pr_debug and friends
btrfs: implement btrfs_debug* in terms of helper macro
ACPI: use proper DYNAMIC_DEBUG_BRANCH macro
ACPI: remove unused __acpi_handle_debug macro
ACPI: implement acpi_handle_debug in terms of _dynamic_func_call
dynamic_debug: introduce accessors for string members of struct
_ddebug
dynamic_debug: drop use of bitfields in struct _ddebug
dynamic_debug: introduce CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS
x86: jump_label: introduce ASM_STATIC_KEY_INIT_{TRUE,FALSE}
x86_64: use relative pointers with dynamic debug

arch/x86/Kconfig | 1 +
arch/x86/include/asm/dynamic_debug.h | 35 +++++++++
arch/x86/include/asm/jump_label.h | 18 +++++
fs/btrfs/ctree.h | 34 +++------
include/linux/acpi.h | 11 +--
include/linux/device.h | 6 +-
include/linux/dynamic_debug.h | 126 +++++++++++++++++++--------------
include/linux/jump_label.h | 2 +
include/linux/net.h | 6 +-
include/linux/printk.h | 6 +-
kernel/module.c | 6 +-
lib/Kconfig.debug | 3 +
lib/dynamic_debug.c | 133 ++++++++++++++++++++++++-----------
13 files changed, 251 insertions(+), 136 deletions(-)
create mode 100644 arch/x86/include/asm/dynamic_debug.h

--
2.16.4



2018-09-19 22:05:37

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 12/22] dynamic_debug: add static inline stub for ddebug_add_module

For symmetry with ddebug_remove_module, and to avoid a bit of ifdeffery
in module.c, move the declaration of ddebug_add_module inside #if
defined(CONFIG_DYNAMIC_DEBUG) and add a corresponding no-op stub in the
#else branch.

Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 10 ++++++++--
kernel/module.c | 2 --
2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 0a643316597c..6a002b789d51 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -47,10 +47,10 @@ struct _ddebug {
} __attribute__((aligned(8)));


-int ddebug_add_module(struct _ddebug *tab, unsigned int n,
- const char *modname);

#if defined(CONFIG_DYNAMIC_DEBUG)
+int ddebug_add_module(struct _ddebug *tab, unsigned int n,
+ const char *modname);
extern int ddebug_remove_module(const char *mod_name);
extern __printf(2, 3)
void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...);
@@ -152,6 +152,12 @@ do { \
#include <linux/string.h>
#include <linux/errno.h>

+static inline int ddebug_add_module(struct _ddebug *tab, unsigned int n,
+ const char *modname)
+{
+ return 0;
+}
+
static inline int ddebug_remove_module(const char *mod)
{
return 0;
diff --git a/kernel/module.c b/kernel/module.c
index 381f9bf282fe..be2727c5a003 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2715,9 +2715,7 @@ static void dynamic_debug_setup(struct module *mod, struct _ddebug *debug, unsig
{
if (!debug)
return;
-#ifdef CONFIG_DYNAMIC_DEBUG
ddebug_add_module(debug, num, mod->name);
-#endif
}

static void dynamic_debug_remove(struct module *mod, struct _ddebug *debug)
--
2.16.4


2018-09-19 22:05:45

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 17/22] ACPI: implement acpi_handle_debug in terms of _dynamic_func_call

With coming changes on x86-64, all dynamic debug descriptors in a
translation unit must have distinct names. The macro _dynamic_func_call
takes care of that. No functional change.

Cc: [email protected]
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/acpi.h | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index e12d5ef1a054..83bacf9039e9 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -977,12 +977,8 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
#else
#if defined(CONFIG_DYNAMIC_DEBUG)
#define acpi_handle_debug(handle, fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __acpi_handle_debug(&descriptor, handle, pr_fmt(fmt), \
- ##__VA_ARGS__); \
-} while (0)
+ _dynamic_func_call(fmt, __acpi_handle_debug, \
+ handle, pr_fmt(fmt), ##__VA_ARGS__)
#else
#define acpi_handle_debug(handle, fmt, ...) \
({ \
--
2.16.4


2018-09-19 22:05:49

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 18/22] dynamic_debug: introduce accessors for string members of struct _ddebug

When we introduce compact versions of these pointers (a la
CONFIG_GENERIC_BUG_RELATIVE_POINTERS), all access to these members must
go via appropriate accessors. This just mass-converts dynamic_debug.c to
use the new accessors.

Signed-off-by: Rasmus Villemoes <[email protected]>
---
lib/dynamic_debug.c | 51 ++++++++++++++++++++++++++++++++++-----------------
1 file changed, 34 insertions(+), 17 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index e90459dca34b..dbd837f486f9 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -37,6 +37,23 @@
#include <linux/device.h>
#include <linux/netdevice.h>

+static inline const char *dd_modname(const struct _ddebug *dd)
+{
+ return dd->modname;
+}
+static inline const char *dd_function(const struct _ddebug *dd)
+{
+ return dd->function;
+}
+static inline const char *dd_filename(const struct _ddebug *dd)
+{
+ return dd->filename;
+}
+static inline const char *dd_format(const struct _ddebug *dd)
+{
+ return dd->format;
+}
+
extern struct _ddebug __start___verbose[];
extern struct _ddebug __stop___verbose[];

@@ -158,21 +175,21 @@ static int ddebug_change(const struct ddebug_query *query,

/* match against the source filename */
if (query->filename &&
- !match_wildcard(query->filename, dp->filename) &&
+ !match_wildcard(query->filename, dd_filename(dp)) &&
!match_wildcard(query->filename,
- kbasename(dp->filename)) &&
+ kbasename(dd_filename(dp))) &&
!match_wildcard(query->filename,
- trim_prefix(dp->filename)))
+ trim_prefix(dd_filename(dp))))
continue;

/* match against the function */
if (query->function &&
- !match_wildcard(query->function, dp->function))
+ !match_wildcard(query->function, dd_function(dp)))
continue;

/* match against the format */
if (query->format &&
- !strstr(dp->format, query->format))
+ !strstr(dd_format(dp), query->format))
continue;

/* match against the line number range */
@@ -197,8 +214,8 @@ static int ddebug_change(const struct ddebug_query *query,
#endif
dp->flags = newflags;
vpr_info("changed %s:%d [%s]%s =%s\n",
- trim_prefix(dp->filename), dp->lineno,
- dt->mod_name, dp->function,
+ trim_prefix(dd_filename(dp)), dp->lineno,
+ dt->mod_name, dd_function(dp),
ddebug_describe_flags(dp, flagbuf,
sizeof(flagbuf)));
}
@@ -533,10 +550,10 @@ static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
pos_after_tid = pos;
if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
- desc->modname);
+ dd_modname(desc));
if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
- desc->function);
+ dd_function(desc));
if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
pos += snprintf(buf + pos, remaining(pos), "%d:",
desc->lineno);
@@ -790,10 +807,10 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
}

seq_printf(m, "%s:%u [%s]%s =%s \"",
- trim_prefix(dp->filename), dp->lineno,
- iter->table->mod_name, dp->function,
+ trim_prefix(dd_filename(dp)), dp->lineno,
+ iter->table->mod_name, dd_function(dp),
ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
- seq_escape(m, dp->format, "\t\r\n\"");
+ seq_escape(m, dd_format(dp), "\t\r\n\"");
seq_puts(m, "\"\n");

return 0;
@@ -987,20 +1004,20 @@ static int __init dynamic_debug_init(void)
return 1;
}
iter = __start___verbose;
- modname = iter->modname;
+ modname = dd_modname(iter);
iter_start = iter;
for (; iter < __stop___verbose; iter++) {
entries++;
- verbose_bytes += strlen(iter->modname) + strlen(iter->function)
- + strlen(iter->filename) + strlen(iter->format);
+ verbose_bytes += strlen(dd_modname(iter)) + strlen(dd_function(iter))
+ + strlen(dd_filename(iter)) + strlen(dd_format(iter));

- if (strcmp(modname, iter->modname)) {
+ if (strcmp(modname, dd_modname(iter))) {
modct++;
ret = ddebug_add_module(iter_start, n, modname);
if (ret)
goto out_err;
n = 0;
- modname = iter->modname;
+ modname = dd_modname(iter);
iter_start = iter;
}
n++;
--
2.16.4


2018-09-19 22:06:01

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 15/22] ACPI: use proper DYNAMIC_DEBUG_BRANCH macro

dynamic debug may be implemented via static keys, but ACPI is missing
out on that runtime benefit since it open-codes one possible definition
of DYNAMIC_DEBUG_BRANCH.

Cc: [email protected]
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/acpi.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index de8d3d3fa651..21e03aa32aae 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -982,7 +982,7 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
#define acpi_handle_debug(handle, fmt, ...) \
do { \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
__acpi_handle_debug(&descriptor, handle, pr_fmt(fmt), \
##__VA_ARGS__); \
} while (0)
--
2.16.4


2018-09-19 22:06:16

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 16/22] ACPI: remove unused __acpi_handle_debug macro

If CONFIG_DYNAMIC_DEBUG is not set, acpi_handle_debug directly invokes
acpi_handle_printk (if DEBUG) or does a no-printk (if !DEBUG). So this
macro is never used.

Cc: [email protected]
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/acpi.h | 3 ---
1 file changed, 3 deletions(-)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 21e03aa32aae..e12d5ef1a054 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -948,9 +948,6 @@ acpi_handle_printk(const char *level, void *handle, const char *fmt, ...) {}
#if defined(CONFIG_ACPI) && defined(CONFIG_DYNAMIC_DEBUG)
__printf(3, 4)
void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const char *fmt, ...);
-#else
-#define __acpi_handle_debug(descriptor, handle, fmt, ...) \
- acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__);
#endif

/*
--
2.16.4


2018-09-19 22:06:23

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 22/22] x86_64: use relative pointers with dynamic debug

Similar to how x86_64 uses bug_entry-relative pointers to reduce
sizeof(struct bug_entry), the same thing can now be done for struct
_ddebug, saving 16 bytes for each of those (i.e., each pr_debug, dev_dbg
etc. in a CONFIG_DYNAMIC_DEBUG kernel).

Note the use of .ifndef/.endif in asm to avoid

fs/aio.c:1382: Error: symbol `__UNIQUE_ID_ddebug112' is already defined

This is due to uses of pr_debug et al in functions that get inlined. In
such a case, __COUNTER__ is obviously only expanded once, but the asm()
is repeated once for every inlined instance. Letting all instances share
the same descriptor object is the right thing to do; that is also what
happens when it is the compiler that defines a static object inside an
inline(d) function.

Cc: [email protected]
Signed-off-by: Rasmus Villemoes <[email protected]>
---
arch/x86/Kconfig | 1 +
arch/x86/include/asm/dynamic_debug.h | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 36 insertions(+)
create mode 100644 arch/x86/include/asm/dynamic_debug.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 1a0be022f91d..a44168930e52 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -90,6 +90,7 @@ config X86
select CLOCKSOURCE_WATCHDOG
select DCACHE_WORD_ACCESS
select DMA_DIRECT_OPS
+ select DYNAMIC_DEBUG_RELATIVE_POINTERS if X86_64
select EDAC_ATOMIC_SCRUB
select EDAC_SUPPORT
select GENERIC_CLOCKEVENTS
diff --git a/arch/x86/include/asm/dynamic_debug.h b/arch/x86/include/asm/dynamic_debug.h
new file mode 100644
index 000000000000..350ef6e2feff
--- /dev/null
+++ b/arch/x86/include/asm/dynamic_debug.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_DYNAMIC_DEBUG_H
+#define _ASM_X86_DYNAMIC_DEBUG_H
+
+#ifdef HAVE_JUMP_LABEL
+# ifdef DEBUG
+# define _DPRINTK_ASM_KEY_INIT ASM_STATIC_KEY_INIT_TRUE
+# else
+# define _DPRINTK_ASM_KEY_INIT ASM_STATIC_KEY_INIT_FALSE
+# endif
+#else
+# define _DPRINTK_ASM_KEY_INIT ""
+#endif
+
+#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
+ extern struct _ddebug name; \
+ asm volatile(".ifndef " __stringify(name) "\n" \
+ ".pushsection __verbose,\"aw\"\n" \
+ "1:\n" \
+ __stringify(name) ":\n" \
+ "\t.long %c0 - 1b \t# _ddebug::modname_disp\n" \
+ "\t.long %c1 - 1b \t# _ddebug::function_disp\n" \
+ "\t.long %c2 - 1b \t# _ddebug::filename_disp\n" \
+ "\t.long %c3 - 1b \t# _ddebug::format_disp\n" \
+ "\t.long %c4 \t# _ddebug::flags_lineno\n" \
+ "\t.long 0 \t# <padding>\n" \
+ _DPRINTK_ASM_KEY_INIT \
+ ".popsection\n" \
+ ".endif\n" \
+ : : "i" (KBUILD_MODNAME), "i" (__func__), \
+ "i" (__FILE__), "i" (fmt), \
+ "i" (_DPRINTK_FLAGS_LINENO_INIT))
+
+#endif /* _ASM_X86_DYNAMIC_DEBUG_H */
+
--
2.16.4


2018-09-19 22:06:26

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 13/22] dynamic_debug: refactor dynamic_pr_debug and friends

For the upcoming 'define the _ddebug descriptor in assembly', we need
all the descriptors in a translation unit to have distinct
names (because asm does not understand C scope). The easiest way to
achieve that is as usual with an extra level of macros, passing the
identifier to use to the innermost macro, generating it via __UNIQUE_ID
or something.

However, instead of repeating that exercise for dynamic_pr_debug,
dynamic_dev_dbg, dynamic_netdev_dbg and dynamic_hex_dump separately, we
can use the similarity between their bodies to implement them via a
common macro, _dynamic_func_call - though the hex_dump case requires
a slight variant, since print_hex_dump does not take the _ddebug
descriptor. We'll also get to use that variant elsewhere (btrfs).

Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 72 ++++++++++++++++++++++++++-----------------
1 file changed, 43 insertions(+), 29 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 6a002b789d51..b9424097df37 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -112,40 +112,54 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,

#endif

-#define dynamic_pr_debug(fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __dynamic_pr_debug(&descriptor, pr_fmt(fmt), \
- ##__VA_ARGS__); \
+#define __dynamic_func_call(id, fmt, func, ...) do { \
+ DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
+ if (DYNAMIC_DEBUG_BRANCH(id)) \
+ func(&id, ##__VA_ARGS__); \
} while (0)

-#define dynamic_dev_dbg(dev, fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __dynamic_dev_dbg(&descriptor, dev, fmt, \
- ##__VA_ARGS__); \
+#define __dynamic_func_call_no_desc(id, fmt, func, ...) do { \
+ DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
+ if (DYNAMIC_DEBUG_BRANCH(id)) \
+ func(__VA_ARGS__); \
} while (0)

-#define dynamic_netdev_dbg(dev, fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __dynamic_netdev_dbg(&descriptor, dev, fmt, \
- ##__VA_ARGS__); \
-} while (0)
+/*
+ * "Factory macro" for generating a call to func, guarded by a
+ * DYNAMIC_DEBUG_BRANCH. The dynamic debug decriptor will be
+ * initialized using the fmt argument. The function will be called with
+ * the address of the descriptor as first argument, followed by all
+ * the varargs. Note that fmt is repeated in invocations of this
+ * macro.
+ */
+#define _dynamic_func_call(fmt, func, ...) \
+ __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
+/*
+ * A variant that does the same, except that the descriptor is not
+ * passed as the first argument to the function; it is only called
+ * with precisely the macro's varargs.
+ */
+#define _dynamic_func_call_no_desc(fmt, func, ...) \
+ __dynamic_func_call_no_desc(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)

-#define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
- groupsize, buf, len, ascii) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, \
- __builtin_constant_p(prefix_str) ? prefix_str : "hexdump");\
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- print_hex_dump(KERN_DEBUG, prefix_str, \
- prefix_type, rowsize, groupsize, \
- buf, len, ascii); \
-} while (0)
+#define dynamic_pr_debug(fmt, ...) \
+ _dynamic_func_call(fmt, __dynamic_pr_debug, \
+ pr_fmt(fmt), ##__VA_ARGS__)
+
+#define dynamic_dev_dbg(dev, fmt, ...) \
+ _dynamic_func_call(fmt,__dynamic_dev_dbg, \
+ dev, fmt, ##__VA_ARGS__)
+
+#define dynamic_netdev_dbg(dev, fmt, ...) \
+ _dynamic_func_call(fmt, __dynamic_netdev_dbg, \
+ dev, fmt, ##__VA_ARGS__)
+
+#define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
+ groupsize, buf, len, ascii) \
+ _dynamic_func_call_no_desc(__builtin_constant_p(prefix_str) ? prefix_str : "hexdump", \
+ print_hex_dump, \
+ KERN_DEBUG, prefix_str, prefix_type, \
+ rowsize, groupsize, buf, len, ascii)

#else

--
2.16.4


2018-09-19 22:06:26

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 20/22] dynamic_debug: introduce CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS

Based on the same idea for struct bug_entry, an architecture can opt-in
to use relative pointers in struct _ddebug. It only makes sense for 64
bit architectures, where one saves 16 bytes per entry (out of 40 or 56,
depending on CONFIG_JUMP_LABEL). The architecture is responsible for
providing a suitable DEFINE_DYNAMIC_DEBUG_METADATA macro in
<asm/dynamic_debug.h>.

Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 14 ++++++++++++++
lib/Kconfig.debug | 3 +++
lib/dynamic_debug.c | 20 ++++++++++++++++++++
3 files changed, 37 insertions(+)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index e1be30e8422b..cc4222a20aa1 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -16,10 +16,17 @@ struct _ddebug {
* These fields are used to drive the user interface
* for selecting and displaying debug callsites.
*/
+#ifdef CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS
+ signed int modname_disp;
+ signed int function_disp;
+ signed int filename_disp;
+ signed int format_disp;
+#else
const char *modname;
const char *function;
const char *filename;
const char *format;
+#endif
/*
* The flags field controls the behaviour at the callsite.
* The bits here are changed dynamically when the user
@@ -70,6 +77,12 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
const struct net_device *dev,
const char *fmt, ...);

+#ifdef CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS
+#include <asm/dynamic_debug.h>
+#ifndef DEFINE_DYNAMIC_DEBUG_METADATA
+# error "asm/dynamic_debug.h must provide definition of DEFINE_DYNAMIC_DEBUG_METADATA"
+#endif
+#else
#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
static struct _ddebug __aligned(8) \
__attribute__((section("__verbose"))) name = { \
@@ -80,6 +93,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
.flags_lineno = _DPRINTK_FLAGS_LINENO_INIT, \
_DPRINTK_KEY_INIT \
}
+#endif

#ifdef HAVE_JUMP_LABEL

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 4966c4fbe7f7..a4113f746826 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -146,6 +146,9 @@ config DYNAMIC_DEBUG
See Documentation/admin-guide/dynamic-debug-howto.rst for additional
information.

+config DYNAMIC_DEBUG_RELATIVE_POINTERS
+ bool
+
endmenu # "printk and dmesg options"

menu "Compile-time checks and compiler options"
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 9d4c840ff0de..61e61b36e479 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -37,6 +37,24 @@
#include <linux/device.h>
#include <linux/netdevice.h>

+#ifdef CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS
+static inline const char *dd_modname(const struct _ddebug *dd)
+{
+ return (const char *)dd + dd->modname_disp;
+}
+static inline const char *dd_function(const struct _ddebug *dd)
+{
+ return (const char *)dd + dd->function_disp;
+}
+static inline const char *dd_filename(const struct _ddebug *dd)
+{
+ return (const char *)dd + dd->filename_disp;
+}
+static inline const char *dd_format(const struct _ddebug *dd)
+{
+ return (const char *)dd + dd->format_disp;
+}
+#else
static inline const char *dd_modname(const struct _ddebug *dd)
{
return dd->modname;
@@ -53,6 +71,8 @@ static inline const char *dd_format(const struct _ddebug *dd)
{
return dd->format;
}
+#endif
+
static inline unsigned dd_lineno(const struct _ddebug *dd)
{
return dd->flags_lineno >> 8;
--
2.16.4


2018-09-19 22:06:28

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 19/22] dynamic_debug: drop use of bitfields in struct _ddebug

Properly initializing a struct containing bitfields in assembly is
hard. Instead, merge lineno and flags to a single unsigned int, which we
mask manually. This should not cause any worse code than what gcc would
need to generate for accessing the bitfields anyway.

Actually, on 64 bit, there is a four byte hole after these fields, so we
could just give flags and lineno each their own u32. But I don't think
that's worth the ifdeffery.

Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 12 +++++-------
lib/dynamic_debug.c | 44 ++++++++++++++++++++++++++++---------------
2 files changed, 34 insertions(+), 22 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index b9424097df37..e1be30e8422b 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -20,7 +20,6 @@ struct _ddebug {
const char *function;
const char *filename;
const char *format;
- unsigned int lineno:18;
/*
* The flags field controls the behaviour at the callsite.
* The bits here are changed dynamically when the user
@@ -37,7 +36,7 @@ struct _ddebug {
#else
#define _DPRINTK_FLAGS_DEFAULT 0
#endif
- unsigned int flags:8;
+ unsigned int flags_lineno; /* flags in lower 8 bits, lineno in upper 24 */
#ifdef HAVE_JUMP_LABEL
union {
struct static_key_true dd_key_true;
@@ -46,7 +45,7 @@ struct _ddebug {
#endif
} __attribute__((aligned(8)));

-
+#define _DPRINTK_FLAGS_LINENO_INIT (((unsigned)__LINE__ << 8) | _DPRINTK_FLAGS_DEFAULT)

#if defined(CONFIG_DYNAMIC_DEBUG)
int ddebug_add_module(struct _ddebug *tab, unsigned int n,
@@ -78,8 +77,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
.function = __func__, \
.filename = __FILE__, \
.format = (fmt), \
- .lineno = __LINE__, \
- .flags = _DPRINTK_FLAGS_DEFAULT, \
+ .flags_lineno = _DPRINTK_FLAGS_LINENO_INIT, \
_DPRINTK_KEY_INIT \
}

@@ -104,10 +102,10 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,

#ifdef DEBUG
#define DYNAMIC_DEBUG_BRANCH(descriptor) \
- likely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
+ likely(descriptor.flags_lineno & _DPRINTK_FLAGS_PRINT)
#else
#define DYNAMIC_DEBUG_BRANCH(descriptor) \
- unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
+ unlikely(descriptor.flags_lineno & _DPRINTK_FLAGS_PRINT)
#endif

#endif
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index dbd837f486f9..9d4c840ff0de 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -53,6 +53,18 @@ static inline const char *dd_format(const struct _ddebug *dd)
{
return dd->format;
}
+static inline unsigned dd_lineno(const struct _ddebug *dd)
+{
+ return dd->flags_lineno >> 8;
+}
+static inline unsigned dd_flags(const struct _ddebug *dd)
+{
+ return dd->flags_lineno & 0xff;
+}
+static inline void dd_set_flags(struct _ddebug *dd, unsigned newflags)
+{
+ dd->flags_lineno = (dd_lineno(dd) << 8) | newflags;
+}

extern struct _ddebug __start___verbose[];
extern struct _ddebug __stop___verbose[];
@@ -111,7 +123,7 @@ static char *ddebug_describe_flags(struct _ddebug *dp, char *buf,

BUG_ON(maxlen < 6);
for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
- if (dp->flags & opt_array[i].flag)
+ if (dd_flags(dp) & opt_array[i].flag)
*p++ = opt_array[i].opt_char;
if (p == buf)
*p++ = '_';
@@ -157,7 +169,7 @@ static int ddebug_change(const struct ddebug_query *query,
{
int i;
struct ddebug_table *dt;
- unsigned int newflags;
+ unsigned int newflags, oldflags;
unsigned int nfound = 0;
char flagbuf[10];

@@ -194,27 +206,28 @@ static int ddebug_change(const struct ddebug_query *query,

/* match against the line number range */
if (query->first_lineno &&
- dp->lineno < query->first_lineno)
+ dd_lineno(dp) < query->first_lineno)
continue;
if (query->last_lineno &&
- dp->lineno > query->last_lineno)
+ dd_lineno(dp) > query->last_lineno)
continue;

nfound++;

- newflags = (dp->flags & mask) | flags;
- if (newflags == dp->flags)
+ oldflags = dd_flags(dp);
+ newflags = (oldflags & mask) | flags;
+ if (newflags == oldflags)
continue;
#ifdef HAVE_JUMP_LABEL
- if (dp->flags & _DPRINTK_FLAGS_PRINT) {
+ if (oldflags & _DPRINTK_FLAGS_PRINT) {
if (!(flags & _DPRINTK_FLAGS_PRINT))
static_branch_disable(&dp->key.dd_key_true);
} else if (flags & _DPRINTK_FLAGS_PRINT)
static_branch_enable(&dp->key.dd_key_true);
#endif
- dp->flags = newflags;
+ dd_set_flags(dp, newflags);
vpr_info("changed %s:%d [%s]%s =%s\n",
- trim_prefix(dd_filename(dp)), dp->lineno,
+ trim_prefix(dd_filename(dp)), dd_lineno(dp),
dt->mod_name, dd_function(dp),
ddebug_describe_flags(dp, flagbuf,
sizeof(flagbuf)));
@@ -537,10 +550,11 @@ static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
{
int pos_after_tid;
int pos = 0;
+ unsigned flags = dd_flags(desc);

*buf = '\0';

- if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
+ if (flags & _DPRINTK_FLAGS_INCL_TID) {
if (in_interrupt())
pos += snprintf(buf + pos, remaining(pos), "<intr> ");
else
@@ -548,15 +562,15 @@ static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
task_pid_vnr(current));
}
pos_after_tid = pos;
- if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
+ if (flags & _DPRINTK_FLAGS_INCL_MODNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
dd_modname(desc));
- if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
+ if (flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
dd_function(desc));
- if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
+ if (flags & _DPRINTK_FLAGS_INCL_LINENO)
pos += snprintf(buf + pos, remaining(pos), "%d:",
- desc->lineno);
+ dd_lineno(desc));
if (pos - pos_after_tid)
pos += snprintf(buf + pos, remaining(pos), " ");
if (pos >= PREFIX_SIZE)
@@ -807,7 +821,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
}

seq_printf(m, "%s:%u [%s]%s =%s \"",
- trim_prefix(dd_filename(dp)), dp->lineno,
+ trim_prefix(dd_filename(dp)), dd_lineno(dp),
iter->table->mod_name, dd_function(dp),
ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
seq_escape(m, dd_format(dp), "\t\r\n\"");
--
2.16.4


2018-09-19 22:06:34

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 21/22] x86: jump_label: introduce ASM_STATIC_KEY_INIT_{TRUE,FALSE}

These will be useful when defining the contents of (a struct containing)
a static key in inline assembly.

Cc: [email protected]
Signed-off-by: Rasmus Villemoes <[email protected]>
---
arch/x86/include/asm/jump_label.h | 18 ++++++++++++++++++
include/linux/jump_label.h | 2 ++
2 files changed, 20 insertions(+)

diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h
index 8c0de4282659..2736f7ff6806 100644
--- a/arch/x86/include/asm/jump_label.h
+++ b/arch/x86/include/asm/jump_label.h
@@ -110,4 +110,22 @@ struct jump_entry {

#endif /* __ASSEMBLY__ */

+#ifdef CONFIG_X86_64
+#define ASM_STATIC_KEY_INIT_TRUE \
+ "\t.long 1 \t# .enabled\n" \
+ "\t.long 0 \t# <padding>\n" \
+ "\t.quad "__stringify(__JUMP_TYPE_TRUE)"\t# .type\n"
+#define ASM_STATIC_KEY_INIT_FALSE \
+ "\t.long 0 \t# .enabled\n" \
+ "\t.long 0 \t# <padding>\n" \
+ "\t.quad "__stringify(__JUMP_TYPE_FALSE)"\t# .type\n"
+#else
+#define ASM_STATIC_KEY_INIT_TRUE \
+ "\t.long 1 \t# .enabled\n" \
+ "\t.long "__stringify(__JUMP_TYPE_TRUE)"\t# .type\n"
+#define ASM_STATIC_KEY_INIT_FALSE \
+ "\t.long 0 \t# .enabled\n" \
+ "\t.long "__stringify(__JUMP_TYPE_FALSE)"\t# .type\n"
+#endif
+
#endif
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index 1a0b6f17a5d6..6e98193ae708 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -132,6 +132,8 @@ struct module;

#ifdef HAVE_JUMP_LABEL

+#define __JUMP_TYPE_FALSE 0
+#define __JUMP_TYPE_TRUE 1
#define JUMP_TYPE_FALSE 0UL
#define JUMP_TYPE_TRUE 1UL
#define JUMP_TYPE_LINKED 2UL
--
2.16.4


2018-09-19 22:06:40

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 14/22] btrfs: implement btrfs_debug* in terms of helper macro

First, the btrfs_debug macros open-code (one possible definition of)
DYNAMIC_DEBUG_BRANCH, so they don't benefit from the HAVE_JUMP_LABEL
optimization.

Second, changes on x86-64 later in this series require that all struct
_ddebug descriptors in a translation unit use distinct identifiers.

Using the new _dynamic_func_call_no_desc helper macro from
dynamic_debug.h takes care of both of these.

Cc: [email protected]
Signed-off-by: Rasmus Villemoes <[email protected]>
---
fs/btrfs/ctree.h | 34 ++++++++++------------------------
1 file changed, 10 insertions(+), 24 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 2cddfe7806a4..7ae6cdad5b38 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3353,31 +3353,17 @@ void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...);

#if defined(CONFIG_DYNAMIC_DEBUG)
#define btrfs_debug(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk(fs_info, KERN_DEBUG fmt, ##args); \
-} while (0)
-#define btrfs_debug_in_rcu(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk_in_rcu(fs_info, KERN_DEBUG fmt, ##args); \
-} while (0)
+ _dynamic_func_call_no_desc(fmt, btrfs_printk, \
+ fs_info, KERN_DEBUG fmt, ##args)
+#define btrfs_debug_in_rcu(fs_info, fmt, args...) \
+ _dynamic_func_call_no_desc(fmt, btrfs_printk_in_rcu, \
+ fs_info, KERN_DEBUG fmt, ##args)
#define btrfs_debug_rl_in_rcu(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk_rl_in_rcu(fs_info, KERN_DEBUG fmt, \
- ##args);\
-} while (0)
-#define btrfs_debug_rl(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk_ratelimited(fs_info, KERN_DEBUG fmt, \
- ##args); \
-} while (0)
+ _dynamic_func_call_no_desc(fmt, btrfs_printk_rl_in_rcu, \
+ fs_info, KERN_DEBUG fmt, ##args)
+#define btrfs_debug_rl(fs_info, fmt, args...) \
+ _dynamic_func_call_no_desc(fmt, btrfs_printk_ratelimited, \
+ fs_info, KERN_DEBUG fmt, ##args)
#elif defined(DEBUG)
#define btrfs_debug(fs_info, fmt, args...) \
btrfs_printk(fs_info, KERN_DEBUG fmt, ##args)
--
2.16.4


2018-09-19 22:06:59

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 09/22] dynamic_debug: use pointer comparison in ddebug_remove_module

Now that we store the passed-in string directly in ddebug_add_module, we
can use pointer equality instead of strcmp. This is a little more
efficient, but more importantly, this also makes the code somewhat more
correct:

Currently, if one loads and then unloads a module whose name happens to
match the KBUILD_MODNAME of some built-in functionality (which need not
even be modular at all), all of their dynamic debug entries vanish along
with those of the actual module. For example, loading and unloading a
core.ko hides all pr_debugs from drivers/base/core.c and other built-in
files called core.c (incidentally, there is an in-tree module whose name
is core, but I just tested this with an out-of-tree trivial one).

Signed-off-by: Rasmus Villemoes <[email protected]>
---
lib/dynamic_debug.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 2155e0e23530..ab81155f928d 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -929,9 +929,10 @@ int ddebug_remove_module(const char *mod_name)

mutex_lock(&ddebug_lock);
list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
- if (!strcmp(dt->mod_name, mod_name)) {
+ if (dt->mod_name == mod_name) {
ddebug_table_free(dt);
ret = 0;
+ break;
}
}
mutex_unlock(&ddebug_lock);
--
2.16.4


2018-09-19 22:06:56

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 11/22] dynamic_debug: move pr_err from module.c to ddebug_add_module

This serves two purposes: First, we get a diagnostic if (though
extremely unlikely), any of the calls of ddebug_add_module for built-in
code fails, effectively disabling dynamic_debug. Second, I want to make
struct _ddebug opaque, and avoid accessing any of its members outside
dynamic_debug.[ch].

Signed-off-by: Rasmus Villemoes <[email protected]>
---
kernel/module.c | 4 +---
lib/dynamic_debug.c | 4 +++-
2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index 6746c85511fe..381f9bf282fe 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2716,9 +2716,7 @@ static void dynamic_debug_setup(struct module *mod, struct _ddebug *debug, unsig
if (!debug)
return;
#ifdef CONFIG_DYNAMIC_DEBUG
- if (ddebug_add_module(debug, num, mod->name))
- pr_err("dynamic debug error adding module: %s\n",
- debug->modname);
+ ddebug_add_module(debug, num, mod->name);
#endif
}

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index f1de45a100fa..e90459dca34b 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -849,8 +849,10 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
struct ddebug_table *dt;

dt = kzalloc(sizeof(*dt), GFP_KERNEL);
- if (dt == NULL)
+ if (dt == NULL) {
+ pr_err("error adding module: %s\n", name);
return -ENOMEM;
+ }
/*
* For built-in modules, name lives in .rodata and is
* immortal. For loaded modules, name points at the name[]
--
2.16.4


2018-09-19 22:07:02

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 10/22] dynamic_debug: remove unused EXPORT_SYMBOLs

The only caller of ddebug_{add,remove}_module outside dynamic_debug.c is
kernel/module.c, which is obviously not itself modular (though it would
be an interesting exercise to make that happen...). I also fail to see
how these interfaces can be used by modules, in-tree or not.

Signed-off-by: Rasmus Villemoes <[email protected]>
---
lib/dynamic_debug.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index ab81155f928d..f1de45a100fa 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -868,7 +868,6 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
vpr_info("%u debug prints in module %s\n", n, dt->mod_name);
return 0;
}
-EXPORT_SYMBOL_GPL(ddebug_add_module);

/* helper for ddebug_dyndbg_(boot|module)_param_cb */
static int ddebug_dyndbg_param_cb(char *param, char *val,
@@ -938,7 +937,6 @@ int ddebug_remove_module(const char *mod_name)
mutex_unlock(&ddebug_lock);
return ret;
}
-EXPORT_SYMBOL_GPL(ddebug_remove_module);

static void ddebug_remove_all_tables(void)
{
--
2.16.4


2018-09-19 22:07:18

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 07/22] dynamic_debug: consolidate DEFINE_DYNAMIC_DEBUG_METADATA definitions

Instead of defining DEFINE_DYNAMIC_DEBUG_METADATA in terms of a helper
DEFINE_DYNAMIC_DEBUG_METADATA_KEY, that needs another helper
dd_key_init to be properly defined, just make the various #ifdef
branches define a _DPRINTK_KEY_INIT that can be used directly, similar
to _DPRINTK_FLAGS_DEFAULT.

Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 22 +++++++---------------
1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 2fd8006153c3..0a643316597c 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -71,7 +71,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
const struct net_device *dev,
const char *fmt, ...);

-#define DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, key, init) \
+#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
static struct _ddebug __aligned(8) \
__attribute__((section("__verbose"))) name = { \
.modname = KBUILD_MODNAME, \
@@ -80,35 +80,27 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
.format = (fmt), \
.lineno = __LINE__, \
.flags = _DPRINTK_FLAGS_DEFAULT, \
- dd_key_init(key, init) \
+ _DPRINTK_KEY_INIT \
}

#ifdef HAVE_JUMP_LABEL

-#define dd_key_init(key, init) key = (init)
-
#ifdef DEBUG
-#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
- DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_true, \
- (STATIC_KEY_TRUE_INIT))
+
+#define _DPRINTK_KEY_INIT .key.dd_key_true = (STATIC_KEY_TRUE_INIT)

#define DYNAMIC_DEBUG_BRANCH(descriptor) \
static_branch_likely(&descriptor.key.dd_key_true)
#else
-#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
- DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_false, \
- (STATIC_KEY_FALSE_INIT))
+#define _DPRINTK_KEY_INIT .key.dd_key_false = (STATIC_KEY_FALSE_INIT)

#define DYNAMIC_DEBUG_BRANCH(descriptor) \
static_branch_unlikely(&descriptor.key.dd_key_false)
#endif

-#else
-
-#define dd_key_init(key, init)
+#else /* !HAVE_JUMP_LABEL */

-#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
- DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, 0, 0)
+#define _DPRINTK_KEY_INIT

#ifdef DEBUG
#define DYNAMIC_DEBUG_BRANCH(descriptor) \
--
2.16.4


2018-09-19 22:07:23

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 05/22] linux/printk.h: use DYNAMIC_DEBUG_BRANCH in pr_debug_ratelimited

pr_debug_ratelimited tests the dynamic debug descriptor the old-fashioned
way, and doesn't utilize the static key/jump label implementation on
architectures that HAVE_JUMP_LABEL. Use the DYNAMIC_DEBUG_BRANCH which
is defined appropriately.

Cc: Petr Mladek <[email protected]>
Cc: Steven Rostedt <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/printk.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index cf3eccfe1543..d3ba3245531d 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -466,7 +466,7 @@ do { \
DEFAULT_RATELIMIT_INTERVAL, \
DEFAULT_RATELIMIT_BURST); \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, pr_fmt(fmt)); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
__ratelimit(&_rs)) \
__dynamic_pr_debug(&descriptor, pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
--
2.16.4


2018-09-19 22:07:26

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 08/22] dynamic_debug: don't duplicate modname in ddebug_add_module

For built-in modules, we're already reusing the passed-in string via
kstrdup_const(). But for actual modules (i.e. when we're called from
dynamic_debug_setup in module.c), the passed-in string (which points
at the name[] array inside struct module) is also
guaranteed to live at least as long as the struct ddebug_table, since
free_module() calls ddebug_remove_module().

Signed-off-by: Rasmus Villemoes <[email protected]>
---
lib/dynamic_debug.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index c7c96bc7654a..2155e0e23530 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -847,17 +847,17 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
const char *name)
{
struct ddebug_table *dt;
- const char *new_name;

dt = kzalloc(sizeof(*dt), GFP_KERNEL);
if (dt == NULL)
return -ENOMEM;
- new_name = kstrdup_const(name, GFP_KERNEL);
- if (new_name == NULL) {
- kfree(dt);
- return -ENOMEM;
- }
- dt->mod_name = new_name;
+ /*
+ * For built-in modules, name lives in .rodata and is
+ * immortal. For loaded modules, name points at the name[]
+ * member of struct module, which lives at least as long as
+ * this struct ddebug_table.
+ */
+ dt->mod_name = name;
dt->num_ddebugs = n;
dt->ddebugs = tab;

@@ -913,7 +913,6 @@ int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
static void ddebug_table_free(struct ddebug_table *dt)
{
list_del_init(&dt->link);
- kfree_const(dt->mod_name);
kfree(dt);
}

--
2.16.4


2018-09-19 22:07:27

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 06/22] linux/printk.h: use unique identifier for each struct _ddebug

Changes on x86-64 later in this series require that all struct _ddebug
descriptors in a translation unit uses distinct identifiers. Realize
that for pr_debug_ratelimited by generating such an identifier via
__UNIQUE_ID and pass that to an extra level of macros.

No functional change.

Cc: Petr Mladek <[email protected]>
Cc: Steven Rostedt <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/printk.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index d3ba3245531d..70df2c578d40 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -460,7 +460,7 @@ extern int kptr_restrict;
/* If you are writing a driver, please use dev_dbg instead */
#if defined(CONFIG_DYNAMIC_DEBUG)
/* descriptor check is first to prevent flooding with "callbacks suppressed" */
-#define pr_debug_ratelimited(fmt, ...) \
+#define _pr_debug_ratelimited(descriptor, fmt, ...) \
do { \
static DEFINE_RATELIMIT_STATE(_rs, \
DEFAULT_RATELIMIT_INTERVAL, \
@@ -470,6 +470,8 @@ do { \
__ratelimit(&_rs)) \
__dynamic_pr_debug(&descriptor, pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
+#define pr_debug_ratelimited(fmt, ...) \
+ _pr_debug_ratelimited(__UNIQUE_ID(ddebug), fmt, ##__VA_ARGS__)
#elif defined(DEBUG)
#define pr_debug_ratelimited(fmt, ...) \
printk_ratelimited(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
--
2.16.4


2018-09-19 22:07:48

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 03/22] linux/net.h: use DYNAMIC_DEBUG_BRANCH in net_dbg_ratelimited

net_dbg_ratelimited tests the dynamic debug descriptor the old-fashioned
way, and doesn't utilize the static key/jump label implementation on
architectures that HAVE_JUMP_LABEL. Use the DYNAMIC_DEBUG_BRANCH which
is defined appropriately.

Cc: [email protected]
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/net.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/net.h b/include/linux/net.h
index e0930678c8bf..651fca72286c 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -263,7 +263,7 @@ do { \
#define net_dbg_ratelimited(fmt, ...) \
do { \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
net_ratelimit()) \
__dynamic_pr_debug(&descriptor, pr_fmt(fmt), \
##__VA_ARGS__); \
--
2.16.4


2018-09-19 22:07:57

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 01/22] linux/device.h: use DYNAMIC_DEBUG_BRANCH in dev_dbg_ratelimited

dev_dbg_ratelimited tests the dynamic debug descriptor the old-fashioned
way, and doesn't utilize the static key/jump label implementation on
architectures that HAVE_JUMP_LABEL. Use the DYNAMIC_DEBUG_BRANCH which
is defined appropriately.

Cc: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/device.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/device.h b/include/linux/device.h
index 8f882549edee..0d8ed2adfc73 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1503,7 +1503,7 @@ do { \
DEFAULT_RATELIMIT_INTERVAL, \
DEFAULT_RATELIMIT_BURST); \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
__ratelimit(&_rs)) \
__dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \
##__VA_ARGS__); \
--
2.16.4


2018-09-19 22:07:58

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 04/22] linux/net.h: use unique identifier for each struct _ddebug

Changes on x86-64 later in this series require that all struct _ddebug
descriptors in a translation unit uses distinct identifiers. Realize
that for net_dbg_ratelimited by generating such an identifier via
__UNIQUE_ID and pass that to an extra level of macros.

No functional change.

Cc: [email protected]
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/net.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/net.h b/include/linux/net.h
index 651fca72286c..397243a25f56 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -260,7 +260,7 @@ do { \
#define net_info_ratelimited(fmt, ...) \
net_ratelimited_function(pr_info, fmt, ##__VA_ARGS__)
#if defined(CONFIG_DYNAMIC_DEBUG)
-#define net_dbg_ratelimited(fmt, ...) \
+#define _net_dbg_ratelimited(descriptor, fmt, ...) \
do { \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
@@ -268,6 +268,8 @@ do { \
__dynamic_pr_debug(&descriptor, pr_fmt(fmt), \
##__VA_ARGS__); \
} while (0)
+#define net_dbg_ratelimited(fmt, ...) \
+ _net_dbg_ratelimited(__UNIQUE_ID(ddebug), fmt, ##__VA_ARGS__)
#elif defined(DEBUG)
#define net_dbg_ratelimited(fmt, ...) \
net_ratelimited_function(pr_debug, fmt, ##__VA_ARGS__)
--
2.16.4


2018-09-19 22:08:03

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 02/22] linux/device.h: use unique identifier for each struct _ddebug

Changes on x86-64 later in this series require that all struct _ddebug
descriptors in a translation unit uses distinct identifiers. Realize
that for dev_dbg_ratelimited by generating such an identifier via
__UNIQUE_ID and pass that to an extra level of macros.

No functional change.

Cc: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/device.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/device.h b/include/linux/device.h
index 0d8ed2adfc73..81108db013e4 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1497,7 +1497,7 @@ do { \
dev_level_ratelimited(dev_info, dev, fmt, ##__VA_ARGS__)
#if defined(CONFIG_DYNAMIC_DEBUG)
/* descriptor check is first to prevent flooding with "callbacks suppressed" */
-#define dev_dbg_ratelimited(dev, fmt, ...) \
+#define _dev_dbg_ratelimited(descriptor, dev, fmt, ...) \
do { \
static DEFINE_RATELIMIT_STATE(_rs, \
DEFAULT_RATELIMIT_INTERVAL, \
@@ -1508,6 +1508,8 @@ do { \
__dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \
##__VA_ARGS__); \
} while (0)
+#define dev_dbg_ratelimited(dev, fmt, ...) \
+ _dev_dbg_ratelimited(__UNIQUE_ID(ddebug), dev, fmt, ##__VA_ARGS__)
#elif defined(DEBUG)
#define dev_dbg_ratelimited(dev, fmt, ...) \
do { \
--
2.16.4


2018-09-20 08:09:30

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH 00/22] various dynamic_debug patches

On Thursday, September 20, 2018 12:04:22 AM CEST Rasmus Villemoes wrote:
> This started as an experiment to see how hard it would be to change
> the four pointers in struct _ddebug into relative offsets, a la
> CONFIG_GENERIC_BUG_RELATIVE_POINTERS, thus saving 16 bytes per
> pr_debug site (and thus exactly making up for the extra space used by
> the introduction of jump labels in 9049fc74). I stumbled on a few
> things that are probably worth fixing regardless of whether the latter
> half of this series is deemed worthwhile.
>
> Patch relationships: 1-2, 3-4, 5-6 and 15-16 can be applied
> individually, though 2, 4 and 6 probably makes most sense in the
> context of the final goal of the series.

OK, I can take the [15-16/22] separately.

Thanks,
Rafael


2018-09-20 08:10:22

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH 17/22] ACPI: implement acpi_handle_debug in terms of _dynamic_func_call

On Thursday, September 20, 2018 12:04:39 AM CEST Rasmus Villemoes wrote:
> With coming changes on x86-64, all dynamic debug descriptors in a
> translation unit must have distinct names. The macro _dynamic_func_call
> takes care of that. No functional change.
>
> Cc: [email protected]
> Signed-off-by: Rasmus Villemoes <[email protected]>
> ---
> include/linux/acpi.h | 8 ++------
> 1 file changed, 2 insertions(+), 6 deletions(-)
>
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index e12d5ef1a054..83bacf9039e9 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -977,12 +977,8 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
> #else
> #if defined(CONFIG_DYNAMIC_DEBUG)
> #define acpi_handle_debug(handle, fmt, ...) \
> -do { \
> - DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
> - if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
> - __acpi_handle_debug(&descriptor, handle, pr_fmt(fmt), \
> - ##__VA_ARGS__); \
> -} while (0)
> + _dynamic_func_call(fmt, __acpi_handle_debug, \
> + handle, pr_fmt(fmt), ##__VA_ARGS__)
> #else
> #define acpi_handle_debug(handle, fmt, ...) \
> ({ \
>

Acked-by: Rafael J. Wysocki <[email protected]>



2018-09-20 08:48:40

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH 01/22] linux/device.h: use DYNAMIC_DEBUG_BRANCH in dev_dbg_ratelimited

On Thu, Sep 20, 2018 at 12:04:23AM +0200, Rasmus Villemoes wrote:
> dev_dbg_ratelimited tests the dynamic debug descriptor the old-fashioned
> way, and doesn't utilize the static key/jump label implementation on
> architectures that HAVE_JUMP_LABEL. Use the DYNAMIC_DEBUG_BRANCH which
> is defined appropriately.
>
> Cc: Greg Kroah-Hartman <[email protected]>
> Signed-off-by: Rasmus Villemoes <[email protected]>

Reviewed-by: Greg Kroah-Hartman <[email protected]>

2018-09-20 08:49:33

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH 02/22] linux/device.h: use unique identifier for each struct _ddebug

On Thu, Sep 20, 2018 at 12:04:24AM +0200, Rasmus Villemoes wrote:
> Changes on x86-64 later in this series require that all struct _ddebug
> descriptors in a translation unit uses distinct identifiers. Realize
> that for dev_dbg_ratelimited by generating such an identifier via
> __UNIQUE_ID and pass that to an extra level of macros.
>
> No functional change.
>
> Cc: Greg Kroah-Hartman <[email protected]>
> Signed-off-by: Rasmus Villemoes <[email protected]>

Reviewed-by: Greg Kroah-Hartman <[email protected]>

2018-09-20 10:57:24

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH 23/22] x86: dynamic_debug: protect against dynamic debug identifier reuse

Most invocations of DEFINE_DYNAMIC_DEBUG_METADATA happen through
"public" macros such as pr_debug or netdev_dbg, which have been updated
to ensure they pass a unique identifier to use as the name for the
struct _ddebug instance. But it is still possible that someone invokes
DEFINE_DYNAMIC_DEBUG_METADATA directly, or creates a new wrapper macro
that does not do the extra-level-of-macros-passing-on-a__UNIQUE_ID
dance. On x86-64, all subsequent uses of that same identifier would
silently reuse the first instance, which is bad.

But we can catch such cases by defining a guard symbol that is unique
per expansion of DEFINE_DYNAMIC_DEBUG_METADATA. This still allows gcc to
emit multiple copies of some static inline function that has a pr_debug
call (because all such copies would pass the same value of %5 to the
assembler), but prevents repeated naked
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, "bla") - even with a helpful
error message saying that '"descriptor" used as _ddebug identifer more
than once'.

Cc: [email protected]
Signed-off-by: Rasmus Villemoes <[email protected]>
---
Just in case it wasn't already ugly enough ;)

arch/x86/include/asm/dynamic_debug.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/dynamic_debug.h b/arch/x86/include/asm/dynamic_debug.h
index 350ef6e2feff..69167f40482c 100644
--- a/arch/x86/include/asm/dynamic_debug.h
+++ b/arch/x86/include/asm/dynamic_debug.h
@@ -26,10 +26,15 @@
"\t.long 0 \t# <padding>\n" \
_DPRINTK_ASM_KEY_INIT \
".popsection\n" \
+ ".set "__stringify(name)".ddebug.once, %c5\n" \
+ ".elseif "__stringify(name)".ddebug.once - %c5\n" \
+ ".line "__stringify(__LINE__) " - 1\n" \
+ ".error \"'"__stringify(name)"' used as _ddebug identifier more than once\"\n" \
".endif\n" \
: : "i" (KBUILD_MODNAME), "i" (__func__), \
"i" (__FILE__), "i" (fmt), \
- "i" (_DPRINTK_FLAGS_LINENO_INIT))
+ "i" (_DPRINTK_FLAGS_LINENO_INIT), \
+ "i" (__COUNTER__))

#endif /* _ASM_X86_DYNAMIC_DEBUG_H */

--
2.16.4


2018-09-20 13:11:06

by David Sterba

[permalink] [raw]
Subject: Re: [PATCH 14/22] btrfs: implement btrfs_debug* in terms of helper macro

On Thu, Sep 20, 2018 at 12:04:36AM +0200, Rasmus Villemoes wrote:
> First, the btrfs_debug macros open-code (one possible definition of)
> DYNAMIC_DEBUG_BRANCH, so they don't benefit from the HAVE_JUMP_LABEL
> optimization.
>
> Second, changes on x86-64 later in this series require that all struct
> _ddebug descriptors in a translation unit use distinct identifiers.
>
> Using the new _dynamic_func_call_no_desc helper macro from
> dynamic_debug.h takes care of both of these.
>
> Cc: [email protected]
> Signed-off-by: Rasmus Villemoes <[email protected]>

Acked-by: David Sterba <[email protected]>

Per the cover letter, I assume you'll take it through your git tree.

2018-09-20 14:12:58

by Rasmus Villemoes

[permalink] [raw]
Subject: Re: [PATCH 14/22] btrfs: implement btrfs_debug* in terms of helper macro

On 2018-09-20 15:10, David Sterba wrote:
> On Thu, Sep 20, 2018 at 12:04:36AM +0200, Rasmus Villemoes wrote:
>> First, the btrfs_debug macros open-code (one possible definition of)
>> DYNAMIC_DEBUG_BRANCH, so they don't benefit from the HAVE_JUMP_LABEL
>> optimization.
>>
>> Second, changes on x86-64 later in this series require that all struct
>> _ddebug descriptors in a translation unit use distinct identifiers.
>>
>> Using the new _dynamic_func_call_no_desc helper macro from
>> dynamic_debug.h takes care of both of these.
>>
>> Cc: [email protected]
>> Signed-off-by: Rasmus Villemoes <[email protected]>
>
> Acked-by: David Sterba <[email protected]>
>
> Per the cover letter, I assume you'll take it through your git tree.

Thanks. I don't have a git tree feeding to -next myself, but these will
probably be routed through akpm or x86.

Rasmus


2018-09-22 01:16:44

by Jason Baron

[permalink] [raw]
Subject: Re: [PATCH 00/22] various dynamic_debug patches

On 09/19/2018 06:04 PM, Rasmus Villemoes wrote:
> This started as an experiment to see how hard it would be to change
> the four pointers in struct _ddebug into relative offsets, a la
> CONFIG_GENERIC_BUG_RELATIVE_POINTERS, thus saving 16 bytes per
> pr_debug site (and thus exactly making up for the extra space used by
> the introduction of jump labels in 9049fc74). I stumbled on a few
> things that are probably worth fixing regardless of whether the latter
> half of this series is deemed worthwhile.
>
> Patch relationships: 1-2, 3-4, 5-6 and 15-16 can be applied
> individually, though 2, 4 and 6 probably makes most sense in the
> context of the final goal of the series.
>
> 7-12 I believe make sense on their own. Patch 13 again only makes
> sense if we go all the way, and 14 and 17 depend on 13.
>
> 18-21 are more preparatory patches, and finally 22 switch over x86-64
> to use CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS. I've tested that the
> end result boots under virtme and that the dynamic_debug control file
> has the expected contents.
>

I would like to to see all these patches included. Feel free to add:
Acked-by: Jason Baron <[email protected]>

I've been wanting to add DYNAMIC_DEBUG_BRANCH to the
[dev,net,pr].*ratelimited functions. That should reduce the size of the
text as well.

Thanks,

-Jason

2018-09-27 07:52:50

by Petr Mladek

[permalink] [raw]
Subject: Re: [PATCH 05/22] linux/printk.h: use DYNAMIC_DEBUG_BRANCH in pr_debug_ratelimited

On Thu 2018-09-20 00:04:27, Rasmus Villemoes wrote:
> pr_debug_ratelimited tests the dynamic debug descriptor the old-fashioned
> way, and doesn't utilize the static key/jump label implementation on
> architectures that HAVE_JUMP_LABEL. Use the DYNAMIC_DEBUG_BRANCH which
> is defined appropriately.
>
> Cc: Petr Mladek <[email protected]>
> Cc: Steven Rostedt <[email protected]>
> Signed-off-by: Rasmus Villemoes <[email protected]>

Acked-by: Petr Mladek <[email protected]>

It is an independent fix. I am going to take it via printk.git
unless anyone is against it.

Best Regards,
Petr

> ---
> include/linux/printk.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/linux/printk.h b/include/linux/printk.h
> index cf3eccfe1543..d3ba3245531d 100644
> --- a/include/linux/printk.h
> +++ b/include/linux/printk.h
> @@ -466,7 +466,7 @@ do { \
> DEFAULT_RATELIMIT_INTERVAL, \
> DEFAULT_RATELIMIT_BURST); \
> DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, pr_fmt(fmt)); \
> - if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
> + if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
> __ratelimit(&_rs)) \
> __dynamic_pr_debug(&descriptor, pr_fmt(fmt), ##__VA_ARGS__); \
> } while (0)
> --
> 2.16.4
>

2018-09-27 08:24:07

by Petr Mladek

[permalink] [raw]
Subject: Re: [PATCH 06/22] linux/printk.h: use unique identifier for each struct _ddebug

On Thu 2018-09-20 00:04:28, Rasmus Villemoes wrote:
> Changes on x86-64 later in this series require that all struct _ddebug
> descriptors in a translation unit uses distinct identifiers. Realize
> that for pr_debug_ratelimited by generating such an identifier via
> __UNIQUE_ID and pass that to an extra level of macros.
>
> No functional change.
>
> Cc: Petr Mladek <[email protected]>
> Cc: Steven Rostedt <[email protected]>
> Signed-off-by: Rasmus Villemoes <[email protected]>

Acked-by: Petr Mladek <[email protected]>

My understanding is that this patch would go with the other changes
via Andrew's tree.

Best Regards,
Petr

2018-09-27 08:41:50

by Rasmus Villemoes

[permalink] [raw]
Subject: Re: [PATCH 06/22] linux/printk.h: use unique identifier for each struct _ddebug

On 2018-09-27 10:22, Petr Mladek wrote:
> On Thu 2018-09-20 00:04:28, Rasmus Villemoes wrote:
>> Changes on x86-64 later in this series require that all struct _ddebug
>> descriptors in a translation unit uses distinct identifiers. Realize
>> that for pr_debug_ratelimited by generating such an identifier via
>> __UNIQUE_ID and pass that to an extra level of macros.
>>
>> No functional change.
>>
>> Cc: Petr Mladek <[email protected]>
>> Cc: Steven Rostedt <[email protected]>
>> Signed-off-by: Rasmus Villemoes <[email protected]>
>
> Acked-by: Petr Mladek <[email protected]>
>
> My understanding is that this patch would go with the other changes
> via Andrew's tree.

Yes. I'm still waiting for x86 folks to comment on the x86 parts, and if
they get rejected, this patch (and others in the series) become
pointless - unless some other 64 bit arch decides to play along.

Rasmus

2018-10-02 08:21:56

by Rasmus Villemoes

[permalink] [raw]
Subject: Re: [PATCH 21/22] x86: jump_label: introduce ASM_STATIC_KEY_INIT_{TRUE,FALSE}

On 2018-09-20 00:04, Rasmus Villemoes wrote:
> These will be useful when defining the contents of (a struct containing)
> a static key in inline assembly.

May I politely ask someone in the x86 camp to comment on patches
21,22,23 in this series? If the memory savings is deemed
not-worth-the-asm-complexity, a number of preparatory patches become
pointless, and I'd like to figure out which ones I should ask Andrew to
pick up.

Thanks,
Rasmus

2018-10-02 09:50:04

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH 21/22] x86: jump_label: introduce ASM_STATIC_KEY_INIT_{TRUE,FALSE}


* Rasmus Villemoes <[email protected]> wrote:

> These will be useful when defining the contents of (a struct containing)
> a static key in inline assembly.
>
> Cc: [email protected]
> Signed-off-by: Rasmus Villemoes <[email protected]>
> ---
> arch/x86/include/asm/jump_label.h | 18 ++++++++++++++++++
> include/linux/jump_label.h | 2 ++
> 2 files changed, 20 insertions(+)
>
> diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h
> index 8c0de4282659..2736f7ff6806 100644
> --- a/arch/x86/include/asm/jump_label.h
> +++ b/arch/x86/include/asm/jump_label.h
> @@ -110,4 +110,22 @@ struct jump_entry {
>
> #endif /* __ASSEMBLY__ */
>
> +#ifdef CONFIG_X86_64
> +#define ASM_STATIC_KEY_INIT_TRUE \
> + "\t.long 1 \t# .enabled\n" \
> + "\t.long 0 \t# <padding>\n" \
> + "\t.quad "__stringify(__JUMP_TYPE_TRUE)"\t# .type\n"
> +#define ASM_STATIC_KEY_INIT_FALSE \
> + "\t.long 0 \t# .enabled\n" \
> + "\t.long 0 \t# <padding>\n" \
> + "\t.quad "__stringify(__JUMP_TYPE_FALSE)"\t# .type\n"
> +#else
> +#define ASM_STATIC_KEY_INIT_TRUE \
> + "\t.long 1 \t# .enabled\n" \
> + "\t.long "__stringify(__JUMP_TYPE_TRUE)"\t# .type\n"
> +#define ASM_STATIC_KEY_INIT_FALSE \
> + "\t.long 0 \t# .enabled\n" \
> + "\t.long "__stringify(__JUMP_TYPE_FALSE)"\t# .type\n"
> +#endif
> +
> #endif
> diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
> index 1a0b6f17a5d6..6e98193ae708 100644
> --- a/include/linux/jump_label.h
> +++ b/include/linux/jump_label.h
> @@ -132,6 +132,8 @@ struct module;
>
> #ifdef HAVE_JUMP_LABEL
>
> +#define __JUMP_TYPE_FALSE 0
> +#define __JUMP_TYPE_TRUE 1
> #define JUMP_TYPE_FALSE 0UL
> #define JUMP_TYPE_TRUE 1UL
> #define JUMP_TYPE_LINKED 2UL

Looks sane!

Reviewed-by: Ingo Molnar <[email protected]>

Thanks,

Ingo

2018-10-02 09:52:35

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH 22/22] x86_64: use relative pointers with dynamic debug


* Rasmus Villemoes <[email protected]> wrote:

> Similar to how x86_64 uses bug_entry-relative pointers to reduce
> sizeof(struct bug_entry), the same thing can now be done for struct
> _ddebug, saving 16 bytes for each of those (i.e., each pr_debug, dev_dbg
> etc. in a CONFIG_DYNAMIC_DEBUG kernel).
>
> Note the use of .ifndef/.endif in asm to avoid
>
> fs/aio.c:1382: Error: symbol `__UNIQUE_ID_ddebug112' is already defined
>
> This is due to uses of pr_debug et al in functions that get inlined. In
> such a case, __COUNTER__ is obviously only expanded once, but the asm()
> is repeated once for every inlined instance. Letting all instances share
> the same descriptor object is the right thing to do; that is also what
> happens when it is the compiler that defines a static object inside an
> inline(d) function.
>
> Cc: [email protected]
> Signed-off-by: Rasmus Villemoes <[email protected]>
> ---
> arch/x86/Kconfig | 1 +
> arch/x86/include/asm/dynamic_debug.h | 35 +++++++++++++++++++++++++++++++++++
> 2 files changed, 36 insertions(+)
> create mode 100644 arch/x86/include/asm/dynamic_debug.h
>
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 1a0be022f91d..a44168930e52 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -90,6 +90,7 @@ config X86
> select CLOCKSOURCE_WATCHDOG
> select DCACHE_WORD_ACCESS
> select DMA_DIRECT_OPS
> + select DYNAMIC_DEBUG_RELATIVE_POINTERS if X86_64
> select EDAC_ATOMIC_SCRUB
> select EDAC_SUPPORT
> select GENERIC_CLOCKEVENTS
> diff --git a/arch/x86/include/asm/dynamic_debug.h b/arch/x86/include/asm/dynamic_debug.h
> new file mode 100644
> index 000000000000..350ef6e2feff
> --- /dev/null
> +++ b/arch/x86/include/asm/dynamic_debug.h
> @@ -0,0 +1,35 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_X86_DYNAMIC_DEBUG_H
> +#define _ASM_X86_DYNAMIC_DEBUG_H
> +
> +#ifdef HAVE_JUMP_LABEL
> +# ifdef DEBUG
> +# define _DPRINTK_ASM_KEY_INIT ASM_STATIC_KEY_INIT_TRUE
> +# else
> +# define _DPRINTK_ASM_KEY_INIT ASM_STATIC_KEY_INIT_FALSE
> +# endif
> +#else
> +# define _DPRINTK_ASM_KEY_INIT ""
> +#endif
> +
> +#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
> + extern struct _ddebug name; \
> + asm volatile(".ifndef " __stringify(name) "\n" \
> + ".pushsection __verbose,\"aw\"\n" \
> + "1:\n" \
> + __stringify(name) ":\n" \
> + "\t.long %c0 - 1b \t# _ddebug::modname_disp\n" \
> + "\t.long %c1 - 1b \t# _ddebug::function_disp\n" \
> + "\t.long %c2 - 1b \t# _ddebug::filename_disp\n" \
> + "\t.long %c3 - 1b \t# _ddebug::format_disp\n" \
> + "\t.long %c4 \t# _ddebug::flags_lineno\n" \
> + "\t.long 0 \t# <padding>\n" \
> + _DPRINTK_ASM_KEY_INIT \
> + ".popsection\n" \
> + ".endif\n" \
> + : : "i" (KBUILD_MODNAME), "i" (__func__), \
> + "i" (__FILE__), "i" (fmt), \
> + "i" (_DPRINTK_FLAGS_LINENO_INIT))
> +
> +#endif /* _ASM_X86_DYNAMIC_DEBUG_H */
> +

Reviewed-by: Ingo Molnar <[email protected]>

Thanks,

Ingo

2018-10-03 09:29:09

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH 00/22] various dynamic_debug patches

On Thursday, September 20, 2018 10:05:00 AM CEST Rafael J. Wysocki wrote:
> On Thursday, September 20, 2018 12:04:22 AM CEST Rasmus Villemoes wrote:
> > This started as an experiment to see how hard it would be to change
> > the four pointers in struct _ddebug into relative offsets, a la
> > CONFIG_GENERIC_BUG_RELATIVE_POINTERS, thus saving 16 bytes per
> > pr_debug site (and thus exactly making up for the extra space used by
> > the introduction of jump labels in 9049fc74). I stumbled on a few
> > things that are probably worth fixing regardless of whether the latter
> > half of this series is deemed worthwhile.
> >
> > Patch relationships: 1-2, 3-4, 5-6 and 15-16 can be applied
> > individually, though 2, 4 and 6 probably makes most sense in the
> > context of the final goal of the series.
>
> OK, I can take the [15-16/22] separately.

And they have been applied now.

Thanks,
Rafael


2018-10-03 21:41:04

by Rasmus Villemoes

[permalink] [raw]
Subject: Re: [PATCH 22/22] x86_64: use relative pointers with dynamic debug

On 2018-10-02 11:50, Ingo Molnar wrote:
>
> * Rasmus Villemoes <[email protected]> wrote:
>
>> Similar to how x86_64 uses bug_entry-relative pointers to reduce
>> sizeof(struct bug_entry), the same thing can now be done for struct
>> _ddebug, saving 16 bytes for each of those (i.e., each pr_debug, dev_dbg
>> etc. in a CONFIG_DYNAMIC_DEBUG kernel).
>
> Reviewed-by: Ingo Molnar <[email protected]>

Thanks! Can I assume this also applies to the latecomer 23/22, which I
think I'm gonna squash with 22/22? Then I'll resend the series with
various tags included and ask Andrew to pick it up.

Rasmus



2018-10-09 11:22:01

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 20/23] dynamic_debug: introduce CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS

Based on the same idea for struct bug_entry, an architecture can opt-in
to use relative pointers in struct _ddebug. It only makes sense for 64
bit architectures, where one saves 16 bytes per entry (out of 40 or 56,
depending on CONFIG_JUMP_LABEL). The architecture is responsible for
providing a suitable DEFINE_DYNAMIC_DEBUG_METADATA macro in
<asm/dynamic_debug.h>.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 14 ++++++++++++++
lib/Kconfig.debug | 3 +++
lib/dynamic_debug.c | 20 ++++++++++++++++++++
3 files changed, 37 insertions(+)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index e1be30e8422b..cc4222a20aa1 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -16,10 +16,17 @@ struct _ddebug {
* These fields are used to drive the user interface
* for selecting and displaying debug callsites.
*/
+#ifdef CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS
+ signed int modname_disp;
+ signed int function_disp;
+ signed int filename_disp;
+ signed int format_disp;
+#else
const char *modname;
const char *function;
const char *filename;
const char *format;
+#endif
/*
* The flags field controls the behaviour at the callsite.
* The bits here are changed dynamically when the user
@@ -70,6 +77,12 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
const struct net_device *dev,
const char *fmt, ...);

+#ifdef CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS
+#include <asm/dynamic_debug.h>
+#ifndef DEFINE_DYNAMIC_DEBUG_METADATA
+# error "asm/dynamic_debug.h must provide definition of DEFINE_DYNAMIC_DEBUG_METADATA"
+#endif
+#else
#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
static struct _ddebug __aligned(8) \
__attribute__((section("__verbose"))) name = { \
@@ -80,6 +93,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
.flags_lineno = _DPRINTK_FLAGS_LINENO_INIT, \
_DPRINTK_KEY_INIT \
}
+#endif

#ifdef HAVE_JUMP_LABEL

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 4966c4fbe7f7..a4113f746826 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -146,6 +146,9 @@ config DYNAMIC_DEBUG
See Documentation/admin-guide/dynamic-debug-howto.rst for additional
information.

+config DYNAMIC_DEBUG_RELATIVE_POINTERS
+ bool
+
endmenu # "printk and dmesg options"

menu "Compile-time checks and compiler options"
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 9d4c840ff0de..61e61b36e479 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -37,6 +37,24 @@
#include <linux/device.h>
#include <linux/netdevice.h>

+#ifdef CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS
+static inline const char *dd_modname(const struct _ddebug *dd)
+{
+ return (const char *)dd + dd->modname_disp;
+}
+static inline const char *dd_function(const struct _ddebug *dd)
+{
+ return (const char *)dd + dd->function_disp;
+}
+static inline const char *dd_filename(const struct _ddebug *dd)
+{
+ return (const char *)dd + dd->filename_disp;
+}
+static inline const char *dd_format(const struct _ddebug *dd)
+{
+ return (const char *)dd + dd->format_disp;
+}
+#else
static inline const char *dd_modname(const struct _ddebug *dd)
{
return dd->modname;
@@ -53,6 +71,8 @@ static inline const char *dd_format(const struct _ddebug *dd)
{
return dd->format;
}
+#endif
+
static inline unsigned dd_lineno(const struct _ddebug *dd)
{
return dd->flags_lineno >> 8;
--
2.19.1.3.g1d92a00e68


2018-10-09 11:22:12

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 22/23] x86_64: use relative pointers with dynamic debug

Similar to how x86_64 uses bug_entry-relative pointers to reduce
sizeof(struct bug_entry), the same thing can now be done for struct
_ddebug, saving 16 bytes for each of those (i.e., each pr_debug, dev_dbg
etc. in a CONFIG_DYNAMIC_DEBUG kernel).

Note the use of .ifndef/.endif in asm to avoid

fs/aio.c:1382: Error: symbol `__UNIQUE_ID_ddebug112' is already defined

This is due to uses of pr_debug et al in functions that get inlined. In
such a case, __COUNTER__ is obviously only expanded once, but the asm()
is repeated once for every inlined instance. Letting all instances share
the same descriptor object is the right thing to do; that is also what
happens when it is the compiler that defines a static object inside an
inline(d) function.

Cc: [email protected]
Reviewed-by: Ingo Molnar <[email protected]>
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
arch/x86/Kconfig | 1 +
arch/x86/include/asm/dynamic_debug.h | 35 ++++++++++++++++++++++++++++
2 files changed, 36 insertions(+)
create mode 100644 arch/x86/include/asm/dynamic_debug.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 1a0be022f91d..a44168930e52 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -90,6 +90,7 @@ config X86
select CLOCKSOURCE_WATCHDOG
select DCACHE_WORD_ACCESS
select DMA_DIRECT_OPS
+ select DYNAMIC_DEBUG_RELATIVE_POINTERS if X86_64
select EDAC_ATOMIC_SCRUB
select EDAC_SUPPORT
select GENERIC_CLOCKEVENTS
diff --git a/arch/x86/include/asm/dynamic_debug.h b/arch/x86/include/asm/dynamic_debug.h
new file mode 100644
index 000000000000..350ef6e2feff
--- /dev/null
+++ b/arch/x86/include/asm/dynamic_debug.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_DYNAMIC_DEBUG_H
+#define _ASM_X86_DYNAMIC_DEBUG_H
+
+#ifdef HAVE_JUMP_LABEL
+# ifdef DEBUG
+# define _DPRINTK_ASM_KEY_INIT ASM_STATIC_KEY_INIT_TRUE
+# else
+# define _DPRINTK_ASM_KEY_INIT ASM_STATIC_KEY_INIT_FALSE
+# endif
+#else
+# define _DPRINTK_ASM_KEY_INIT ""
+#endif
+
+#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
+ extern struct _ddebug name; \
+ asm volatile(".ifndef " __stringify(name) "\n" \
+ ".pushsection __verbose,\"aw\"\n" \
+ "1:\n" \
+ __stringify(name) ":\n" \
+ "\t.long %c0 - 1b \t# _ddebug::modname_disp\n" \
+ "\t.long %c1 - 1b \t# _ddebug::function_disp\n" \
+ "\t.long %c2 - 1b \t# _ddebug::filename_disp\n" \
+ "\t.long %c3 - 1b \t# _ddebug::format_disp\n" \
+ "\t.long %c4 \t# _ddebug::flags_lineno\n" \
+ "\t.long 0 \t# <padding>\n" \
+ _DPRINTK_ASM_KEY_INIT \
+ ".popsection\n" \
+ ".endif\n" \
+ : : "i" (KBUILD_MODNAME), "i" (__func__), \
+ "i" (__FILE__), "i" (fmt), \
+ "i" (_DPRINTK_FLAGS_LINENO_INIT))
+
+#endif /* _ASM_X86_DYNAMIC_DEBUG_H */
+
--
2.19.1.3.g1d92a00e68


2018-10-09 11:22:17

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 21/23] x86: jump_label: introduce ASM_STATIC_KEY_INIT_{TRUE,FALSE}

These will be useful when defining the contents of (a struct containing)
a static key in inline assembly.

Cc: [email protected]
Reviewed-by: Ingo Molnar <[email protected]>
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
arch/x86/include/asm/jump_label.h | 18 ++++++++++++++++++
include/linux/jump_label.h | 2 ++
2 files changed, 20 insertions(+)

diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h
index 8c0de4282659..2736f7ff6806 100644
--- a/arch/x86/include/asm/jump_label.h
+++ b/arch/x86/include/asm/jump_label.h
@@ -110,4 +110,22 @@ struct jump_entry {

#endif /* __ASSEMBLY__ */

+#ifdef CONFIG_X86_64
+#define ASM_STATIC_KEY_INIT_TRUE \
+ "\t.long 1 \t# .enabled\n" \
+ "\t.long 0 \t# <padding>\n" \
+ "\t.quad "__stringify(__JUMP_TYPE_TRUE)"\t# .type\n"
+#define ASM_STATIC_KEY_INIT_FALSE \
+ "\t.long 0 \t# .enabled\n" \
+ "\t.long 0 \t# <padding>\n" \
+ "\t.quad "__stringify(__JUMP_TYPE_FALSE)"\t# .type\n"
+#else
+#define ASM_STATIC_KEY_INIT_TRUE \
+ "\t.long 1 \t# .enabled\n" \
+ "\t.long "__stringify(__JUMP_TYPE_TRUE)"\t# .type\n"
+#define ASM_STATIC_KEY_INIT_FALSE \
+ "\t.long 0 \t# .enabled\n" \
+ "\t.long "__stringify(__JUMP_TYPE_FALSE)"\t# .type\n"
+#endif
+
#endif
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index 1a0b6f17a5d6..6e98193ae708 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -132,6 +132,8 @@ struct module;

#ifdef HAVE_JUMP_LABEL

+#define __JUMP_TYPE_FALSE 0
+#define __JUMP_TYPE_TRUE 1
#define JUMP_TYPE_FALSE 0UL
#define JUMP_TYPE_TRUE 1UL
#define JUMP_TYPE_LINKED 2UL
--
2.19.1.3.g1d92a00e68


2018-10-09 11:22:20

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 18/23] dynamic_debug: introduce accessors for string members of struct _ddebug

When we introduce compact versions of these pointers (a la
CONFIG_GENERIC_BUG_RELATIVE_POINTERS), all access to these members must
go via appropriate accessors. This just mass-converts dynamic_debug.c to
use the new accessors.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
lib/dynamic_debug.c | 51 ++++++++++++++++++++++++++++++---------------
1 file changed, 34 insertions(+), 17 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index e90459dca34b..dbd837f486f9 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -37,6 +37,23 @@
#include <linux/device.h>
#include <linux/netdevice.h>

+static inline const char *dd_modname(const struct _ddebug *dd)
+{
+ return dd->modname;
+}
+static inline const char *dd_function(const struct _ddebug *dd)
+{
+ return dd->function;
+}
+static inline const char *dd_filename(const struct _ddebug *dd)
+{
+ return dd->filename;
+}
+static inline const char *dd_format(const struct _ddebug *dd)
+{
+ return dd->format;
+}
+
extern struct _ddebug __start___verbose[];
extern struct _ddebug __stop___verbose[];

@@ -158,21 +175,21 @@ static int ddebug_change(const struct ddebug_query *query,

/* match against the source filename */
if (query->filename &&
- !match_wildcard(query->filename, dp->filename) &&
+ !match_wildcard(query->filename, dd_filename(dp)) &&
!match_wildcard(query->filename,
- kbasename(dp->filename)) &&
+ kbasename(dd_filename(dp))) &&
!match_wildcard(query->filename,
- trim_prefix(dp->filename)))
+ trim_prefix(dd_filename(dp))))
continue;

/* match against the function */
if (query->function &&
- !match_wildcard(query->function, dp->function))
+ !match_wildcard(query->function, dd_function(dp)))
continue;

/* match against the format */
if (query->format &&
- !strstr(dp->format, query->format))
+ !strstr(dd_format(dp), query->format))
continue;

/* match against the line number range */
@@ -197,8 +214,8 @@ static int ddebug_change(const struct ddebug_query *query,
#endif
dp->flags = newflags;
vpr_info("changed %s:%d [%s]%s =%s\n",
- trim_prefix(dp->filename), dp->lineno,
- dt->mod_name, dp->function,
+ trim_prefix(dd_filename(dp)), dp->lineno,
+ dt->mod_name, dd_function(dp),
ddebug_describe_flags(dp, flagbuf,
sizeof(flagbuf)));
}
@@ -533,10 +550,10 @@ static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
pos_after_tid = pos;
if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
- desc->modname);
+ dd_modname(desc));
if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
- desc->function);
+ dd_function(desc));
if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
pos += snprintf(buf + pos, remaining(pos), "%d:",
desc->lineno);
@@ -790,10 +807,10 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
}

seq_printf(m, "%s:%u [%s]%s =%s \"",
- trim_prefix(dp->filename), dp->lineno,
- iter->table->mod_name, dp->function,
+ trim_prefix(dd_filename(dp)), dp->lineno,
+ iter->table->mod_name, dd_function(dp),
ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
- seq_escape(m, dp->format, "\t\r\n\"");
+ seq_escape(m, dd_format(dp), "\t\r\n\"");
seq_puts(m, "\"\n");

return 0;
@@ -987,20 +1004,20 @@ static int __init dynamic_debug_init(void)
return 1;
}
iter = __start___verbose;
- modname = iter->modname;
+ modname = dd_modname(iter);
iter_start = iter;
for (; iter < __stop___verbose; iter++) {
entries++;
- verbose_bytes += strlen(iter->modname) + strlen(iter->function)
- + strlen(iter->filename) + strlen(iter->format);
+ verbose_bytes += strlen(dd_modname(iter)) + strlen(dd_function(iter))
+ + strlen(dd_filename(iter)) + strlen(dd_format(iter));

- if (strcmp(modname, iter->modname)) {
+ if (strcmp(modname, dd_modname(iter))) {
modct++;
ret = ddebug_add_module(iter_start, n, modname);
if (ret)
goto out_err;
n = 0;
- modname = iter->modname;
+ modname = dd_modname(iter);
iter_start = iter;
}
n++;
--
2.19.1.3.g1d92a00e68


2018-10-09 11:22:27

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 19/23] dynamic_debug: drop use of bitfields in struct _ddebug

Properly initializing a struct containing bitfields in assembly is
hard. Instead, merge lineno and flags to a single unsigned int, which we
mask manually. This should not cause any worse code than what gcc would
need to generate for accessing the bitfields anyway.

Actually, on 64 bit, there is a four byte hole after these fields, so we
could just give flags and lineno each their own u32. But I don't think
that's worth the ifdeffery.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 12 ++++------
lib/dynamic_debug.c | 44 +++++++++++++++++++++++------------
2 files changed, 34 insertions(+), 22 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index b9424097df37..e1be30e8422b 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -20,7 +20,6 @@ struct _ddebug {
const char *function;
const char *filename;
const char *format;
- unsigned int lineno:18;
/*
* The flags field controls the behaviour at the callsite.
* The bits here are changed dynamically when the user
@@ -37,7 +36,7 @@ struct _ddebug {
#else
#define _DPRINTK_FLAGS_DEFAULT 0
#endif
- unsigned int flags:8;
+ unsigned int flags_lineno; /* flags in lower 8 bits, lineno in upper 24 */
#ifdef HAVE_JUMP_LABEL
union {
struct static_key_true dd_key_true;
@@ -46,7 +45,7 @@ struct _ddebug {
#endif
} __attribute__((aligned(8)));

-
+#define _DPRINTK_FLAGS_LINENO_INIT (((unsigned)__LINE__ << 8) | _DPRINTK_FLAGS_DEFAULT)

#if defined(CONFIG_DYNAMIC_DEBUG)
int ddebug_add_module(struct _ddebug *tab, unsigned int n,
@@ -78,8 +77,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
.function = __func__, \
.filename = __FILE__, \
.format = (fmt), \
- .lineno = __LINE__, \
- .flags = _DPRINTK_FLAGS_DEFAULT, \
+ .flags_lineno = _DPRINTK_FLAGS_LINENO_INIT, \
_DPRINTK_KEY_INIT \
}

@@ -104,10 +102,10 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,

#ifdef DEBUG
#define DYNAMIC_DEBUG_BRANCH(descriptor) \
- likely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
+ likely(descriptor.flags_lineno & _DPRINTK_FLAGS_PRINT)
#else
#define DYNAMIC_DEBUG_BRANCH(descriptor) \
- unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
+ unlikely(descriptor.flags_lineno & _DPRINTK_FLAGS_PRINT)
#endif

#endif
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index dbd837f486f9..9d4c840ff0de 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -53,6 +53,18 @@ static inline const char *dd_format(const struct _ddebug *dd)
{
return dd->format;
}
+static inline unsigned dd_lineno(const struct _ddebug *dd)
+{
+ return dd->flags_lineno >> 8;
+}
+static inline unsigned dd_flags(const struct _ddebug *dd)
+{
+ return dd->flags_lineno & 0xff;
+}
+static inline void dd_set_flags(struct _ddebug *dd, unsigned newflags)
+{
+ dd->flags_lineno = (dd_lineno(dd) << 8) | newflags;
+}

extern struct _ddebug __start___verbose[];
extern struct _ddebug __stop___verbose[];
@@ -111,7 +123,7 @@ static char *ddebug_describe_flags(struct _ddebug *dp, char *buf,

BUG_ON(maxlen < 6);
for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
- if (dp->flags & opt_array[i].flag)
+ if (dd_flags(dp) & opt_array[i].flag)
*p++ = opt_array[i].opt_char;
if (p == buf)
*p++ = '_';
@@ -157,7 +169,7 @@ static int ddebug_change(const struct ddebug_query *query,
{
int i;
struct ddebug_table *dt;
- unsigned int newflags;
+ unsigned int newflags, oldflags;
unsigned int nfound = 0;
char flagbuf[10];

@@ -194,27 +206,28 @@ static int ddebug_change(const struct ddebug_query *query,

/* match against the line number range */
if (query->first_lineno &&
- dp->lineno < query->first_lineno)
+ dd_lineno(dp) < query->first_lineno)
continue;
if (query->last_lineno &&
- dp->lineno > query->last_lineno)
+ dd_lineno(dp) > query->last_lineno)
continue;

nfound++;

- newflags = (dp->flags & mask) | flags;
- if (newflags == dp->flags)
+ oldflags = dd_flags(dp);
+ newflags = (oldflags & mask) | flags;
+ if (newflags == oldflags)
continue;
#ifdef HAVE_JUMP_LABEL
- if (dp->flags & _DPRINTK_FLAGS_PRINT) {
+ if (oldflags & _DPRINTK_FLAGS_PRINT) {
if (!(flags & _DPRINTK_FLAGS_PRINT))
static_branch_disable(&dp->key.dd_key_true);
} else if (flags & _DPRINTK_FLAGS_PRINT)
static_branch_enable(&dp->key.dd_key_true);
#endif
- dp->flags = newflags;
+ dd_set_flags(dp, newflags);
vpr_info("changed %s:%d [%s]%s =%s\n",
- trim_prefix(dd_filename(dp)), dp->lineno,
+ trim_prefix(dd_filename(dp)), dd_lineno(dp),
dt->mod_name, dd_function(dp),
ddebug_describe_flags(dp, flagbuf,
sizeof(flagbuf)));
@@ -537,10 +550,11 @@ static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
{
int pos_after_tid;
int pos = 0;
+ unsigned flags = dd_flags(desc);

*buf = '\0';

- if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
+ if (flags & _DPRINTK_FLAGS_INCL_TID) {
if (in_interrupt())
pos += snprintf(buf + pos, remaining(pos), "<intr> ");
else
@@ -548,15 +562,15 @@ static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
task_pid_vnr(current));
}
pos_after_tid = pos;
- if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
+ if (flags & _DPRINTK_FLAGS_INCL_MODNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
dd_modname(desc));
- if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
+ if (flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
dd_function(desc));
- if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
+ if (flags & _DPRINTK_FLAGS_INCL_LINENO)
pos += snprintf(buf + pos, remaining(pos), "%d:",
- desc->lineno);
+ dd_lineno(desc));
if (pos - pos_after_tid)
pos += snprintf(buf + pos, remaining(pos), " ");
if (pos >= PREFIX_SIZE)
@@ -807,7 +821,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
}

seq_printf(m, "%s:%u [%s]%s =%s \"",
- trim_prefix(dd_filename(dp)), dp->lineno,
+ trim_prefix(dd_filename(dp)), dd_lineno(dp),
iter->table->mod_name, dd_function(dp),
ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
seq_escape(m, dd_format(dp), "\t\r\n\"");
--
2.19.1.3.g1d92a00e68


2018-10-09 11:22:39

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 17/23] ACPI: implement acpi_handle_debug in terms of _dynamic_func_call

With coming changes on x86-64, all dynamic debug descriptors in a
translation unit must have distinct names. The macro _dynamic_func_call
takes care of that. No functional change.

Cc: [email protected]
Acked-by: Rafael J. Wysocki <[email protected]>
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/acpi.h | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index e12d5ef1a054..83bacf9039e9 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -977,12 +977,8 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
#else
#if defined(CONFIG_DYNAMIC_DEBUG)
#define acpi_handle_debug(handle, fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __acpi_handle_debug(&descriptor, handle, pr_fmt(fmt), \
- ##__VA_ARGS__); \
-} while (0)
+ _dynamic_func_call(fmt, __acpi_handle_debug, \
+ handle, pr_fmt(fmt), ##__VA_ARGS__)
#else
#define acpi_handle_debug(handle, fmt, ...) \
({ \
--
2.19.1.3.g1d92a00e68


2018-10-09 11:22:43

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 23/23] x86: dynamic_debug: protect against dynamic debug identifier reuse

Most invocations of DEFINE_DYNAMIC_DEBUG_METADATA happen through
"public" macros such as pr_debug or netdev_dbg, which have been updated
to ensure they pass a unique identifier to use as the name for the
struct _ddebug instance. But it is still possible that someone invokes
DEFINE_DYNAMIC_DEBUG_METADATA directly, or creates a new wrapper macro
that does not do the extra-level-of-macros-passing-on-a__UNIQUE_ID
dance. On x86-64, all subsequent uses of that same identifier would
silently reuse the first instance, which is bad.

But we can catch such cases by defining a guard symbol that is unique
per expansion of DEFINE_DYNAMIC_DEBUG_METADATA. This still allows gcc to
emit multiple copies of some static inline function that has a pr_debug
call (because all such copies would pass the same value of %5 to the
assembler), but prevents repeated naked
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, "bla") - even with a helpful
error message saying that '"descriptor" used as _ddebug identifer more
than once'.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
arch/x86/include/asm/dynamic_debug.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/dynamic_debug.h b/arch/x86/include/asm/dynamic_debug.h
index 350ef6e2feff..69167f40482c 100644
--- a/arch/x86/include/asm/dynamic_debug.h
+++ b/arch/x86/include/asm/dynamic_debug.h
@@ -26,10 +26,15 @@
"\t.long 0 \t# <padding>\n" \
_DPRINTK_ASM_KEY_INIT \
".popsection\n" \
+ ".set "__stringify(name)".ddebug.once, %c5\n" \
+ ".elseif "__stringify(name)".ddebug.once - %c5\n" \
+ ".line "__stringify(__LINE__) " - 1\n" \
+ ".error \"'"__stringify(name)"' used as _ddebug identifier more than once\"\n" \
".endif\n" \
: : "i" (KBUILD_MODNAME), "i" (__func__), \
"i" (__FILE__), "i" (fmt), \
- "i" (_DPRINTK_FLAGS_LINENO_INIT))
+ "i" (_DPRINTK_FLAGS_LINENO_INIT), \
+ "i" (__COUNTER__))

#endif /* _ASM_X86_DYNAMIC_DEBUG_H */

--
2.19.1.3.g1d92a00e68


2018-10-09 11:22:49

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 14/23] btrfs: implement btrfs_debug* in terms of helper macro

First, the btrfs_debug macros open-code (one possible definition of)
DYNAMIC_DEBUG_BRANCH, so they don't benefit from the HAVE_JUMP_LABEL
optimization.

Second, changes on x86-64 later in this series require that all struct
_ddebug descriptors in a translation unit use distinct identifiers.

Using the new _dynamic_func_call_no_desc helper macro from
dynamic_debug.h takes care of both of these.

Cc: [email protected]
Acked-by: David Sterba <[email protected]>
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
fs/btrfs/ctree.h | 34 ++++++++++------------------------
1 file changed, 10 insertions(+), 24 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 2cddfe7806a4..7ae6cdad5b38 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3353,31 +3353,17 @@ void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...);

#if defined(CONFIG_DYNAMIC_DEBUG)
#define btrfs_debug(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk(fs_info, KERN_DEBUG fmt, ##args); \
-} while (0)
-#define btrfs_debug_in_rcu(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk_in_rcu(fs_info, KERN_DEBUG fmt, ##args); \
-} while (0)
+ _dynamic_func_call_no_desc(fmt, btrfs_printk, \
+ fs_info, KERN_DEBUG fmt, ##args)
+#define btrfs_debug_in_rcu(fs_info, fmt, args...) \
+ _dynamic_func_call_no_desc(fmt, btrfs_printk_in_rcu, \
+ fs_info, KERN_DEBUG fmt, ##args)
#define btrfs_debug_rl_in_rcu(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk_rl_in_rcu(fs_info, KERN_DEBUG fmt, \
- ##args);\
-} while (0)
-#define btrfs_debug_rl(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk_ratelimited(fs_info, KERN_DEBUG fmt, \
- ##args); \
-} while (0)
+ _dynamic_func_call_no_desc(fmt, btrfs_printk_rl_in_rcu, \
+ fs_info, KERN_DEBUG fmt, ##args)
+#define btrfs_debug_rl(fs_info, fmt, args...) \
+ _dynamic_func_call_no_desc(fmt, btrfs_printk_ratelimited, \
+ fs_info, KERN_DEBUG fmt, ##args)
#elif defined(DEBUG)
#define btrfs_debug(fs_info, fmt, args...) \
btrfs_printk(fs_info, KERN_DEBUG fmt, ##args)
--
2.19.1.3.g1d92a00e68


2018-10-09 11:22:57

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 16/23] ACPI: remove unused __acpi_handle_debug macro

If CONFIG_DYNAMIC_DEBUG is not set, acpi_handle_debug directly invokes
acpi_handle_printk (if DEBUG) or does a no-printk (if !DEBUG). So this
macro is never used.

Cc: [email protected]
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/acpi.h | 3 ---
1 file changed, 3 deletions(-)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 21e03aa32aae..e12d5ef1a054 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -948,9 +948,6 @@ acpi_handle_printk(const char *level, void *handle, const char *fmt, ...) {}
#if defined(CONFIG_ACPI) && defined(CONFIG_DYNAMIC_DEBUG)
__printf(3, 4)
void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const char *fmt, ...);
-#else
-#define __acpi_handle_debug(descriptor, handle, fmt, ...) \
- acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__);
#endif

/*
--
2.19.1.3.g1d92a00e68


2018-10-09 11:23:10

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 12/23] dynamic_debug: add static inline stub for ddebug_add_module

For symmetry with ddebug_remove_module, and to avoid a bit of ifdeffery
in module.c, move the declaration of ddebug_add_module inside #if
defined(CONFIG_DYNAMIC_DEBUG) and add a corresponding no-op stub in the
#else branch.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 10 ++++++++--
kernel/module.c | 2 --
2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 0a643316597c..6a002b789d51 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -47,10 +47,10 @@ struct _ddebug {
} __attribute__((aligned(8)));


-int ddebug_add_module(struct _ddebug *tab, unsigned int n,
- const char *modname);

#if defined(CONFIG_DYNAMIC_DEBUG)
+int ddebug_add_module(struct _ddebug *tab, unsigned int n,
+ const char *modname);
extern int ddebug_remove_module(const char *mod_name);
extern __printf(2, 3)
void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...);
@@ -152,6 +152,12 @@ do { \
#include <linux/string.h>
#include <linux/errno.h>

+static inline int ddebug_add_module(struct _ddebug *tab, unsigned int n,
+ const char *modname)
+{
+ return 0;
+}
+
static inline int ddebug_remove_module(const char *mod)
{
return 0;
diff --git a/kernel/module.c b/kernel/module.c
index 381f9bf282fe..be2727c5a003 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2715,9 +2715,7 @@ static void dynamic_debug_setup(struct module *mod, struct _ddebug *debug, unsig
{
if (!debug)
return;
-#ifdef CONFIG_DYNAMIC_DEBUG
ddebug_add_module(debug, num, mod->name);
-#endif
}

static void dynamic_debug_remove(struct module *mod, struct _ddebug *debug)
--
2.19.1.3.g1d92a00e68


2018-10-09 11:23:16

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 13/23] dynamic_debug: refactor dynamic_pr_debug and friends

For the upcoming 'define the _ddebug descriptor in assembly', we need
all the descriptors in a translation unit to have distinct
names (because asm does not understand C scope). The easiest way to
achieve that is as usual with an extra level of macros, passing the
identifier to use to the innermost macro, generating it via __UNIQUE_ID
or something.

However, instead of repeating that exercise for dynamic_pr_debug,
dynamic_dev_dbg, dynamic_netdev_dbg and dynamic_hex_dump separately, we
can use the similarity between their bodies to implement them via a
common macro, _dynamic_func_call - though the hex_dump case requires
a slight variant, since print_hex_dump does not take the _ddebug
descriptor. We'll also get to use that variant elsewhere (btrfs).

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 72 +++++++++++++++++++++--------------
1 file changed, 43 insertions(+), 29 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 6a002b789d51..b9424097df37 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -112,40 +112,54 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,

#endif

-#define dynamic_pr_debug(fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __dynamic_pr_debug(&descriptor, pr_fmt(fmt), \
- ##__VA_ARGS__); \
+#define __dynamic_func_call(id, fmt, func, ...) do { \
+ DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
+ if (DYNAMIC_DEBUG_BRANCH(id)) \
+ func(&id, ##__VA_ARGS__); \
} while (0)

-#define dynamic_dev_dbg(dev, fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __dynamic_dev_dbg(&descriptor, dev, fmt, \
- ##__VA_ARGS__); \
+#define __dynamic_func_call_no_desc(id, fmt, func, ...) do { \
+ DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
+ if (DYNAMIC_DEBUG_BRANCH(id)) \
+ func(__VA_ARGS__); \
} while (0)

-#define dynamic_netdev_dbg(dev, fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __dynamic_netdev_dbg(&descriptor, dev, fmt, \
- ##__VA_ARGS__); \
-} while (0)
+/*
+ * "Factory macro" for generating a call to func, guarded by a
+ * DYNAMIC_DEBUG_BRANCH. The dynamic debug decriptor will be
+ * initialized using the fmt argument. The function will be called with
+ * the address of the descriptor as first argument, followed by all
+ * the varargs. Note that fmt is repeated in invocations of this
+ * macro.
+ */
+#define _dynamic_func_call(fmt, func, ...) \
+ __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
+/*
+ * A variant that does the same, except that the descriptor is not
+ * passed as the first argument to the function; it is only called
+ * with precisely the macro's varargs.
+ */
+#define _dynamic_func_call_no_desc(fmt, func, ...) \
+ __dynamic_func_call_no_desc(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)

-#define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
- groupsize, buf, len, ascii) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, \
- __builtin_constant_p(prefix_str) ? prefix_str : "hexdump");\
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- print_hex_dump(KERN_DEBUG, prefix_str, \
- prefix_type, rowsize, groupsize, \
- buf, len, ascii); \
-} while (0)
+#define dynamic_pr_debug(fmt, ...) \
+ _dynamic_func_call(fmt, __dynamic_pr_debug, \
+ pr_fmt(fmt), ##__VA_ARGS__)
+
+#define dynamic_dev_dbg(dev, fmt, ...) \
+ _dynamic_func_call(fmt,__dynamic_dev_dbg, \
+ dev, fmt, ##__VA_ARGS__)
+
+#define dynamic_netdev_dbg(dev, fmt, ...) \
+ _dynamic_func_call(fmt, __dynamic_netdev_dbg, \
+ dev, fmt, ##__VA_ARGS__)
+
+#define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
+ groupsize, buf, len, ascii) \
+ _dynamic_func_call_no_desc(__builtin_constant_p(prefix_str) ? prefix_str : "hexdump", \
+ print_hex_dump, \
+ KERN_DEBUG, prefix_str, prefix_type, \
+ rowsize, groupsize, buf, len, ascii)

#else

--
2.19.1.3.g1d92a00e68


2018-10-09 11:23:19

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 11/23] dynamic_debug: move pr_err from module.c to ddebug_add_module

This serves two purposes: First, we get a diagnostic if (though
extremely unlikely), any of the calls of ddebug_add_module for built-in
code fails, effectively disabling dynamic_debug. Second, I want to make
struct _ddebug opaque, and avoid accessing any of its members outside
dynamic_debug.[ch].

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
kernel/module.c | 4 +---
lib/dynamic_debug.c | 4 +++-
2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index 6746c85511fe..381f9bf282fe 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2716,9 +2716,7 @@ static void dynamic_debug_setup(struct module *mod, struct _ddebug *debug, unsig
if (!debug)
return;
#ifdef CONFIG_DYNAMIC_DEBUG
- if (ddebug_add_module(debug, num, mod->name))
- pr_err("dynamic debug error adding module: %s\n",
- debug->modname);
+ ddebug_add_module(debug, num, mod->name);
#endif
}

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index f1de45a100fa..e90459dca34b 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -849,8 +849,10 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
struct ddebug_table *dt;

dt = kzalloc(sizeof(*dt), GFP_KERNEL);
- if (dt == NULL)
+ if (dt == NULL) {
+ pr_err("error adding module: %s\n", name);
return -ENOMEM;
+ }
/*
* For built-in modules, name lives in .rodata and is
* immortal. For loaded modules, name points at the name[]
--
2.19.1.3.g1d92a00e68


2018-10-09 11:23:48

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 09/23] dynamic_debug: use pointer comparison in ddebug_remove_module

Now that we store the passed-in string directly in ddebug_add_module, we
can use pointer equality instead of strcmp. This is a little more
efficient, but more importantly, this also makes the code somewhat more
correct:

Currently, if one loads and then unloads a module whose name happens to
match the KBUILD_MODNAME of some built-in functionality (which need not
even be modular at all), all of their dynamic debug entries vanish along
with those of the actual module. For example, loading and unloading a
core.ko hides all pr_debugs from drivers/base/core.c and other built-in
files called core.c (incidentally, there is an in-tree module whose name
is core, but I just tested this with an out-of-tree trivial one).

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
lib/dynamic_debug.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 2155e0e23530..ab81155f928d 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -929,9 +929,10 @@ int ddebug_remove_module(const char *mod_name)

mutex_lock(&ddebug_lock);
list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
- if (!strcmp(dt->mod_name, mod_name)) {
+ if (dt->mod_name == mod_name) {
ddebug_table_free(dt);
ret = 0;
+ break;
}
}
mutex_unlock(&ddebug_lock);
--
2.19.1.3.g1d92a00e68


2018-10-09 11:23:51

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 07/23] dynamic_debug: consolidate DEFINE_DYNAMIC_DEBUG_METADATA definitions

Instead of defining DEFINE_DYNAMIC_DEBUG_METADATA in terms of a helper
DEFINE_DYNAMIC_DEBUG_METADATA_KEY, that needs another helper
dd_key_init to be properly defined, just make the various #ifdef
branches define a _DPRINTK_KEY_INIT that can be used directly, similar
to _DPRINTK_FLAGS_DEFAULT.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 22 +++++++---------------
1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 2fd8006153c3..0a643316597c 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -71,7 +71,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
const struct net_device *dev,
const char *fmt, ...);

-#define DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, key, init) \
+#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
static struct _ddebug __aligned(8) \
__attribute__((section("__verbose"))) name = { \
.modname = KBUILD_MODNAME, \
@@ -80,35 +80,27 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
.format = (fmt), \
.lineno = __LINE__, \
.flags = _DPRINTK_FLAGS_DEFAULT, \
- dd_key_init(key, init) \
+ _DPRINTK_KEY_INIT \
}

#ifdef HAVE_JUMP_LABEL

-#define dd_key_init(key, init) key = (init)
-
#ifdef DEBUG
-#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
- DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_true, \
- (STATIC_KEY_TRUE_INIT))
+
+#define _DPRINTK_KEY_INIT .key.dd_key_true = (STATIC_KEY_TRUE_INIT)

#define DYNAMIC_DEBUG_BRANCH(descriptor) \
static_branch_likely(&descriptor.key.dd_key_true)
#else
-#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
- DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_false, \
- (STATIC_KEY_FALSE_INIT))
+#define _DPRINTK_KEY_INIT .key.dd_key_false = (STATIC_KEY_FALSE_INIT)

#define DYNAMIC_DEBUG_BRANCH(descriptor) \
static_branch_unlikely(&descriptor.key.dd_key_false)
#endif

-#else
-
-#define dd_key_init(key, init)
+#else /* !HAVE_JUMP_LABEL */

-#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
- DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, 0, 0)
+#define _DPRINTK_KEY_INIT

#ifdef DEBUG
#define DYNAMIC_DEBUG_BRANCH(descriptor) \
--
2.19.1.3.g1d92a00e68


2018-10-09 11:23:55

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 05/23] linux/printk.h: use DYNAMIC_DEBUG_BRANCH in pr_debug_ratelimited

pr_debug_ratelimited tests the dynamic debug descriptor the old-fashioned
way, and doesn't utilize the static key/jump label implementation on
architectures that HAVE_JUMP_LABEL. Use the DYNAMIC_DEBUG_BRANCH which
is defined appropriately.

Acked-by: Petr Mladek <[email protected]>
Acked-by: Jason Baron <[email protected]>
Cc: Steven Rostedt <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/printk.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index cf3eccfe1543..d3ba3245531d 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -466,7 +466,7 @@ do { \
DEFAULT_RATELIMIT_INTERVAL, \
DEFAULT_RATELIMIT_BURST); \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, pr_fmt(fmt)); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
__ratelimit(&_rs)) \
__dynamic_pr_debug(&descriptor, pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
--
2.19.1.3.g1d92a00e68


2018-10-09 11:23:57

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 06/23] linux/printk.h: use unique identifier for each struct _ddebug

Changes on x86-64 later in this series require that all struct _ddebug
descriptors in a translation unit uses distinct identifiers. Realize
that for pr_debug_ratelimited by generating such an identifier via
__UNIQUE_ID and pass that to an extra level of macros.

No functional change.

Acked-by: Petr Mladek <[email protected]>
Acked-by: Jason Baron <[email protected]>
Cc: Steven Rostedt <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/printk.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index d3ba3245531d..70df2c578d40 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -460,7 +460,7 @@ extern int kptr_restrict;
/* If you are writing a driver, please use dev_dbg instead */
#if defined(CONFIG_DYNAMIC_DEBUG)
/* descriptor check is first to prevent flooding with "callbacks suppressed" */
-#define pr_debug_ratelimited(fmt, ...) \
+#define _pr_debug_ratelimited(descriptor, fmt, ...) \
do { \
static DEFINE_RATELIMIT_STATE(_rs, \
DEFAULT_RATELIMIT_INTERVAL, \
@@ -470,6 +470,8 @@ do { \
__ratelimit(&_rs)) \
__dynamic_pr_debug(&descriptor, pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
+#define pr_debug_ratelimited(fmt, ...) \
+ _pr_debug_ratelimited(__UNIQUE_ID(ddebug), fmt, ##__VA_ARGS__)
#elif defined(DEBUG)
#define pr_debug_ratelimited(fmt, ...) \
printk_ratelimited(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
--
2.19.1.3.g1d92a00e68


2018-10-09 11:23:58

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 03/23] linux/net.h: use DYNAMIC_DEBUG_BRANCH in net_dbg_ratelimited

net_dbg_ratelimited tests the dynamic debug descriptor the old-fashioned
way, and doesn't utilize the static key/jump label implementation on
architectures that HAVE_JUMP_LABEL. Use the DYNAMIC_DEBUG_BRANCH which
is defined appropriately.

Cc: [email protected]
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/net.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/net.h b/include/linux/net.h
index e0930678c8bf..651fca72286c 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -263,7 +263,7 @@ do { \
#define net_dbg_ratelimited(fmt, ...) \
do { \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
net_ratelimit()) \
__dynamic_pr_debug(&descriptor, pr_fmt(fmt), \
##__VA_ARGS__); \
--
2.19.1.3.g1d92a00e68


2018-10-09 11:24:11

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 04/23] linux/net.h: use unique identifier for each struct _ddebug

Changes on x86-64 later in this series require that all struct _ddebug
descriptors in a translation unit uses distinct identifiers. Realize
that for net_dbg_ratelimited by generating such an identifier via
__UNIQUE_ID and pass that to an extra level of macros.

No functional change.

Cc: [email protected]
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/net.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/net.h b/include/linux/net.h
index 651fca72286c..397243a25f56 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -260,7 +260,7 @@ do { \
#define net_info_ratelimited(fmt, ...) \
net_ratelimited_function(pr_info, fmt, ##__VA_ARGS__)
#if defined(CONFIG_DYNAMIC_DEBUG)
-#define net_dbg_ratelimited(fmt, ...) \
+#define _net_dbg_ratelimited(descriptor, fmt, ...) \
do { \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
@@ -268,6 +268,8 @@ do { \
__dynamic_pr_debug(&descriptor, pr_fmt(fmt), \
##__VA_ARGS__); \
} while (0)
+#define net_dbg_ratelimited(fmt, ...) \
+ _net_dbg_ratelimited(__UNIQUE_ID(ddebug), fmt, ##__VA_ARGS__)
#elif defined(DEBUG)
#define net_dbg_ratelimited(fmt, ...) \
net_ratelimited_function(pr_debug, fmt, ##__VA_ARGS__)
--
2.19.1.3.g1d92a00e68


2018-10-09 11:24:14

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 15/23] ACPI: use proper DYNAMIC_DEBUG_BRANCH macro

dynamic debug may be implemented via static keys, but ACPI is missing
out on that runtime benefit since it open-codes one possible definition
of DYNAMIC_DEBUG_BRANCH.

Cc: [email protected]
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/acpi.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index de8d3d3fa651..21e03aa32aae 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -982,7 +982,7 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
#define acpi_handle_debug(handle, fmt, ...) \
do { \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
__acpi_handle_debug(&descriptor, handle, pr_fmt(fmt), \
##__VA_ARGS__); \
} while (0)
--
2.19.1.3.g1d92a00e68


2018-10-09 11:24:32

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 01/23] linux/device.h: use DYNAMIC_DEBUG_BRANCH in dev_dbg_ratelimited

dev_dbg_ratelimited tests the dynamic debug descriptor the old-fashioned
way, and doesn't utilize the static key/jump label implementation on
architectures that HAVE_JUMP_LABEL. Use the DYNAMIC_DEBUG_BRANCH which
is defined appropriately.

Reviewed-by: Greg Kroah-Hartman <[email protected]>
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/device.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/device.h b/include/linux/device.h
index 8f882549edee..0d8ed2adfc73 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1503,7 +1503,7 @@ do { \
DEFAULT_RATELIMIT_INTERVAL, \
DEFAULT_RATELIMIT_BURST); \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
__ratelimit(&_rs)) \
__dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \
##__VA_ARGS__); \
--
2.19.1.3.g1d92a00e68


2018-10-09 11:24:33

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 10/23] dynamic_debug: remove unused EXPORT_SYMBOLs

The only caller of ddebug_{add,remove}_module outside dynamic_debug.c is
kernel/module.c, which is obviously not itself modular (though it would
be an interesting exercise to make that happen...). I also fail to see
how these interfaces can be used by modules, in-tree or not.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
lib/dynamic_debug.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index ab81155f928d..f1de45a100fa 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -868,7 +868,6 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
vpr_info("%u debug prints in module %s\n", n, dt->mod_name);
return 0;
}
-EXPORT_SYMBOL_GPL(ddebug_add_module);

/* helper for ddebug_dyndbg_(boot|module)_param_cb */
static int ddebug_dyndbg_param_cb(char *param, char *val,
@@ -938,7 +937,6 @@ int ddebug_remove_module(const char *mod_name)
mutex_unlock(&ddebug_lock);
return ret;
}
-EXPORT_SYMBOL_GPL(ddebug_remove_module);

static void ddebug_remove_all_tables(void)
{
--
2.19.1.3.g1d92a00e68


2018-10-09 11:24:49

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 08/23] dynamic_debug: don't duplicate modname in ddebug_add_module

For built-in modules, we're already reusing the passed-in string via
kstrdup_const(). But for actual modules (i.e. when we're called from
dynamic_debug_setup in module.c), the passed-in string (which points
at the name[] array inside struct module) is also
guaranteed to live at least as long as the struct ddebug_table, since
free_module() calls ddebug_remove_module().

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
lib/dynamic_debug.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index c7c96bc7654a..2155e0e23530 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -847,17 +847,17 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
const char *name)
{
struct ddebug_table *dt;
- const char *new_name;

dt = kzalloc(sizeof(*dt), GFP_KERNEL);
if (dt == NULL)
return -ENOMEM;
- new_name = kstrdup_const(name, GFP_KERNEL);
- if (new_name == NULL) {
- kfree(dt);
- return -ENOMEM;
- }
- dt->mod_name = new_name;
+ /*
+ * For built-in modules, name lives in .rodata and is
+ * immortal. For loaded modules, name points at the name[]
+ * member of struct module, which lives at least as long as
+ * this struct ddebug_table.
+ */
+ dt->mod_name = name;
dt->num_ddebugs = n;
dt->ddebugs = tab;

@@ -913,7 +913,6 @@ int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
static void ddebug_table_free(struct ddebug_table *dt)
{
list_del_init(&dt->link);
- kfree_const(dt->mod_name);
kfree(dt);
}

--
2.19.1.3.g1d92a00e68


2018-10-09 11:25:18

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 00/23] various dynamic_debug patches

v2: Added various acks/reviews. I'll follow up with rewriting the x86
part as asm macros once that work is in mainline.

Patches 15, 16 are in next-20181009; in hindsight I should probably
have asked Rafael not to pick those. Patch 17 textually depend on
those, and patch 19 removes the .flags field, so depends on 15 so that
there are no references to that field. I'm included all patches here
hoping that the merge conflicts are trivial, given that it's just same
patches present in multiple branches.

Andrew, can you pick up these to give them some time in -next?

v1 cover letter:

This started as an experiment to see how hard it would be to change
the four pointers in struct _ddebug into relative offsets, a la
CONFIG_GENERIC_BUG_RELATIVE_POINTERS, thus saving 16 bytes per
pr_debug site (and thus exactly making up for the extra space used by
the introduction of jump labels in 9049fc74). I stumbled on a few
things that are probably worth fixing regardless of whether the latter
half of this series is deemed worthwhile.

Patch relationships: 1-2, 3-4, 5-6 and 15-16 can be applied
individually, though 2, 4 and 6 probably makes most sense in the
context of the final goal of the series.

7-12 I believe make sense on their own. Patch 13 again only makes
sense if we go all the way, and 14 and 17 depend on 13.

18-21 are more preparatory patches, and finally 22 switch over x86-64
to use CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS. I've tested that the
end result boots under virtme and that the dynamic_debug control file
has the expected contents.

Rasmus Villemoes (23):
linux/device.h: use DYNAMIC_DEBUG_BRANCH in dev_dbg_ratelimited
linux/device.h: use unique identifier for each struct _ddebug
linux/net.h: use DYNAMIC_DEBUG_BRANCH in net_dbg_ratelimited
linux/net.h: use unique identifier for each struct _ddebug
linux/printk.h: use DYNAMIC_DEBUG_BRANCH in pr_debug_ratelimited
linux/printk.h: use unique identifier for each struct _ddebug
dynamic_debug: consolidate DEFINE_DYNAMIC_DEBUG_METADATA definitions
dynamic_debug: don't duplicate modname in ddebug_add_module
dynamic_debug: use pointer comparison in ddebug_remove_module
dynamic_debug: remove unused EXPORT_SYMBOLs
dynamic_debug: move pr_err from module.c to ddebug_add_module
dynamic_debug: add static inline stub for ddebug_add_module
dynamic_debug: refactor dynamic_pr_debug and friends
btrfs: implement btrfs_debug* in terms of helper macro
ACPI: use proper DYNAMIC_DEBUG_BRANCH macro
ACPI: remove unused __acpi_handle_debug macro
ACPI: implement acpi_handle_debug in terms of _dynamic_func_call
dynamic_debug: introduce accessors for string members of struct
_ddebug
dynamic_debug: drop use of bitfields in struct _ddebug
dynamic_debug: introduce CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS
x86: jump_label: introduce ASM_STATIC_KEY_INIT_{TRUE,FALSE}
x86_64: use relative pointers with dynamic debug
x86: dynamic_debug: protect against dynamic debug identifier reuse

arch/x86/Kconfig | 1 +
arch/x86/include/asm/dynamic_debug.h | 40 ++++++++
arch/x86/include/asm/jump_label.h | 18 ++++
fs/btrfs/ctree.h | 34 ++-----
include/linux/acpi.h | 11 +--
include/linux/device.h | 6 +-
include/linux/dynamic_debug.h | 126 +++++++++++++++----------
include/linux/jump_label.h | 2 +
include/linux/net.h | 6 +-
include/linux/printk.h | 6 +-
kernel/module.c | 6 +-
lib/Kconfig.debug | 3 +
lib/dynamic_debug.c | 133 ++++++++++++++++++---------
13 files changed, 256 insertions(+), 136 deletions(-)
create mode 100644 arch/x86/include/asm/dynamic_debug.h

--
2.19.1.3.g1d92a00e68


2018-10-09 11:25:25

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v2 02/23] linux/device.h: use unique identifier for each struct _ddebug

Changes on x86-64 later in this series require that all struct _ddebug
descriptors in a translation unit uses distinct identifiers. Realize
that for dev_dbg_ratelimited by generating such an identifier via
__UNIQUE_ID and pass that to an extra level of macros.

No functional change.

Reviewed-by: Greg Kroah-Hartman <[email protected]>
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/device.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/device.h b/include/linux/device.h
index 0d8ed2adfc73..81108db013e4 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1497,7 +1497,7 @@ do { \
dev_level_ratelimited(dev_info, dev, fmt, ##__VA_ARGS__)
#if defined(CONFIG_DYNAMIC_DEBUG)
/* descriptor check is first to prevent flooding with "callbacks suppressed" */
-#define dev_dbg_ratelimited(dev, fmt, ...) \
+#define _dev_dbg_ratelimited(descriptor, dev, fmt, ...) \
do { \
static DEFINE_RATELIMIT_STATE(_rs, \
DEFAULT_RATELIMIT_INTERVAL, \
@@ -1508,6 +1508,8 @@ do { \
__dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \
##__VA_ARGS__); \
} while (0)
+#define dev_dbg_ratelimited(dev, fmt, ...) \
+ _dev_dbg_ratelimited(__UNIQUE_ID(ddebug), dev, fmt, ##__VA_ARGS__)
#elif defined(DEBUG)
#define dev_dbg_ratelimited(dev, fmt, ...) \
do { \
--
2.19.1.3.g1d92a00e68


2018-10-10 09:38:33

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH v2 00/23] various dynamic_debug patches

On Tue, Oct 9, 2018 at 1:20 PM Rasmus Villemoes
<[email protected]> wrote:
>
> v2: Added various acks/reviews. I'll follow up with rewriting the x86
> part as asm macros once that work is in mainline.
>
> Patches 15, 16 are in next-20181009; in hindsight I should probably
> have asked Rafael not to pick those.

So I have dropped them (which was easy enough to do).

Thanks,
Rafael

2018-10-10 09:39:27

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH v2 15/23] ACPI: use proper DYNAMIC_DEBUG_BRANCH macro

On Tue, Oct 9, 2018 at 1:21 PM Rasmus Villemoes
<[email protected]> wrote:
>
> dynamic debug may be implemented via static keys, but ACPI is missing
> out on that runtime benefit since it open-codes one possible definition
> of DYNAMIC_DEBUG_BRANCH.
>
> Cc: [email protected]
> Acked-by: Jason Baron <[email protected]>
> Signed-off-by: Rasmus Villemoes <[email protected]>

Acked-by: Rafael J. Wysocki <[email protected]>

> ---
> include/linux/acpi.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index de8d3d3fa651..21e03aa32aae 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -982,7 +982,7 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
> #define acpi_handle_debug(handle, fmt, ...) \
> do { \
> DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
> - if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
> + if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
> __acpi_handle_debug(&descriptor, handle, pr_fmt(fmt), \
> ##__VA_ARGS__); \
> } while (0)
> --
> 2.19.1.3.g1d92a00e68
>

2018-10-10 09:41:02

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH v2 16/23] ACPI: remove unused __acpi_handle_debug macro

On Tue, Oct 9, 2018 at 1:20 PM Rasmus Villemoes
<[email protected]> wrote:
>
> If CONFIG_DYNAMIC_DEBUG is not set, acpi_handle_debug directly invokes
> acpi_handle_printk (if DEBUG) or does a no-printk (if !DEBUG). So this
> macro is never used.
>
> Cc: [email protected]
> Acked-by: Jason Baron <[email protected]>
> Signed-off-by: Rasmus Villemoes <[email protected]>

Acked-by: Rafael J. Wysocki <[email protected]>

> ---
> include/linux/acpi.h | 3 ---
> 1 file changed, 3 deletions(-)
>
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 21e03aa32aae..e12d5ef1a054 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -948,9 +948,6 @@ acpi_handle_printk(const char *level, void *handle, const char *fmt, ...) {}
> #if defined(CONFIG_ACPI) && defined(CONFIG_DYNAMIC_DEBUG)
> __printf(3, 4)
> void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const char *fmt, ...);
> -#else
> -#define __acpi_handle_debug(descriptor, handle, fmt, ...) \
> - acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__);
> #endif
>
> /*
> --
> 2.19.1.3.g1d92a00e68
>

2018-11-09 23:12:11

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 20/23] dynamic_debug: introduce CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS

Based on the same idea for struct bug_entry, an architecture can opt-in
to use relative pointers in struct _ddebug. It only makes sense for 64
bit architectures, where one saves 16 bytes per entry (out of 40 or 56,
depending on CONFIG_JUMP_LABEL). The architecture is responsible for
providing a suitable DEFINE_DYNAMIC_DEBUG_METADATA macro in
<asm/dynamic_debug.h>.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 14 ++++++++++++++
lib/Kconfig.debug | 3 +++
lib/dynamic_debug.c | 20 ++++++++++++++++++++
3 files changed, 37 insertions(+)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index e1be30e8422b..cc4222a20aa1 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -16,10 +16,17 @@ struct _ddebug {
* These fields are used to drive the user interface
* for selecting and displaying debug callsites.
*/
+#ifdef CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS
+ signed int modname_disp;
+ signed int function_disp;
+ signed int filename_disp;
+ signed int format_disp;
+#else
const char *modname;
const char *function;
const char *filename;
const char *format;
+#endif
/*
* The flags field controls the behaviour at the callsite.
* The bits here are changed dynamically when the user
@@ -70,6 +77,12 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
const struct net_device *dev,
const char *fmt, ...);

+#ifdef CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS
+#include <asm/dynamic_debug.h>
+#ifndef DEFINE_DYNAMIC_DEBUG_METADATA
+# error "asm/dynamic_debug.h must provide definition of DEFINE_DYNAMIC_DEBUG_METADATA"
+#endif
+#else
#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
static struct _ddebug __aligned(8) \
__attribute__((section("__verbose"))) name = { \
@@ -80,6 +93,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
.flags_lineno = _DPRINTK_FLAGS_LINENO_INIT, \
_DPRINTK_KEY_INIT \
}
+#endif

#ifdef HAVE_JUMP_LABEL

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 1af29b8224fd..1cac0ed659b6 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -146,6 +146,9 @@ config DYNAMIC_DEBUG
See Documentation/admin-guide/dynamic-debug-howto.rst for additional
information.

+config DYNAMIC_DEBUG_RELATIVE_POINTERS
+ bool
+
endmenu # "printk and dmesg options"

menu "Compile-time checks and compiler options"
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 9d4c840ff0de..61e61b36e479 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -37,6 +37,24 @@
#include <linux/device.h>
#include <linux/netdevice.h>

+#ifdef CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS
+static inline const char *dd_modname(const struct _ddebug *dd)
+{
+ return (const char *)dd + dd->modname_disp;
+}
+static inline const char *dd_function(const struct _ddebug *dd)
+{
+ return (const char *)dd + dd->function_disp;
+}
+static inline const char *dd_filename(const struct _ddebug *dd)
+{
+ return (const char *)dd + dd->filename_disp;
+}
+static inline const char *dd_format(const struct _ddebug *dd)
+{
+ return (const char *)dd + dd->format_disp;
+}
+#else
static inline const char *dd_modname(const struct _ddebug *dd)
{
return dd->modname;
@@ -53,6 +71,8 @@ static inline const char *dd_format(const struct _ddebug *dd)
{
return dd->format;
}
+#endif
+
static inline unsigned dd_lineno(const struct _ddebug *dd)
{
return dd->flags_lineno >> 8;
--
2.19.1.6.gbde171bbf5


2018-11-09 23:12:14

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 23/23] x86_64: use relative pointers with dynamic debug

Similar to how x86_64 uses bug_entry-relative pointers to reduce
sizeof(struct bug_entry), the same thing can now be done for struct
_ddebug, saving 16 bytes for each of those (i.e., each pr_debug, dev_dbg
etc. in a CONFIG_DYNAMIC_DEBUG kernel).

Note the use of .ifndef/.endif in asm to avoid

fs/aio.c:1382: Error: symbol `__UNIQUE_ID_ddebug112' is already defined

This is due to uses of pr_debug et al in functions that get inlined. In
such a case, __COUNTER__ is obviously only expanded once, but the asm()
is repeated once for every inlined instance. Letting all instances share
the same descriptor object is the right thing to do; that is also what
happens when it is the compiler that defines a static object inside an
inline(d) function.

That, however, leads to another problem if the same identifier is used
in two different DEFINE_DYNAMIC_DEBUG_METADATA() in the same translation
unit: They would both end up referring to the same (first occuring)
instance. So the second one would end up using the wrong file, line,
function etc. information. All current in-tree macro users of
DEFINE_DYNAMIC_DEBUG_METADATA() have been updated to ensure they use
UNIQUE_ID to generate the identifier.

To prevent such a problem from going unnoticed, we use a guard symbol in
assembly whose value is unique per DEFINE_DYNAMIC_DEBUG_METADATA
invocation.

Cc: [email protected]
Cc: Ingo Molnar <[email protected]>
Cc: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
arch/x86/Kconfig | 1 +
arch/x86/include/asm/dynamic_debug.h | 58 ++++++++++++++++++++++++++++
arch/x86/kernel/macros.S | 1 +
3 files changed, 60 insertions(+)
create mode 100644 arch/x86/include/asm/dynamic_debug.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ba7e3464ee92..c7cb31f39e5a 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -91,6 +91,7 @@ config X86
select CLOCKSOURCE_WATCHDOG
select DCACHE_WORD_ACCESS
select DMA_DIRECT_OPS
+ select DYNAMIC_DEBUG_RELATIVE_POINTERS if X86_64
select EDAC_ATOMIC_SCRUB
select EDAC_SUPPORT
select GENERIC_CLOCKEVENTS
diff --git a/arch/x86/include/asm/dynamic_debug.h b/arch/x86/include/asm/dynamic_debug.h
new file mode 100644
index 000000000000..80730409183f
--- /dev/null
+++ b/arch/x86/include/asm/dynamic_debug.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_DYNAMIC_DEBUG_H
+#define _ASM_X86_DYNAMIC_DEBUG_H
+
+#ifndef __ASSEMBLY__
+
+#ifdef DEBUG
+#define _DPRINTK_INIT_TRUE 1
+#else
+#define _DPRINTK_INIT_TRUE 0
+#endif
+
+#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
+ extern struct _ddebug name; \
+ asm volatile("DYNAMIC_DEBUG_METADATA" \
+ " ident="__stringify(name) \
+ " modname=%c0" \
+ " func=%c1" \
+ " file=%c2" \
+ " fmt=%c3" \
+ " flag_line=%c4" \
+ " init_true=%c5" \
+ " cnt=%c6" \
+ : : "i" (KBUILD_MODNAME), "i" (__func__), \
+ "i" (__FILE__), "i" (fmt), \
+ "i" (_DPRINTK_FLAGS_LINENO_INIT), \
+ "i" (_DPRINTK_INIT_TRUE), \
+ "i" (__COUNTER__) \
+ )
+
+#else /* __ASSEMBLY__ */
+
+.macro DYNAMIC_DEBUG_METADATA ident modname func file fmt flag_line init_true cnt
+.ifndef \ident
+ .pushsection __verbose,"aw"
+\ident :
+ .long \modname - \ident
+ .long \func - \ident
+ .long \file - \ident
+ .long \fmt - \ident
+ .long \flag_line
+ .long 0
+ .if \init_true
+ STATIC_KEY_INIT_TRUE
+ .else
+ STATIC_KEY_INIT_FALSE
+ .endif
+ .popsection
+ .set \ident\().ddebug.once, \cnt
+.elseif \ident\().ddebug.once - \cnt
+ .error "'\ident' used as _ddebug identifier more than once"
+.endif
+.endm
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_X86_DYNAMIC_DEBUG_H */
+
diff --git a/arch/x86/kernel/macros.S b/arch/x86/kernel/macros.S
index 161c95059044..2c2b8e5229a9 100644
--- a/arch/x86/kernel/macros.S
+++ b/arch/x86/kernel/macros.S
@@ -14,3 +14,4 @@
#include <asm/asm.h>
#include <asm/cpufeature.h>
#include <asm/jump_label.h>
+#include <asm/dynamic_debug.h>
--
2.19.1.6.gbde171bbf5


2018-11-09 23:12:25

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 22/23] x86: jump_label: introduce asm macros STATIC_KEY_INIT{,_TRUE,_FALSE}

These will be useful when defining the contents of (a struct containing)
a static key in assembly.

Cc: [email protected]
Cc: Ingo Molnar <[email protected]>
Cc: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
arch/x86/include/asm/jump_label.h | 17 +++++++++++++++++
1 file changed, 17 insertions(+)

diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h
index a5fb34fe56a4..f8b5c77ec96d 100644
--- a/arch/x86/include/asm/jump_label.h
+++ b/arch/x86/include/asm/jump_label.h
@@ -12,6 +12,7 @@

#include <asm/asm.h>
#include <asm/nops.h>
+#include <asm-generic/jump_label.h>

#ifndef __ASSEMBLY__

@@ -64,6 +65,22 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool
.popsection
.endm

+.macro STATIC_KEY_INIT enabled:req type:req
+ .long \enabled # .enabled
+#ifdef CONFIG_X86_64
+ .long 0 # <padding>
+#endif
+ _ASM_PTR \type # .type
+.endm
+
+.macro STATIC_KEY_INIT_TRUE
+ STATIC_KEY_INIT 1 JUMP_TYPE_TRUE
+.endm
+
+.macro STATIC_KEY_INIT_FALSE
+ STATIC_KEY_INIT 0 JUMP_TYPE_FALSE
+.endm
+
#endif /* __ASSEMBLY__ */

#endif
--
2.19.1.6.gbde171bbf5


2018-11-09 23:12:32

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 21/23] jump_label: move JUMP_TYPE_* constants to new asm-generic file

I'm going to need to refer to the JUMP_TYPE_FALSE and JUMP_TYPE_TRUE
constants from asm code. In order to do that, move them to an
asm-generic header and define them using the UL() helper macro.

Cc: Ingo Molnar <[email protected]>
Cc: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/asm-generic/jump_label.h | 11 +++++++++++
include/linux/jump_label.h | 6 +-----
2 files changed, 12 insertions(+), 5 deletions(-)
create mode 100644 include/asm-generic/jump_label.h

diff --git a/include/asm-generic/jump_label.h b/include/asm-generic/jump_label.h
new file mode 100644
index 000000000000..ff72c4c68ce3
--- /dev/null
+++ b/include/asm-generic/jump_label.h
@@ -0,0 +1,11 @@
+#ifndef __ASM_GENERIC_JUMP_LABEL_H
+#define __ASM_GENERIC_JUMP_LABEL_H
+
+#include <linux/const.h>
+
+#define JUMP_TYPE_FALSE UL(0)
+#define JUMP_TYPE_TRUE UL(1)
+#define JUMP_TYPE_LINKED UL(2)
+#define JUMP_TYPE_MASK UL(3)
+
+#endif /* __ASM_GENERIC_JUMP_LABEL_H */
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index 5df6a621e464..989fa8c328fd 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -119,6 +119,7 @@ struct static_key {

#ifdef HAVE_JUMP_LABEL
#include <asm/jump_label.h>
+#include <asm-generic/jump_label.h>

#ifndef __ASSEMBLY__
#ifdef CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE
@@ -194,11 +195,6 @@ struct module;

#ifdef HAVE_JUMP_LABEL

-#define JUMP_TYPE_FALSE 0UL
-#define JUMP_TYPE_TRUE 1UL
-#define JUMP_TYPE_LINKED 2UL
-#define JUMP_TYPE_MASK 3UL
-
static __always_inline bool static_key_false(struct static_key *key)
{
return arch_static_branch(key, false);
--
2.19.1.6.gbde171bbf5


2018-11-09 23:12:44

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 18/23] dynamic_debug: introduce accessors for string members of struct _ddebug

When we introduce compact versions of these pointers (a la
CONFIG_GENERIC_BUG_RELATIVE_POINTERS), all access to these members must
go via appropriate accessors. This just mass-converts dynamic_debug.c to
use the new accessors.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
lib/dynamic_debug.c | 51 ++++++++++++++++++++++++++++++---------------
1 file changed, 34 insertions(+), 17 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index e90459dca34b..dbd837f486f9 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -37,6 +37,23 @@
#include <linux/device.h>
#include <linux/netdevice.h>

+static inline const char *dd_modname(const struct _ddebug *dd)
+{
+ return dd->modname;
+}
+static inline const char *dd_function(const struct _ddebug *dd)
+{
+ return dd->function;
+}
+static inline const char *dd_filename(const struct _ddebug *dd)
+{
+ return dd->filename;
+}
+static inline const char *dd_format(const struct _ddebug *dd)
+{
+ return dd->format;
+}
+
extern struct _ddebug __start___verbose[];
extern struct _ddebug __stop___verbose[];

@@ -158,21 +175,21 @@ static int ddebug_change(const struct ddebug_query *query,

/* match against the source filename */
if (query->filename &&
- !match_wildcard(query->filename, dp->filename) &&
+ !match_wildcard(query->filename, dd_filename(dp)) &&
!match_wildcard(query->filename,
- kbasename(dp->filename)) &&
+ kbasename(dd_filename(dp))) &&
!match_wildcard(query->filename,
- trim_prefix(dp->filename)))
+ trim_prefix(dd_filename(dp))))
continue;

/* match against the function */
if (query->function &&
- !match_wildcard(query->function, dp->function))
+ !match_wildcard(query->function, dd_function(dp)))
continue;

/* match against the format */
if (query->format &&
- !strstr(dp->format, query->format))
+ !strstr(dd_format(dp), query->format))
continue;

/* match against the line number range */
@@ -197,8 +214,8 @@ static int ddebug_change(const struct ddebug_query *query,
#endif
dp->flags = newflags;
vpr_info("changed %s:%d [%s]%s =%s\n",
- trim_prefix(dp->filename), dp->lineno,
- dt->mod_name, dp->function,
+ trim_prefix(dd_filename(dp)), dp->lineno,
+ dt->mod_name, dd_function(dp),
ddebug_describe_flags(dp, flagbuf,
sizeof(flagbuf)));
}
@@ -533,10 +550,10 @@ static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
pos_after_tid = pos;
if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
- desc->modname);
+ dd_modname(desc));
if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
- desc->function);
+ dd_function(desc));
if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
pos += snprintf(buf + pos, remaining(pos), "%d:",
desc->lineno);
@@ -790,10 +807,10 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
}

seq_printf(m, "%s:%u [%s]%s =%s \"",
- trim_prefix(dp->filename), dp->lineno,
- iter->table->mod_name, dp->function,
+ trim_prefix(dd_filename(dp)), dp->lineno,
+ iter->table->mod_name, dd_function(dp),
ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
- seq_escape(m, dp->format, "\t\r\n\"");
+ seq_escape(m, dd_format(dp), "\t\r\n\"");
seq_puts(m, "\"\n");

return 0;
@@ -987,20 +1004,20 @@ static int __init dynamic_debug_init(void)
return 1;
}
iter = __start___verbose;
- modname = iter->modname;
+ modname = dd_modname(iter);
iter_start = iter;
for (; iter < __stop___verbose; iter++) {
entries++;
- verbose_bytes += strlen(iter->modname) + strlen(iter->function)
- + strlen(iter->filename) + strlen(iter->format);
+ verbose_bytes += strlen(dd_modname(iter)) + strlen(dd_function(iter))
+ + strlen(dd_filename(iter)) + strlen(dd_format(iter));

- if (strcmp(modname, iter->modname)) {
+ if (strcmp(modname, dd_modname(iter))) {
modct++;
ret = ddebug_add_module(iter_start, n, modname);
if (ret)
goto out_err;
n = 0;
- modname = iter->modname;
+ modname = dd_modname(iter);
iter_start = iter;
}
n++;
--
2.19.1.6.gbde171bbf5


2018-11-09 23:12:51

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 17/23] ACPI: implement acpi_handle_debug in terms of _dynamic_func_call

With coming changes on x86-64, all dynamic debug descriptors in a
translation unit must have distinct names. The macro _dynamic_func_call
takes care of that. No functional change.

Cc: [email protected]
Acked-by: Rafael J. Wysocki <[email protected]>
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/acpi.h | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index de8633456d71..b284598ae023 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -975,12 +975,8 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
#else
#if defined(CONFIG_DYNAMIC_DEBUG)
#define acpi_handle_debug(handle, fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __acpi_handle_debug(&descriptor, handle, pr_fmt(fmt), \
- ##__VA_ARGS__); \
-} while (0)
+ _dynamic_func_call(fmt, __acpi_handle_debug, \
+ handle, pr_fmt(fmt), ##__VA_ARGS__)
#else
#define acpi_handle_debug(handle, fmt, ...) \
({ \
--
2.19.1.6.gbde171bbf5


2018-11-09 23:13:04

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 14/23] btrfs: implement btrfs_debug* in terms of helper macro

First, the btrfs_debug macros open-code (one possible definition of)
DYNAMIC_DEBUG_BRANCH, so they don't benefit from the HAVE_JUMP_LABEL
optimization.

Second, changes on x86-64 later in this series require that all struct
_ddebug descriptors in a translation unit use distinct identifiers.

Using the new _dynamic_func_call_no_desc helper macro from
dynamic_debug.h takes care of both of these.

Cc: [email protected]
Acked-by: David Sterba <[email protected]>
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
fs/btrfs/ctree.h | 34 ++++++++++------------------------
1 file changed, 10 insertions(+), 24 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 80953528572d..0d55bf56872f 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3334,31 +3334,17 @@ void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...);

#if defined(CONFIG_DYNAMIC_DEBUG)
#define btrfs_debug(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk(fs_info, KERN_DEBUG fmt, ##args); \
-} while (0)
-#define btrfs_debug_in_rcu(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk_in_rcu(fs_info, KERN_DEBUG fmt, ##args); \
-} while (0)
+ _dynamic_func_call_no_desc(fmt, btrfs_printk, \
+ fs_info, KERN_DEBUG fmt, ##args)
+#define btrfs_debug_in_rcu(fs_info, fmt, args...) \
+ _dynamic_func_call_no_desc(fmt, btrfs_printk_in_rcu, \
+ fs_info, KERN_DEBUG fmt, ##args)
#define btrfs_debug_rl_in_rcu(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk_rl_in_rcu(fs_info, KERN_DEBUG fmt, \
- ##args);\
-} while (0)
-#define btrfs_debug_rl(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk_ratelimited(fs_info, KERN_DEBUG fmt, \
- ##args); \
-} while (0)
+ _dynamic_func_call_no_desc(fmt, btrfs_printk_rl_in_rcu, \
+ fs_info, KERN_DEBUG fmt, ##args)
+#define btrfs_debug_rl(fs_info, fmt, args...) \
+ _dynamic_func_call_no_desc(fmt, btrfs_printk_ratelimited, \
+ fs_info, KERN_DEBUG fmt, ##args)
#elif defined(DEBUG)
#define btrfs_debug(fs_info, fmt, args...) \
btrfs_printk(fs_info, KERN_DEBUG fmt, ##args)
--
2.19.1.6.gbde171bbf5


2018-11-09 23:13:08

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 15/23] ACPI: use proper DYNAMIC_DEBUG_BRANCH macro

dynamic debug may be implemented via static keys, but ACPI is missing
out on that runtime benefit since it open-codes one possible definition
of DYNAMIC_DEBUG_BRANCH.

Cc: [email protected]
Acked-by: Jason Baron <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/acpi.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index ed80f147bd50..052e6492ebd7 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -980,7 +980,7 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
#define acpi_handle_debug(handle, fmt, ...) \
do { \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
__acpi_handle_debug(&descriptor, handle, pr_fmt(fmt), \
##__VA_ARGS__); \
} while (0)
--
2.19.1.6.gbde171bbf5


2018-11-09 23:13:19

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 13/23] dynamic_debug: refactor dynamic_pr_debug and friends

For the upcoming 'define the _ddebug descriptor in assembly', we need
all the descriptors in a translation unit to have distinct
names (because asm does not understand C scope). The easiest way to
achieve that is as usual with an extra level of macros, passing the
identifier to use to the innermost macro, generating it via __UNIQUE_ID
or something.

However, instead of repeating that exercise for dynamic_pr_debug,
dynamic_dev_dbg, dynamic_netdev_dbg and dynamic_hex_dump separately, we
can use the similarity between their bodies to implement them via a
common macro, _dynamic_func_call - though the hex_dump case requires
a slight variant, since print_hex_dump does not take the _ddebug
descriptor. We'll also get to use that variant elsewhere (btrfs).

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 72 +++++++++++++++++++++--------------
1 file changed, 43 insertions(+), 29 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 6a002b789d51..b9424097df37 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -112,40 +112,54 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,

#endif

-#define dynamic_pr_debug(fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __dynamic_pr_debug(&descriptor, pr_fmt(fmt), \
- ##__VA_ARGS__); \
+#define __dynamic_func_call(id, fmt, func, ...) do { \
+ DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
+ if (DYNAMIC_DEBUG_BRANCH(id)) \
+ func(&id, ##__VA_ARGS__); \
} while (0)

-#define dynamic_dev_dbg(dev, fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __dynamic_dev_dbg(&descriptor, dev, fmt, \
- ##__VA_ARGS__); \
+#define __dynamic_func_call_no_desc(id, fmt, func, ...) do { \
+ DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
+ if (DYNAMIC_DEBUG_BRANCH(id)) \
+ func(__VA_ARGS__); \
} while (0)

-#define dynamic_netdev_dbg(dev, fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __dynamic_netdev_dbg(&descriptor, dev, fmt, \
- ##__VA_ARGS__); \
-} while (0)
+/*
+ * "Factory macro" for generating a call to func, guarded by a
+ * DYNAMIC_DEBUG_BRANCH. The dynamic debug decriptor will be
+ * initialized using the fmt argument. The function will be called with
+ * the address of the descriptor as first argument, followed by all
+ * the varargs. Note that fmt is repeated in invocations of this
+ * macro.
+ */
+#define _dynamic_func_call(fmt, func, ...) \
+ __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
+/*
+ * A variant that does the same, except that the descriptor is not
+ * passed as the first argument to the function; it is only called
+ * with precisely the macro's varargs.
+ */
+#define _dynamic_func_call_no_desc(fmt, func, ...) \
+ __dynamic_func_call_no_desc(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)

-#define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
- groupsize, buf, len, ascii) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, \
- __builtin_constant_p(prefix_str) ? prefix_str : "hexdump");\
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- print_hex_dump(KERN_DEBUG, prefix_str, \
- prefix_type, rowsize, groupsize, \
- buf, len, ascii); \
-} while (0)
+#define dynamic_pr_debug(fmt, ...) \
+ _dynamic_func_call(fmt, __dynamic_pr_debug, \
+ pr_fmt(fmt), ##__VA_ARGS__)
+
+#define dynamic_dev_dbg(dev, fmt, ...) \
+ _dynamic_func_call(fmt,__dynamic_dev_dbg, \
+ dev, fmt, ##__VA_ARGS__)
+
+#define dynamic_netdev_dbg(dev, fmt, ...) \
+ _dynamic_func_call(fmt, __dynamic_netdev_dbg, \
+ dev, fmt, ##__VA_ARGS__)
+
+#define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
+ groupsize, buf, len, ascii) \
+ _dynamic_func_call_no_desc(__builtin_constant_p(prefix_str) ? prefix_str : "hexdump", \
+ print_hex_dump, \
+ KERN_DEBUG, prefix_str, prefix_type, \
+ rowsize, groupsize, buf, len, ascii)

#else

--
2.19.1.6.gbde171bbf5


2018-11-09 23:13:31

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 11/23] dynamic_debug: move pr_err from module.c to ddebug_add_module

This serves two purposes: First, we get a diagnostic if (though
extremely unlikely), any of the calls of ddebug_add_module for built-in
code fails, effectively disabling dynamic_debug. Second, I want to make
struct _ddebug opaque, and avoid accessing any of its members outside
dynamic_debug.[ch].

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
kernel/module.c | 4 +---
lib/dynamic_debug.c | 4 +++-
2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index 49a405891587..80ede55db25a 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2716,9 +2716,7 @@ static void dynamic_debug_setup(struct module *mod, struct _ddebug *debug, unsig
if (!debug)
return;
#ifdef CONFIG_DYNAMIC_DEBUG
- if (ddebug_add_module(debug, num, mod->name))
- pr_err("dynamic debug error adding module: %s\n",
- debug->modname);
+ ddebug_add_module(debug, num, mod->name);
#endif
}

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index f1de45a100fa..e90459dca34b 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -849,8 +849,10 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
struct ddebug_table *dt;

dt = kzalloc(sizeof(*dt), GFP_KERNEL);
- if (dt == NULL)
+ if (dt == NULL) {
+ pr_err("error adding module: %s\n", name);
return -ENOMEM;
+ }
/*
* For built-in modules, name lives in .rodata and is
* immortal. For loaded modules, name points at the name[]
--
2.19.1.6.gbde171bbf5


2018-11-09 23:13:36

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 10/23] dynamic_debug: remove unused EXPORT_SYMBOLs

The only caller of ddebug_{add,remove}_module outside dynamic_debug.c is
kernel/module.c, which is obviously not itself modular (though it would
be an interesting exercise to make that happen...). I also fail to see
how these interfaces can be used by modules, in-tree or not.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
lib/dynamic_debug.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index ab81155f928d..f1de45a100fa 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -868,7 +868,6 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
vpr_info("%u debug prints in module %s\n", n, dt->mod_name);
return 0;
}
-EXPORT_SYMBOL_GPL(ddebug_add_module);

/* helper for ddebug_dyndbg_(boot|module)_param_cb */
static int ddebug_dyndbg_param_cb(char *param, char *val,
@@ -938,7 +937,6 @@ int ddebug_remove_module(const char *mod_name)
mutex_unlock(&ddebug_lock);
return ret;
}
-EXPORT_SYMBOL_GPL(ddebug_remove_module);

static void ddebug_remove_all_tables(void)
{
--
2.19.1.6.gbde171bbf5


2018-11-09 23:13:42

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 09/23] dynamic_debug: use pointer comparison in ddebug_remove_module

Now that we store the passed-in string directly in ddebug_add_module, we
can use pointer equality instead of strcmp. This is a little more
efficient, but more importantly, this also makes the code somewhat more
correct:

Currently, if one loads and then unloads a module whose name happens to
match the KBUILD_MODNAME of some built-in functionality (which need not
even be modular at all), all of their dynamic debug entries vanish along
with those of the actual module. For example, loading and unloading a
core.ko hides all pr_debugs from drivers/base/core.c and other built-in
files called core.c (incidentally, there is an in-tree module whose name
is core, but I just tested this with an out-of-tree trivial one).

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
lib/dynamic_debug.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 2155e0e23530..ab81155f928d 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -929,9 +929,10 @@ int ddebug_remove_module(const char *mod_name)

mutex_lock(&ddebug_lock);
list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
- if (!strcmp(dt->mod_name, mod_name)) {
+ if (dt->mod_name == mod_name) {
ddebug_table_free(dt);
ret = 0;
+ break;
}
}
mutex_unlock(&ddebug_lock);
--
2.19.1.6.gbde171bbf5


2018-11-09 23:13:49

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 19/23] dynamic_debug: drop use of bitfields in struct _ddebug

Properly initializing a struct containing bitfields in assembly is
hard. Instead, merge lineno and flags to a single unsigned int, which we
mask manually. This should not cause any worse code than what gcc would
need to generate for accessing the bitfields anyway.

Actually, on 64 bit, there is a four byte hole after these fields, so we
could just give flags and lineno each their own u32. But I don't think
that's worth the ifdeffery.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 12 ++++------
lib/dynamic_debug.c | 44 +++++++++++++++++++++++------------
2 files changed, 34 insertions(+), 22 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index b9424097df37..e1be30e8422b 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -20,7 +20,6 @@ struct _ddebug {
const char *function;
const char *filename;
const char *format;
- unsigned int lineno:18;
/*
* The flags field controls the behaviour at the callsite.
* The bits here are changed dynamically when the user
@@ -37,7 +36,7 @@ struct _ddebug {
#else
#define _DPRINTK_FLAGS_DEFAULT 0
#endif
- unsigned int flags:8;
+ unsigned int flags_lineno; /* flags in lower 8 bits, lineno in upper 24 */
#ifdef HAVE_JUMP_LABEL
union {
struct static_key_true dd_key_true;
@@ -46,7 +45,7 @@ struct _ddebug {
#endif
} __attribute__((aligned(8)));

-
+#define _DPRINTK_FLAGS_LINENO_INIT (((unsigned)__LINE__ << 8) | _DPRINTK_FLAGS_DEFAULT)

#if defined(CONFIG_DYNAMIC_DEBUG)
int ddebug_add_module(struct _ddebug *tab, unsigned int n,
@@ -78,8 +77,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
.function = __func__, \
.filename = __FILE__, \
.format = (fmt), \
- .lineno = __LINE__, \
- .flags = _DPRINTK_FLAGS_DEFAULT, \
+ .flags_lineno = _DPRINTK_FLAGS_LINENO_INIT, \
_DPRINTK_KEY_INIT \
}

@@ -104,10 +102,10 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,

#ifdef DEBUG
#define DYNAMIC_DEBUG_BRANCH(descriptor) \
- likely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
+ likely(descriptor.flags_lineno & _DPRINTK_FLAGS_PRINT)
#else
#define DYNAMIC_DEBUG_BRANCH(descriptor) \
- unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
+ unlikely(descriptor.flags_lineno & _DPRINTK_FLAGS_PRINT)
#endif

#endif
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index dbd837f486f9..9d4c840ff0de 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -53,6 +53,18 @@ static inline const char *dd_format(const struct _ddebug *dd)
{
return dd->format;
}
+static inline unsigned dd_lineno(const struct _ddebug *dd)
+{
+ return dd->flags_lineno >> 8;
+}
+static inline unsigned dd_flags(const struct _ddebug *dd)
+{
+ return dd->flags_lineno & 0xff;
+}
+static inline void dd_set_flags(struct _ddebug *dd, unsigned newflags)
+{
+ dd->flags_lineno = (dd_lineno(dd) << 8) | newflags;
+}

extern struct _ddebug __start___verbose[];
extern struct _ddebug __stop___verbose[];
@@ -111,7 +123,7 @@ static char *ddebug_describe_flags(struct _ddebug *dp, char *buf,

BUG_ON(maxlen < 6);
for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
- if (dp->flags & opt_array[i].flag)
+ if (dd_flags(dp) & opt_array[i].flag)
*p++ = opt_array[i].opt_char;
if (p == buf)
*p++ = '_';
@@ -157,7 +169,7 @@ static int ddebug_change(const struct ddebug_query *query,
{
int i;
struct ddebug_table *dt;
- unsigned int newflags;
+ unsigned int newflags, oldflags;
unsigned int nfound = 0;
char flagbuf[10];

@@ -194,27 +206,28 @@ static int ddebug_change(const struct ddebug_query *query,

/* match against the line number range */
if (query->first_lineno &&
- dp->lineno < query->first_lineno)
+ dd_lineno(dp) < query->first_lineno)
continue;
if (query->last_lineno &&
- dp->lineno > query->last_lineno)
+ dd_lineno(dp) > query->last_lineno)
continue;

nfound++;

- newflags = (dp->flags & mask) | flags;
- if (newflags == dp->flags)
+ oldflags = dd_flags(dp);
+ newflags = (oldflags & mask) | flags;
+ if (newflags == oldflags)
continue;
#ifdef HAVE_JUMP_LABEL
- if (dp->flags & _DPRINTK_FLAGS_PRINT) {
+ if (oldflags & _DPRINTK_FLAGS_PRINT) {
if (!(flags & _DPRINTK_FLAGS_PRINT))
static_branch_disable(&dp->key.dd_key_true);
} else if (flags & _DPRINTK_FLAGS_PRINT)
static_branch_enable(&dp->key.dd_key_true);
#endif
- dp->flags = newflags;
+ dd_set_flags(dp, newflags);
vpr_info("changed %s:%d [%s]%s =%s\n",
- trim_prefix(dd_filename(dp)), dp->lineno,
+ trim_prefix(dd_filename(dp)), dd_lineno(dp),
dt->mod_name, dd_function(dp),
ddebug_describe_flags(dp, flagbuf,
sizeof(flagbuf)));
@@ -537,10 +550,11 @@ static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
{
int pos_after_tid;
int pos = 0;
+ unsigned flags = dd_flags(desc);

*buf = '\0';

- if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
+ if (flags & _DPRINTK_FLAGS_INCL_TID) {
if (in_interrupt())
pos += snprintf(buf + pos, remaining(pos), "<intr> ");
else
@@ -548,15 +562,15 @@ static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
task_pid_vnr(current));
}
pos_after_tid = pos;
- if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
+ if (flags & _DPRINTK_FLAGS_INCL_MODNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
dd_modname(desc));
- if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
+ if (flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
dd_function(desc));
- if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
+ if (flags & _DPRINTK_FLAGS_INCL_LINENO)
pos += snprintf(buf + pos, remaining(pos), "%d:",
- desc->lineno);
+ dd_lineno(desc));
if (pos - pos_after_tid)
pos += snprintf(buf + pos, remaining(pos), " ");
if (pos >= PREFIX_SIZE)
@@ -807,7 +821,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
}

seq_printf(m, "%s:%u [%s]%s =%s \"",
- trim_prefix(dd_filename(dp)), dp->lineno,
+ trim_prefix(dd_filename(dp)), dd_lineno(dp),
iter->table->mod_name, dd_function(dp),
ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
seq_escape(m, dd_format(dp), "\t\r\n\"");
--
2.19.1.6.gbde171bbf5


2018-11-09 23:14:08

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 16/23] ACPI: remove unused __acpi_handle_debug macro

If CONFIG_DYNAMIC_DEBUG is not set, acpi_handle_debug directly invokes
acpi_handle_printk (if DEBUG) or does a no-printk (if !DEBUG). So this
macro is never used.

Cc: [email protected]
Acked-by: Jason Baron <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/acpi.h | 3 ---
1 file changed, 3 deletions(-)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 052e6492ebd7..de8633456d71 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -946,9 +946,6 @@ acpi_handle_printk(const char *level, void *handle, const char *fmt, ...) {}
#if defined(CONFIG_ACPI) && defined(CONFIG_DYNAMIC_DEBUG)
__printf(3, 4)
void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const char *fmt, ...);
-#else
-#define __acpi_handle_debug(descriptor, handle, fmt, ...) \
- acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__);
#endif

/*
--
2.19.1.6.gbde171bbf5


2018-11-09 23:14:10

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 03/23] linux/net.h: use DYNAMIC_DEBUG_BRANCH in net_dbg_ratelimited

net_dbg_ratelimited tests the dynamic debug descriptor the old-fashioned
way, and doesn't utilize the static key/jump label implementation on
architectures that HAVE_JUMP_LABEL. Use the DYNAMIC_DEBUG_BRANCH which
is defined appropriately.

Cc: [email protected]
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/net.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/net.h b/include/linux/net.h
index e0930678c8bf..651fca72286c 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -263,7 +263,7 @@ do { \
#define net_dbg_ratelimited(fmt, ...) \
do { \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
net_ratelimit()) \
__dynamic_pr_debug(&descriptor, pr_fmt(fmt), \
##__VA_ARGS__); \
--
2.19.1.6.gbde171bbf5


2018-11-09 23:14:27

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 02/23] linux/device.h: use unique identifier for each struct _ddebug

Changes on x86-64 later in this series require that all struct _ddebug
descriptors in a translation unit uses distinct identifiers. Realize
that for dev_dbg_ratelimited by generating such an identifier via
__UNIQUE_ID and pass that to an extra level of macros.

No functional change.

Reviewed-by: Greg Kroah-Hartman <[email protected]>
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/device.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/device.h b/include/linux/device.h
index 061cd83ac64c..6e0909db6dda 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1532,7 +1532,7 @@ do { \
dev_level_ratelimited(dev_info, dev, fmt, ##__VA_ARGS__)
#if defined(CONFIG_DYNAMIC_DEBUG)
/* descriptor check is first to prevent flooding with "callbacks suppressed" */
-#define dev_dbg_ratelimited(dev, fmt, ...) \
+#define _dev_dbg_ratelimited(descriptor, dev, fmt, ...) \
do { \
static DEFINE_RATELIMIT_STATE(_rs, \
DEFAULT_RATELIMIT_INTERVAL, \
@@ -1543,6 +1543,8 @@ do { \
__dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \
##__VA_ARGS__); \
} while (0)
+#define dev_dbg_ratelimited(dev, fmt, ...) \
+ _dev_dbg_ratelimited(__UNIQUE_ID(ddebug), dev, fmt, ##__VA_ARGS__)
#elif defined(DEBUG)
#define dev_dbg_ratelimited(dev, fmt, ...) \
do { \
--
2.19.1.6.gbde171bbf5


2018-11-09 23:14:27

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 12/23] dynamic_debug: add static inline stub for ddebug_add_module

For symmetry with ddebug_remove_module, and to avoid a bit of ifdeffery
in module.c, move the declaration of ddebug_add_module inside #if
defined(CONFIG_DYNAMIC_DEBUG) and add a corresponding no-op stub in the
#else branch.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 10 ++++++++--
kernel/module.c | 2 --
2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 0a643316597c..6a002b789d51 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -47,10 +47,10 @@ struct _ddebug {
} __attribute__((aligned(8)));


-int ddebug_add_module(struct _ddebug *tab, unsigned int n,
- const char *modname);

#if defined(CONFIG_DYNAMIC_DEBUG)
+int ddebug_add_module(struct _ddebug *tab, unsigned int n,
+ const char *modname);
extern int ddebug_remove_module(const char *mod_name);
extern __printf(2, 3)
void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...);
@@ -152,6 +152,12 @@ do { \
#include <linux/string.h>
#include <linux/errno.h>

+static inline int ddebug_add_module(struct _ddebug *tab, unsigned int n,
+ const char *modname)
+{
+ return 0;
+}
+
static inline int ddebug_remove_module(const char *mod)
{
return 0;
diff --git a/kernel/module.c b/kernel/module.c
index 80ede55db25a..208422b47b08 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2715,9 +2715,7 @@ static void dynamic_debug_setup(struct module *mod, struct _ddebug *debug, unsig
{
if (!debug)
return;
-#ifdef CONFIG_DYNAMIC_DEBUG
ddebug_add_module(debug, num, mod->name);
-#endif
}

static void dynamic_debug_remove(struct module *mod, struct _ddebug *debug)
--
2.19.1.6.gbde171bbf5


2018-11-09 23:14:32

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 01/23] linux/device.h: use DYNAMIC_DEBUG_BRANCH in dev_dbg_ratelimited

dev_dbg_ratelimited tests the dynamic debug descriptor the old-fashioned
way, and doesn't utilize the static key/jump label implementation on
architectures that HAVE_JUMP_LABEL. Use the DYNAMIC_DEBUG_BRANCH which
is defined appropriately.

Reviewed-by: Greg Kroah-Hartman <[email protected]>
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/device.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/device.h b/include/linux/device.h
index 1b25c7a43f4c..061cd83ac64c 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1538,7 +1538,7 @@ do { \
DEFAULT_RATELIMIT_INTERVAL, \
DEFAULT_RATELIMIT_BURST); \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
__ratelimit(&_rs)) \
__dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \
##__VA_ARGS__); \
--
2.19.1.6.gbde171bbf5


2018-11-09 23:14:38

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 00/23] various dynamic_debug patches

This started as an experiment to see how hard it would be to change
the four pointers in struct _ddebug into relative offsets, a la
CONFIG_GENERIC_BUG_RELATIVE_POINTERS, thus saving 16 bytes per
pr_debug site (and thus exactly making up for the extra space used by
the introduction of jump labels in 9049fc74). I stumbled on a few
things that are probably worth fixing regardless of whether that goal
is deemed worthwhile.

v2: Added various acks/reviews.

v3: Rebased on top of v4.20-rc1, and (consequently) reimplemented the
x86 part using Nadav's asm macro infrastructure. I've taken the
liberty of preserving acks/reviews for the first 20, since the rebase
was completely clean. OTOH, I've removed any acks/reviews from the
last three patches, since they are essentially completely new in this
version.

Since there are some interdependencies, it's simplest if these go
through the same tree. Andrew, can I get you to pick up patches 1
through 17? They should be ready for some time in -next. If and when
the last three (new) patches get ack'ed, I'll ask you to pick up the
last 6 (Jason has ack'ed 18-20, but they don't make much sense without
at least one arch opting in to use DYNAMIC_DEBUG_RELATIVE_POINTERS).

Rasmus Villemoes (23):
linux/device.h: use DYNAMIC_DEBUG_BRANCH in dev_dbg_ratelimited
linux/device.h: use unique identifier for each struct _ddebug
linux/net.h: use DYNAMIC_DEBUG_BRANCH in net_dbg_ratelimited
linux/net.h: use unique identifier for each struct _ddebug
linux/printk.h: use DYNAMIC_DEBUG_BRANCH in pr_debug_ratelimited
linux/printk.h: use unique identifier for each struct _ddebug
dynamic_debug: consolidate DEFINE_DYNAMIC_DEBUG_METADATA definitions
dynamic_debug: don't duplicate modname in ddebug_add_module
dynamic_debug: use pointer comparison in ddebug_remove_module
dynamic_debug: remove unused EXPORT_SYMBOLs
dynamic_debug: move pr_err from module.c to ddebug_add_module
dynamic_debug: add static inline stub for ddebug_add_module
dynamic_debug: refactor dynamic_pr_debug and friends
btrfs: implement btrfs_debug* in terms of helper macro
ACPI: use proper DYNAMIC_DEBUG_BRANCH macro
ACPI: remove unused __acpi_handle_debug macro
ACPI: implement acpi_handle_debug in terms of _dynamic_func_call
dynamic_debug: introduce accessors for string members of struct
_ddebug
dynamic_debug: drop use of bitfields in struct _ddebug
dynamic_debug: introduce CONFIG_DYNAMIC_DEBUG_RELATIVE_POINTERS
jump_label: move JUMP_TYPE_* constants to new asm-generic file
x86: jump_label: introduce asm macros STATIC_KEY_INIT{,_TRUE,_FALSE}
x86_64: use relative pointers with dynamic debug

arch/x86/Kconfig | 1 +
arch/x86/include/asm/dynamic_debug.h | 58 ++++++++++++
arch/x86/include/asm/jump_label.h | 17 ++++
arch/x86/kernel/macros.S | 1 +
fs/btrfs/ctree.h | 34 ++-----
include/asm-generic/jump_label.h | 11 +++
include/linux/acpi.h | 11 +--
include/linux/device.h | 6 +-
include/linux/dynamic_debug.h | 126 +++++++++++++++----------
include/linux/jump_label.h | 6 +-
include/linux/net.h | 6 +-
include/linux/printk.h | 6 +-
kernel/module.c | 6 +-
lib/Kconfig.debug | 3 +
lib/dynamic_debug.c | 133 ++++++++++++++++++---------
15 files changed, 284 insertions(+), 141 deletions(-)
create mode 100644 arch/x86/include/asm/dynamic_debug.h
create mode 100644 include/asm-generic/jump_label.h

--
2.19.1.6.gbde171bbf5


2018-11-09 23:14:50

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 08/23] dynamic_debug: don't duplicate modname in ddebug_add_module

For built-in modules, we're already reusing the passed-in string via
kstrdup_const(). But for actual modules (i.e. when we're called from
dynamic_debug_setup in module.c), the passed-in string (which points
at the name[] array inside struct module) is also
guaranteed to live at least as long as the struct ddebug_table, since
free_module() calls ddebug_remove_module().

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
lib/dynamic_debug.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index c7c96bc7654a..2155e0e23530 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -847,17 +847,17 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
const char *name)
{
struct ddebug_table *dt;
- const char *new_name;

dt = kzalloc(sizeof(*dt), GFP_KERNEL);
if (dt == NULL)
return -ENOMEM;
- new_name = kstrdup_const(name, GFP_KERNEL);
- if (new_name == NULL) {
- kfree(dt);
- return -ENOMEM;
- }
- dt->mod_name = new_name;
+ /*
+ * For built-in modules, name lives in .rodata and is
+ * immortal. For loaded modules, name points at the name[]
+ * member of struct module, which lives at least as long as
+ * this struct ddebug_table.
+ */
+ dt->mod_name = name;
dt->num_ddebugs = n;
dt->ddebugs = tab;

@@ -913,7 +913,6 @@ int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
static void ddebug_table_free(struct ddebug_table *dt)
{
list_del_init(&dt->link);
- kfree_const(dt->mod_name);
kfree(dt);
}

--
2.19.1.6.gbde171bbf5


2018-11-09 23:15:04

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 07/23] dynamic_debug: consolidate DEFINE_DYNAMIC_DEBUG_METADATA definitions

Instead of defining DEFINE_DYNAMIC_DEBUG_METADATA in terms of a helper
DEFINE_DYNAMIC_DEBUG_METADATA_KEY, that needs another helper
dd_key_init to be properly defined, just make the various #ifdef
branches define a _DPRINTK_KEY_INIT that can be used directly, similar
to _DPRINTK_FLAGS_DEFAULT.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 22 +++++++---------------
1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 2fd8006153c3..0a643316597c 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -71,7 +71,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
const struct net_device *dev,
const char *fmt, ...);

-#define DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, key, init) \
+#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
static struct _ddebug __aligned(8) \
__attribute__((section("__verbose"))) name = { \
.modname = KBUILD_MODNAME, \
@@ -80,35 +80,27 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
.format = (fmt), \
.lineno = __LINE__, \
.flags = _DPRINTK_FLAGS_DEFAULT, \
- dd_key_init(key, init) \
+ _DPRINTK_KEY_INIT \
}

#ifdef HAVE_JUMP_LABEL

-#define dd_key_init(key, init) key = (init)
-
#ifdef DEBUG
-#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
- DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_true, \
- (STATIC_KEY_TRUE_INIT))
+
+#define _DPRINTK_KEY_INIT .key.dd_key_true = (STATIC_KEY_TRUE_INIT)

#define DYNAMIC_DEBUG_BRANCH(descriptor) \
static_branch_likely(&descriptor.key.dd_key_true)
#else
-#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
- DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_false, \
- (STATIC_KEY_FALSE_INIT))
+#define _DPRINTK_KEY_INIT .key.dd_key_false = (STATIC_KEY_FALSE_INIT)

#define DYNAMIC_DEBUG_BRANCH(descriptor) \
static_branch_unlikely(&descriptor.key.dd_key_false)
#endif

-#else
-
-#define dd_key_init(key, init)
+#else /* !HAVE_JUMP_LABEL */

-#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
- DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, 0, 0)
+#define _DPRINTK_KEY_INIT

#ifdef DEBUG
#define DYNAMIC_DEBUG_BRANCH(descriptor) \
--
2.19.1.6.gbde171bbf5


2018-11-09 23:15:09

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 06/23] linux/printk.h: use unique identifier for each struct _ddebug

Changes on x86-64 later in this series require that all struct _ddebug
descriptors in a translation unit uses distinct identifiers. Realize
that for pr_debug_ratelimited by generating such an identifier via
__UNIQUE_ID and pass that to an extra level of macros.

No functional change.

Acked-by: Petr Mladek <[email protected]>
Acked-by: Jason Baron <[email protected]>
Cc: Steven Rostedt <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/printk.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index d3ba3245531d..70df2c578d40 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -460,7 +460,7 @@ extern int kptr_restrict;
/* If you are writing a driver, please use dev_dbg instead */
#if defined(CONFIG_DYNAMIC_DEBUG)
/* descriptor check is first to prevent flooding with "callbacks suppressed" */
-#define pr_debug_ratelimited(fmt, ...) \
+#define _pr_debug_ratelimited(descriptor, fmt, ...) \
do { \
static DEFINE_RATELIMIT_STATE(_rs, \
DEFAULT_RATELIMIT_INTERVAL, \
@@ -470,6 +470,8 @@ do { \
__ratelimit(&_rs)) \
__dynamic_pr_debug(&descriptor, pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
+#define pr_debug_ratelimited(fmt, ...) \
+ _pr_debug_ratelimited(__UNIQUE_ID(ddebug), fmt, ##__VA_ARGS__)
#elif defined(DEBUG)
#define pr_debug_ratelimited(fmt, ...) \
printk_ratelimited(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
--
2.19.1.6.gbde171bbf5


2018-11-09 23:15:17

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 05/23] linux/printk.h: use DYNAMIC_DEBUG_BRANCH in pr_debug_ratelimited

pr_debug_ratelimited tests the dynamic debug descriptor the old-fashioned
way, and doesn't utilize the static key/jump label implementation on
architectures that HAVE_JUMP_LABEL. Use the DYNAMIC_DEBUG_BRANCH which
is defined appropriately.

Acked-by: Petr Mladek <[email protected]>
Acked-by: Jason Baron <[email protected]>
Cc: Steven Rostedt <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/printk.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index cf3eccfe1543..d3ba3245531d 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -466,7 +466,7 @@ do { \
DEFAULT_RATELIMIT_INTERVAL, \
DEFAULT_RATELIMIT_BURST); \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, pr_fmt(fmt)); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
__ratelimit(&_rs)) \
__dynamic_pr_debug(&descriptor, pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
--
2.19.1.6.gbde171bbf5


2018-11-09 23:15:29

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v3 04/23] linux/net.h: use unique identifier for each struct _ddebug

Changes on x86-64 later in this series require that all struct _ddebug
descriptors in a translation unit uses distinct identifiers. Realize
that for net_dbg_ratelimited by generating such an identifier via
__UNIQUE_ID and pass that to an extra level of macros.

No functional change.

Cc: [email protected]
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/net.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/net.h b/include/linux/net.h
index 651fca72286c..397243a25f56 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -260,7 +260,7 @@ do { \
#define net_info_ratelimited(fmt, ...) \
net_ratelimited_function(pr_info, fmt, ##__VA_ARGS__)
#if defined(CONFIG_DYNAMIC_DEBUG)
-#define net_dbg_ratelimited(fmt, ...) \
+#define _net_dbg_ratelimited(descriptor, fmt, ...) \
do { \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
@@ -268,6 +268,8 @@ do { \
__dynamic_pr_debug(&descriptor, pr_fmt(fmt), \
##__VA_ARGS__); \
} while (0)
+#define net_dbg_ratelimited(fmt, ...) \
+ _net_dbg_ratelimited(__UNIQUE_ID(ddebug), fmt, ##__VA_ARGS__)
#elif defined(DEBUG)
#define net_dbg_ratelimited(fmt, ...) \
net_ratelimited_function(pr_debug, fmt, ##__VA_ARGS__)
--
2.19.1.6.gbde171bbf5


2018-11-09 23:23:26

by Joe Perches

[permalink] [raw]
Subject: Re: [PATCH v3 04/23] linux/net.h: use unique identifier for each struct _ddebug

On Sat, 2018-11-10 at 00:10 +0100, Rasmus Villemoes wrote:
> Changes on x86-64 later in this series require that all struct _ddebug
> descriptors in a translation unit uses distinct identifiers. Realize
> that for net_dbg_ratelimited by generating such an identifier via
> __UNIQUE_ID and pass that to an extra level of macros.
>
> No functional change.

Why does this require an extra indirection _<macro>?

> Cc: [email protected]
> Acked-by: Jason Baron <[email protected]>
> Signed-off-by: Rasmus Villemoes <[email protected]>
> ---
> include/linux/net.h | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/net.h b/include/linux/net.h
> index 651fca72286c..397243a25f56 100644
> --- a/include/linux/net.h
> +++ b/include/linux/net.h
> @@ -260,7 +260,7 @@ do { \
> #define net_info_ratelimited(fmt, ...) \
> net_ratelimited_function(pr_info, fmt, ##__VA_ARGS__)
> #if defined(CONFIG_DYNAMIC_DEBUG)
> -#define net_dbg_ratelimited(fmt, ...) \
> +#define _net_dbg_ratelimited(descriptor, fmt, ...) \
> do { \
> DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
> if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
> @@ -268,6 +268,8 @@ do { \
> __dynamic_pr_debug(&descriptor, pr_fmt(fmt), \
> ##__VA_ARGS__); \
> } while (0)
> +#define net_dbg_ratelimited(fmt, ...) \
> + _net_dbg_ratelimited(__UNIQUE_ID(ddebug), fmt, ##__VA_ARGS__)
> #elif defined(DEBUG)
> #define net_dbg_ratelimited(fmt, ...) \
> net_ratelimited_function(pr_debug, fmt, ##__VA_ARGS__)


2018-11-09 23:32:31

by Rasmus Villemoes

[permalink] [raw]
Subject: Re: [PATCH v3 04/23] linux/net.h: use unique identifier for each struct _ddebug

On 10/11/2018 00.22, Joe Perches wrote:
> On Sat, 2018-11-10 at 00:10 +0100, Rasmus Villemoes wrote:
>> Changes on x86-64 later in this series require that all struct _ddebug
>> descriptors in a translation unit uses distinct identifiers. Realize
>> that for net_dbg_ratelimited by generating such an identifier via
>> __UNIQUE_ID and pass that to an extra level of macros.
>>
>> No functional change.
>
> Why does this require an extra indirection _<macro>?
>

Because the identifier used in the

>> DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);

line must be the same as the one in the

>> if (DYNAMIC_DEBUG_BRANCH(descriptor) &&

line. That identifier used to be simply "descriptor", with C scope rules
making that ok. But because of the asm games I'm playing later, I need
to generate a fresh identifier for each instance. That identifier must
be referenced in two places in the C source - hence the need to use an
extra level of macros to have the __UNIQUE_ID() expanded before
_net_dbg_ratelimited gets expanded.

More or less every use of __UNIQUE_ID requires such an extra level
(because one very rarely needs to use an identifier exactly once - the
point of giving stuff a name is to refer to it again.)

Rasmus

2019-02-12 22:13:00

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v4 10/14] dynamic_debug: refactor dynamic_pr_debug and friends

For the upcoming 'define the _ddebug descriptor in assembly', we need
all the descriptors in a translation unit to have distinct
names (because asm does not understand C scope). The easiest way to
achieve that is as usual with an extra level of macros, passing the
identifier to use to the innermost macro, generating it via __UNIQUE_ID
or something.

However, instead of repeating that exercise for dynamic_pr_debug,
dynamic_dev_dbg, dynamic_netdev_dbg and dynamic_hex_dump separately, we
can use the similarity between their bodies to implement them via a
common macro, _dynamic_func_call - though the hex_dump case requires
a slight variant, since print_hex_dump does not take the _ddebug
descriptor. We'll also get to use that variant elsewhere (btrfs).

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 72 +++++++++++++++++++++--------------
1 file changed, 43 insertions(+), 29 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 3f8977cfa479..c2be029b9b53 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -112,40 +112,54 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,

#endif

-#define dynamic_pr_debug(fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __dynamic_pr_debug(&descriptor, pr_fmt(fmt), \
- ##__VA_ARGS__); \
+#define __dynamic_func_call(id, fmt, func, ...) do { \
+ DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
+ if (DYNAMIC_DEBUG_BRANCH(id)) \
+ func(&id, ##__VA_ARGS__); \
} while (0)

-#define dynamic_dev_dbg(dev, fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __dynamic_dev_dbg(&descriptor, dev, fmt, \
- ##__VA_ARGS__); \
+#define __dynamic_func_call_no_desc(id, fmt, func, ...) do { \
+ DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
+ if (DYNAMIC_DEBUG_BRANCH(id)) \
+ func(__VA_ARGS__); \
} while (0)

-#define dynamic_netdev_dbg(dev, fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __dynamic_netdev_dbg(&descriptor, dev, fmt, \
- ##__VA_ARGS__); \
-} while (0)
+/*
+ * "Factory macro" for generating a call to func, guarded by a
+ * DYNAMIC_DEBUG_BRANCH. The dynamic debug decriptor will be
+ * initialized using the fmt argument. The function will be called with
+ * the address of the descriptor as first argument, followed by all
+ * the varargs. Note that fmt is repeated in invocations of this
+ * macro.
+ */
+#define _dynamic_func_call(fmt, func, ...) \
+ __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
+/*
+ * A variant that does the same, except that the descriptor is not
+ * passed as the first argument to the function; it is only called
+ * with precisely the macro's varargs.
+ */
+#define _dynamic_func_call_no_desc(fmt, func, ...) \
+ __dynamic_func_call_no_desc(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)

-#define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
- groupsize, buf, len, ascii) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, \
- __builtin_constant_p(prefix_str) ? prefix_str : "hexdump");\
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- print_hex_dump(KERN_DEBUG, prefix_str, \
- prefix_type, rowsize, groupsize, \
- buf, len, ascii); \
-} while (0)
+#define dynamic_pr_debug(fmt, ...) \
+ _dynamic_func_call(fmt, __dynamic_pr_debug, \
+ pr_fmt(fmt), ##__VA_ARGS__)
+
+#define dynamic_dev_dbg(dev, fmt, ...) \
+ _dynamic_func_call(fmt,__dynamic_dev_dbg, \
+ dev, fmt, ##__VA_ARGS__)
+
+#define dynamic_netdev_dbg(dev, fmt, ...) \
+ _dynamic_func_call(fmt, __dynamic_netdev_dbg, \
+ dev, fmt, ##__VA_ARGS__)
+
+#define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
+ groupsize, buf, len, ascii) \
+ _dynamic_func_call_no_desc(__builtin_constant_p(prefix_str) ? prefix_str : "hexdump", \
+ print_hex_dump, \
+ KERN_DEBUG, prefix_str, prefix_type, \
+ rowsize, groupsize, buf, len, ascii)

#else

--
2.20.1


2019-02-12 22:13:31

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v4 13/14] ACPI: remove unused __acpi_handle_debug macro

If CONFIG_DYNAMIC_DEBUG is not set, acpi_handle_debug directly invokes
acpi_handle_printk (if DEBUG) or does a no-printk (if !DEBUG). So this
macro is never used.

Cc: [email protected]
Acked-by: Jason Baron <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/acpi.h | 3 ---
1 file changed, 3 deletions(-)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index bcdfbb2bea24..07b9fa507824 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -953,9 +953,6 @@ acpi_handle_printk(const char *level, void *handle, const char *fmt, ...) {}
#if defined(CONFIG_ACPI) && defined(CONFIG_DYNAMIC_DEBUG)
__printf(3, 4)
void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const char *fmt, ...);
-#else
-#define __acpi_handle_debug(descriptor, handle, fmt, ...) \
- acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__);
#endif

/*
--
2.20.1


2019-02-12 22:15:23

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v4 14/14] ACPI: implement acpi_handle_debug in terms of _dynamic_func_call

With coming changes on x86-64, all dynamic debug descriptors in a
translation unit must have distinct names. The macro _dynamic_func_call
takes care of that. No functional change.

Cc: [email protected]
Acked-by: Rafael J. Wysocki <[email protected]>
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/acpi.h | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 07b9fa507824..96c4eaed9439 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -982,12 +982,8 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
#else
#if defined(CONFIG_DYNAMIC_DEBUG)
#define acpi_handle_debug(handle, fmt, ...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
- __acpi_handle_debug(&descriptor, handle, pr_fmt(fmt), \
- ##__VA_ARGS__); \
-} while (0)
+ _dynamic_func_call(fmt, __acpi_handle_debug, \
+ handle, pr_fmt(fmt), ##__VA_ARGS__)
#else
#define acpi_handle_debug(handle, fmt, ...) \
({ \
--
2.20.1


2019-02-12 22:15:30

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v4 12/14] ACPI: use proper DYNAMIC_DEBUG_BRANCH macro

dynamic debug may be implemented via static keys, but ACPI is missing
out on that runtime benefit since it open-codes one possible definition
of DYNAMIC_DEBUG_BRANCH.

Cc: [email protected]
Acked-by: Jason Baron <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/acpi.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 87715f20b69a..bcdfbb2bea24 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -987,7 +987,7 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
#define acpi_handle_debug(handle, fmt, ...) \
do { \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
__acpi_handle_debug(&descriptor, handle, pr_fmt(fmt), \
##__VA_ARGS__); \
} while (0)
--
2.20.1


2019-02-12 22:16:26

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v4 11/14] btrfs: implement btrfs_debug* in terms of helper macro

First, the btrfs_debug macros open-code (one possible definition of)
DYNAMIC_DEBUG_BRANCH, so they don't benefit from the CONFIG_JUMP_LABEL
optimization.

Second, a planned change of struct _ddebug (to reduce its size on 64
bit machines) requires that all descriptors in a translation unit use
distinct identifiers.

Using the new _dynamic_func_call_no_desc helper macro from
dynamic_debug.h takes care of both of these. No functional change.

Cc: [email protected]
Acked-by: David Sterba <[email protected]>
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
fs/btrfs/ctree.h | 34 ++++++++++------------------------
1 file changed, 10 insertions(+), 24 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 7a2a2621f0d9..94618a028730 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3415,31 +3415,17 @@ void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...);

#if defined(CONFIG_DYNAMIC_DEBUG)
#define btrfs_debug(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk(fs_info, KERN_DEBUG fmt, ##args); \
-} while (0)
-#define btrfs_debug_in_rcu(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk_in_rcu(fs_info, KERN_DEBUG fmt, ##args); \
-} while (0)
+ _dynamic_func_call_no_desc(fmt, btrfs_printk, \
+ fs_info, KERN_DEBUG fmt, ##args)
+#define btrfs_debug_in_rcu(fs_info, fmt, args...) \
+ _dynamic_func_call_no_desc(fmt, btrfs_printk_in_rcu, \
+ fs_info, KERN_DEBUG fmt, ##args)
#define btrfs_debug_rl_in_rcu(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk_rl_in_rcu(fs_info, KERN_DEBUG fmt, \
- ##args);\
-} while (0)
-#define btrfs_debug_rl(fs_info, fmt, args...) \
-do { \
- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
- btrfs_printk_ratelimited(fs_info, KERN_DEBUG fmt, \
- ##args); \
-} while (0)
+ _dynamic_func_call_no_desc(fmt, btrfs_printk_rl_in_rcu, \
+ fs_info, KERN_DEBUG fmt, ##args)
+#define btrfs_debug_rl(fs_info, fmt, args...) \
+ _dynamic_func_call_no_desc(fmt, btrfs_printk_ratelimited, \
+ fs_info, KERN_DEBUG fmt, ##args)
#elif defined(DEBUG)
#define btrfs_debug(fs_info, fmt, args...) \
btrfs_printk(fs_info, KERN_DEBUG fmt, ##args)
--
2.20.1


2019-02-12 22:17:20

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v4 09/14] dynamic_debug: add static inline stub for ddebug_add_module

For symmetry with ddebug_remove_module, and to avoid a bit of ifdeffery
in module.c, move the declaration of ddebug_add_module inside #if
defined(CONFIG_DYNAMIC_DEBUG) and add a corresponding no-op stub in the
#else branch.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 10 ++++++++--
kernel/module.c | 2 --
2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index b17725400f75..3f8977cfa479 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -47,10 +47,10 @@ struct _ddebug {
} __attribute__((aligned(8)));


-int ddebug_add_module(struct _ddebug *tab, unsigned int n,
- const char *modname);

#if defined(CONFIG_DYNAMIC_DEBUG)
+int ddebug_add_module(struct _ddebug *tab, unsigned int n,
+ const char *modname);
extern int ddebug_remove_module(const char *mod_name);
extern __printf(2, 3)
void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...);
@@ -152,6 +152,12 @@ do { \
#include <linux/string.h>
#include <linux/errno.h>

+static inline int ddebug_add_module(struct _ddebug *tab, unsigned int n,
+ const char *modname)
+{
+ return 0;
+}
+
static inline int ddebug_remove_module(const char *mod)
{
return 0;
diff --git a/kernel/module.c b/kernel/module.c
index 7b1d437c1ea6..0b9aa8ab89f0 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2719,9 +2719,7 @@ static void dynamic_debug_setup(struct module *mod, struct _ddebug *debug, unsig
{
if (!debug)
return;
-#ifdef CONFIG_DYNAMIC_DEBUG
ddebug_add_module(debug, num, mod->name);
-#endif
}

static void dynamic_debug_remove(struct module *mod, struct _ddebug *debug)
--
2.20.1


2019-02-12 22:17:40

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v4 06/14] dynamic_debug: use pointer comparison in ddebug_remove_module

Now that we store the passed-in string directly in ddebug_add_module, we
can use pointer equality instead of strcmp. This is a little more
efficient, but more importantly, this also makes the code somewhat more
correct:

Currently, if one loads and then unloads a module whose name happens to
match the KBUILD_MODNAME of some built-in functionality (which need not
even be modular at all), all of their dynamic debug entries vanish along
with those of the actual module. For example, loading and unloading a
core.ko hides all pr_debugs from drivers/base/core.c and other built-in
files called core.c (incidentally, there is an in-tree module whose name
is core, but I just tested this with an out-of-tree trivial one).

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
lib/dynamic_debug.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 8274c4ea75e0..214828c65625 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -929,9 +929,10 @@ int ddebug_remove_module(const char *mod_name)

mutex_lock(&ddebug_lock);
list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
- if (!strcmp(dt->mod_name, mod_name)) {
+ if (dt->mod_name == mod_name) {
ddebug_table_free(dt);
ret = 0;
+ break;
}
}
mutex_unlock(&ddebug_lock);
--
2.20.1


2019-02-12 22:20:19

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v4 08/14] dynamic_debug: move pr_err from module.c to ddebug_add_module

This serves two purposes: First, we get a diagnostic if (though
extremely unlikely), any of the calls of ddebug_add_module for built-in
code fails, effectively disabling dynamic_debug. Second, I want to make
struct _ddebug opaque, and avoid accessing any of its members outside
dynamic_debug.[ch].

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
kernel/module.c | 4 +---
lib/dynamic_debug.c | 4 +++-
2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index 2ad1b5239910..7b1d437c1ea6 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2720,9 +2720,7 @@ static void dynamic_debug_setup(struct module *mod, struct _ddebug *debug, unsig
if (!debug)
return;
#ifdef CONFIG_DYNAMIC_DEBUG
- if (ddebug_add_module(debug, num, mod->name))
- pr_err("dynamic debug error adding module: %s\n",
- debug->modname);
+ ddebug_add_module(debug, num, mod->name);
#endif
}

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 7b76f43edaef..7bdf98c37e91 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -849,8 +849,10 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
struct ddebug_table *dt;

dt = kzalloc(sizeof(*dt), GFP_KERNEL);
- if (dt == NULL)
+ if (dt == NULL) {
+ pr_err("error adding module: %s\n", name);
return -ENOMEM;
+ }
/*
* For built-in modules, name lives in .rodata and is
* immortal. For loaded modules, name points at the name[]
--
2.20.1


2019-02-12 22:20:48

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v4 05/14] dynamic_debug: don't duplicate modname in ddebug_add_module

For built-in modules, we're already reusing the passed-in string via
kstrdup_const(). But for actual modules (i.e. when we're called from
dynamic_debug_setup in module.c), the passed-in string (which points
at the name[] array inside struct module) is also
guaranteed to live at least as long as the struct ddebug_table, since
free_module() calls ddebug_remove_module().

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
lib/dynamic_debug.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index dbf2b457e47e..8274c4ea75e0 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -847,17 +847,17 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
const char *name)
{
struct ddebug_table *dt;
- const char *new_name;

dt = kzalloc(sizeof(*dt), GFP_KERNEL);
if (dt == NULL)
return -ENOMEM;
- new_name = kstrdup_const(name, GFP_KERNEL);
- if (new_name == NULL) {
- kfree(dt);
- return -ENOMEM;
- }
- dt->mod_name = new_name;
+ /*
+ * For built-in modules, name lives in .rodata and is
+ * immortal. For loaded modules, name points at the name[]
+ * member of struct module, which lives at least as long as
+ * this struct ddebug_table.
+ */
+ dt->mod_name = name;
dt->num_ddebugs = n;
dt->ddebugs = tab;

@@ -913,7 +913,6 @@ int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
static void ddebug_table_free(struct ddebug_table *dt)
{
list_del_init(&dt->link);
- kfree_const(dt->mod_name);
kfree(dt);
}

--
2.20.1


2019-02-12 22:24:08

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v4 07/14] dynamic_debug: remove unused EXPORT_SYMBOLs

The only caller of ddebug_{add,remove}_module outside dynamic_debug.c is
kernel/module.c, which is obviously not itself modular (though it would
be an interesting exercise to make that happen...). I also fail to see
how these interfaces can be used by modules, in-tree or not.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
lib/dynamic_debug.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 214828c65625..7b76f43edaef 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -868,7 +868,6 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
vpr_info("%u debug prints in module %s\n", n, dt->mod_name);
return 0;
}
-EXPORT_SYMBOL_GPL(ddebug_add_module);

/* helper for ddebug_dyndbg_(boot|module)_param_cb */
static int ddebug_dyndbg_param_cb(char *param, char *val,
@@ -938,7 +937,6 @@ int ddebug_remove_module(const char *mod_name)
mutex_unlock(&ddebug_lock);
return ret;
}
-EXPORT_SYMBOL_GPL(ddebug_remove_module);

static void ddebug_remove_all_tables(void)
{
--
2.20.1


2019-02-12 22:24:48

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v4 03/14] linux/printk.h: use DYNAMIC_DEBUG_BRANCH in pr_debug_ratelimited

pr_debug_ratelimited tests the dynamic debug descriptor the
old-fashioned way, and doesn't utilize the static key/jump label
implementation when CONFIG_JUMP_LABEL is set. Use the
DYNAMIC_DEBUG_BRANCH which is defined appropriately.

Acked-by: Petr Mladek <[email protected]>
Acked-by: Jason Baron <[email protected]>
Cc: Steven Rostedt <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/printk.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index 77740a506ebb..02b5c115d89b 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -461,7 +461,7 @@ do { \
DEFAULT_RATELIMIT_INTERVAL, \
DEFAULT_RATELIMIT_BURST); \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, pr_fmt(fmt)); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
__ratelimit(&_rs)) \
__dynamic_pr_debug(&descriptor, pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
--
2.20.1


2019-02-12 22:24:58

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v4 04/14] dynamic_debug: consolidate DEFINE_DYNAMIC_DEBUG_METADATA definitions

Instead of defining DEFINE_DYNAMIC_DEBUG_METADATA in terms of a helper
DEFINE_DYNAMIC_DEBUG_METADATA_KEY, that needs another helper
dd_key_init to be properly defined, just make the various #ifdef
branches define a _DPRINTK_KEY_INIT that can be used directly, similar
to _DPRINTK_FLAGS_DEFAULT.

Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/dynamic_debug.h | 22 +++++++---------------
1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index b3419da1a776..b17725400f75 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -71,7 +71,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
const struct net_device *dev,
const char *fmt, ...);

-#define DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, key, init) \
+#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
static struct _ddebug __aligned(8) \
__attribute__((section("__verbose"))) name = { \
.modname = KBUILD_MODNAME, \
@@ -80,35 +80,27 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
.format = (fmt), \
.lineno = __LINE__, \
.flags = _DPRINTK_FLAGS_DEFAULT, \
- dd_key_init(key, init) \
+ _DPRINTK_KEY_INIT \
}

#ifdef CONFIG_JUMP_LABEL

-#define dd_key_init(key, init) key = (init)
-
#ifdef DEBUG
-#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
- DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_true, \
- (STATIC_KEY_TRUE_INIT))
+
+#define _DPRINTK_KEY_INIT .key.dd_key_true = (STATIC_KEY_TRUE_INIT)

#define DYNAMIC_DEBUG_BRANCH(descriptor) \
static_branch_likely(&descriptor.key.dd_key_true)
#else
-#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
- DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_false, \
- (STATIC_KEY_FALSE_INIT))
+#define _DPRINTK_KEY_INIT .key.dd_key_false = (STATIC_KEY_FALSE_INIT)

#define DYNAMIC_DEBUG_BRANCH(descriptor) \
static_branch_unlikely(&descriptor.key.dd_key_false)
#endif

-#else
-
-#define dd_key_init(key, init)
+#else /* !HAVE_JUMP_LABEL */

-#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
- DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, 0, 0)
+#define _DPRINTK_KEY_INIT

#ifdef DEBUG
#define DYNAMIC_DEBUG_BRANCH(descriptor) \
--
2.20.1


2019-02-12 22:25:06

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v4 02/14] linux/net.h: use DYNAMIC_DEBUG_BRANCH in net_dbg_ratelimited

net_dbg_ratelimited tests the dynamic debug descriptor the
old-fashioned way, and doesn't utilize the static key/jump label
implementation when CONFIG_JUMP_LABEL is set. Use the
DYNAMIC_DEBUG_BRANCH which is defined appropriately.

Cc: [email protected]
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/net.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/net.h b/include/linux/net.h
index e0930678c8bf..651fca72286c 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -263,7 +263,7 @@ do { \
#define net_dbg_ratelimited(fmt, ...) \
do { \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
net_ratelimit()) \
__dynamic_pr_debug(&descriptor, pr_fmt(fmt), \
##__VA_ARGS__); \
--
2.20.1


2019-02-12 22:25:12

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v4 01/14] linux/device.h: use DYNAMIC_DEBUG_BRANCH in dev_dbg_ratelimited

dev_dbg_ratelimited tests the dynamic debug descriptor the
old-fashioned way, and doesn't utilize the static key/jump label
implementation when CONFIG_JUMP_LABEL is set. Use the
DYNAMIC_DEBUG_BRANCH which is defined appropriately.

Reviewed-by: Greg Kroah-Hartman <[email protected]>
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/device.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/device.h b/include/linux/device.h
index 6cb4640b6160..b49b142c5d6a 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1548,7 +1548,7 @@ do { \
DEFAULT_RATELIMIT_INTERVAL, \
DEFAULT_RATELIMIT_BURST); \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
- if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
+ if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
__ratelimit(&_rs)) \
__dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \
##__VA_ARGS__); \
--
2.20.1


2019-02-12 22:25:16

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH v4 00/14] various dynamic_debug patches

This started as an experiment to see how hard it would be to change
the four pointers in struct _ddebug into relative offsets, a la
CONFIG_GENERIC_BUG_RELATIVE_POINTERS, thus saving 16 bytes per
pr_debug site (and thus exactly making up for the extra space used by
the introduction of jump labels in 9049fc74). I stumbled on a few
things that are probably worth fixing regardless of whether that goal
is deemed worthwhile.

Back at v3 (in November), I redid the implementation on top of the
fancy new asm-macros stuff. Luckily enough, v3 didn't get picked up,
since the asm-macros were backed out again. I still want to do the
relative-pointers thing eventually, but we're close to the merge
window opening, so here's just most of the "incidental" patches, some
of which also serve as preparation for the relative pointers.

I'm not sure how long an Ack/Reviewed-by is good for, but OTOH it also
feels rude to just drop them on the floor. I've kept those tags since
the rebasing to current master went completely smooth.

Andrew, please pick these up for soaking in -next.

v3 series: lkml.kernel.org/r/[email protected]
v2 series: lkml.kernel.org/r/[email protected]

Rasmus Villemoes (14):
linux/device.h: use DYNAMIC_DEBUG_BRANCH in dev_dbg_ratelimited
linux/net.h: use DYNAMIC_DEBUG_BRANCH in net_dbg_ratelimited
linux/printk.h: use DYNAMIC_DEBUG_BRANCH in pr_debug_ratelimited
dynamic_debug: consolidate DEFINE_DYNAMIC_DEBUG_METADATA definitions
dynamic_debug: don't duplicate modname in ddebug_add_module
dynamic_debug: use pointer comparison in ddebug_remove_module
dynamic_debug: remove unused EXPORT_SYMBOLs
dynamic_debug: move pr_err from module.c to ddebug_add_module
dynamic_debug: add static inline stub for ddebug_add_module
dynamic_debug: refactor dynamic_pr_debug and friends
btrfs: implement btrfs_debug* in terms of helper macro
ACPI: use proper DYNAMIC_DEBUG_BRANCH macro
ACPI: remove unused __acpi_handle_debug macro
ACPI: implement acpi_handle_debug in terms of _dynamic_func_call

fs/btrfs/ctree.h | 34 ++++--------
include/linux/acpi.h | 11 +---
include/linux/device.h | 2 +-
include/linux/dynamic_debug.h | 102 +++++++++++++++++++---------------
include/linux/net.h | 2 +-
include/linux/printk.h | 2 +-
kernel/module.c | 6 +-
lib/dynamic_debug.c | 22 ++++----
8 files changed, 84 insertions(+), 97 deletions(-)

--
2.20.1