1 什么是进程冻结

进程冻结技术(freezing of tasks)是指在系统hibernate或者suspend的时候,将用户进程和部分内核线程置于“可控”的暂停状态。

2 为什么需要冻结技术

假设没有冻结技术,进程可以在任意可调度的点暂停,而且直到cpu_down才会暂停并迁移。这会给系统带来很多问题:

(1)有可能破坏文件系统。在系统创建hibernate image到cpu down之间,如果有进程还在修改文件系统的内容,这将会导致系统恢复之后无法完全恢复文件系统;

(2)有可能导致创建hibernation image失败。创建hibernation image需要足够的内存空间,但是在这期间如果还有进程在申请内存,就可能导致创建失败;

(3)有可能干扰设备的suspend和resume。在cpu down之前,device suspend期间,如果进程还在访问设备,尤其是访问竞争资源,就有可能引起设备suspend异常;

(4)有可能导致进程感知系统休眠。系统休眠的理想状态是所有任务对休眠过程无感知,睡醒之后全部自动恢复工作,但是有些进程,比如某个进程需要所有cpu online才能正常工作,如果进程不冻结,那么在休眠过程中将会工作异常。

3 代码实现框架

冻结的对象是内核中可以被调度执行的实体,包括用户进程、内核线程和work_queue。用户进程默认是可以被冻结的,借用信号处理机制实现;内核线程和work_queue默认是不能被冻结的,少数内核线程和work_queue在创建时指定了freezable标志,这些任务需要对freeze状态进行判断,当系统进入freezing时,主动暂停运行。

kernel threads可以通过调用kthread_freezable_should_stop来判断freezing状态,并主动调用__refrigerator进入冻结;work_queue通过判断max_active属性,如果max_active=0,则不能入队新的work,所有work延后执行。

标记系统freeze状态的有三个重要的全局变量:pm_freezing、system_freezing_cnt和pm_nosig_freezing,如果全为0,表示系统未进入冻结;system_freezing_cnt>0表示系统进入冻结,pm_freezing=true表示冻结用户进程,pm_nosig_freezing=true表示冻结内核线程和workqueue。它们会在freeze_processes和freeze_kernel_threads中置位,在thaw_processes和thaw_kernel_threads中清零。

fake_signal_wake_up函数巧妙的利用了信号处理机制,只设置任务的TIF_SIGPENDING位,但不传递任何信号,然后唤醒任务;这样任务在返回用户态时会进入信号处理流程,检查系统的freeze状态,并做相应处理。

任务主动调用try_to_freeze的代码如下:

  1. static inline bool try_to_freeze_unsafe(void)
  2. {
  3. if (likely(!freezing(current))) //检查系统是否处于freezing状态
  4. return false;
  5. return __refrigerator(false); //主动进入冻结
  6. }
  7. static inline bool freezing(struct task_struct *p)
  8. {
  9. if (likely(!atomic_read(&system_freezing_cnt))) //系统总体进入freezing
  10. return false;
  11. return freezing_slow_path(p);
  12. }
  13. bool freezing_slow_path(struct task_struct *p)
  14. {
  15. if (p->flags & PF_NOFREEZE) //当前进程是否允许冻结
  16. return false;
  17. if (pm_nosig_freezing || cgroup_freezing(p)) //系统冻结kernel threads
  18. return true;
  19. if (pm_freezing && !(p->flags & PF_KTHREAD)) //系统冻结用户进程
  20. return true;
  21. return false;
  22. }

进入冻结状态直到恢复的主要函数:

bool __refrigerator(bool check_kthr_stop)

  1. {
  2. ...
  3. for (;;) {
  4. set_current_state(TASK_UNINTERRUPTIBLE); //设置进程为UNINTERRUPTIBLE状态
  5. spin_lock_irq(&freezer_lock);
  6. current->flags |= PF_FROZEN; //设置已冻结状态
  7. if (!freezing(current) ||
  8. (check_kthr_stop && kthread_should_stop())) //判断系统是否还处于冻结
  9. current->flags &= ~PF_FROZEN; //如果系统已解冻,则取消冻结状态
  10. spin_unlock_irq(&freezer_lock);
  11. if (!(current->flags & PF_FROZEN)) //如果已取消冻结,跳出循环,恢复执行
  12. break;
  13. was_frozen = true;
  14. schedule();
  15. }
  16. ......
  17. }

4 参考文献

(1) http://www.wowotech.net/linux_kenrel/suspend_and_resume.html

(2) http://www.wowotech.net/linux_kenrel/std_str_func.html

(3) kenrel document: freezing-of-tasks.txt

