aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2014-09-30 09:26:00 -0400
committerIngo Molnar <mingo@kernel.org>2014-10-03 00:09:30 -0400
commit8acd91e8620836a56ff62028ed28ba629f2881a0 (patch)
tree4a95b0d1a41b75f6ad4cd8a6c59dcdb9268d1e4b /lib
parentdebfab74e453f079cd8b12b0604387a8c510ef3a (diff)
locking/lockdep: Revert qrwlock recusive stuff
Commit f0bab73cb539 ("locking/lockdep: Restrict the use of recursive read_lock() with qrwlock") changed lockdep to try and conform to the qrwlock semantics which differ from the traditional rwlock semantics. In particular qrwlock is fair outside of interrupt context, but in interrupt context readers will ignore all fairness. The problem modeling this is that read and write side have different lock state (interrupts) semantics but we only have a single representation of these. Therefore lockdep will get confused, thinking the lock can cause interrupt lock inversions. So revert it for now; the old rwlock semantics were already imperfectly modeled and the qrwlock extra won't fit either. If we want to properly fix this, I think we need to resurrect the work by Gautham did a few years ago that split the read and write state of locks: http://lwn.net/Articles/332801/ FWIW the locking selftest that would've failed (and was reported by Borislav earlier) is something like: RL(X1); /* IRQ-ON */ LOCK(A); UNLOCK(A); RU(X1); IRQ_ENTER(); RL(X1); /* IN-IRQ */ RU(X1); IRQ_EXIT(); At which point it would report that because A is an IRQ-unsafe lock we can suffer the following inversion: CPU0 CPU1 lock(A) lock(X1) lock(A) <IRQ> lock(X1) And this is 'wrong' because X1 can recurse (assuming the above lock are in fact read-lock) but lockdep doesn't know about this. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Waiman Long <Waiman.Long@hp.com> Cc: ego@linux.vnet.ibm.com Cc: bp@alien8.de Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Link: http://lkml.kernel.org/r/20140930132600.GA7444@worktop.programming.kicks-ass.net Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/locking-selftest.c56
1 files changed, 7 insertions, 49 deletions
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
index 62af709b2083..872a15a2a637 100644
--- a/lib/locking-selftest.c
+++ b/lib/locking-selftest.c
@@ -267,46 +267,19 @@ GENERATE_TESTCASE(AA_rsem)
267#undef E 267#undef E
268 268
269/* 269/*
270 * Special-case for read-locking, they are not allowed to 270 * Special-case for read-locking, they are
271 * recurse on the same lock class except under interrupt context: 271 * allowed to recurse on the same lock class:
272 */ 272 */
273static void rlock_AA1(void) 273static void rlock_AA1(void)
274{ 274{
275 RL(X1); 275 RL(X1);
276 RL(X1); // this one should fail 276 RL(X1); // this one should NOT fail
277} 277}
278 278
279static void rlock_AA1B(void) 279static void rlock_AA1B(void)
280{ 280{
281 RL(X1); 281 RL(X1);
282 RL(X2); // this one should fail 282 RL(X2); // this one should NOT fail
283}
284
285static void rlock_AHA1(void)
286{
287 RL(X1);
288 HARDIRQ_ENTER();
289 RL(X1); // this one should NOT fail
290 HARDIRQ_EXIT();
291}
292
293static void rlock_AHA1B(void)
294{
295 RL(X1);
296 HARDIRQ_ENTER();
297 RL(X2); // this one should NOT fail
298 HARDIRQ_EXIT();
299}
300
301static void rlock_ASAHA1(void)
302{
303 RL(X1);
304 SOFTIRQ_ENTER();
305 RL(X1); // this one should NOT fail
306 HARDIRQ_ENTER();
307 RL(X1); // this one should NOT fail
308 HARDIRQ_EXIT();
309 SOFTIRQ_EXIT();
310} 283}
311 284
312static void rsem_AA1(void) 285static void rsem_AA1(void)
@@ -1096,7 +1069,7 @@ static inline void print_testname(const char *testname)
1096 print_testname(desc); \ 1069 print_testname(desc); \
1097 dotest(name##_spin, FAILURE, LOCKTYPE_SPIN); \ 1070 dotest(name##_spin, FAILURE, LOCKTYPE_SPIN); \
1098 dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK); \ 1071 dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK); \
1099 dotest(name##_rlock, FAILURE, LOCKTYPE_RWLOCK); \ 1072 dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK); \
1100 dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \ 1073 dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \
1101 dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \ 1074 dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \
1102 dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \ 1075 dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \
@@ -1857,14 +1830,14 @@ void locking_selftest(void)
1857 printk(" --------------------------------------------------------------------------\n"); 1830 printk(" --------------------------------------------------------------------------\n");
1858 print_testname("recursive read-lock"); 1831 print_testname("recursive read-lock");
1859 printk(" |"); 1832 printk(" |");
1860 dotest(rlock_AA1, FAILURE, LOCKTYPE_RWLOCK); 1833 dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK);
1861 printk(" |"); 1834 printk(" |");
1862 dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM); 1835 dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM);
1863 printk("\n"); 1836 printk("\n");
1864 1837
1865 print_testname("recursive read-lock #2"); 1838 print_testname("recursive read-lock #2");
1866 printk(" |"); 1839 printk(" |");
1867 dotest(rlock_AA1B, FAILURE, LOCKTYPE_RWLOCK); 1840 dotest(rlock_AA1B, SUCCESS, LOCKTYPE_RWLOCK);
1868 printk(" |"); 1841 printk(" |");
1869 dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM); 1842 dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM);
1870 printk("\n"); 1843 printk("\n");
@@ -1883,21 +1856,6 @@ void locking_selftest(void)
1883 dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM); 1856 dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM);
1884 printk("\n"); 1857 printk("\n");
1885 1858
1886 print_testname("recursive rlock with interrupt");
1887 printk(" |");
1888 dotest(rlock_AHA1, SUCCESS, LOCKTYPE_RWLOCK);
1889 printk("\n");
1890
1891 print_testname("recursive rlock with interrupt #2");
1892 printk(" |");
1893 dotest(rlock_AHA1B, SUCCESS, LOCKTYPE_RWLOCK);
1894 printk("\n");
1895
1896 print_testname("recursive rlock with interrupt #3");
1897 printk(" |");
1898 dotest(rlock_ASAHA1, SUCCESS, LOCKTYPE_RWLOCK);
1899 printk("\n");
1900
1901 printk(" --------------------------------------------------------------------------\n"); 1859 printk(" --------------------------------------------------------------------------\n");
1902 1860
1903 /* 1861 /*