From: Josh Law <objecting@objecting.org>
To: Andrew Morton <akpm@linux-foundation.org>,
Josh Law <objecting@objecting.org>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH 1/3] lib/bug: annotate concurrent access to bug->flags with READ_ONCE/WRITE_ONCE
Date: Sun, 15 Mar 2026 19:49:37 +0000 [thread overview]
Message-ID: <20260315194939.328612-2-objecting@objecting.org> (raw)
In-Reply-To: <20260315194939.328612-1-objecting@objecting.org>
Multiple CPUs can hit a WARN_ON_ONCE simultaneously, causing concurrent
reads and writes to bug->flags without synchronization. In __report_bug(),
the flags are read to check BUGFLAG_DONE and then BUGFLAG_DONE is set via
a plain read-modify-write. The race is benign since the store is
idempotent, but KCSAN will flag this as a data race.
Read the flags once with READ_ONCE and reuse the cached value for both
the flag checks and the WRITE_ONCE store. Also annotate the concurrent
clear in clear_once_table(). Update the misleading comment that claimed
concurrency is not an issue.
Signed-off-by: Josh Law <objecting@objecting.org>
---
lib/bug.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/lib/bug.c b/lib/bug.c
index bbc301097749..037c7370dadf 100644
--- a/lib/bug.c
+++ b/lib/bug.c
@@ -201,6 +201,7 @@ static enum bug_trap_type __report_bug(struct bug_entry *bug, unsigned long buga
{
bool warning, once, done, no_cut, has_args;
const char *file, *fmt;
+ unsigned short flags;
unsigned line;
if (!bug) {
@@ -217,20 +218,24 @@ static enum bug_trap_type __report_bug(struct bug_entry *bug, unsigned long buga
bug_get_file_line(bug, &file, &line);
fmt = bug_get_format(bug);
- warning = bug->flags & BUGFLAG_WARNING;
- once = bug->flags & BUGFLAG_ONCE;
- done = bug->flags & BUGFLAG_DONE;
- no_cut = bug->flags & BUGFLAG_NO_CUT_HERE;
- has_args = bug->flags & BUGFLAG_ARGS;
+ flags = READ_ONCE(bug->flags);
+ warning = flags & BUGFLAG_WARNING;
+ once = flags & BUGFLAG_ONCE;
+ done = flags & BUGFLAG_DONE;
+ no_cut = flags & BUGFLAG_NO_CUT_HERE;
+ has_args = flags & BUGFLAG_ARGS;
if (warning && once) {
if (done)
return BUG_TRAP_TYPE_WARN;
/*
- * Since this is the only store, concurrency is not an issue.
+ * Multiple CPUs can hit a WARN_ON_ONCE at the same time
+ * and both read done == false. The race is benign: setting
+ * BUGFLAG_DONE is idempotent, and the worst case is that
+ * the warning prints a few extra times.
*/
- bug->flags |= BUGFLAG_DONE;
+ WRITE_ONCE(bug->flags, flags | BUGFLAG_DONE);
}
/*
@@ -289,7 +294,7 @@ static void clear_once_table(struct bug_entry *start, struct bug_entry *end)
struct bug_entry *bug;
for (bug = start; bug < end; bug++)
- bug->flags &= ~BUGFLAG_DONE;
+ WRITE_ONCE(bug->flags, READ_ONCE(bug->flags) & ~BUGFLAG_DONE);
}
void generic_bug_clear_once(void)
--
2.34.1
next prev parent reply other threads:[~2026-03-15 19:49 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-15 19:49 [PATCH 0/3] lib/bug: concurrency fix, cleanups, and debugfs inspection Josh Law
2026-03-15 19:49 ` Josh Law [this message]
2026-03-15 19:49 ` [PATCH 2/3] lib/bug: clean up types in bug reporting helpers Josh Law
2026-03-15 19:49 ` [PATCH 3/3] lib/bug: add debugfs interface to list all BUG/WARN sites Josh Law
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260315194939.328612-2-objecting@objecting.org \
--to=objecting@objecting.org \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®