* [PATCH 1/2] Allow the 'cut here' oops line to be displayed before calling BUG() @ 2009-08-20 10:49 David Howells 2009-08-20 10:50 ` [PATCH 2/2] Use the cut_here() function in AFS, CacheFiles, FS-Cache and RxRPC David Howells 2009-08-25 11:36 ` [PATCH 1/2] Allow the 'cut here' oops line to be displayed before calling BUG() Pavel Machek 0 siblings, 2 replies; 6+ messages in thread From: David Howells @ 2009-08-20 10:49 UTC (permalink / raw) To: torvalds, akpm; +Cc: dhowells, linux-kernel Allow the 'cut here' oops line to be displayed before calling BUG() as useful information is often displayed before BUG() is called. Also use this to limit recursive oopsing. Signed-off-by: David Howells <dhowells@redhat.com> --- include/linux/bug.h | 8 ++++++++ include/linux/sched.h | 9 +++++++++ lib/bug.c | 31 +++++++++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/include/linux/bug.h b/include/linux/bug.h index d276b55..290309f 100644 --- a/include/linux/bug.h +++ b/include/linux/bug.h @@ -26,6 +26,8 @@ enum bug_trap_type report_bug(unsigned long bug_addr, struct pt_regs *regs); /* These are defined by the architecture */ int is_valid_bugaddr(unsigned long addr); +extern bool cut_here(void); + #else /* !CONFIG_GENERIC_BUG */ static inline enum bug_trap_type report_bug(unsigned long bug_addr, @@ -34,5 +36,11 @@ static inline enum bug_trap_type report_bug(unsigned long bug_addr, return BUG_TRAP_TYPE_BUG; } +static inline bool cut_here(void) +{ + return true; +} + #endif /* CONFIG_GENERIC_BUG */ + #endif /* _LINUX_BUG_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 0f1ea4a..f4b9782 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1199,6 +1199,9 @@ struct task_struct { */ unsigned char fpu_counter; s8 oomkilladj; /* OOM kill score adjustment (bit shift). */ + + unsigned char oopsing; /* oopsing state */ + #ifdef CONFIG_BLK_DEV_IO_TRACE unsigned int btrace_seq; #endif @@ -1700,6 +1703,12 @@ extern cputime_t task_gtime(struct task_struct *p); #define PF_FREEZER_NOSIG 0x80000000 /* Freezer won't send signals to it */ /* + * current->oopsing flags + */ +#define OOPS_CUT_HERE 0x01 /* set if the "cut here" message is displayed */ +#define OOPS_REPORTED 0x02 /* recursion limiter */ + +/* * Only the _current_ task can read/write to tsk->flags, but other * tasks can access tsk->flags in readonly mode for example * with tsk_used_math (like during threaded core dumping). diff --git a/lib/bug.c b/lib/bug.c index 300e41a..2d0ed45 100644 --- a/lib/bug.c +++ b/lib/bug.c @@ -125,6 +125,31 @@ const struct bug_entry *find_bug(unsigned long bugaddr) return module_find_bug(bugaddr); } +/** + * cut_here - Begin BUG() output + * + * Begin the outputting of a BUG() report with a 'cut here' line. This ensures + * we produce at most one 'cut here' line per process. This allows us to + * extend a BUG() report with extra information in front of it. + * + * We return true if the caller is free to go ahead and report their oops. + * + * We return false if we've detected a recursive oops - in which case the + * caller should take care, and possibly not do anything other than call BUG(), + * lest they cause further recursion. This is particularly true of things that + * might go wrong in the exit path. + */ +bool cut_here(void) +{ + if (!(current->oopsing & OOPS_CUT_HERE)) { + current->oopsing |= OOPS_CUT_HERE; + printk(KERN_EMERG "------------[ cut here ]------------\n"); + } + + return !(current->oopsing & OOPS_REPORTED); +} +EXPORT_SYMBOL(cut_here); + enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) { const struct bug_entry *bug; @@ -134,9 +159,9 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) if (!is_valid_bugaddr(bugaddr)) return BUG_TRAP_TYPE_NONE; - bug = find_bug(bugaddr); + cut_here(); - printk(KERN_EMERG "------------[ cut here ]------------\n"); + bug = find_bug(bugaddr); file = NULL; line = 0; @@ -169,6 +194,8 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) return BUG_TRAP_TYPE_WARN; } + current->oopsing |= OOPS_REPORTED; + if (file) printk(KERN_CRIT "kernel BUG at %s:%u!\n", file, line); ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] Use the cut_here() function in AFS, CacheFiles, FS-Cache and RxRPC 2009-08-20 10:49 [PATCH 1/2] Allow the 'cut here' oops line to be displayed before calling BUG() David Howells @ 2009-08-20 10:50 ` David Howells 2009-08-20 15:32 ` Linus Torvalds 2009-08-25 11:36 ` [PATCH 1/2] Allow the 'cut here' oops line to be displayed before calling BUG() Pavel Machek 1 sibling, 1 reply; 6+ messages in thread From: David Howells @ 2009-08-20 10:50 UTC (permalink / raw) To: torvalds, akpm; +Cc: dhowells, linux-kernel Use the cut_here() function in AFS, CacheFiles, FS-Cache and RxRPC to put pertinent extra information between the "cut here" line and the BUG report. Signed-off-by: David Howells <dhowells@redhat.com> --- fs/afs/internal.h | 11 ++++++----- fs/cachefiles/internal.h | 9 +++++---- fs/fscache/internal.h | 9 +++++---- net/rxrpc/ar-internal.h | 4 ++++ 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 106be66..59049b0 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -18,6 +18,7 @@ #include <linux/key.h> #include <linux/workqueue.h> #include <linux/sched.h> +#include <linux/bug.h> #include "afs.h" #include "afs_vl.h" @@ -803,7 +804,7 @@ do { \ #define ASSERT(X) \ do { \ if (unlikely(!(X))) { \ - printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "AFS: Assertion failed\n"); \ BUG(); \ } \ @@ -812,7 +813,7 @@ do { \ #define ASSERTCMP(X, OP, Y) \ do { \ if (unlikely(!((X) OP (Y)))) { \ - printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "AFS: Assertion failed\n"); \ printk(KERN_ERR "%lu " #OP " %lu is false\n", \ (unsigned long)(X), (unsigned long)(Y)); \ @@ -825,7 +826,7 @@ do { \ #define ASSERTRANGE(L, OP1, N, OP2, H) \ do { \ if (unlikely(!((L) OP1 (N)) || !((N) OP2 (H)))) { \ - printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "AFS: Assertion failed\n"); \ printk(KERN_ERR "%lu "#OP1" %lu "#OP2" %lu is false\n", \ (unsigned long)(L), (unsigned long)(N), \ @@ -840,7 +841,7 @@ do { \ #define ASSERTIF(C, X) \ do { \ if (unlikely((C) && !(X))) { \ - printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "AFS: Assertion failed\n"); \ BUG(); \ } \ @@ -849,7 +850,7 @@ do { \ #define ASSERTIFCMP(C, X, OP, Y) \ do { \ if (unlikely((C) && !((X) OP (Y)))) { \ - printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "AFS: Assertion failed\n"); \ printk(KERN_ERR "%lu " #OP " %lu is false\n", \ (unsigned long)(X), (unsigned long)(Y)); \ diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index f7c255f..96007a7 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -14,6 +14,7 @@ #include <linux/wait.h> #include <linux/workqueue.h> #include <linux/security.h> +#include <linux/bug.h> struct cachefiles_cache; struct cachefiles_object; @@ -313,7 +314,7 @@ do { \ #define ASSERT(X) \ do { \ if (unlikely(!(X))) { \ - printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "CacheFiles: Assertion failed\n"); \ BUG(); \ } \ @@ -322,7 +323,7 @@ do { \ #define ASSERTCMP(X, OP, Y) \ do { \ if (unlikely(!((X) OP (Y)))) { \ - printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "CacheFiles: Assertion failed\n"); \ printk(KERN_ERR "%lx " #OP " %lx is false\n", \ (unsigned long)(X), (unsigned long)(Y)); \ @@ -333,7 +334,7 @@ do { \ #define ASSERTIF(C, X) \ do { \ if (unlikely((C) && !(X))) { \ - printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "CacheFiles: Assertion failed\n"); \ BUG(); \ } \ @@ -342,7 +343,7 @@ do { \ #define ASSERTIFCMP(C, X, OP, Y) \ do { \ if (unlikely((C) && !((X) OP (Y)))) { \ - printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "CacheFiles: Assertion failed\n"); \ printk(KERN_ERR "%lx " #OP " %lx is false\n", \ (unsigned long)(X), (unsigned long)(Y)); \ diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index 1c34130..c969199 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h @@ -23,6 +23,7 @@ #include <linux/fscache-cache.h> #include <linux/sched.h> +#include <linux/bug.h> #define FSCACHE_MIN_THREADS 4 #define FSCACHE_MAX_THREADS 32 @@ -333,7 +334,7 @@ do { \ #define ASSERT(X) \ do { \ if (unlikely(!(X))) { \ - printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "FS-Cache: Assertion failed\n"); \ BUG(); \ } \ @@ -342,7 +343,7 @@ do { \ #define ASSERTCMP(X, OP, Y) \ do { \ if (unlikely(!((X) OP (Y)))) { \ - printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "FS-Cache: Assertion failed\n"); \ printk(KERN_ERR "%lx " #OP " %lx is false\n", \ (unsigned long)(X), (unsigned long)(Y)); \ @@ -353,7 +354,7 @@ do { \ #define ASSERTIF(C, X) \ do { \ if (unlikely((C) && !(X))) { \ - printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "FS-Cache: Assertion failed\n"); \ BUG(); \ } \ @@ -362,7 +363,7 @@ do { \ #define ASSERTIFCMP(C, X, OP, Y) \ do { \ if (unlikely((C) && !((X) OP (Y)))) { \ - printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "FS-Cache: Assertion failed\n"); \ printk(KERN_ERR "%lx " #OP " %lx is false\n", \ (unsigned long)(X), (unsigned long)(Y)); \ diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index 3e7318c..de6a21b 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h @@ -687,6 +687,7 @@ do { \ do { \ if (unlikely(!(X))) { \ printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "RxRPC: Assertion failed\n"); \ BUG(); \ } \ @@ -696,6 +697,7 @@ do { \ do { \ if (unlikely(!((X) OP (Y)))) { \ printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "RxRPC: Assertion failed\n"); \ printk(KERN_ERR "%lu " #OP " %lu is false\n", \ (unsigned long)(X), (unsigned long)(Y)); \ @@ -709,6 +711,7 @@ do { \ do { \ if (unlikely((C) && !(X))) { \ printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "RxRPC: Assertion failed\n"); \ BUG(); \ } \ @@ -718,6 +721,7 @@ do { \ do { \ if (unlikely((C) && !((X) OP (Y)))) { \ printk(KERN_ERR "\n"); \ + cut_here(); \ printk(KERN_ERR "RxRPC: Assertion failed\n"); \ printk(KERN_ERR "%lu " #OP " %lu is false\n", \ (unsigned long)(X), (unsigned long)(Y)); \ ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] Use the cut_here() function in AFS, CacheFiles, FS-Cache and RxRPC 2009-08-20 10:50 ` [PATCH 2/2] Use the cut_here() function in AFS, CacheFiles, FS-Cache and RxRPC David Howells @ 2009-08-20 15:32 ` Linus Torvalds 2009-08-20 16:06 ` David Howells 0 siblings, 1 reply; 6+ messages in thread From: Linus Torvalds @ 2009-08-20 15:32 UTC (permalink / raw) To: David Howells; +Cc: akpm, linux-kernel On Thu, 20 Aug 2009, David Howells wrote: > > Use the cut_here() function in AFS, CacheFiles, FS-Cache and RxRPC to put > pertinent extra information between the "cut here" line and the BUG report. No. This is fundamentally the wrong approach. > #define ASSERT(X) \ > do { \ > if (unlikely(!(X))) { \ > - printk(KERN_ERR "\n"); \ > + cut_here(); \ > printk(KERN_ERR "AFS: Assertion failed\n"); \ > BUG(); \ Instead of doing that "cut_here()" thing, you should either use the WARN() thing that has a format string already, or we should extend BUG() to have that kind of thing too. So in this case I think that you should use WARN() instead, ie change it to be #define ASSERT(x) do { \ if (WARN(X, "AFS: Assertion failed")) \ do_exit(SIGSEGV); \ } while (0) instead. And yes, in the long run, I really think we should just extend the current BUG() reporting to have that kind of semantics, but I think your "cut_here()" thing is a horrible hack. Linus ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] Use the cut_here() function in AFS, CacheFiles, FS-Cache and RxRPC 2009-08-20 15:32 ` Linus Torvalds @ 2009-08-20 16:06 ` David Howells 2009-08-20 16:44 ` Linus Torvalds 0 siblings, 1 reply; 6+ messages in thread From: David Howells @ 2009-08-20 16:06 UTC (permalink / raw) To: Linus Torvalds; +Cc: dhowells, akpm, linux-kernel Linus Torvalds <torvalds@linux-foundation.org> wrote: > instead. And yes, in the long run, I really think we should just extend > the current BUG() reporting to have that kind of semantics, but I think > your "cut_here()" thing is a horrible hack. What about situations where I want to print quite a lot of information, say several lines' worth? For instance, if you look at cachefiles_mark_object_active() in fs/cachefiles/namei.c, you'll see something like (which extended by one of my patches): wait_for_old_object: if (xobject->fscache.state < FSCACHE_OBJECT_DYING) { unsigned keylen; u8 *keybuf; printk(KERN_ERR "\n"); printk(KERN_ERR "CacheFiles: Error:" " Unexpected object collision\n"); printk(KERN_ERR "xobject: OBJ%x\n", xobject->fscache.debug_id); printk(KERN_ERR "xobjstate=%s\n", fscache_object_states[xobject->fscache.state]); printk(KERN_ERR "xobjflags=%lx\n", xobject->fscache.flags); printk(KERN_ERR "xobjevent=%lx [%lx]\n", xobject->fscache.events, xobject->fscache.event_mask); printk(KERN_ERR "xops=%u inp=%u exc=%u\n", xobject->fscache.n_ops, xobject->fscache.n_in_progress, xobject->fscache.n_exclusive); printk(KERN_ERR "xcookie=%p [pr=%p nd=%p fl=%lx]\n", xobject->fscache.cookie, xobject->fscache.cookie->parent, xobject->fscache.cookie->netfs_data, xobject->fscache.cookie->flags); printk(KERN_ERR "xparent=%p\n", xobject->fscache.parent); printk(KERN_ERR "object: OBJ%x\n", object->fscache.debug_id); printk(KERN_ERR "cookie=%p [pr=%p nd=%p fl=%lx]\n", object->fscache.cookie, object->fscache.cookie->parent, object->fscache.cookie->netfs_data, object->fscache.cookie->flags); printk(KERN_ERR "parent=%p\n", object->fscache.parent); keybuf = kmalloc(512, GFP_NOIO); if (keybuf) { struct fscache_cookie *cookie; unsigned loop; cookie = object->fscache.cookie; keylen = cookie->def->get_key(cookie->netfs_data, keybuf, 512); printk(KERN_ERR "okey=[%u] '", keylen); for (loop = 0; loop < keylen; loop++) printk("%02x", keybuf[loop]); printk("'\n"); cookie = xobject->fscache.cookie; keylen = cookie->def->get_key(cookie->netfs_data, keybuf, 512); printk(KERN_ERR "xkey=[%u] '", keylen); for (loop = 0; loop < keylen; loop++) printk("%02x", keybuf[loop]); printk("'\n"); kfree(keybuf); } BUG(); With the cut_here() approach, I could put a cut_here() just inside the if-body, but doing it with your approach and putting the whole lot in one format string would also be pretty horrible, and risks overrunning the printk buffer. David ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] Use the cut_here() function in AFS, CacheFiles, FS-Cache and RxRPC 2009-08-20 16:06 ` David Howells @ 2009-08-20 16:44 ` Linus Torvalds 0 siblings, 0 replies; 6+ messages in thread From: Linus Torvalds @ 2009-08-20 16:44 UTC (permalink / raw) To: David Howells; +Cc: akpm, linux-kernel On Thu, 20 Aug 2009, David Howells wrote: > > What about situations where I want to print quite a lot of information, say > several lines' worth? Quite frankly, you shouldn't do that. If your code is so fragile that you need a lot of asserts that have small novellas associated with them, just don't send that code to me. It really is that simple. Linus ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] Allow the 'cut here' oops line to be displayed before calling BUG() 2009-08-20 10:49 [PATCH 1/2] Allow the 'cut here' oops line to be displayed before calling BUG() David Howells 2009-08-20 10:50 ` [PATCH 2/2] Use the cut_here() function in AFS, CacheFiles, FS-Cache and RxRPC David Howells @ 2009-08-25 11:36 ` Pavel Machek 1 sibling, 0 replies; 6+ messages in thread From: Pavel Machek @ 2009-08-25 11:36 UTC (permalink / raw) To: David Howells; +Cc: torvalds, akpm, linux-kernel On Thu 2009-08-20 11:49:56, David Howells wrote: > Allow the 'cut here' oops line to be displayed before calling BUG() as useful > information is often displayed before BUG() is called. Also use this to limit > recursive oopsing. Can we get rid of the stupid 'cut here' line, instead? It does not carry real information, shouts, takes valuable screen space... Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2009-08-25 11:36 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-08-20 10:49 [PATCH 1/2] Allow the 'cut here' oops line to be displayed before calling BUG() David Howells 2009-08-20 10:50 ` [PATCH 2/2] Use the cut_here() function in AFS, CacheFiles, FS-Cache and RxRPC David Howells 2009-08-20 15:32 ` Linus Torvalds 2009-08-20 16:06 ` David Howells 2009-08-20 16:44 ` Linus Torvalds 2009-08-25 11:36 ` [PATCH 1/2] Allow the 'cut here' oops line to be displayed before calling BUG() Pavel Machek
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox