summaryrefslogtreecommitdiffstats
path: root/rt-Fix-rwlocks-rwsem-rt_-down_-read_trylock.patch
blob: 0a2ecaab815a5a622aeb31fcabb1675730cbca4b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
From 956dcc483ffd16f99561df6b1eef993e989789b2 Mon Sep 17 00:00:00 2001
From: Thomas Gleixner <tglx@linutronix.de>
Date: Mon, 14 Sep 2009 19:01:21 +0200
Subject: [PATCH] rt: Fix rwlocks/rwsem rt_[down_]read_trylock()

commit 00261a9426ed50016e07cbef028578e93589761c in tip.

rt_read_trylock() and rt_down_read_trylock() take the lock / semaphore
unconditionally when it is write locked. Check read_depth if current
owns the lock. If it's 0 we know it is write locked and return 0.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 kernel/rt.c |   13 ++++++++++++-
 1 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/kernel/rt.c b/kernel/rt.c
index 710cef5..fd033a9 100644
--- a/kernel/rt.c
+++ b/kernel/rt.c
@@ -204,10 +204,14 @@ int __lockfunc rt_read_trylock(rwlock_t *rwlock)
 	int ret = 1;
 
 	/*
-	 * recursive read locks succeed when current owns the lock
+	 * recursive read locks succeed when current owns the lock,
+	 * but not when read_depth == 0 which means that the lock is
+	 * write locked.
 	 */
 	if (rt_mutex_real_owner(lock) != current)
 		ret = rt_mutex_trylock(lock);
+	else if (!rwlock->read_depth)
+		ret = 0;
 
 	if (ret) {
 		rwlock->read_depth++;
@@ -348,8 +352,15 @@ int  rt_down_read_trylock(struct rw_semaphore *rwsem)
 	struct rt_mutex *lock = &rwsem->lock;
 	int ret = 1;
 
+	/*
+	 * recursive read locks succeed when current owns the rwsem,
+	 * but not when read_depth == 0 which means that the rwsem is
+	 * write locked.
+	 */
 	if (rt_mutex_real_owner(lock) != current)
 		ret = rt_mutex_trylock(&rwsem->lock);
+	else if (!rwsem->read_depth)
+		ret = 0;
 
 	if (ret) {
 		rwsem->read_depth++;
-- 
1.7.0.4