diff options
Diffstat (limited to 'kernel/locking/rwsem-xadd.c')
-rw-r--r-- | kernel/locking/rwsem-xadd.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c index 1d66e08e897d..b4219ff87b8c 100644 --- a/kernel/locking/rwsem-xadd.c +++ b/kernel/locking/rwsem-xadd.c | |||
@@ -12,6 +12,55 @@ | |||
12 | #include <linux/export.h> | 12 | #include <linux/export.h> |
13 | 13 | ||
14 | /* | 14 | /* |
15 | * Guide to the rw_semaphore's count field for common values. | ||
16 | * (32-bit case illustrated, similar for 64-bit) | ||
17 | * | ||
18 | * 0x0000000X (1) X readers active or attempting lock, no writer waiting | ||
19 | * X = #active_readers + #readers attempting to lock | ||
20 | * (X*ACTIVE_BIAS) | ||
21 | * | ||
22 | * 0x00000000 rwsem is unlocked, and no one is waiting for the lock or | ||
23 | * attempting to read lock or write lock. | ||
24 | * | ||
25 | * 0xffff000X (1) X readers active or attempting lock, with waiters for lock | ||
26 | * X = #active readers + # readers attempting lock | ||
27 | * (X*ACTIVE_BIAS + WAITING_BIAS) | ||
28 | * (2) 1 writer attempting lock, no waiters for lock | ||
29 | * X-1 = #active readers + #readers attempting lock | ||
30 | * ((X-1)*ACTIVE_BIAS + ACTIVE_WRITE_BIAS) | ||
31 | * (3) 1 writer active, no waiters for lock | ||
32 | * X-1 = #active readers + #readers attempting lock | ||
33 | * ((X-1)*ACTIVE_BIAS + ACTIVE_WRITE_BIAS) | ||
34 | * | ||
35 | * 0xffff0001 (1) 1 reader active or attempting lock, waiters for lock | ||
36 | * (WAITING_BIAS + ACTIVE_BIAS) | ||
37 | * (2) 1 writer active or attempting lock, no waiters for lock | ||
38 | * (ACTIVE_WRITE_BIAS) | ||
39 | * | ||
40 | * 0xffff0000 (1) There are writers or readers queued but none active | ||
41 | * or in the process of attempting lock. | ||
42 | * (WAITING_BIAS) | ||
43 | * Note: writer can attempt to steal lock for this count by adding | ||
44 | * ACTIVE_WRITE_BIAS in cmpxchg and checking the old count | ||
45 | * | ||
46 | * 0xfffe0001 (1) 1 writer active, or attempting lock. Waiters on queue. | ||
47 | * (ACTIVE_WRITE_BIAS + WAITING_BIAS) | ||
48 | * | ||
49 | * Note: Readers attempt to lock by adding ACTIVE_BIAS in down_read and checking | ||
50 | * the count becomes more than 0 for successful lock acquisition, | ||
51 | * i.e. the case where there are only readers or nobody has lock. | ||
52 | * (1st and 2nd case above). | ||
53 | * | ||
54 | * Writers attempt to lock by adding ACTIVE_WRITE_BIAS in down_write and | ||
55 | * checking the count becomes ACTIVE_WRITE_BIAS for successful lock | ||
56 | * acquisition (i.e. nobody else has lock or attempts lock). If | ||
57 | * unsuccessful, in rwsem_down_write_failed, we'll check to see if there | ||
58 | * are only waiters but none active (5th case above), and attempt to | ||
59 | * steal the lock. | ||
60 | * | ||
61 | */ | ||
62 | |||
63 | /* | ||
15 | * Initialize an rwsem: | 64 | * Initialize an rwsem: |
16 | */ | 65 | */ |
17 | void __init_rwsem(struct rw_semaphore *sem, const char *name, | 66 | void __init_rwsem(struct rw_semaphore *sem, const char *name, |