Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Peter Zijlstra and committed by
Ingo Molnar
8acd91e8 debfab74

+8 -64
+1 -9
include/linux/lockdep.h
··· 478 478 * on the per lock-class debug mode: 479 479 */ 480 480 481 - /* 482 - * Read states in the 2-bit held_lock:read field: 483 - * 0: Exclusive lock 484 - * 1: Shareable lock, cannot be recursively called 485 - * 2: Shareable lock, can be recursively called 486 - * 3: Shareable lock, cannot be recursively called except in interrupt context 487 - */ 488 481 #define lock_acquire_exclusive(l, s, t, n, i) lock_acquire(l, s, t, 0, 1, n, i) 489 482 #define lock_acquire_shared(l, s, t, n, i) lock_acquire(l, s, t, 1, 1, n, i) 490 483 #define lock_acquire_shared_recursive(l, s, t, n, i) lock_acquire(l, s, t, 2, 1, n, i) 491 - #define lock_acquire_shared_irecursive(l, s, t, n, i) lock_acquire(l, s, t, 3, 1, n, i) 492 484 493 485 #define spin_acquire(l, s, t, i) lock_acquire_exclusive(l, s, t, NULL, i) 494 486 #define spin_acquire_nest(l, s, t, n, i) lock_acquire_exclusive(l, s, t, n, i) 495 487 #define spin_release(l, n, i) lock_release(l, n, i) 496 488 497 489 #define rwlock_acquire(l, s, t, i) lock_acquire_exclusive(l, s, t, NULL, i) 498 - #define rwlock_acquire_read(l, s, t, i) lock_acquire_shared_irecursive(l, s, t, NULL, i) 490 + #define rwlock_acquire_read(l, s, t, i) lock_acquire_shared_recursive(l, s, t, NULL, i) 499 491 #define rwlock_release(l, n, i) lock_release(l, n, i) 500 492 501 493 #define seqcount_acquire(l, s, t, i) lock_acquire_exclusive(l, s, t, NULL, i)
-6
kernel/locking/lockdep.c
··· 3597 3597 raw_local_irq_save(flags); 3598 3598 check_flags(flags); 3599 3599 3600 - /* 3601 - * An interrupt recursive read in interrupt context can be considered 3602 - * to be the same as a recursive read from checking perspective. 3603 - */ 3604 - if ((read == 3) && in_interrupt()) 3605 - read = 2; 3606 3600 current->lockdep_recursion = 1; 3607 3601 trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip); 3608 3602 __lock_acquire(lock, subclass, trylock, read, check,
+7 -49
lib/locking-selftest.c
··· 267 267 #undef E 268 268 269 269 /* 270 - * Special-case for read-locking, they are not allowed to 271 - * recurse on the same lock class except under interrupt context: 270 + * Special-case for read-locking, they are 271 + * allowed to recurse on the same lock class: 272 272 */ 273 273 static void rlock_AA1(void) 274 274 { 275 275 RL(X1); 276 - RL(X1); // this one should fail 276 + RL(X1); // this one should NOT fail 277 277 } 278 278 279 279 static void rlock_AA1B(void) 280 280 { 281 281 RL(X1); 282 - RL(X2); // this one should fail 283 - } 284 - 285 - static void rlock_AHA1(void) 286 - { 287 - RL(X1); 288 - HARDIRQ_ENTER(); 289 - RL(X1); // this one should NOT fail 290 - HARDIRQ_EXIT(); 291 - } 292 - 293 - static void rlock_AHA1B(void) 294 - { 295 - RL(X1); 296 - HARDIRQ_ENTER(); 297 - RL(X2); // this one should NOT fail 298 - HARDIRQ_EXIT(); 299 - } 300 - 301 - static 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(); 282 + RL(X2); // this one should NOT fail 310 283 } 311 284 312 285 static void rsem_AA1(void) ··· 1069 1096 print_testname(desc); \ 1070 1097 dotest(name##_spin, FAILURE, LOCKTYPE_SPIN); \ 1071 1098 dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK); \ 1072 - dotest(name##_rlock, FAILURE, LOCKTYPE_RWLOCK); \ 1099 + dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK); \ 1073 1100 dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \ 1074 1101 dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \ 1075 1102 dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \ ··· 1830 1857 printk(" --------------------------------------------------------------------------\n"); 1831 1858 print_testname("recursive read-lock"); 1832 1859 printk(" |"); 1833 - dotest(rlock_AA1, FAILURE, LOCKTYPE_RWLOCK); 1860 + dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK); 1834 1861 printk(" |"); 1835 1862 dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM); 1836 1863 printk("\n"); 1837 1864 1838 1865 print_testname("recursive read-lock #2"); 1839 1866 printk(" |"); 1840 - dotest(rlock_AA1B, FAILURE, LOCKTYPE_RWLOCK); 1867 + dotest(rlock_AA1B, SUCCESS, LOCKTYPE_RWLOCK); 1841 1868 printk(" |"); 1842 1869 dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM); 1843 1870 printk("\n"); ··· 1854 1881 dotest(rlock_AA3, FAILURE, LOCKTYPE_RWLOCK); 1855 1882 printk(" |"); 1856 1883 dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM); 1857 - printk("\n"); 1858 - 1859 - print_testname("recursive rlock with interrupt"); 1860 - printk(" |"); 1861 - dotest(rlock_AHA1, SUCCESS, LOCKTYPE_RWLOCK); 1862 - printk("\n"); 1863 - 1864 - print_testname("recursive rlock with interrupt #2"); 1865 - printk(" |"); 1866 - dotest(rlock_AHA1B, SUCCESS, LOCKTYPE_RWLOCK); 1867 - printk("\n"); 1868 - 1869 - print_testname("recursive rlock with interrupt #3"); 1870 - printk(" |"); 1871 - dotest(rlock_ASAHA1, SUCCESS, LOCKTYPE_RWLOCK); 1872 1884 printk("\n"); 1873 1885 1874 1886 printk(" --------------------------------------------------------------------------\n");