Linux进程冻结技术的更多相关文章

  1. Linux进程冻结技术【转】

    转自:http://blog.csdn.net/zdy0_2004/article/details/50018843 http://www.wowotech.net/ 1 什么是进程冻结 进程冻结技术 ...

  2. Linux进程自保护攻防对抗技术研究(Process Kill Technology && Process Protection Against In Linux)

    0. 引言 0x1: Linux系统攻防思想 在linux下进行"进程kill"和"进程保护"的总体思路有以下几个,我们围绕这几个核心思想展开进行研究 . 直接 ...

  3. linux进程及进程控制

    Linux进程控制   程序是一组可执行的静态指令集,而进程(process)是一个执行中的程序实例.利用分时技术,在Linux操作系统上同时可以运行多个进程.分时技术的基本原理是把CPU的运行时间划 ...

  4. linux 进程地址空间的一步步探究

    我们知道,在32位机器上linux操作系统中的进程的地址空间大小是4G,其中0-3G是用户空间,3G-4G是内核空间.其实,这个4G的地址空间是不存在的,也就是我们所说的虚拟内存空间. 那虚拟内存空间 ...

  5. linux 进程(一)---基本概念

    一.进程的定义         进程是操作系统的概念,每当我们执行一个程序时,对于操作系统来讲就创建了一个进程,在这个过程中,伴随着资源的分配和释放.可以认为进程是一个程序的一次执行过程.   二.进 ...

  6. Cgroup maintainer丽泽范:解剖Linux核心容器技术

    摘要:Cgroup和namespace等内核特性如何出现,在社区处于如何的开发状况?Docker如火如荼.内核社区是否会因此加紧完好容器技术的隔离性安全性?华为Linux内核高级project师李泽帆 ...

  7. Linux进程实践(1) --Linux进程编程概述

    进程 VS. 程序 什么是程序? 程序是完成特定任务的一系列指令集合. 什么是进程? [1]从用户的角度来看:进程是程序的一次执行过程 [2]从操作系统的核心来看:进程是操作系统分配的内存.CPU时间 ...

  8. Linux进程上下文切换过程context_switch详解--Linux进程的管理与调度(二十一)

    1 前景回顾 1.1 Linux的调度器组成 2个调度器 可以用两种方法来激活调度 一种是直接的, 比如进程打算睡眠或出于其他原因放弃CPU 另一种是通过周期性的机制, 以固定的频率运行, 不时的检测 ...

  9. Linux进程调度器概述--Linux进程的管理与调度(十五)

    调度器面对的情形就是这样, 其任务是在程序之间共享CPU时间, 创造并行执行的错觉, 该任务分为两个不同的部分, 其中一个涉及调度策略, 另外一个涉及上下文切换. 1 背景知识 1.1 什么是调度器 ...

随机推荐

  1. Android -- Fragment动画异常Unknown animation name: objectAnimator

    异常 Caused by: java.lang.RuntimeException: Unknown animation name: objectAnimator 异常代码 FragmentTransa ...

  2. MySql无法远程登录以及IP被锁解决办法

    授权 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '' WITH GRANT OPTION;Query OK, 0 rows aff ...

  3. 重新安装 RCU-数据库 2014-11-22

    删除数据库Endv(原RCU数据库) 重建数据库为LLS(新RCU数据库)..略.. Database Control URL 为 https://www:1158/em 管理资料档案库已置于安全模式 ...

  4. 部署项目Nginx+Tornado+Supervisor

    http://www.jianshu.com/p/9bebb99368ea Tornado Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻 ...

  5. java科学计数法转换成普通计数法

    java科学计数法转换成普通计数法: String sjiachun = "12345E-10"; BigDecimal db = new BigDecimal(sjiachun) ...

  6. 搭建一个SpringBoot项目

    1.创建项目 New->Spring Starter Project 2.添加支持 增加对mybatis plus的支持,修改pom.xml,增加如下内容: <dependency> ...

  7. uni-app - 如何打包

    H5,spa应用,必须在服务器环境下运行 多看官方文档,打包涉及到支付.以及各平台兼容性,通过 官方API链接如下: https://uniapp.dcloud.io/platform H5打包 An ...

  8. Java从零开始学六(运算符)

    运算符 一.赋值运算符号 No. 赋值运算符号 描述 1 = 赋值 int num=22; System.out.println("num= "+num); num=num-3; ...

  9. Oracle使用——PLSQL的中文乱码显示全是问号

    问题 这两天刚将PLSQL与Oracle配置好,但是在PLSQL中插入数据时.出现一个问题,PLSQL中的表里无法显示中文,中文无法保存.无法输出.中文在表中显示问号.如图: 原因 经过一番查证,发现 ...

  10. 在Loadrunner中如何用system函数执行系统命令

    前提: windows 系统 实现功能:用 LR 中的system函数执行系统命令 相关功能:在LR中利用C函数建立文件,写文件,读文件. 主要相关函数:sprintf/fopen/fgetc/fre ...