关于might_sleep的一点说明【转】
转自:http://blog.csdn.net/chen_chuang_/article/details/48462575
这个函数我在看代码时基本上是直接忽略的(因为我知道它实际上不干什么事),不过因为内核中很多函数一开始就会用一下它,为了方便那些正在学习内核源码的网友,本帖专门讨论一下该函数到底被内核用来干什么。
简单地说,如果没有调试的需求(绝大多数下你平常跑的系统都是release版本的kernel),那么这个宏(或者函数,称谓并不重要)什么实质性的活都不干,内核只是用它来做一件事,就是提醒你,调用该函数的函数可能会sleep,这个跟其名字也是匹配的: The function calling might_sleep() might sleep。如果你想看源码,我把它列在下面:
点击(此处)折叠或打开
- # define might_resched() do { } while (0)
- # define might_sleep() do { might_resched(); } while (0)
看到没,啥事都没干。其实内核源码对此也有明确的注释:might_sleep - annotation for functions that can sleep。所以对于release版的kernel image而言,might_sleep的作用仅仅是一个annotation,提醒使用者,一个使用might_sleep的函数在其后的代码执行中可能会sleep。
不过如果有调试需求介入的话,比如你的系统莫名其妙地随机性地crash掉,在经过一段艰难的案情分析排查之后,最后你决定打开内核的CONFIG_DEBUG_ATOMIC_SLEEP选项,那么此时might_sleep对案情的进一步推进就可能产生贡献了。CONFIG_DEBUG_ATOMIC_SLEEP选项主要用来排查是否在一个ATOMIC操作的上下文中有函数发生sleep行为,关于什么是ATOMIC操作,内核源码在might_sleep函数前也有一段注释:
this macro will print a stack trace if it is executed in an atomic context (spinlock, irq-handler, ...)
所以很明显,一个进程获得了spinlock之后它就进入了这里所谓的atomic context,或者是在一个irq-handler,也就是一个中断上下文中。这两种上下文中理论上不应该让当前的execution path进入sleep状态(虽然不是强制规定,换句话说,一个拥有spinlock的进程进入sleep并不必然意味着系统就一定会deadlock等,但是对内核编程而言,还是应该尽力避开这个雷区)。
在CONFIG_DEBUG_ATOMIC_SLEEP选项打开的情形下,might_sleep又有哪些特殊的功能呢?先看看内核中的源码:
点击(此处)折叠或打开
- void __might_sleep(const char *file, int line, int preempt_offset)
- {
- static unsigned long prev_jiffy; /* ratelimiting */
- if ((preempt_count_equals(preempt_offset) && !irqs_disabled()) ||
- system_state != SYSTEM_RUNNING || oops_in_progress)
- return;
- if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
- return;
- prev_jiffy = jiffies;
- printk(KERN_ERR
- "BUG: sleeping function called from invalid context at %s:%d\n",
- file, line);
- printk(KERN_ERR
- "in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s\n",
- in_atomic(), irqs_disabled(),
- current->pid, current->comm);
- if (irqs_disabled())
- print_irqtrace_events(current);
- dump_stack();
- }
上面的代码我进行了轻微的删减,去除了一些只有CONFIG_DEBUG_ATOMIC_SLEEP选项使能的情形下不干活的函数。
点击(此处)折叠或打开
- # define might_sleep() \
- do { __might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0)
在当前CONFIG_DEBUG_ATOMIC_SLEEP选项使能的前提下, 可以看到__might_sleep还是干了不少事情的,最主要的工作是在第一个if语句那里,尤其是preempt_count_equals和 irqs_disabled,都是用来判断当前的上下文是否是一个atomic context,因为我们知道,只要进程获得了spin_lock的任一个变种形式的lock,那么无论是单处理器系统还是多处理器系统,都会导致preempt_count发生变化,而irq_disabled则是用来判断当前中断是否开启。__might_sleep正是根据这些信息来判断当前正在执行的代码上下文是否是个atomic,如果不是,那么函数就直接返回了,因为一切正常。如果是,那么代码下行。
所以让CONFIG_DEBUG_ATOMIC_SLEEP选项打开,可以捕捉到在一个atomic context中是否发生了sleep,如果你的代码不小心在某处的确出现了这种情形,那么might_sleep会通过后续的printk以及dump_stack来协助你发现这种情形。
至于__might_sleep函数中的system_state,它是一个全局性的enum型变量,主要用来记录当前系统的状态:
点击(此处)折叠或打开
- enum system_states system_state __read_mostly;
- EXPORT_SYMBOL(system_state);
注意system_state已经被export出来,所以内核模块可以直接读该值来判断当前系统的运行状态,常见的状态包括:
点击(此处)折叠或打开
- extern enum system_states {
- SYSTEM_BOOTING,
- SYSTEM_RUNNING,
- SYSTEM_HALT,
- SYSTEM_POWER_OFF,
- SYSTEM_RESTART,
- SYSTEM_SUSPEND_DISK,
- } system_state;
最常见的状态当然是SYSTEM_RUNNING了,你的系统正常起来之后就处于这个状态。因为跟当前的话题没有直接的关联,这里只提一下好了。
阅读(1) | 评论(0) | 转发(0) |
上一篇:proc函数
下一篇:linux程序设计---多线程
- linux 常见服务端口
- 【ROOTFS搭建】busybox的httpd...
- xmanager 2.0 for linux配置
- 什么是shell
- linux socket的bug??
- linux dhcp peizhi roc
- 关于Unix文件的软链接
- 求教这个命令什么意思,我是新...
- sed -e "/grep/d" 是什么意思...
- 谁能够帮我解决LINUX 2.6 10...
关于might_sleep的一点说明【转】相关推荐
- 关于might_sleep的一点说明---CONFIG_DEBUG_ATOMIC_SLEEP【转】
转自:http://blog.chinaunix.net/uid-23769728-id-3157536.html 这个函数我在看代码时基本上是直接忽略的(因为我知道它实际上不干什么事),不过因为内核 ...
- 零起点学算法07——复杂一点的表达式计算
零起点学算法07--复杂一点的表达式计算 Description 下面你来计算一个复杂一点的计算表达式 Input 没有输入 Output 输出表达式的值,保留2位小数 题目分析:根号要用sqrt来算 ...
- 关于位姿变换的一点体会
关于位姿变换的一点体会 1.题外话 2.刚体的位姿变换 2.1 位姿变换的定义 2.2 旋转矩阵的具体形式 2.2.1 二维情况 2.2.2 三维情况 3.旋转方向 4.平移方向 1.题外话 对于刚体 ...
- spring的事务隔离_再深一点:面试工作两不误,源码级理解Spring事务
原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处. Spring有5种隔离级别,7种传播行为.这是面试常问的内容,也是代码中经常碰到的知识点.这些知识枯燥而且乏味,其中有些非 ...
- tensorflow youtube的一点笔记
最近在看TensorFlow的YouTube频道 https://www.youtube.com/tensorflow 内容挺多,不过只看一遍的话,基本过一遍也就都忘了,所以随手记下来一些概念,凭印象 ...
- 台湾前十大科技公司拼不过三星(往后一点三星都不要买啦!)
台湾前十大科技公司拼不过三星,往后一点三星都不要买啦!本来还可以买它的内存和液晶,不过现在是一点都不能买了,再买就真反了他了! 三星像糖果也像毒药,让台湾LED类股1年涨3倍,但也让鸿海市值一夜之间消 ...
- 数学 计算机工作,不过有人说先学数学,后学计算机后劲足一点,工作也可以的,这估...
不过有人说先学数学,后学计算机后劲足一点,工作也可以的,这估计是对有实力的人而言. 相关句子 2.爱因斯坦有句话对我很有启发.他说:"人的差异在业余."据计算,一个人到60岁,除吃 ...
- 均匀分布取某一点概率_概率和概率分布
概率与概率分布是统计学中的基础概念,在我们的高中的课本中就接触过了,如果有遗忘,一起来回顾一下吧! 知识点: 概率 概率分布 一.概率 说到概率,需要先了解一个概念,叫做随机试验.随机试验是指在相同条 ...
- u一点·料:阿里巴巴1688ued体验设计践行之路. 导读
U一点·料 阿里巴巴1688UED体验设计践行之路 阿里巴巴1688用户体验部著 前言 既赶路,也感受路 文 / 汪方进 用户体验设计师作为一个职能岗位,在国内互联网公司中存在已有十几年的时间了,早期 ...
最新文章
- R语言使用ggplot2包使用geom_dotplot函数绘制分组点图(添加均值、标准偏差)实战(dot plot)
- 基于libzplay 实现window下音乐频谱动态显示
- HTML5音乐播放器(四):播放列表与播放方式
- 当Android工程中提示你找不到头文件,但你已经设置头文件路径了
- mysql聚簇索引存储结构_MySQL聚簇索引的实际应用于结构描述
- 组织配置java项目的外部lib包
- bzoj 1179: [Apio2009]Atm(Trajan+SPFA)
- Caused by: java.lang.ClassNotFoundException: backtype.storm.topology.IRichSpout
- IP子网划分【网工复习专题】2022.5.8
- java robot识别验证码,robotframework处理登录验证码
- 客户端性能测试工具-Wetest、cude PC
- java计算2个日期的天数时间差
- STM32中关于高电平有效,低电平有效的一点理解
- 面试官没想到我对redis数据结构这么了解,直接给offer
- 安规电容知识详解,X电容和Y电容
- paper—SCI答复审稿人的回信技巧
- 查看linux系统是centos还是ubuntu的方法
- Linux 下 Shell 命令 IFS 分隔符 -- 应用场景 解决办法
- 客户流失预测_如何不预测和防止客户流失
- libcurl linux 静态链接库_Linux ubuntu OpenSSL + curl 静态库编译及使用