Ian Campbell
2011-Jan-17 14:15 UTC
[Xen-devel] [PATCH] xen: debugging aid to track those who have disabled preemption
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1295273570 0 # Node ID 15e53a2463f084c3adbbb21b4deb30d0d4f79b45 # Parent 711cbaa038cae8c03cf825165d2e07b0a3c94f89 xen: debugging aid to track those who have disabled preemption. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 711cbaa038ca -r 15e53a2463f0 xen/common/preempt.c --- a/xen/common/preempt.c Mon Jan 17 14:12:48 2011 +0000 +++ b/xen/common/preempt.c Mon Jan 17 14:12:50 2011 +0000 @@ -21,5 +21,48 @@ */ #include <xen/preempt.h> +#include <xen/symbols.h> DEFINE_PER_CPU(unsigned int, __preempt_count); + +#ifdef DEBUG_PREEMPT + +#define NR_PREEMPT_DEBUG 16 + +struct preempt_info { + const char *file; + unsigned long line; + const char *func; + unsigned long r0, r1; +}; +typedef struct preempt_info preempt_info_t[NR_PREEMPT_DEBUG]; + +DEFINE_PER_CPU(preempt_info_t, __preempt_debug); + +void preempt_debug(const char *file, const unsigned long line, const char *func) +{ + struct preempt_info *pi = &this_cpu(__preempt_debug)[preempt_count()]; + if (preempt_count() >= NR_PREEMPT_DEBUG) + return; + pi->file = file; + pi->func = func; + pi->line = line; + pi->r0 = (unsigned long)__builtin_return_address(0); + pi->r1 = (unsigned long)__builtin_return_address(1); +} + +void preempt_debug_dump(void) +{ + struct preempt_info *pi = this_cpu(__preempt_debug); + int i, count = preempt_count(); + + printk("preempt debug on CPU%d, count %d:\n", smp_processor_id(), count); + count = min(count, NR_PREEMPT_DEBUG); + for(i=0;i<count;i++, pi++) { + printk("%d @ 0x%p\n", i, pi); + printk(" %s %s:%ld\n", pi->func, pi->file, pi->line); + printk(" %#lx", pi->r0); print_symbol(" %s\n", pi->r0); + printk(" %#lx", pi->r1); print_symbol(" %s\n", pi->r1); + } +} +#endif diff -r 711cbaa038ca -r 15e53a2463f0 xen/drivers/char/console.c --- a/xen/drivers/char/console.c Mon Jan 17 14:12:48 2011 +0000 +++ b/xen/drivers/char/console.c Mon Jan 17 14:12:50 2011 +0000 @@ -961,6 +961,7 @@ void panic(const char *fmt, ...) printk("Panic on CPU %d:\n", smp_processor_id()); printk("%s", buf); printk("****************************************\n\n"); + preempt_debug_dump(); if ( opt_noreboot ) printk("Manual reset required (''noreboot'' specified)\n"); else diff -r 711cbaa038ca -r 15e53a2463f0 xen/include/xen/preempt.h --- a/xen/include/xen/preempt.h Mon Jan 17 14:12:48 2011 +0000 +++ b/xen/include/xen/preempt.h Mon Jan 17 14:12:50 2011 +0000 @@ -18,7 +18,18 @@ DECLARE_PER_CPU(unsigned int, __preempt_ #define preempt_count() (this_cpu(__preempt_count)) +//#define DEBUG_PREEMPT + +#ifdef DEBUG_PREEMPT +extern void preempt_debug(const char *file, const unsigned long line, const char *func); +extern void preempt_debug_dump(void); +#else +static inline void preempt_debug(const char *file, const unsigned long line, const char *func) {} +static inline void preempt_debug_dump(void) {} +#endif + #define preempt_disable() do { \ + preempt_debug(__FILE__, __LINE__, __func__);\ preempt_count()++; \ barrier(); \ } while (0) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jan-17 14:17 UTC
[Xen-devel] Re: [PATCH] xen: debugging aid to track those who have disabled preemption
This is obviously a bit skanky but I figured it might be useful to others in the future even if it never gets further than the list archive. Ian. On Mon, 2011-01-17 at 14:15 +0000, Ian Campbell wrote:> # HG changeset patch > # User Ian Campbell <ian.campbell@citrix.com> > # Date 1295273570 0 > # Node ID 15e53a2463f084c3adbbb21b4deb30d0d4f79b45 > # Parent 711cbaa038cae8c03cf825165d2e07b0a3c94f89 > xen: debugging aid to track those who have disabled preemption. > > Signed-off-by: Ian Campbell <ian.campbell@citrix.com> > > diff -r 711cbaa038ca -r 15e53a2463f0 xen/common/preempt.c > --- a/xen/common/preempt.c Mon Jan 17 14:12:48 2011 +0000 > +++ b/xen/common/preempt.c Mon Jan 17 14:12:50 2011 +0000 > @@ -21,5 +21,48 @@ > */ > > #include <xen/preempt.h> > +#include <xen/symbols.h> > > DEFINE_PER_CPU(unsigned int, __preempt_count); > + > +#ifdef DEBUG_PREEMPT > + > +#define NR_PREEMPT_DEBUG 16 > + > +struct preempt_info { > + const char *file; > + unsigned long line; > + const char *func; > + unsigned long r0, r1; > +}; > +typedef struct preempt_info preempt_info_t[NR_PREEMPT_DEBUG]; > + > +DEFINE_PER_CPU(preempt_info_t, __preempt_debug); > + > +void preempt_debug(const char *file, const unsigned long line, const char *func) > +{ > + struct preempt_info *pi = &this_cpu(__preempt_debug)[preempt_count()]; > + if (preempt_count() >= NR_PREEMPT_DEBUG) > + return; > + pi->file = file; > + pi->func = func; > + pi->line = line; > + pi->r0 = (unsigned long)__builtin_return_address(0); > + pi->r1 = (unsigned long)__builtin_return_address(1); > +} > + > +void preempt_debug_dump(void) > +{ > + struct preempt_info *pi = this_cpu(__preempt_debug); > + int i, count = preempt_count(); > + > + printk("preempt debug on CPU%d, count %d:\n", smp_processor_id(), count); > + count = min(count, NR_PREEMPT_DEBUG); > + for(i=0;i<count;i++, pi++) { > + printk("%d @ 0x%p\n", i, pi); > + printk(" %s %s:%ld\n", pi->func, pi->file, pi->line); > + printk(" %#lx", pi->r0); print_symbol(" %s\n", pi->r0); > + printk(" %#lx", pi->r1); print_symbol(" %s\n", pi->r1); > + } > +} > +#endif > diff -r 711cbaa038ca -r 15e53a2463f0 xen/drivers/char/console.c > --- a/xen/drivers/char/console.c Mon Jan 17 14:12:48 2011 +0000 > +++ b/xen/drivers/char/console.c Mon Jan 17 14:12:50 2011 +0000 > @@ -961,6 +961,7 @@ void panic(const char *fmt, ...) > printk("Panic on CPU %d:\n", smp_processor_id()); > printk("%s", buf); > printk("****************************************\n\n"); > + preempt_debug_dump(); > if ( opt_noreboot ) > printk("Manual reset required (''noreboot'' specified)\n"); > else > diff -r 711cbaa038ca -r 15e53a2463f0 xen/include/xen/preempt.h > --- a/xen/include/xen/preempt.h Mon Jan 17 14:12:48 2011 +0000 > +++ b/xen/include/xen/preempt.h Mon Jan 17 14:12:50 2011 +0000 > @@ -18,7 +18,18 @@ DECLARE_PER_CPU(unsigned int, __preempt_ > > #define preempt_count() (this_cpu(__preempt_count)) > > +//#define DEBUG_PREEMPT > + > +#ifdef DEBUG_PREEMPT > +extern void preempt_debug(const char *file, const unsigned long line, const char *func); > +extern void preempt_debug_dump(void); > +#else > +static inline void preempt_debug(const char *file, const unsigned long line, const char *func) {} > +static inline void preempt_debug_dump(void) {} > +#endif > + > #define preempt_disable() do { \ > + preempt_debug(__FILE__, __LINE__, __func__);\ > preempt_count()++; \ > barrier(); \ > } while (0)_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Jan-18 10:13 UTC
Re: [Xen-devel] Re: [PATCH] xen: debugging aid to track those who have disabled preemption
Yep, I gave this one a bit of thought and it''s a bit too rough and ready to be a general debug aid. If nothing else, the lack of matching between preempt_enable and _disable calls means that precisely in the case things go wrong, you can end up popping the wrong things off the debug stack. I''ll keep this patch in mind though for future debugging. -- Keir On 17/01/2011 14:17, "Ian Campbell" <Ian.Campbell@eu.citrix.com> wrote:> This is obviously a bit skanky but I figured it might be useful to > others in the future even if it never gets further than the list > archive. > > Ian. > > On Mon, 2011-01-17 at 14:15 +0000, Ian Campbell wrote: >> # HG changeset patch >> # User Ian Campbell <ian.campbell@citrix.com> >> # Date 1295273570 0 >> # Node ID 15e53a2463f084c3adbbb21b4deb30d0d4f79b45 >> # Parent 711cbaa038cae8c03cf825165d2e07b0a3c94f89 >> xen: debugging aid to track those who have disabled preemption. >> >> Signed-off-by: Ian Campbell <ian.campbell@citrix.com> >> >> diff -r 711cbaa038ca -r 15e53a2463f0 xen/common/preempt.c >> --- a/xen/common/preempt.c Mon Jan 17 14:12:48 2011 +0000 >> +++ b/xen/common/preempt.c Mon Jan 17 14:12:50 2011 +0000 >> @@ -21,5 +21,48 @@ >> */ >> >> #include <xen/preempt.h> >> +#include <xen/symbols.h> >> >> DEFINE_PER_CPU(unsigned int, __preempt_count); >> + >> +#ifdef DEBUG_PREEMPT >> + >> +#define NR_PREEMPT_DEBUG 16 >> + >> +struct preempt_info { >> + const char *file; >> + unsigned long line; >> + const char *func; >> + unsigned long r0, r1; >> +}; >> +typedef struct preempt_info preempt_info_t[NR_PREEMPT_DEBUG]; >> + >> +DEFINE_PER_CPU(preempt_info_t, __preempt_debug); >> + >> +void preempt_debug(const char *file, const unsigned long line, const char >> *func) >> +{ >> + struct preempt_info *pi = &this_cpu(__preempt_debug)[preempt_count()]; >> + if (preempt_count() >= NR_PREEMPT_DEBUG) >> + return; >> + pi->file = file; >> + pi->func = func; >> + pi->line = line; >> + pi->r0 = (unsigned long)__builtin_return_address(0); >> + pi->r1 = (unsigned long)__builtin_return_address(1); >> +} >> + >> +void preempt_debug_dump(void) >> +{ >> + struct preempt_info *pi = this_cpu(__preempt_debug); >> + int i, count = preempt_count(); >> + >> + printk("preempt debug on CPU%d, count %d:\n", smp_processor_id(), count); >> + count = min(count, NR_PREEMPT_DEBUG); >> + for(i=0;i<count;i++, pi++) { >> + printk("%d @ 0x%p\n", i, pi); >> + printk(" %s %s:%ld\n", pi->func, pi->file, pi->line); >> + printk(" %#lx", pi->r0); print_symbol(" %s\n", pi->r0); >> + printk(" %#lx", pi->r1); print_symbol(" %s\n", pi->r1); >> + } >> +} >> +#endif >> diff -r 711cbaa038ca -r 15e53a2463f0 xen/drivers/char/console.c >> --- a/xen/drivers/char/console.c Mon Jan 17 14:12:48 2011 +0000 >> +++ b/xen/drivers/char/console.c Mon Jan 17 14:12:50 2011 +0000 >> @@ -961,6 +961,7 @@ void panic(const char *fmt, ...) >> printk("Panic on CPU %d:\n", smp_processor_id()); >> printk("%s", buf); >> printk("****************************************\n\n"); >> + preempt_debug_dump(); >> if ( opt_noreboot ) >> printk("Manual reset required (''noreboot'' specified)\n"); >> else >> diff -r 711cbaa038ca -r 15e53a2463f0 xen/include/xen/preempt.h >> --- a/xen/include/xen/preempt.h Mon Jan 17 14:12:48 2011 +0000 >> +++ b/xen/include/xen/preempt.h Mon Jan 17 14:12:50 2011 +0000 >> @@ -18,7 +18,18 @@ DECLARE_PER_CPU(unsigned int, __preempt_ >> >> #define preempt_count() (this_cpu(__preempt_count)) >> >> +//#define DEBUG_PREEMPT >> + >> +#ifdef DEBUG_PREEMPT >> +extern void preempt_debug(const char *file, const unsigned long line, const >> char *func); >> +extern void preempt_debug_dump(void); >> +#else >> +static inline void preempt_debug(const char *file, const unsigned long line, >> const char *func) {} >> +static inline void preempt_debug_dump(void) {} >> +#endif >> + >> #define preempt_disable() do { \ >> + preempt_debug(__FILE__, __LINE__, __func__);\ >> preempt_count()++; \ >> barrier(); \ >> } while (0) > > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel