spinlock in linux kernel

作为一种锁机制, spinlock可以制造一段临界区, 同一时刻只有一个线程能进入这个临界区, 从而达到保护数据的目的. semaphore, mutext也有同样的作用.

spinlock采用busy waiting的实现方式, 无法获取锁时线程一直处于忙等待状态(而不是进入休眠,放弃处理器).

使用spinlock的注意事项

1. 持有spinlock的上下文不能主动放弃处理器. 包括禁止抢占, 不能休眠. 如果中断中也要获取spinlock, 需要禁止中断.

2. 持有spinlock的时间越短越好.

3. 锁被持有时, 持有者不允许再次尝试获取该锁.

4. 尽量避免使用多个锁, 否则复杂度会大大提高. 在必须获取多个锁时, 始终以相同的顺序获得.

linux kernel中的spinlock相关接口函数

o 定义时初始化: static DEFINE_SPINLOCK(lock);

o 动态初始化: spin_lock_init(lock);



o 获得/释放锁

void spin_lock(spinlock_t *lock);

void spin_unlock(spinlock_t *lock);



o 获得锁之前禁止中断, 并保存之前的中断状态, 以待恢复.

void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);

void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);



o 获得锁之前禁止中断

void spin_lock_irq(spinlock_t *lock);

void spin_unlock_irq(spinlock_t *lock);



o 获得锁之前禁止软中断

void spin_lock_bh(spinlock_t *lock);

void spin_unlock_bh(spinlock_t *lock);

arm linux kernel中spinlock的实现

include/linux/spinlock.h



对于单核处理器(UP: uniprocessor)和多核处理器(SMP: symmetric multiprocessor), 会包含不同的头文件.



在单核处理器的系统中, spinlock的实现比较简单. spin_lock()只会做禁止抢占动作, spin_lock_irqsave()会禁止中断. 除此之外并没有锁相关的工作.



在多核处理器的系统中, 获得spinlock之后会置一个标志, 下面是arm架构的实现:



arch/arm/include/asm/spinlock.h

static inline void arch_spin_lock(arch_spinlock_t *lock)
{
unsigned long tmp; __asm__ __volatile__(
"1: ldrex %0, [%1]\n"
" teq %0, #0\n"
WFE("ne")
" strexeq %0, %2, [%1]\n"
" teqeq %0, #0\n"
" bne 1b"
: "=&r" (tmp)
: "r" (&lock->lock), "r" (1)
: "cc"); smp_mb();
}

1. 把lock->lock中的值加载到tmp里. ldrex将&lock->lock这个地址标记为当前CPU独占访问, 此时如果另一个CPU执行后面的strexeq指令, 则会失败返回1. . 这就保证了lock操作的原子操作.

2. 如果tmp为0, 则锁可以被获取, 向&lock->lock中写1. 写成功后退出. strex解除当前CPU对&lock->lock地址的独占.

如果tmp不为0, 则当前CPU通过wfe指令进入省电状态.

3. sev指令或中断发生, CPU继续执行, 则"bne 1b"又跳到步骤1. 这里就是spinlock的自旋操作了.



wfe(wait for event)指令会使当前CPU停止执行, 直到发生了以下任一件事:



1. IRQ/FIQ产生.

2. Data abort异常产生.

3. Debug请求.

4. 其他处理器用sev(set event)指令发出事件消息.

