关于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) |
关于might_sleep的一点说明【转】的更多相关文章
- 关于might_sleep的一点说明---CONFIG_DEBUG_ATOMIC_SLEEP【转】
转自:http://blog.chinaunix.net/uid-23769728-id-3157536.html 这个函数我在看代码时基本上是直接忽略的(因为我知道它实际上不干什么事),不过因为内核 ...
- 关于自己写C++的一点风格
现在,我学了很长时间的C++,但是自己就是无法精通.许多知识是入门书上没有的.现在写C++最重要的就是风格问题. 我现在的C++风格: 把自己所有的东西都放在一个名称空间下. 没有全局的函数,有的函数 ...
- 学习AOP之深入一点Spring Aop
上一篇<学习AOP之认识一下SpringAOP>中大体的了解了代理.动态代理及SpringAop的知识.因为写的篇幅长了点所以还是再写一篇吧.接下来开始深入一点Spring aop的一些实 ...
- 一点公益商城开发系统模式Ring Buffer+
一个队列如果只生产不消费肯定不行的,那么如何及时消费Ring Buffer的数据呢?简单的方案就是当Ring Buffer"写满"的时候一次性将数据"消费"掉. ...
- SVM一点心得体会
支持向量机的学习说是刚刚开始,又不合理,只能说隔了很长的时间再看,终于在分类这块的层面上有了新的认识. 总的来说,支持向量机分为线性支持向量机和非线性支持向量机,线性支持向量机又可以分为硬间隔最大化线 ...
- [网站性能1]对.net系统架构改造的一点经验和教训
文章来源:http://www.admin10000.com/document/2111.html 在互联网行业,基于Unix/Linux的网站系统架构毫无疑问是当今主流的架构解决方案,这不仅仅是因为 ...
- 关于js的回调函数的一点看法
算了一下又有好几个月没写博客了,最近在忙公司android的项目,所以也就很少抽时间来写些东西了.刚闲下来,我就翻了翻之前看的东西.做了android之后更加感觉到手机端开发的重要性,现在做nativ ...
- .NET支持多平台后的一点拙见
我们目前对.NET的理解大部分可以归纳为:起初它是Java平台(注意是平台,不要跟Java语言搞混淆)的一个克隆品,后来慢慢演变,有了自己的特性.由于Java平台最显著的特点就是“平台独立性”(或者说 ...
- 每天多一点(2016.12.04)》Javascript隐式转换
乱想 javascript为什么需要隐式转换?如果没有会出现什么情况? 找了一圈没有看到关于这个的讨论,只好自己研究了,可能不一定正确,自行辨知. 郁闷就是郁闷在好好的,为什么要搞个隐式转换,一般来讲 ...
随机推荐
- HSF原理
HSF(High-speed Service Framework),高速服务框架,是阿里系主要采用的服务框架,其目的是作为桥梁联通不同的业务系统,解耦系统之间的实现依赖.其高速体现在底层的非阻塞I/O ...
- mysql(二) 慢查询分析(一)
如下表结构: CREATE TABLE `trade_order` ( `order_id` ) unsigned NOT NULL AUTO_INCREMENT COMMENT '订单编号', `t ...
- java map的键是唯一的 所有 用set类型存放
- 【bzoj1717】[Usaco2006 Dec]Milk Patterns 产奶的模式 后缀数组+离散化
题目描述 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个“模式”. John的牛奶按质量可以被赋予一 ...
- 【转】c# 类反射简单操作
转:http://www.jb51.net/article/25863.htm 首先建立一个测试的类 复制代码代码如下: public class MyClass { public int one ...
- BZOJ3832 [Poi2014]Rally 【拓扑序 + 堆】
题目链接 BZOJ3832 题解 神思路orz,根本不会做 设\(f[i]\)为到\(i\)的最长路,\(g[i]\)为\(i\)出发的最长路,二者可以拓扑序后\(dp\)求得 那么一条边\((u,v ...
- https客户端遇到过的问题
1.用.p12格式的证书,在windows上调试完全没问题,在Linux服务器上,提示无效证书格式. 解决方法:将.p12格式的证书转换为.jks格式的证书. 将.p12格式的证书转换为.jks格式的 ...
- swift的UIbutton
override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, ...
- Machine Learning CodeForces - 940F (带修改的莫队)
You come home and fell some unpleasant smell. Where is it coming from? You are given an array a. You ...
- BroadcastReceiver学习
一.使用系统广播.以监听电话状态为例 1.写一个类继承自BroadcastReceiver类 package com.diysoul.android.blacklist.receivers; impo ...