diff options
-rw-r--r-- | include/linux/percpu-rwsem.h | 6 | ||||
-rw-r--r-- | include/linux/rwsem.h | 6 | ||||
-rw-r--r-- | kernel/locking/rwsem-xadd.c | 2 |
3 files changed, 13 insertions, 1 deletions
diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h index b1f37a89e368..79b99d653e03 100644 --- a/include/linux/percpu-rwsem.h +++ b/include/linux/percpu-rwsem.h | |||
@@ -133,7 +133,7 @@ static inline void percpu_rwsem_release(struct percpu_rw_semaphore *sem, | |||
133 | lock_release(&sem->rw_sem.dep_map, 1, ip); | 133 | lock_release(&sem->rw_sem.dep_map, 1, ip); |
134 | #ifdef CONFIG_RWSEM_SPIN_ON_OWNER | 134 | #ifdef CONFIG_RWSEM_SPIN_ON_OWNER |
135 | if (!read) | 135 | if (!read) |
136 | sem->rw_sem.owner = NULL; | 136 | sem->rw_sem.owner = RWSEM_OWNER_UNKNOWN; |
137 | #endif | 137 | #endif |
138 | } | 138 | } |
139 | 139 | ||
@@ -141,6 +141,10 @@ static inline void percpu_rwsem_acquire(struct percpu_rw_semaphore *sem, | |||
141 | bool read, unsigned long ip) | 141 | bool read, unsigned long ip) |
142 | { | 142 | { |
143 | lock_acquire(&sem->rw_sem.dep_map, 0, 1, read, 1, NULL, ip); | 143 | lock_acquire(&sem->rw_sem.dep_map, 0, 1, read, 1, NULL, ip); |
144 | #ifdef CONFIG_RWSEM_SPIN_ON_OWNER | ||
145 | if (!read) | ||
146 | sem->rw_sem.owner = current; | ||
147 | #endif | ||
144 | } | 148 | } |
145 | 149 | ||
146 | #endif | 150 | #endif |
diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h index 56707d5ff6ad..ab93b6eae696 100644 --- a/include/linux/rwsem.h +++ b/include/linux/rwsem.h | |||
@@ -44,6 +44,12 @@ struct rw_semaphore { | |||
44 | #endif | 44 | #endif |
45 | }; | 45 | }; |
46 | 46 | ||
47 | /* | ||
48 | * Setting bit 0 of the owner field with other non-zero bits will indicate | ||
49 | * that the rwsem is writer-owned with an unknown owner. | ||
50 | */ | ||
51 | #define RWSEM_OWNER_UNKNOWN ((struct task_struct *)-1L) | ||
52 | |||
47 | extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem); | 53 | extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem); |
48 | extern struct rw_semaphore *rwsem_down_read_failed_killable(struct rw_semaphore *sem); | 54 | extern struct rw_semaphore *rwsem_down_read_failed_killable(struct rw_semaphore *sem); |
49 | extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem); | 55 | extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem); |
diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c index 604d247ea8c3..a90336779375 100644 --- a/kernel/locking/rwsem-xadd.c +++ b/kernel/locking/rwsem-xadd.c | |||
@@ -352,6 +352,8 @@ static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem) | |||
352 | struct task_struct *owner; | 352 | struct task_struct *owner; |
353 | bool ret = true; | 353 | bool ret = true; |
354 | 354 | ||
355 | BUILD_BUG_ON(!rwsem_has_anonymous_owner(RWSEM_OWNER_UNKNOWN)); | ||
356 | |||
355 | if (need_resched()) | 357 | if (need_resched()) |
356 | return false; | 358 | return false; |
357 | 359 | ||