queued spinlock锁的使用

qspinlock是queued spinlock的简称,主要用于解决在锁竞争激烈的情况下来减少spinlock 所
损失的性能,提高系统总体性能
qspinlock的数据结构定义在kernel/qspinlock.c中
struct __qspinlock {
	union {
		atomic_t val;
#ifdef __LITTLE_ENDIAN
		struct {
			u8	locked;
			u8	pending;
		};
		struct {
			u16	locked_pending;
			u16	tail;
		};
#else
		struct {
			u16	tail;
			u16	locked_pending;
		};
		struct {
			u8	reserved[2];
			u8	pending;
			u8	locked;
		};
#endif
可以看到qspinlock 就是一个原子变量,但是在实际使用中却将这个原子变量分成很多位域
具体位域如下:
/*
 * Bitfields in the atomic value:
 *
 * When NR_CPUS < 16K
 *  0- 7: locked byte
 *     8: pending
 *  9-15: not used
 * 16-17: tail index
 * 18-31: tail cpu (+1)
 *
 * When NR_CPUS >= 16K
 *  0- 7: locked byte
 *     8: pending
 *  9-10: tail index
 * 11-31: tail cpu (+1)
 */
 qspinlock 提供的API 都定义在include/asm-generic/qspinlock.h中
 #define arch_spin_is_locked(l)		queued_spin_is_locked(l)
#define arch_spin_is_contended(l)	queued_spin_is_contended(l)
#define arch_spin_value_unlocked(l)	queued_spin_value_unlocked(l)
#define arch_spin_lock(l)		queued_spin_lock(l)
#define arch_spin_trylock(l)		queued_spin_trylock(l)
#define arch_spin_unlock(l)		queued_spin_unlock(l)

从这里可以知道用户并不知能直接调用qspinlock的提供的锁函数。而是使用传统的spinlock的接口接口就可以
static __always_inline int spin_is_locked(spinlock_t *lock)
{
	return raw_spin_is_locked(&lock->rlock);
}
#define raw_spin_is_locked(lock)	arch_spin_is_locked(&(lock)->raw_lock)
所以内核采用qspinlock 对用户来讲是透明的,只要内核使能了qspinlock,用户不用改任何code 就可以享受到qspinlock带来的
性能提升
从makefile 中可以知道要使能qspinlock的话,应该打开CONFIG_QUEUED_SPINLOCKS
obj-$(CONFIG_QUEUED_SPINLOCKS) += qspinlock.o

你可能感兴趣的:(Linux,源码分析)