x86, asm: Fix a compilation issue with clang
[pandora-kernel.git] / lib / rwsem.c
index bbe48c0..19c5fa9 100644 (file)
@@ -64,7 +64,7 @@ __rwsem_do_wake(struct rw_semaphore *sem, enum rwsem_wake_type wake_type)
        struct rwsem_waiter *waiter;
        struct task_struct *tsk;
        struct list_head *next;
-       signed long oldcount, woken, loop, adjustment;
+       long oldcount, woken, loop, adjustment;
 
        waiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list);
        if (waiter->type == RWSEM_WAITING_FOR_WRITE) {
@@ -145,10 +145,9 @@ __rwsem_do_wake(struct rw_semaphore *sem, enum rwsem_wake_type wake_type)
  */
 struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem)
 {
-       signed long adjustment = -RWSEM_ACTIVE_READ_BIAS;
+       long count, adjustment = -RWSEM_ACTIVE_READ_BIAS;
        struct rwsem_waiter waiter;
        struct task_struct *tsk = current;
-       signed long count;
 
        /* set up my own style of waitqueue */
        waiter.task = tsk;
@@ -163,8 +162,14 @@ struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem)
        /* we're now waiting on the lock, but no longer actively locking */
        count = rwsem_atomic_update(adjustment, sem);
 
-       /* If there are no active locks, wake the front queued process(es). */
-       if (!(count & RWSEM_ACTIVE_MASK))
+       /* If there are no active locks, wake the front queued process(es).
+        *
+        * If there are no writers and we are first in the queue,
+        * wake our own waiter to join the existing active readers !
+        */
+       if (count == RWSEM_WAITING_BIAS ||
+           (count > RWSEM_WAITING_BIAS &&
+            adjustment != -RWSEM_ACTIVE_READ_BIAS))
                sem = __rwsem_do_wake(sem, RWSEM_WAKE_ANY);
 
        raw_spin_unlock_irq(&sem->wait_lock);
@@ -187,10 +192,9 @@ struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem)
  */
 struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore *sem)
 {
-       signed long adjustment = -RWSEM_ACTIVE_WRITE_BIAS;
+       long count, adjustment = -RWSEM_ACTIVE_WRITE_BIAS;
        struct rwsem_waiter waiter;
        struct task_struct *tsk = current;
-       signed long count;
 
        /* set up my own style of waitqueue */
        waiter.task = tsk;
@@ -219,7 +223,9 @@ struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore *sem)
                        count = RWSEM_ACTIVE_WRITE_BIAS;
                        if (!list_is_singular(&sem->wait_list))
                                count += RWSEM_WAITING_BIAS;
-                       if (cmpxchg(&sem->count, RWSEM_WAITING_BIAS, count) ==
+
+                       if (sem->count == RWSEM_WAITING_BIAS &&
+                           cmpxchg(&sem->count, RWSEM_WAITING_BIAS, count) ==
                                                        RWSEM_WAITING_BIAS)
                                break;
                }