Linux内核spin_lock、spin_lock_irq 和 spin_lock_irqsave 分析

转自:http://blog.csdn.net/wh_19910525/article/details/11536279

在Linux内核中何时使用spin_lock,何时使用spin_lock_irqsave很容易混淆。首先看一下代码是如何实现的。

spin_lock的调用关系

  • spin_lock  ----->  raw_spin_lock
1 static inline void __raw_spin_lock(raw_spinlock_t *lock)
2 {
3         preempt_disable();
4         spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
5         LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
6 }   
  • spin_lock_irq的调用关系

spin_lock_irq------> raw_spin_lock_irq

1 static inline void __raw_spin_lock_irq(raw_spinlock_t *lock)
2 {
3         local_irq_disable();
4         preempt_disable();
5         spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
6         LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
7 }  

1. 可以看出来他们两者只有一个差别:是否调用local_irq_disable()函数, 即是否禁止本地中断。

2. 在任何情况下使用spin_lock_irq都是安全的。因为它既禁止本地中断,又禁止内核抢占。

3. spin_lock比spin_lock_irq速度快,但是它并不是任何情况下都是安全的。

1. spin_lock/spin_unlock:

进程A中调用了spin_lock(&lock)然后进入临界区,此时来了一个中断(interrupt),该中断也运行在和进程A相同的CPU上,并且在该中断处理程序中恰巧也会spin_lock(&lock), 试图获取同一个锁。由于是在同一个CPU上被中断,进程A会被设置为TASK_INTERRUPT状态,中断处理程序无法获得锁,会不停的忙等,由于进程A被设置为中断状态,schedule()进程调度就无法再调度进程A运行,这样就导致了死锁!

但是如果该中断处理程序运行在不同的CPU上就不会触发死锁。 因为在不同的CPU上出现中断不会导致进程A的状态被设为TASK_INTERRUPT,只是换出。当中断处理程序忙等被换出后,进程A还是有机会获得CPU,执行并退出临界区。所以在使用spin_lock时要明确知道该锁不会在中断处理程序中使用。

2. spin_lock_irqsave/spin_unlock_irqrestore

使用spin_lock_irqsave在于你不期望在离开临界区后,改变中断的开启/关闭状态!进入临界区是关闭的,离开后它同样应该是关闭的!

如果自旋锁在中断处理函数中被用到,那么在获取该锁之前需要关闭本地中断,spin_lock_irqsave 只是下列动作的一个便利接口:
1 保存本地中断状态(这里的本地即当前的cpu的所有中断)
2 关闭本地中断
3 获取自旋锁

解锁时通过 spin_unlock_irqrestore完成释放锁、恢复本地中断到之前的状态等工作

3. spin_lock_irq/spin_unlock_irq

spin_lock_irq----->raw_spin_lock_irq

spin_lock_irq 和 spin_unlock_irq, 如果你确定在获取锁之前本地中断是开启的,那么就不需要保存中断状态,解锁的时候直接将本地中断启用就可以啦

时间: 2024-10-27 02:59:48

Linux内核spin_lock、spin_lock_irq 和 spin_lock_irqsave 分析的相关文章

Linux内核OOM机制的详细分析(转)

Linux 内核 有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了 防止内存耗尽而内核会把该进程杀掉.典型的情况是:某天一台机器突然ssh远程登录不了,但能ping通,说明不是网络的故障,原因是sshd进程被 OOM killer杀掉了(多次遇到这样的假死状况).重启机器后查看系统日志/var/log/messages会发现 Out of Memory: Kill process 1865(sshd)

Linux 内核 TCP MSS 机制详细分析

作者:[email protected]知道创宇 404 实验室时间:2019 年 6 月 26 日英文版本:https://paper.seebug.org/967/ 前言 上周Linux内核修复了4个CVE漏洞[1],其中的CVE-2019-11477感觉是一个很厉害的Dos漏洞,不过因为有其他事打断,所以进展的速度比较慢,这期间网上已经有相关的分析文章了.[2][3] 而我在尝试复现CVE-2019-11477漏洞的过程中,在第一步设置MSS的问题上就遇到问题了,无法达到预期效果,但是目前

Linux内核TCP MSS机制详细分析

前言 上周Linux内核修复了4个CVE漏洞[1],其中的CVE-2019-11477感觉是一个很厉害的Dos漏洞,不过因为有其他事打断,所以进展的速度比较慢,这期间网上已经有相关的分析文章了.[2][3] 而我在尝试复现CVE-2019-11477漏洞的过程中,在第一步设置MSS的问题上就遇到问题了,无法达到预期效果,但是目前公开的分析文章却没对该部分内容进行详细分析.所以本文将通过Linux内核源码对TCP的MSS机制进行详细分析. 测试环境 1. 存在漏洞的靶机 操作系统版本:Ubuntu

Linux内核0.00-boot.s源代码分析

     1 /*************************************************************************   2  > File Name: boot.s   3  > Author: Linpeng1577   4  > Mail:[email protected] or [email protected]   5  > Created Time: Sun 02 Nov 2014 11:42:53 PM PST   6  

Linux内核OOM机制的详细分析

http://blog.chinaunix.net/uid-29242873-id-3942763.html Linux 内核有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽而内核会把该进程杀掉.典型的情况是:某天一台机器突然ssh远程登录不了,但能ping通,说明不是网络的故障,原因是sshd进程被OOM killer杀掉了(多次遇到这样的假死状况).重启机器后查看系统日志/var/lo

Linux内核跟踪之trace框架分析【转】

转自:http://blog.chinaunix.net/uid-20543183-id-1930846.html ------------------------------------------ 本文系本站原创,欢迎转载! 转载请注明出处:http://ericxiao.cublog.cn/ ------------------------------------------ 一: 前言 本文主要是对trace的框架做详尽的分析, 在后续的分析中,再来分析接入到框架中的几个重要的trace

Linux内核编程:源码分析之防御性编程学习

  /*  *Kernel  : Linux2.6.32.63   *File    : \scripts\mod\modpost.h              \scripts\mod\modpost.c    *Author  : DavidLin         *Date    : 2014-12-25pm         *Email   : [email protected] or [email protected]         *world   : the city of SZ

linux 内核源码牛人分析 链接分享

0xAX 在这一块走的很远呀~ https://github.com/0xAX/linux-insides 涉及: booting concepts datastructures initialization theory mm

Linux内核--网络栈实现分析(一)--网络栈初始化

本文分析基于内核Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7488828 更多请看专栏,地址http://blog.csdn.net/column/details/linux-kernel-net.html 作者:闫明 以后的系列博文将深入分析Linux内核的网络栈实现原理,这里看到曹桂平博士的分析后,也决定选择Linux内核1.2.13版本进行分析. 原因如下: 1.功能和网络栈层次