Re: [PATCH v2 03/13] rwsem: move rwsem_down_failed_common code into rwsem_down_{read,write}_failed

2013-04-27 Thread Davidlohr Bueso
Sorry, but I just couldn't help myself :)

From: Davidlohr Bueso 
Subject: [PATCH] rwsem: no need for explicit signed longs

Signed-off-by: Davidlohr Bueso 
---
 lib/rwsem.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/lib/rwsem.c b/lib/rwsem.c
index 4e4c889..50fdd89 100644
--- a/lib/rwsem.c
+++ b/lib/rwsem.c
@@ -63,7 +63,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) {
@@ -144,11 +144,10 @@ __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;
waiter.type = RWSEM_WAITING_FOR_READ;
@@ -192,10 +191,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;
-- 
1.7.11.7



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 03/13] rwsem: move rwsem_down_failed_common code into rwsem_down_{read,write}_failed

2013-04-27 Thread Davidlohr Bueso
Sorry, but I just couldn't help myself :)

From: Davidlohr Bueso davidlohr.bu...@hp.com
Subject: [PATCH] rwsem: no need for explicit signed longs

Signed-off-by: Davidlohr Bueso davidlohr.bu...@hp.com
---
 lib/rwsem.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/lib/rwsem.c b/lib/rwsem.c
index 4e4c889..50fdd89 100644
--- a/lib/rwsem.c
+++ b/lib/rwsem.c
@@ -63,7 +63,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) {
@@ -144,11 +144,10 @@ __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;
waiter.type = RWSEM_WAITING_FOR_READ;
@@ -192,10 +191,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;
-- 
1.7.11.7



--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 03/13] rwsem: move rwsem_down_failed_common code into rwsem_down_{read,write}_failed

2013-03-28 Thread Rik van Riel

On 03/15/2013 06:54 AM, Michel Lespinasse wrote:

Remove the rwsem_down_failed_common function and replace it with two
identical copies of its code in rwsem_down_{read,write}_failed.

This is because we want to make different optimizations in
rwsem_down_{read,write}_failed; we are adding this pure-duplication
step as a separate commit in order to make it easier to check the
following steps.

Signed-off-by: Michel Lespinasse 


Reviewed-by: Rik van Riel 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 03/13] rwsem: move rwsem_down_failed_common code into rwsem_down_{read,write}_failed

