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
queued spinlock锁的使用
最新推荐文章于 2024-02-01 15:06:24 发布