The descriptor flags are accessed concurrently. Use READ_ONCE()/WRITE_ONCE() to keep their contents consistent.
Signed-off-by: Thomas Weißschuh <[email protected]> --- I am not entirely sure about this. We are only using single bits, so torn reads/writes should not matter. But LKMM has no guidance on this as far as I can see. Also for Rust this seems to be necessary. --- include/linux/dynamic_debug.h | 6 +++--- lib/dynamic_debug.c | 24 +++++++++++++----------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index b1ff7c0e9a5f..6986142928ef 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -164,7 +164,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor, #define __dynamic_dump_stack(desc) \ { \ - if (desc.flags & _DPRINTK_FLAGS_INCL_STACK) \ + if (READ_ONCE(desc.flags) & _DPRINTK_FLAGS_INCL_STACK) \ dump_stack(); \ } @@ -207,10 +207,10 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor, #ifdef DEBUG #define DYNAMIC_DEBUG_BRANCH(descriptor) \ - likely(descriptor.flags & _DPRINTK_FLAGS_PRINT) + likely(READ_ONCE(descriptor.flags) & _DPRINTK_FLAGS_PRINT) #else #define DYNAMIC_DEBUG_BRANCH(descriptor) \ - unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) + unlikely(READ_ONCE(descriptor.flags) & _DPRINTK_FLAGS_PRINT) #endif #endif /* CONFIG_JUMP_LABEL */ diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 18a71a9108d3..6dfd125fa6be 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -244,7 +244,7 @@ static int ddebug_change(const struct ddebug_query *query, nfound++; - newflags = (dp->flags & modifiers->mask) | modifiers->flags; + newflags = (READ_ONCE(dp->flags) & modifiers->mask) | modifiers->flags; if (newflags == dp->flags) continue; #ifdef CONFIG_JUMP_LABEL @@ -260,7 +260,7 @@ static int ddebug_change(const struct ddebug_query *query, dt->mod_name, dp->function, ddebug_describe_flags(dp->flags, &fbuf), ddebug_describe_flags(newflags, &nbuf)); - dp->flags = newflags; + WRITE_ONCE(dp->flags, newflags); } } mutex_unlock(&ddebug_lock); @@ -822,12 +822,12 @@ static int remaining(int wrote) return 0; } -static char *__dynamic_emit_prefix(const struct _ddebug *desc, char *buf) +static char *__dynamic_emit_prefix(const struct _ddebug *desc, u8 flags, char *buf) { int pos_after_tid; int pos = 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 @@ -835,16 +835,16 @@ 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:", desc->modname); - if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) + if (flags & _DPRINTK_FLAGS_INCL_FUNCNAME) pos += snprintf(buf + pos, remaining(pos), "%s:", desc->function); - if (desc->flags & _DPRINTK_FLAGS_INCL_SOURCENAME) + if (flags & _DPRINTK_FLAGS_INCL_SOURCENAME) pos += snprintf(buf + pos, remaining(pos), "%s:", trim_prefix(desc->filename)); - if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO) + if (flags & _DPRINTK_FLAGS_INCL_LINENO) pos += snprintf(buf + pos, remaining(pos), "%d:", desc->lineno); if (pos - pos_after_tid) @@ -857,8 +857,10 @@ static char *__dynamic_emit_prefix(const struct _ddebug *desc, char *buf) static inline char *dynamic_emit_prefix(struct _ddebug *desc, char *buf) { - if (unlikely(desc->flags & _DPRINTK_FLAGS_INCL_ANY)) - return __dynamic_emit_prefix(desc, buf); + u8 flags = READ_ONCE(desc->flags); + + if (unlikely(flags & _DPRINTK_FLAGS_INCL_ANY)) + return __dynamic_emit_prefix(desc, flags, buf); return buf; } @@ -1146,7 +1148,7 @@ 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, - ddebug_describe_flags(dp->flags, &flags)); + ddebug_describe_flags(READ_ONCE(dp->flags), &flags)); seq_escape_str(m, dp->format, ESCAPE_SPACE, "\t\r\n\""); seq_putc(m, '"'); -- 2.56.0

