diff options
Diffstat (limited to 'kernel/locking')
| -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, |