2013-03-28 Thread Peter Hurley
On Fri, 2013-03-15 at 03:54 -0700, Michel Lespinasse wrote:
> Remove the rwsem_down_failed_common function and replace it with two
> identical copies of its code in rwsem_down_{read,write}_failed.
> 
> This is because we want to make different optimizations in
> rwsem_down_{read,write}_failed; we are adding this pure-duplication
> step as a separate commit in order to make it easier to check the
> following steps.
> 
> Signed-off-by: Michel Lespinasse 
> 
> ---
>  lib/rwsem.c | 72 
> -
>  1 file changed, 57 insertions(+), 15 deletions(-)
> 
> diff --git a/lib/rwsem.c b/lib/rwsem.c
> index 40636454cf3c..fb658af1c12c 100644
> --- a/lib/rwsem.c
> +++ b/lib/rwsem.c
> @@ -178,12 +178,12 @@ try_again_write:
>  }
>  
>  /*
> - * wait for a lock to be granted
> + * wait for the read lock to be granted
>   */
> -static struct rw_semaphore __sched *
> -rwsem_down_failed_common(struct rw_semaphore *sem,
> -  enum rwsem_waiter_type type, signed long adjustment)
> +struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem)
>  {
> + enum rwsem_waiter_type type = RWSEM_WAITING_FOR_READ;
> + signed long adjustment = -RWSEM_ACTIVE_READ_BIAS;

Again, just my opinion (and I suspect you only did this because that's
what was here) but I think this should be:

+   long adjustment = -RWSEM_ACTIVE_READ_BIAS;

>   struct rwsem_waiter waiter;
>   struct task_struct *tsk = current;
>   signed long count;

Same here.

> @@ -238,21 +238,63 @@ rwsem_down_failed_common(struct rw_semaphore *sem,
>  }
>  
>  /*
> - * wait for the read lock to be granted
> - */
> -struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem)
> -{
> - return rwsem_down_failed_common(sem, RWSEM_WAITING_FOR_READ,
> - -RWSEM_ACTIVE_READ_BIAS);
> -}
> -
> -/*
>   * wait for the write lock to be granted
>   */
>  struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore 
> *sem)
>  {
> - return rwsem_down_failed_common(sem, RWSEM_WAITING_FOR_WRITE,
> - -RWSEM_ACTIVE_WRITE_BIAS);
> + enum rwsem_waiter_type type = RWSEM_WAITING_FOR_WRITE;
> + signed long adjustment = -RWSEM_ACTIVE_WRITE_BIAS;

Same here.

> + struct rwsem_waiter waiter;
> + struct task_struct *tsk = current;
> + signed long count;

And here.

> +
> + /* set up my own style of waitqueue */
> + waiter.task = tsk;
> + waiter.type = type;
> + get_task_struct(tsk);
> +
> + raw_spin_lock_irq(>wait_lock);
> + if (list_empty(>wait_list))
> + adjustment += RWSEM_WAITING_BIAS;
> + list_add_tail(, >wait_list);
> +
> + /* 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) up.
> +  *
> +  * Alternatively, if we're called from a failed down_write(), there
> +  * were already threads queued before us and there are no active
> +  * writers, the lock must be read owned; so we try to wake any read
> +  * locks that were queued ahead of us. */
> + if (count == RWSEM_WAITING_BIAS)
> + sem = __rwsem_do_wake(sem, RWSEM_WAKE_NO_ACTIVE);
> + else if (count > RWSEM_WAITING_BIAS &&
> +  adjustment == -RWSEM_ACTIVE_WRITE_BIAS)
> + sem = __rwsem_do_wake(sem, RWSEM_WAKE_READ_OWNED);
> +
> + raw_spin_unlock_irq(>wait_lock);
> +
> + /* wait to be given the lock */
> + while (true) {
> + set_task_state(tsk, TASK_UNINTERRUPTIBLE);
> + if (!waiter.task)
> + break;
> +
> + raw_spin_lock_irq(>wait_lock);
> + /* Try to get the writer sem, may steal from the head writer: */
> + if (type == RWSEM_WAITING_FOR_WRITE)
> + if (try_get_writer_sem(sem, )) {
> + raw_spin_unlock_irq(>wait_lock);
> + return sem;
> + }
> + raw_spin_unlock_irq(>wait_lock);
> + schedule();
> + }
> +
> + tsk->state = TASK_RUNNING;
> +
> + return sem;
>  }
>  
>  /*


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 03/13] rwsem: move rwsem_down_failed_common code into rwsem_down_{read,write}_failed

2013-03-28 Thread Rik van Riel

On 03/15/2013 06:54 AM, Michel Lespinasse wrote:

Remove the rwsem_down_failed_common function and replace it with two
identical copies of its code in rwsem_down_{read,write}_failed.

This is because we want to make different optimizations in
rwsem_down_{read,write}_failed; we are adding this pure-duplication
step as a separate commit in order to make it easier to check the
following steps.

Signed-off-by: Michel Lespinasse wal...@google.com


Reviewed-by: Rik van Riel r...@redhat.com

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 03/13] rwsem: move rwsem_down_failed_common code into rwsem_down_{read,write}_failed

2013-03-28 Thread Peter Hurley
On Fri, 2013-03-15 at 03:54 -0700, Michel Lespinasse wrote:
 Remove the rwsem_down_failed_common function and replace it with two
 identical copies of its code in rwsem_down_{read,write}_failed.
 
 This is because we want to make different optimizations in
 rwsem_down_{read,write}_failed; we are adding this pure-duplication
 step as a separate commit in order to make it easier to check the
 following steps.
 
 Signed-off-by: Michel Lespinasse wal...@google.com
 
 ---
  lib/rwsem.c | 72 
 -
  1 file changed, 57 insertions(+), 15 deletions(-)
 
 diff --git a/lib/rwsem.c b/lib/rwsem.c
 index 40636454cf3c..fb658af1c12c 100644
 --- a/lib/rwsem.c
 +++ b/lib/rwsem.c
 @@ -178,12 +178,12 @@ try_again_write:
  }
  
  /*
 - * wait for a lock to be granted
 + * wait for the read lock to be granted
   */
 -static struct rw_semaphore __sched *
 -rwsem_down_failed_common(struct rw_semaphore *sem,
 -  enum rwsem_waiter_type type, signed long adjustment)
 +struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem)
  {
 + enum rwsem_waiter_type type = RWSEM_WAITING_FOR_READ;
 + signed long adjustment = -RWSEM_ACTIVE_READ_BIAS;

Again, just my opinion (and I suspect you only did this because that's
what was here) but I think this should be:

+   long adjustment = -RWSEM_ACTIVE_READ_BIAS;

   struct rwsem_waiter waiter;
   struct task_struct *tsk = current;
   signed long count;

Same here.

 @@ -238,21 +238,63 @@ rwsem_down_failed_common(struct rw_semaphore *sem,
  }
  
  /*
 - * wait for the read lock to be granted
 - */
 -struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem)
 -{
 - return rwsem_down_failed_common(sem, RWSEM_WAITING_FOR_READ,
 - -RWSEM_ACTIVE_READ_BIAS);
 -}
 -
 -/*
   * wait for the write lock to be granted
   */
  struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore 
 *sem)
  {
 - return rwsem_down_failed_common(sem, RWSEM_WAITING_FOR_WRITE,
 - -RWSEM_ACTIVE_WRITE_BIAS);
 + enum rwsem_waiter_type type = RWSEM_WAITING_FOR_WRITE;
 + signed long adjustment = -RWSEM_ACTIVE_WRITE_BIAS;

Same here.

 + struct rwsem_waiter waiter;
 + struct task_struct *tsk = current;
 + signed long count;

And here.

 +
 + /* set up my own style of waitqueue */
 + waiter.task = tsk;
 + waiter.type = type;
 + get_task_struct(tsk);
 +
 + raw_spin_lock_irq(sem-wait_lock);
 + if (list_empty(sem-wait_list))
 + adjustment += RWSEM_WAITING_BIAS;
 + list_add_tail(waiter.list, sem-wait_list);
 +
 + /* 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) up.
 +  *
 +  * Alternatively, if we're called from a failed down_write(), there
 +  * were already threads queued before us and there are no active
 +  * writers, the lock must be read owned; so we try to wake any read
 +  * locks that were queued ahead of us. */
 + if (count == RWSEM_WAITING_BIAS)
 + sem = __rwsem_do_wake(sem, RWSEM_WAKE_NO_ACTIVE);
 + else if (count  RWSEM_WAITING_BIAS 
 +  adjustment == -RWSEM_ACTIVE_WRITE_BIAS)
 + sem = __rwsem_do_wake(sem, RWSEM_WAKE_READ_OWNED);
 +
 + raw_spin_unlock_irq(sem-wait_lock);
 +
 + /* wait to be given the lock */
 + while (true) {
 + set_task_state(tsk, TASK_UNINTERRUPTIBLE);
 + if (!waiter.task)
 + break;
 +
 + raw_spin_lock_irq(sem-wait_lock);
 + /* Try to get the writer sem, may steal from the head writer: */
 + if (type == RWSEM_WAITING_FOR_WRITE)
 + if (try_get_writer_sem(sem, waiter)) {
 + raw_spin_unlock_irq(sem-wait_lock);
 + return sem;
 + }
 + raw_spin_unlock_irq(sem-wait_lock);
 + schedule();
 + }
 +
 + tsk-state = TASK_RUNNING;
 +
 + return sem;
  }
  
  /*


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 03/13] rwsem: move rwsem_down_failed_common code into rwsem_down_{read,write}_failed

2013-03-15 Thread Michel Lespinasse
Remove the rwsem_down_failed_common function and replace it with two
identical copies of its code in rwsem_down_{read,write}_failed.

This is because we want to make different optimizations in
rwsem_down_{read,write}_failed; we are adding this pure-duplication
step as a separate commit in order to make it easier to check the
following steps.

Signed-off-by: Michel Lespinasse 

---
 lib/rwsem.c | 72 -
 1 file changed, 57 insertions(+), 15 deletions(-)

diff --git a/lib/rwsem.c b/lib/rwsem.c
index 40636454cf3c..fb658af1c12c 100644
--- a/lib/rwsem.c
+++ b/lib/rwsem.c
@@ -178,12 +178,12 @@ try_again_write:
 }
 
 /*
- * wait for a lock to be granted
+ * wait for the read lock to be granted
  */
