linux新内核的freeze框架以及意义【转】
转自:https://blog.csdn.net/dog250/article/details/5303442
linux的电源管理发展非常迅速,比如在挂起到内存的时候,系统会冻结住所有的进程,也就是所有的进程都不再运行,它们被冻结之前,最后的状态被保存,等到解冻的时候,所有进程恢复运行,linux对此的实现非常巧妙,它没有用特殊的机制来实现这一点,而是用它的freeze框架加上信号处理来实现的,在freeze所有进程的时候并没有将之挂起或者说使其不再运行,而是在信号处理的开始挂了一个类似于钩子的东西,把挂起进程交给信号处理来做,freeze框架要做的就是设置一些标志位来指示信号处理要冻结它了,然后设置此进程的信号附着位,这样该进程在返回用户空间的时候就乖乖进入到冻结状态了,这一点下面的代码分析会详述。这么做有几个好处,一来从设计上讲这又是一个为了低耦合而将一个框架分离成几个模块让各个模块分别承担一部分职责的做法,这样的话,将来如要升级会非常灵活,这看似复杂,但是一旦你理解了精要,还是觉得蛮好的;二来从效果上说,冻结进程其实是一个很危险的操作,2.6内核有了内核抢占,如果一个任务在内核中正执行或者正在内核中睡眠,那么它很有可能持有一把锁或者在等待一把锁,这个时候如果使其无条件的冻结,那么等待解冻的时候,解冻的顺序就要求很高了,要不然很容易死锁,因此把冻结操作安排在进程返回用户空间的时候,这样可以保证进程将不在内核了,既然已经到了返回用户空间的前夕,那么可以保证它肯定不会和内核的其它进程或中断引起竞态,这么做简直好的没法说。
int freeze_processes(void)
{
error = try_to_freeze_tasks(true); //低强度冻结
...//错误处理以及信息打印
error = try_to_freeze_tasks(false); //高强度冻结
...//错误以及善后处理
}
static int try_to_freeze_tasks(bool sig_only)
{
struct task_struct *g, *p;
unsigned int todo;
...//这些变量和主要问题无关
do {
todo = 0;
read_lock(&tasklist_lock);
do_each_thread(g, p) {
if (frozen(p) || !freezeable(p))
continue;
if (!freeze_task(p, sig_only)) //这个函数本质上造成了进程的冻结,但是在它里面你却找不到任何“冻结”的操作。
continue;
if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p))
todo++;
//如果有个进程我们目前无法设置它的冻结位,也就是对它无可奈何的时候,我们将todo递增,以表示要再进行一轮,直到将之冻结或者超过预定期限或者别的什么更加重要的事情发生。
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
yield();
//刚才在freeze_task中不是可能给要冻结的进程发送信号了吗(其实就是设置了一个信号位小小欺骗一下,并没有发送真正的信号)?那么此时就要给这个进程机会使之运行,然后在信号处理中真正冻结,注意yield并不改变当前操作进程的任何标志,仅仅让出cpu而已,理想情况,等到这一轮的进程p被真正冻结以后,这个当前调用try_to_freeze_tasks的进程将继续运行,以便使下一个进程冻结
if (time_after(jiffies, end_time))
break;
} while (todo);
...//这下面的我们不必关心
}
return todo ? -EBUSY : 0;
}
bool freeze_task(struct task_struct *p, bool sig_only)
{
if (!freezing(p)) {
rmb();
if (frozen(p))
return false;
if (!sig_only || should_send_signal(p))
set_freeze_flag(p);
else
return false;
}
if (should_send_signal(p)) {
if (!signal_pending(p))
fake_signal_wake_up(p);
//对进程p设置上_TIF_SIGPENDING标志,然后唤醒它,这其实是一场欺骗,根本没有什么信号被发往p,这么做是因为在进程被唤醒后,检查是否有_TIF_SIGPENDING置位,如有的话,在执行get_signal_to_deliver的时候有个死亡之神在等着它,就是get_signal_to_deliver中马上调用的try_to_freeze,以便进程p上当受骗。
} else if (sig_only) {
return false;
} else {
wake_up_state(p, TASK_INTERRUPTIBLE);
}
return true;
}
在get_signal_to_deliver中会调用try_to_freeze,然后这个函数将进程真正冻结,非常安全,因为信号处理在返回用户空间时执行,此时该进程已经退出了内核的执行路径,不会被搅进内核的管理竞态中,是的,此时的事情十分安全:
static inline int try_to_freeze(void)
{
if (freezing(current)) {
refrigerator();
...//别的处理
}
以下这个refrigerator函数彻底冻结了一个进程,即当前进程,它其实就是让当前进程在当前的状态上定格,等到被唤醒以后马上恢复到当前情况,这个当前进程其实睡眠在TASK_UNINTERRUPTIBLE的状态撒谎能够
void refrigerator(void)
{
long save;
task_lock(current);
if (freezing(current)) {
frozen_process(); //freezing已经完成,将该进程设置为frozen
task_unlock(current);
...
save = current->state;
spin_lock_irq(¤t->sighand->siglock);
recalc_sigpending(); //刚才为了欺骗这个进程才使得人家跑到这里准备被绑,现在绑架任务已经完成,清除掉为了引诱目的而设置的标志位
spin_unlock_irq(¤t->sighand->siglock);
for (;;) {
set_current_state(TASK_UNINTERRUPTIBLE);
if (!frozen(current))
break;
schedule();
}
__set_current_state(save); //被唤醒,继续执行
}
唤醒的过程比这简单多了,就是一个一个的调用wake_up_process而已,这实在太简单了以至于不说了。这里就有了一个问题,在2.6.25以来新内核中,增加了对cgroup的支持,那么某种意义上,linux开始支持只有商用unix上才有“容器”的概念,linux内核陆续增加了cgroup对内存,文件等的控制,用户可以对单个group进行资源限制了,在linux内核上,以资源作为区分相当于运行着好几个虚拟机,每台虚拟机都是资源分配的一个单位,如果联系前面刚说的freeze框架的话就会发现,如果把一个cgroup的进程作为一个组进行冻结的话会很有用,比如这样的话我们可以将全组的进程“热迁移”到别的处理器,其实不是真正的热迁移,毕竟那些进程已经不再运行了,呵呵。其实freeze框架本身就可以对热插拔cpu进行支持,cgroup的freeze框架仅仅使得冻结的粒度可以切割了,不再是要么一下子冻结全部然后唤醒全部,要么就一个也不冻结,这就需要一个内核补丁,在最新的2.6.29内核中已经有了这样的机制,其实就是在冻结的时候加上了一个croup作为参数,然后把这个cgroup的进程应用上面的机制将之冻结,linux总是这样,一开始设计时就很灵活,然后后面修改加补丁的时候才不受罪。
另外在2.6.29内核中还有了文件系统的冻结,其实和上述的进程冻结一样,如果说进程冻结是将进程冻结到内存从而为了cpu而做一点事的话,那么文件系统就是将文件系统冻结到磁盘,然后让备份系统做一点事,以使得备份时是一个稳定又一致的文件系统,其实很简单,所谓冻结就是不让挂载不让写,其实用信号量就可以搞定,冻结一个文件系统的时候要得到其bdev的一个相关的信号量,而且挂载和写这个文件系统的时候也要得到这个信号量,如此就完结了。
linux新内核的freeze框架以及意义【转】的更多相关文章
- linux新内核中关闭硬盘的DMA
vortex86 SIS550 Minit-5250E瘦客户机,使用CF卡启动,显示不支持DMA. 搜索得新内核已基本不再使用ide=nodma参数了,查到这篇文章:“Debian下关闭CF卡的DMA ...
- linux新内核的时钟机制代码
http://blog.chinaunix.net/uid-22810130-id-384173.html 如果说cfs是linux的一个很有创意的机制的话,那么linux中另一个创意就是nohz,我 ...
- Linux新内核:提升系统性能 --Linux运维的博客
http://blog.csdn.net/linuxnews/article/details/52864182
- linux如何编译安装新内核支持NTFS文件系统?(以redhat7.2x64为例)
内核,是一个操作系统的核心.它负责管理系统的进程.内存.设备驱动程序.文件和网络系统,决定着系统的性能和稳定性.Linux作为一个自由软件,在广大爱好者的支持下,内核版本不断更新.新的内核修订了旧内核 ...
- Virtio:针对 Linux 的 I/O 虚拟化框架
Virtio:针对 Linux 的 I/O 虚拟化框架 --http://www.ibm.com/developerworks/cn/linux/l-virtio/#ibm-pcon 使用 KVM 和 ...
- linux设备驱动程序--串行通信驱动框架分析
linux 串行通信接口驱动框架 在学习linux内核驱动时,不论是看linux相关的书籍,又或者是直接看linux的源码,总是能在linux中看到各种各样的框架,linux内核极其庞杂,linux各 ...
- 深入linux kernel内核配置选项
============================================================================== 深入linux kernel内核配置选项 ...
- (转)linux IO 内核参数调优 之 参数调节和场景分析
1. pdflush刷新脏数据条件 (linux IO 内核参数调优 之 原理和参数介绍)上一章节讲述了IO内核调优介个重要参数参数. 总结可知cached中的脏数据满足如下几个条件中一个或者多个的时 ...
- [转]Linux中文件权限目录权限的意义及权限对文件目录的意义
转自:http://www.jb51.net/article/77458.htm linux中目录与文件权限的意义 一.文件权限的意义 r:可以读这个文件的具体内容: w:可以编辑这个文件的内容,包括 ...
随机推荐
- 【BZOJ3507】通配符匹配(哈希,动态规划)
[BZOJ3507]通配符匹配(哈希,动态规划) 题面 BZOJ 题解 对于匹配唯一存在影响的只有通配符,而\(?\)的影响也并不大,所以唯一需要仔细考虑的是\(*\). 考虑一个\(dp\),设\( ...
- json序列化 & 反序列化
json序列化: json的dumps方法可以将json格式数据序列为python的相关数据类型,比如str,常用于打印,另外,在序列化时,中文汉字被转换为unicode编码,在dumps函数中添加参 ...
- 在Android中afinal框架下實現sqlite數據庫版本升級的辦法
public abstract void onUpgrade(SQLiteDatabase db,int oldVersion,int new Version) 這個方法在實現時需要重寫. pub ...
- Linux 常用命令——df, du, ln
1. df 列出文件系统的整体磁盘使用量 2. du 评估文件系统的磁盘使用量(常用在推估目录所占容量),也可以计算文件或文件夹大小 3. ln 创建实体连接(hard link) 或 符号连接(Sy ...
- Linux下编译安装Lnmp
1.安装nginx 下载链接http://nginx.org/en/download.html (1)下载,解压 wget http://nginx.org/download/nginx-1.15.8 ...
- c# Bitmap byte[] Stream 文件相互转换
//byte[] 转图片 publicstatic Bitmap BytesToBitmap(byte[] Bytes) { MemoryStream stream = null; try { str ...
- Python基础【day01】:初始模块(五)
本节内容 1.标准库 1.sys 2.os 2.第三方库 1.for mac 2.for linux Python的强大之处在于他有非常丰富和强大的标准库和第三方库,几乎你想实现的任何功能都有相应的P ...
- servlet dispatcher .forward(request, response); 进入其它servlet【原】
dispatcher .forward(request, response); 进入其它servlet 假如我们的web.xml配置如下 <servlet> <servlet-nam ...
- FastReport报表打印总页数的问题?
设置两次报表后加入引号内内容 "第[Page#]页 共[TotalPages#]页" 本站文章除注明转载外,均为本站原创或翻译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动成果 ...
- 破解WPA工具Tkiptun-ng
1.关于Tkiptun-ng 该工具能够将一些帧插入到使用WPA TKIP且开启Qos的无线网络中. 2.Tkiptun-ng原理 Tkiptun-ng设计思路主要是通过获得一个包含明文与MIC(消息 ...