diff -Naru a/lib/rwsem-spinlock.c b/lib/rwsem-spinlock.c --- a/lib/rwsem-spinlock.c 2005-04-14 00:47:04 -07:00 +++ b/lib/rwsem-spinlock.c 2005-04-14 00:47:04 -07:00 @@ -127,12 +127,12 @@ rwsemtrace(sem,"Entering __down_read"); - spin_lock(&sem->wait_lock); + spin_lock_irq(&sem->wait_lock); if (sem->activity>=0 && list_empty(&sem->wait_list)) { /* granted */ sem->activity++; - spin_unlock(&sem->wait_lock); + spin_unlock_irq(&sem->wait_lock); goto out; } @@ -147,7 +147,7 @@ list_add_tail(&waiter.list,&sem->wait_list); /* we don't need to touch the semaphore struct anymore */ - spin_unlock(&sem->wait_lock); + spin_unlock_irq(&sem->wait_lock); /* wait to be given the lock */ for (;;) { @@ -169,9 +169,10 @@ int fastcall __down_read_trylock(struct rw_semaphore *sem) { int ret = 0; + unsigned long flags; rwsemtrace(sem,"Entering __down_read_trylock"); - spin_lock(&sem->wait_lock); + spin_lock_irqsave(&sem->wait_lock, flags); if (sem->activity>=0 && list_empty(&sem->wait_list)) { /* granted */ @@ -179,7 +180,7 @@ ret = 1; } - spin_unlock(&sem->wait_lock); + spin_unlock_irqrestore(&sem->wait_lock, flags); rwsemtrace(sem,"Leaving __down_read_trylock"); return ret; @@ -196,12 +197,12 @@ rwsemtrace(sem,"Entering __down_write"); - spin_lock(&sem->wait_lock); + spin_lock_irq(&sem->wait_lock); if (sem->activity==0 && list_empty(&sem->wait_list)) { /* granted */ sem->activity = -1; - spin_unlock(&sem->wait_lock); + spin_unlock_irq(&sem->wait_lock); goto out; } @@ -216,7 +217,7 @@ list_add_tail(&waiter.list,&sem->wait_list); /* we don't need to touch the semaphore struct anymore */ - spin_unlock(&sem->wait_lock); + spin_unlock_irq(&sem->wait_lock); /* wait to be given the lock */ for (;;) { @@ -238,9 +239,10 @@ int fastcall __down_write_trylock(struct rw_semaphore *sem) { int ret = 0; + unsigned long flags; rwsemtrace(sem,"Entering __down_write_trylock"); - spin_lock(&sem->wait_lock); + spin_lock_irqsave(&sem->wait_lock, flags); if (sem->activity==0 && list_empty(&sem->wait_list)) { /* granted */ @@ -248,7 +250,7 @@ ret = 1; } - spin_unlock(&sem->wait_lock); + spin_unlock_irqrestore(&sem->wait_lock, flags); rwsemtrace(sem,"Leaving __down_write_trylock"); return ret; @@ -259,14 +261,15 @@ */ void fastcall __up_read(struct rw_semaphore *sem) { + unsigned long flags; rwsemtrace(sem,"Entering __up_read"); - spin_lock(&sem->wait_lock); + spin_lock_irqsave(&sem->wait_lock, flags); if (--sem->activity==0 && !list_empty(&sem->wait_list)) sem = __rwsem_wake_one_writer(sem); - spin_unlock(&sem->wait_lock); + spin_unlock_restore(&sem->wait_lock, flags); rwsemtrace(sem,"Leaving __up_read"); } @@ -276,15 +279,16 @@ */ void fastcall __up_write(struct rw_semaphore *sem) { + unsigned long flags; rwsemtrace(sem,"Entering __up_write"); - spin_lock(&sem->wait_lock); + spin_lock_irqsave(&sem->wait_lock, flags); sem->activity = 0; if (!list_empty(&sem->wait_list)) sem = __rwsem_do_wake(sem); - spin_unlock(&sem->wait_lock); + spin_unlock_irqrestore(&sem->wait_lock, flags); rwsemtrace(sem,"Leaving __up_write"); } diff -Naru a/lib/rwsem.c b/lib/rwsem.c --- a/lib/rwsem.c 2005-04-14 00:47:04 -07:00 +++ b/lib/rwsem.c 2005-04-14 00:47:04 -07:00 @@ -127,7 +127,7 @@ set_task_state(tsk,TASK_UNINTERRUPTIBLE); /* set up my own style of waitqueue */ - spin_lock(&sem->wait_lock); + spin_lock_irq(&sem->wait_lock); waiter->task = tsk; get_task_struct(tsk); @@ -142,7 +142,7 @@ if (!(count & RWSEM_ACTIVE_MASK)) sem = __rwsem_do_wake(sem); - spin_unlock(&sem->wait_lock); + spin_unlock_irq(&sem->wait_lock); /* wait to be given the lock */ for (;;) { @@ -195,15 +195,16 @@ */ struct rw_semaphore fastcall *rwsem_wake(struct rw_semaphore *sem) { + unsigned long flags; rwsemtrace(sem,"Entering rwsem_wake"); - spin_lock(&sem->wait_lock); + spin_lock_irqsave(&sem->wait_lock, flags); /* do nothing if list empty */ if (!list_empty(&sem->wait_list)) sem = __rwsem_do_wake(sem); - spin_unlock(&sem->wait_lock); + spin_unlock_irqrestore(&sem->wait_lock, flags); rwsemtrace(sem,"Leaving rwsem_wake"); # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2005/04/05 11:05:24-03:00 akpm@osdl.org # [PATCH] rwsem: Make rwsems use interrupt disabling spinlocks # # # This is a BitKeeper generated diff -Nru style patch. # # # # ChangeSet # # 2005/03/09 10:25:02-08:00 dhowells@redhat.com # # [PATCH] rwsem: Make rwsems use interrupt disabling spinlocks # # # # The attached patch makes read/write semaphores use interrupt disabling # # spinlocks in the slow path, thus rendering the up functions and trylock # # functions available for use in interrupt context. This matches the # # regular semaphore behaviour. # # # # I've assumed that the normal down functions must be called with interrupts # # enabled (since they might schedule), and used the irq-disabling spinlock # # variants that don't save the flags. # # # # Signed-Off-By: David Howells # # Tested-by: Badari Pulavarty # # Signed-off-by: Linus Torvalds # # # # lib/rwsem.c # # 2005/03/09 02:45:16-08:00 dhowells@redhat.com +10 -6 # # rwsem: Make rwsems use interrupt disabling spinlocks # # # # lib/rwsem-spinlock.c # # 2005/03/09 02:43:47-08:00 dhowells@redhat.com +26 -16 # # rwsem: Make rwsems use interrupt disabling spinlocks # # # # lib/rwsem-spinlock.c # 2005/04/05 10:06:32-03:00 akpm@osdl.org +18 -14 # rwsem: Make rwsems use interrupt disabling spinlocks # # lib/rwsem.c # 2005/04/05 10:11:02-03:00 akpm@osdl.org +5 -4 # rwsem: Make rwsems use interrupt disabling spinlocks #