-static struct rw_semaphore __sched *
-rwsem_down_failed_common(struct rw_semaphore *sem,
-enum rwsem_waiter_type type, signed long adjustment)
+struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem)
 {
+   enum rwsem_waiter_type type = RWSEM_WAITING_FOR_READ;
+   signed long adjustment = -RWSEM_ACTIVE_READ_BIAS;
struct rwsem_waiter waiter;
struct task_struct *tsk = current;
signed long count;
@@ -238,21 +238,63 @@ rwsem_down_failed_common(struct rw_semaphore *sem,
 }
 
 /*
- * wait for the read lock to be granted
- */
-struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem)
-{
-   return rwsem_down_failed_common(sem, RWSEM_WAITING_FOR_READ,
-   -RWSEM_ACTIVE_READ_BIAS);
-}
-
-/*
  * wait for the write lock to be granted
  */
 struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore *sem)
 {
-   return rwsem_down_failed_common(sem, RWSEM_WAITING_FOR_WRITE,
-   -RWSEM_ACTIVE_WRITE_BIAS);
+   enum rwsem_waiter_type type = RWSEM_WAITING_FOR_WRITE;
+   signed long 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;
+   waiter.type = type;
+   get_task_struct(tsk);
+
+   raw_spin_lock_irq(>wait_lock);
+   if (list_empty(>wait_list))
+   adjustment += RWSEM_WAITING_BIAS;
+   list_add_tail(, >wait_list);
+
+   /* 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) up.
+*
+* Alternatively, if we're called from a failed down_write(), there
+* were already threads queued before us and there are no active
+* writers, the lock must be read owned; so we try to wake any read
+* locks that were queued ahead of us. */
+   if (count == RWSEM_WAITING_BIAS)
+   sem = __rwsem_do_wake(sem, RWSEM_WAKE_NO_ACTIVE);
+   else if (count > RWSEM_WAITING_BIAS &&
+adjustment == -RWSEM_ACTIVE_WRITE_BIAS)
+   sem = __rwsem_do_wake(sem, RWSEM_WAKE_READ_OWNED);
+
+   raw_spin_unlock_irq(>wait_lock);
+
+   /* wait to be given the lock */
+   while (true) {
+   set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+   if (!waiter.task)
+   break;
+
+   raw_spin_lock_irq(>wait_lock);
+   /* Try to get the writer sem, may steal from the head writer: */
+   if (type == RWSEM_WAITING_FOR_WRITE)
+   if (try_get_writer_sem(sem, )) {
+   raw_spin_unlock_irq(>wait_lock);
+   return sem;
+   }
+   raw_spin_unlock_irq(>wait_lock);
+   schedule();
+   }
+
+   tsk->state = TASK_RUNNING;
+
+   return sem;
 }
 
 /*
-- 
1.8.1.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 03/13] rwsem: move rwsem_down_failed_common code into rwsem_down_{read,write}_failed

2013-03-15 Thread Michel Lespinasse
Remove the rwsem_down_failed_common function and replace it with two
identical copies of its code in rwsem_down_{read,write}_failed.

This is because we want to make different optimizations in
rwsem_down_{read,write}_failed; we are adding this pure-duplication
step as a separate commit in order to make it easier to check the
following steps.

Signed-off-by: Michel Lespinasse wal...@google.com

---
 lib/rwsem.c | 72 -
 1 file changed, 57 insertions(+), 15 deletions(-)

diff --git a/lib/rwsem.c b/lib/rwsem.c
index 40636454cf3c..fb658af1c12c 100644
--- a/lib/rwsem.c
+++ b/lib/rwsem.c
@@ -178,12 +178,12 @@ try_again_write:
 }
 
 /*
- * wait for a lock to be granted
+ * wait for the read lock to be granted
  */
