Messages in this thread Patch in this message | | | Date | Fri, 25 Jan 2013 15:30:09 -0500 | From | Rik van Riel <> | Subject | [RFC PATCH 7/6] kernel: document fast queue spinlocks |
| |
Document the fast queue spinlocks in a way that I can understand.
Signed-off-by: Rik van Riel <riel@redhat.com> --- This may still not be clear to others. Please let me know if you would like me to change/enhance the documentation, so you can understand it too.
kernel/queue_spinlock.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/kernel/queue_spinlock.c b/kernel/queue_spinlock.c index b571508..dc740fe 100644 --- a/kernel/queue_spinlock.c +++ b/kernel/queue_spinlock.c @@ -9,6 +9,23 @@ #include <asm/processor.h> /* for cpu_relax() */ #include <asm/queue_spinlock.h> +/* + * Fast queue spinlocks use a pool of tokens, which contain the actual locks, + * and are continuously moved around. Every spinlock is associated with one + * token, and every CPU is associated with two tokens. + * + * When taking a lock, one of the CPU's tokens is associated with the lock, + * and the lock's token is associated with the CPU. + * + * The token that gets associated with the spinlock at lock time will indicate + * the lock is busy. The token that was previously associated with the spinlock, + * and is now associated with the CPU taking the lock, will indicate whether + * the previous lock holder has already unlocked the lock. + * + * To unlock a fast ticket spinlock, the CPU will unlock the token that it + * associated with the spinlock. + */ + DEFINE_PER_CPU(struct q_spinlock_token *, q_spinlock_token[2]); static inline struct q_spinlock_token * @@ -25,8 +42,11 @@ ____q_spin_lock(struct q_spinlock *lock, token = __this_cpu_read(*percpu_token); token->wait = true; + /* Associate our (marked busy) token with the spinlock. */ prev = xchg(&lock->token, token); + /* The spinlock's old token is ours now. */ __this_cpu_write(*percpu_token, prev); + /* Wait for the spinlock's old token to be unlocked. */ while (ACCESS_ONCE(prev->wait)) cpu_relax(); q_spin_lock_mb(); /* guarantee acquire load semantics */
| |