Read lock recursion is no longer required for ldisc references;
remove mechanism.

Signed-off-by: Peter Hurley <[email protected]>
---
 drivers/tty/tty_ldsem.c   | 83 +++++------------------------------------------
 include/linux/tty_ldisc.h |  2 --
 2 files changed, 8 insertions(+), 77 deletions(-)

diff --git a/drivers/tty/tty_ldsem.c b/drivers/tty/tty_ldsem.c
index c162295..a60d7e3 100644
--- a/drivers/tty/tty_ldsem.c
+++ b/drivers/tty/tty_ldsem.c
@@ -3,28 +3,14 @@
  *
  * The ldisc semaphore is semantically a rw_semaphore but which enforces
  * an alternate policy, namely:
- *   1) Recursive read locking is allowed
- *   2) Supports lock wait timeouts
- *   3) Write waiter has priority, even if lock is already read owned, except:
- *   4) Write waiter does not prevent recursive locking
- *   5) Downgrading is not supported (because of #3 & #4 above)
+ *   1) Supports lock wait timeouts
+ *   2) Write waiter has priority
+ *   3) Downgrading is not supported
  *
  * Implementation notes:
  *   1) Upper half of semaphore count is a wait count (differs from rwsem
  *     in that rwsem normalizes the upper half to the wait bias)
  *   2) Lacks overflow checking
- *   3) Read recursion is tracked with a bitmap indexed by hashed 'current'
- *     This approach results in some false positives; ie, a non-recursive
- *     read lock may be granted while a write lock is waited.
- *     However, this approach does not produce false-negatives
- *     (ie. not granting a read lock to a recursive attempt) which might
- *     deadlock.
- *     Testing the bitmap need not be atomic wrt. setting the bitmap
- *     (as the 'current' thread cannot contend with itself); however,
- *     since the bitmap is cleared when write lock is granted.
- *     Note: increasing the bitmap size reduces the probability of false
- *     positives, and thus the probability of granting a non-recursive
- *     read lock with writer(s) waiting.
  *
  * The generic counting was copied and modified from 
include/asm-generic/rwsem.h
  * by Paul Mackerras <[email protected]>.
@@ -53,12 +39,12 @@
 # ifdef CONFIG_PROVE_LOCKING
 #  define lockdep_acquire(l, s, t, i)          __acq(l, s, t, 0, 2, NULL, i)
 #  define lockdep_acquire_nest(l, s, t, n, i)  __acq(l, s, t, 0, 2, n, i)
-#  define lockdep_acquire_read(l, s, t, i)     __acq(l, s, t, 2, 2, NULL, i)
+#  define lockdep_acquire_read(l, s, t, i)     __acq(l, s, t, 1, 2, NULL, i)
 #  define lockdep_release(l, n, i)             __rel(l, n, i)
 # else
 #  define lockdep_acquire(l, s, t, i)          __acq(l, s, t, 0, 1, NULL, i)
 #  define lockdep_acquire_nest(l, s, t, n, i)  __acq(l, s, t, 0, 1, n, i)
-#  define lockdep_acquire_read(l, s, t, i)     __acq(l, s, t, 2, 1, NULL, i)
+#  define lockdep_acquire_read(l, s, t, i)     __acq(l, s, t, 1, 1, NULL, i)
 #  define lockdep_release(l, n, i)             __rel(l, n, i)
 # endif
 #else
@@ -107,26 +93,6 @@ static inline long ldsem_atomic_update(long delta, struct 
ld_semaphore *sem)
 }
 
 
-static inline unsigned long __hash_current(void)
-{
-       return (unsigned long)current % TASK_MAP_BITS;
-}
-
-static inline void ldsem_clear_task_map(struct ld_semaphore *sem)
-{
-       bitmap_zero(sem->task_map, TASK_MAP_BITS);
-}
-
-static inline void ldsem_update_task_map(struct ld_semaphore *sem)
-{
-       __set_bit(__hash_current(), sem->task_map);
-}
-
-static inline int ldsem_lock_recursion(struct ld_semaphore *sem)
-{
-       return test_bit(__hash_current(), sem->task_map);
-}
-
 /*
  * Initialize an ldsem:
  */
