X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fsparc64%2Flib%2Fdebuglocks.c;h=9fb4dedc89e13934f84bf093bde4ca2145f01825;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=341cce76b773237ec16c572fa442c14506b3dd50;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/sparc64/lib/debuglocks.c b/arch/sparc64/lib/debuglocks.c index 341cce76b..9fb4dedc8 100644 --- a/arch/sparc64/lib/debuglocks.c +++ b/arch/sparc64/lib/debuglocks.c @@ -55,7 +55,7 @@ void _do_spin_lock(spinlock_t *lock, char *str) { unsigned long caller, val; int stuck = INIT_STUCK; - int cpu = smp_processor_id(); + int cpu = get_cpu(); int shown = 0; GET_CALLER(caller); @@ -80,12 +80,14 @@ again: lock->owner_cpu = cpu; current->thread.smp_lock_count++; current->thread.smp_lock_pc = ((unsigned int)caller); + + put_cpu(); } -int _spin_trylock(spinlock_t *lock) +int _do_spin_trylock(spinlock_t *lock) { unsigned long val, caller; - int cpu = smp_processor_id(); + int cpu = get_cpu(); GET_CALLER(caller); __asm__ __volatile__("ldstub [%1], %0" @@ -99,6 +101,9 @@ int _spin_trylock(spinlock_t *lock) current->thread.smp_lock_count++; current->thread.smp_lock_pc = ((unsigned int)caller); } + + put_cpu(); + return val == 0; } @@ -117,7 +122,7 @@ void _do_read_lock (rwlock_t *rw, char *str) { unsigned long caller, val; int stuck = INIT_STUCK; - int cpu = smp_processor_id(); + int cpu = get_cpu(); int shown = 0; GET_CALLER(caller); @@ -148,13 +153,15 @@ wlock_again: rw->reader_pc[cpu] = ((unsigned int)caller); current->thread.smp_lock_count++; current->thread.smp_lock_pc = ((unsigned int)caller); + + put_cpu(); } void _do_read_unlock (rwlock_t *rw, char *str) { unsigned long caller, val; int stuck = INIT_STUCK; - int cpu = smp_processor_id(); + int cpu = get_cpu(); int shown = 0; GET_CALLER(caller); @@ -181,13 +188,15 @@ runlock_again: } goto runlock_again; } + + put_cpu(); } void _do_write_lock (rwlock_t *rw, char *str) { unsigned long caller, val; int stuck = INIT_STUCK; - int cpu = smp_processor_id(); + int cpu = get_cpu(); int shown = 0; GET_CALLER(caller); @@ -263,6 +272,8 @@ wlock_again: rw->writer_cpu = cpu; current->thread.smp_lock_count++; current->thread.smp_lock_pc = ((unsigned int)caller); + + put_cpu(); } void _do_write_unlock(rwlock_t *rw) @@ -299,4 +310,65 @@ wlock_again: } } +int _do_write_trylock (rwlock_t *rw, char *str) +{ + unsigned long caller, val; + int cpu = get_cpu(); + + GET_CALLER(caller); + + /* Try to acuire the write bit. */ + __asm__ __volatile__( +" mov 1, %%g3\n" +" sllx %%g3, 63, %%g3\n" +" ldx [%0], %%g5\n" +" brlz,pn %%g5, 1f\n" +" or %%g5, %%g3, %%g7\n" +" casx [%0], %%g5, %%g7\n" +" membar #StoreLoad | #StoreStore\n" +" ba,pt %%xcc, 2f\n" +" sub %%g5, %%g7, %0\n" +"1: mov 1, %0\n" +"2:" : "=r" (val) + : "0" (&(rw->lock)) + : "g3", "g5", "g7", "memory"); + + if (val) { + put_cpu(); + return 0; + } + + if ((rw->lock & ((1UL<<63)-1UL)) != 0UL) { + /* Readers still around, drop the write + * lock, return failure. + */ + __asm__ __volatile__( +" mov 1, %%g3\n" +" sllx %%g3, 63, %%g3\n" +"1: ldx [%0], %%g5\n" +" andn %%g5, %%g3, %%g7\n" +" casx [%0], %%g5, %%g7\n" +" cmp %%g5, %%g7\n" +" bne,pn %%xcc, 1b\n" +" membar #StoreLoad | #StoreStore" + : /* no outputs */ + : "r" (&(rw->lock)) + : "g3", "g5", "g7", "cc", "memory"); + + put_cpu(); + + return 0; + } + + /* We have it, say who we are. */ + rw->writer_pc = ((unsigned int)caller); + rw->writer_cpu = cpu; + current->thread.smp_lock_count++; + current->thread.smp_lock_pc = ((unsigned int)caller); + + put_cpu(); + + return 1; +} + #endif /* CONFIG_SMP */