spinlock in linux kernel的更多相关文章

  1. LINUX KERNEL SPINLOCK使用不当的后果

    LINUX KERNEL SPINLOCK使用不当的后果 spinlock(自旋锁)是内核中最常见的锁,它的特点是:等待锁的过程中不休眠,而是占着CPU空转,优点是避免了上下文切换的开销,缺点是该CP ...

  2. Intel 80x86 Linux Kernel Interrupt(中断)、Interrupt Priority、Interrupt nesting、Prohibit Things Whthin CPU In The Interrupt Off State

    目录 . 引言 . Linux 中断的概念 . 中断处理流程 . Linux 中断相关的源代码分析 . Linux 硬件中断 . Linux 软中断 . 中断优先级 . CPU在关中断状态下编程要注意 ...

  3. Linux Kernel 排程機制介紹

    http://loda.hala01.com/2011/12/linux-kernel-%E6%8E%92%E7%A8%8B%E6%A9%9F%E5%88%B6%E4%BB%8B%E7%B4%B9/ ...

  4. Linux kernel的中断子系统之(三):IRQ number和中断描述符

    返回目录:<ARM-Linux中断系统>. 总结: 二描述了中断处理示意图,以及关中断.开中断,和IRQ number重要概念. 三介绍了三个重要的结构体,irq_desc.irq_dat ...

  5. 从基本理解到深入探究 Linux kernel 通知链(notifier chain)【转】

    转自:https://blog.csdn.net/u014134180/article/details/86563754 版权声明:本文为博主原创文章,未经博主允许不得转载.——Wu_Being ht ...

  6. linux kernel的中断子系统之(三):IRQ number和中断描述符【转】

    转自:http://www.wowotech.net/linux_kenrel/interrupt_descriptor.html 一.前言 本文主要围绕IRQ number和中断描述符(interr ...

  7. [轉]Exploit The Linux Kernel NULL Pointer Dereference

    Exploit The Linux Kernel NULL Pointer Dereference Author: wztHome: http://hi.baidu.com/wzt85date: 20 ...

  8. linux kernel RCU 以及读写锁

    信号量有一个很明显的缺点,没有区分临界区的读写属性,读写锁允许多个线程进程并发的访问临界区,但是写访问只限于一个线程,在多处理器系统中允许多个读者访问共享资源,但是写者有排他性,读写锁的特性如下:允许 ...

  9. Linux kernel 同步机制

    Linux kernel同步机制(上篇) https://mp.weixin.qq.com/s/mosYi_W-Rp1-HgdtxUqSEgLinux kernel 同步机制(下篇) https:// ...

随机推荐

  1. Manjaro/Arch linux 安装输入法

    输入命令: sudo pacman -Syu fcitx fcitx-googlepinyin fcitx-im fcitx-configtool 编辑 ~/.xprofile:# xfcitxexp ...

  2. [CF] 950A Left-handers, Right-handers and Ambidexters

    A. Left-handers, Right-handers and Ambidexters time limit per test1 second memory limit per test256 ...

  3. <Spring Cloud>入门四 Feign

    1.Feign 之前使用的是Ribbon+RestTemplate调用,通过的是微服务的名字进行调用,实现负载均衡 但是为了满足接口编程,提供了Feign 2.实现 2.1引入坐标 在 ms-comm ...

  4. 查看mysql二进制日志报错问题

    在排查网站被黑时想通过Mysql二进制日志找出修改字段时间,但是使用mysqlbinlog报错: [root@zfszsw1 bin]# ./mysqlbinlog /opt/mysql-bin.00 ...

  5. mybatis完整sql调试

    问题描述 在使用mybatis进行开发的时候,由于可以动态拼接sql,这样大大方便了我们.但是也有一定的问题,当我们动态sql拼接的块很多的时候,我们要想从*mapper.xml中直接找出完整的sql ...

  6. LeetCode(11) Container With Most Water

    题目 Given n non-negative integers a1, a2, -, an, where each represents a point at coordinate (i, ai). ...

  7. 【NEFU 117 素数个数的位数】(素数定理)

    Description 小明是一个聪明的孩子,对数论有着很浓烈的兴趣. 他发现求1到正整数10n 之间有多少个素数是一个很难的问题,该问题的难以决定于n 值的大小. 现在的问题是,告诉你n的值,让你帮 ...

  8. POJ 1949 Chores(DAG上的最长路 , DP)

    题意: 给定n项任务, 每项任务的完成用时t和完成每项任务前需要的k项任务, 求把所有任务完成的最短时间,有当前时间多项任务都可完成, 那么可以同时进行. 分析: 这题关键就是每项任务都会有先决条件, ...

  9. luogu1463 [HAOI2007]反素数

    以下证明来自算法竞赛进阶指南 引理一: 答案就是 \([1,n]\) 之间约数个数最多的最小的数. 证明: 记 \(m\) 是 \([1,n]\) 之间约数个数最多的最小的数.则 \(\forall ...

  10. mysql异常Incorrect string value: '\xE6\xB5\x8B\xE8\xAF\x95' for column 'region_name'

    Incorrect string value: '\xE6\xB5\x8B\xE8\xAF\x95' for column 'region_name' insert语句加的该字段有汉字,乱码造成的 解 ...