@@ -144,7 +110,6 @@ void __init_ldsem(struct ld_semaphore *sem, const char 
*name,
        raw_spin_lock_init(&sem->wait_lock);
        INIT_LIST_HEAD(&sem->read_wait);
        INIT_LIST_HEAD(&sem->write_wait);
-       ldsem_clear_task_map(sem);
 }
 
 static void __ldsem_wake_readers(struct ld_semaphore *sem, int wake_type)
@@ -217,9 +182,6 @@ static void __ldsem_wake_writer(struct ld_semaphore *sem)
                        return;
        } while (1);
 
-       /* reset read lock recursion map */
-       ldsem_clear_task_map(sem);
-
        /* We must be careful not to touch 'waiter' after we set ->task = NULL.
         * It is an allocated on the waiter's stack and may become invalid at
         * any time after that point (due to a wakeup from another source).
@@ -268,17 +230,9 @@ down_failed(struct ld_semaphore *sem, unsigned flags, long 
adjust, long timeout)
        /* set up my own style of waitqueue */
        raw_spin_lock_irq(&sem->wait_lock);
 
-       if (flags & LDSEM_READ_WAIT) {
-               /* Handle recursive read locking -- if the reader already has
-                * a read lock then allow lock acquire without waiting
-                * but also without waking other waiters
-                */
-               if (ldsem_lock_recursion(sem)) {
-                       raw_spin_unlock_irq(&sem->wait_lock);
-                       return sem;
-               }
+       if (flags & LDSEM_READ_WAIT)
                list_add_tail(&waiter.list, &sem->read_wait);
-       } else
+       else
                list_add_tail(&waiter.list, &sem->write_wait);
 
        waiter.task = current;
@@ -358,9 +312,6 @@ static inline int __ldsem_down_read_nested(struct 
ld_semaphore *sem,
                }
        }
        lock_stat(sem, acquired);
-
-       /* used for read lock recursion test */
-       ldsem_update_task_map(sem);
        return 1;
 }
 
@@ -371,17 +322,9 @@ static inline int __ldsem_down_write_nested(struct 
ld_semaphore *sem,
 
        lockdep_acquire(sem, subclass, 0, _RET_IP_);
 
-       raw_spin_lock_irq(&sem->wait_lock);
-
        count = atomic_long_add_return(LDSEM_WRITE_BIAS,
                                       (atomic_long_t *)&sem->count);
-       if (count == LDSEM_WRITE_BIAS) {
-               /* reset read lock recursion map */
-               ldsem_clear_task_map(sem);
-               raw_spin_unlock_irq(&sem->wait_lock);
-       } else {
-               raw_spin_unlock_irq(&sem->wait_lock);
-
+       if (count != LDSEM_WRITE_BIAS) {
                lock_stat(sem, contended);
                if (!down_write_failed(sem, timeout)) {
                        lockdep_release(sem, 1, _RET_IP_);
@@ -414,8 +357,6 @@ int ldsem_down_read_trylock(struct ld_semaphore *sem)
                                                 count + LDSEM_READ_BIAS)) {
                        lockdep_acquire_read(sem, 0, 1, _RET_IP_);
                        lock_stat(sem, acquired);
-
-                       ldsem_update_task_map(sem);
                        return 1;
                }
        }
@@ -438,21 +379,13 @@ int ldsem_down_write_trylock(struct ld_semaphore *sem)
 {
        long count;
 
-       raw_spin_lock_irq(&sem->wait_lock);
-
        count = atomic_long_cmpxchg(&sem->count, LDSEM_UNLOCKED,
                                    LDSEM_WRITE_BIAS);
        if (count == LDSEM_UNLOCKED) {
-               /* reset read lock recursion map */
-               ldsem_clear_task_map(sem);
-
-               raw_spin_unlock_irq(&sem->wait_lock);
-
                lockdep_acquire(sem, 0, 1, _RET_IP_);
                lock_stat(sem, acquired);
                return 1;
        }
-       raw_spin_unlock_irq(&sem->wait_lock);
        return 0;
 }
 
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h
index bbefe71..bfbe41a 100644
--- a/include/linux/tty_ldisc.h
+++ b/include/linux/tty_ldisc.h
@@ -122,8 +122,6 @@ struct ld_semaphore {
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
        struct lockdep_map      dep_map;
 #endif
-#define TASK_MAP_BITS          157
-       DECLARE_BITMAP(task_map, TASK_MAP_BITS);
 };
 
 extern void __init_ldsem(struct ld_semaphore *sem, const char *name,
-- 
1.8.1.2

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

Reply via email to