-static struct rw_semaphore __sched *
-rwsem_down_failed_common(struct rw_semaphore *sem,
-enum rwsem_waiter_type type, signed long adjustment)
+struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem)
 {
+   enum rwsem_waiter_type type = RWSEM_WAITING_FOR_READ;
+   signed long adjustment = -RWSEM_ACTIVE_READ_BIAS;
struct rwsem_waiter waiter;
struct task_struct *tsk = current;
signed long count;
@@ -238,21 +238,63 @@ rwsem_down_failed_common(struct rw_semaphore *sem,
 }
 
 /*
- * wait for the read lock to be granted
- */
-struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem)
-{
-   return rwsem_down_failed_common(sem, RWSEM_WAITING_FOR_READ,
-   -RWSEM_ACTIVE_READ_BIAS);
-}
-
-/*
  * wait for the write lock to be granted
  */
 struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore *sem)
 {
-   return rwsem_down_failed_common(sem, RWSEM_WAITING_FOR_WRITE,
-   -RWSEM_ACTIVE_WRITE_BIAS);
+   enum rwsem_waiter_type type = RWSEM_WAITING_FOR_WRITE;
+   signed long 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;
+   waiter.type = type;
+   get_task_struct(tsk);
+
+   raw_spin_lock_irq(sem-wait_lock);
+   if (list_empty(sem-wait_list))
+   adjustment += RWSEM_WAITING_BIAS;
+   list_add_tail(waiter.list, sem-wait_list);
+
+   /* 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) up.
+*
+* Alternatively, if we're called from a failed down_write(), there
+* were already threads queued before us and there are no active
+* writers, the lock must be read owned; so we try to wake any read
+* locks that were queued ahead of us. */
+   if (count == RWSEM_WAITING_BIAS)
+   sem = __rwsem_do_wake(sem, RWSEM_WAKE_NO_ACTIVE);
+   else if (count  RWSEM_WAITING_BIAS 
+adjustment == -RWSEM_ACTIVE_WRITE_BIAS)
+   sem = __rwsem_do_wake(sem, RWSEM_WAKE_READ_OWNED);
+
+   raw_spin_unlock_irq(sem-wait_lock);
+
+   /* wait to be given the lock */
+   while (true) {
+   set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+   if (!waiter.task)
+   break;
+
+   raw_spin_lock_irq(sem-wait_lock);
+   /* Try to get the writer sem, may steal from the head writer: */
+   if (type == RWSEM_WAITING_FOR_WRITE)
+   if (try_get_writer_sem(sem, waiter)) {
+   raw_spin_unlock_irq(sem-wait_lock);
+   return sem;
+   }
+   raw_spin_unlock_irq(sem-wait_lock);
+   schedule();
+   }
+
+   tsk-state = TASK_RUNNING;
+
+   return sem;
 }
 
 /*
-- 
1.8.1.3
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/