X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fparisc%2Flib%2Fdebuglocks.c;h=5ac3eb04727661c0366bd0d24db184cac055aa5d;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=5166a9378cfa0bd2a9a395eb9d3f716b620fc4f5;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/arch/parisc/lib/debuglocks.c b/arch/parisc/lib/debuglocks.c index 5166a9378..5ac3eb047 100644 --- a/arch/parisc/lib/debuglocks.c +++ b/arch/parisc/lib/debuglocks.c @@ -18,6 +18,11 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * We use pdc_printf() throughout the file for all output messages, to avoid + * losing messages because of disabled interrupts. Since we're using these + * messages for debugging purposes, it makes sense not to send them to the + * linux console. */ @@ -27,12 +32,15 @@ #include #include /* in_interrupt() */ #include +#include /* in_interrupt() */ +#include #undef INIT_STUCK #define INIT_STUCK 1L << 30 #ifdef CONFIG_DEBUG_SPINLOCK + void _dbg_spin_lock(spinlock_t * lock, const char *base_file, int line_no) { volatile unsigned int *a; @@ -59,12 +67,14 @@ try_again: * __ldcw() returns 1 if we get the lock; otherwise we * spin until the value of the lock changes, or we time out. */ + mb(); a = __ldcw_align(lock); while (stuck && (__ldcw(a) == 0)) while ((*a == 0) && --stuck); + mb(); if (unlikely(stuck <= 0)) { - printk(KERN_WARNING + pdc_printf( "%s:%d: spin_lock(%s/%p) stuck in %s at %p(%d)" " owned by %s:%d in %s at %p(%d)\n", base_file, line_no, lock->module, lock, @@ -84,7 +94,7 @@ try_again: lock->bline = line_no; if (unlikely(printed)) { - printk(KERN_WARNING + pdc_printf( "%s:%d: spin_lock grabbed in %s at %p(%d) %ld ticks\n", base_file, line_no, current->comm, inline_pc, cpu, jiffies - started); @@ -94,21 +104,28 @@ try_again: void _dbg_spin_unlock(spinlock_t * lock, const char *base_file, int line_no) { CHECK_LOCK(lock); - volatile unsigned int *a = __ldcw_align(lock); + volatile unsigned int *a; + mb(); + a = __ldcw_align(lock); if (unlikely((*a != 0) && lock->babble)) { lock->babble--; - printk(KERN_WARNING + pdc_printf( "%s:%d: spin_unlock(%s:%p) not locked\n", base_file, line_no, lock->module, lock); } *a = 1; + mb(); } int _dbg_spin_trylock(spinlock_t * lock, const char *base_file, int line_no) { int ret; - volatile unsigned int *a = __ldcw_align(lock); - if ((ret = (__ldcw(a) != 0))) { + volatile unsigned int *a; + mb(); + a = __ldcw_align(lock); + ret = (__ldcw(a) != 0); + mb(); + if (ret) { lock->oncpu = smp_processor_id(); lock->previous = __builtin_return_address(0); lock->task = current; @@ -150,7 +167,7 @@ void _dbg_write_lock(rwlock_t *rw, const char *bfile, int bline) int cpu = smp_processor_id(); if(unlikely(in_interrupt())) { /* acquiring write lock in interrupt context, bad idea */ - printk(KERN_WARNING "write_lock caller: %s:%d, IRQs enabled,\n", bfile, bline); + pdc_printf("write_lock caller: %s:%d, IRQs enabled,\n", bfile, bline); BUG(); } @@ -167,7 +184,7 @@ retry: stuck--; if ((unlikely(stuck <= 0)) && (rw->counter < 0)) { - printk(KERN_WARNING + pdc_printf( "%s:%d: write_lock stuck on writer" " in %s at %p(%d) %ld ticks\n", bfile, bline, current->comm, inline_pc, @@ -176,7 +193,7 @@ retry: printed = 1; } else if (unlikely(stuck <= 0)) { - printk(KERN_WARNING + pdc_printf( "%s:%d: write_lock stuck on reader" " in %s at %p(%d) %ld ticks\n", bfile, bline, current->comm, inline_pc, @@ -194,13 +211,47 @@ retry: rw->counter = -1; /* remember we are locked */ if (unlikely(printed)) { - printk(KERN_WARNING + pdc_printf( "%s:%d: write_lock grabbed in %s at %p(%d) %ld ticks\n", bfile, bline, current->comm, inline_pc, cpu, jiffies - started); } } +int _dbg_write_trylock(rwlock_t *rw, const char *bfile, int bline) +{ +#if 0 + void *inline_pc = __builtin_return_address(0); + int cpu = smp_processor_id(); +#endif + + if(unlikely(in_interrupt())) { /* acquiring write lock in interrupt context, bad idea */ + pdc_printf("write_lock caller: %s:%d, IRQs enabled,\n", bfile, bline); + BUG(); + } + + /* Note: if interrupts are disabled (which is most likely), the printk + will never show on the console. We might need a polling method to flush + the dmesg buffer anyhow. */ + + _raw_spin_lock(&rw->lock); + + if(rw->counter != 0) { + /* this basically never happens */ + _raw_spin_unlock(&rw->lock); + + + return 0; + } + + /* got it. now leave without unlocking */ + rw->counter = -1; /* remember we are locked */ +#if 0 + pdc_printf("%s:%d: try write_lock grabbed in %s at %p(%d)\n", + bfile, bline, current->comm, inline_pc, cpu); +#endif +} + void _dbg_read_lock(rwlock_t * rw, const char *bfile, int bline) { #if 0 @@ -215,7 +266,7 @@ void _dbg_read_lock(rwlock_t * rw, const char *bfile, int bline) rw->counter++; #if 0 - printk(KERN_WARNING + pdc_printf( "%s:%d: read_lock grabbed in %s at %p(%d) %ld ticks\n", bfile, bline, current->comm, inline_pc, cpu, jiffies - started);