mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
debug: Add _ONCE() logic to report_bug()
Josh suggested moving the _ONCE logic inside the trap handler, using a bit in the bug_entry::flags field, avoiding the need for the extra variable. Sadly this only works for WARN_ON_ONCE(), since the others have printk() statements prior to triggering the trap. Still, this saves a fair amount of text and some data: text data filename 10682460 4530992 defconfig-build/vmlinux.orig 10665111 4530096 defconfig-build/vmlinux.patched Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Andy Lutomirski <luto@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
70579a86e3
commit
19d436268d
10 changed files with 52 additions and 25 deletions
28
lib/bug.c
28
lib/bug.c
|
@ -47,7 +47,7 @@
|
|||
#include <linux/sched.h>
|
||||
#include <linux/rculist.h>
|
||||
|
||||
extern const struct bug_entry __start___bug_table[], __stop___bug_table[];
|
||||
extern struct bug_entry __start___bug_table[], __stop___bug_table[];
|
||||
|
||||
static inline unsigned long bug_addr(const struct bug_entry *bug)
|
||||
{
|
||||
|
@ -62,10 +62,10 @@ static inline unsigned long bug_addr(const struct bug_entry *bug)
|
|||
/* Updates are protected by module mutex */
|
||||
static LIST_HEAD(module_bug_list);
|
||||
|
||||
static const struct bug_entry *module_find_bug(unsigned long bugaddr)
|
||||
static struct bug_entry *module_find_bug(unsigned long bugaddr)
|
||||
{
|
||||
struct module *mod;
|
||||
const struct bug_entry *bug = NULL;
|
||||
struct bug_entry *bug = NULL;
|
||||
|
||||
rcu_read_lock_sched();
|
||||
list_for_each_entry_rcu(mod, &module_bug_list, bug_list) {
|
||||
|
@ -122,15 +122,15 @@ void module_bug_cleanup(struct module *mod)
|
|||
|
||||
#else
|
||||
|
||||
static inline const struct bug_entry *module_find_bug(unsigned long bugaddr)
|
||||
static inline struct bug_entry *module_find_bug(unsigned long bugaddr)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
const struct bug_entry *find_bug(unsigned long bugaddr)
|
||||
struct bug_entry *find_bug(unsigned long bugaddr)
|
||||
{
|
||||
const struct bug_entry *bug;
|
||||
struct bug_entry *bug;
|
||||
|
||||
for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
|
||||
if (bugaddr == bug_addr(bug))
|
||||
|
@ -141,9 +141,9 @@ const struct bug_entry *find_bug(unsigned long bugaddr)
|
|||
|
||||
enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
|
||||
{
|
||||
const struct bug_entry *bug;
|
||||
struct bug_entry *bug;
|
||||
const char *file;
|
||||
unsigned line, warning;
|
||||
unsigned line, warning, once, done;
|
||||
|
||||
if (!is_valid_bugaddr(bugaddr))
|
||||
return BUG_TRAP_TYPE_NONE;
|
||||
|
@ -164,6 +164,18 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
|
|||
line = bug->line;
|
||||
#endif
|
||||
warning = (bug->flags & BUGFLAG_WARNING) != 0;
|
||||
once = (bug->flags & BUGFLAG_ONCE) != 0;
|
||||
done = (bug->flags & BUGFLAG_DONE) != 0;
|
||||
|
||||
if (warning && once) {
|
||||
if (done)
|
||||
return BUG_TRAP_TYPE_WARN;
|
||||
|
||||
/*
|
||||
* Since this is the only store, concurrency is not an issue.
|
||||
*/
|
||||
bug->flags |= BUGFLAG_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (warning) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue