Linux的suspend机制的设计原理(续)--cpu的热插拔

简介:

前面简单谈了一下linux的suspend机制的实现,其主要思想就是,启动cpu外的别的cpu都不关闭,而是进入idle然后进入play_dead中执行halt,我们知道halt只有中断可以唤醒,可是醒了以后发现该cpu为dead状态,那么仍然进入halt,如果将设备也停了,那么该cpu就一直halt了,直到我们按下电源,这个就是硬件范畴了,启动cpu则不是进入halt,而是执行一些列操作将快照映像写入磁盘,最后调用power_down关闭电源,这个操作是由pm_ops->enter(PM_SUSPEND_DISK)完成的,这就提供了一个灵活的回调函数机制,将操作策略和执行机制分离,我们可以实现acpi的pm_ops,还可以实现apm的pm_ops,但是不管采用哪一种电源管理,上面说的执行机制是不会变的。在resume的时候,大体策略就是将磁盘的快照映像恢复到内存,然后开启所有的cpu开始工作,由于电源管理的规范,只有一个cpu可以用来唤醒机器,那么这样的话前面的halt调别的cpu也是正当的,当需要唤醒机器的时候,因为suspend到磁盘的时候,启动cpu已经做好了随时被唤醒的准备,所以它当然要担负起唤醒的重任,唤醒函数其实就是software_resume,注意这个函数的定义是late_initcall,这个定义是__define_initcall("7",fn),意思就是在所有设备都启动后再最后调用,因此可以断定,唤醒的时候还是要执行一遍设备初始化的,当所有的设备都初始化完毕以后再调用这个函数,这个函数的主要任务就是将存入磁盘的快照映像恢复入内存,也就是从power_down下面开始而不是继续执行software_resume,这个可以类比一下进程都是从schedule中被切换出去,然后在schedule中被切换回来,实际上如果到了software_resume的末尾就说明恢复磁盘快照映像时出了错误,按照道理是不该执行到software_resume的最后的。

前面讨论的基础是什么?其实就是cpu的热插拔机制,也就是cpu的hotplug机制,所谓热插拔就是可以在系统运行的时候动态的增加或者去除cpu,天啊,cpu都可以热插拔了吗?是的,可以,但是并不像usb那样可以直接针对硬件热插拔,而是在拔下cpu之前必须先通知系统该cpu要被拔下,然后系统确认正常后才可以拔下该cpu,也就是说cpu的热插拔是针对软件的热插拔,其实这很好理解,usb设备仅仅是一个设备,一个硬件插进去会有信息通知cpu,而cpu进而执行软件来初始化该设备,但是cpu拔下来怎么办呢?通知谁呢?难道处理器间中断吗?这样其实也不行,想想看usb也不是可以随意拔掉的,在windows系统上你一般都是点击移除usb设备得到系统确认可以安全移除后才会拔下usb设备的,当然如果你非要强行拔下,损失一般并不大,顶多就是一些数据损失,一般内核在读写外设发现外设不存在或者出错时都会有相应的处理机制,但是cpu就不一样了,在拔下之前,它上面可能运行着一些重要的进程,可能是一些很重要的服务进程,如果它正在该cpu上运行时你把cpu拔了,那么该进程就可能遭受永远的破坏,也很容易造成整个系统死锁,比如拔下的cpu上有一个进程正在内核空间占有一把锁,那么当cpu被拔掉后,这把锁将永远不会释放,其它争夺这把锁的进程就有可能死在那里,而且还会造成连锁反映。于是在cpu被拔掉前,务必要先通过软件down掉该cpu,也就是上面的suspend机制中对待启动cpu之外别的cpu的做法,等待其执行halt后再拔掉,这样就不会有任何损失了。想拔下一个cpu的话可以通过sysfs操作,然后系统会调用cpu_down函数,其实这个函数就是迫使这个cpu切换到执行idle,然后halt,就是靠设置idle的优先级为最高来实现的,这样的话,所有在这个cpu上排队的进程就得不到机会执行进而在这个cpu死了以后被迁移到别的cpu上,那个在这个cpu上的当前进程也会因为优先级低而为idle让出cpu。除了上面要做的之外,还要通知到该被通知的实体,也就是对cpu的热插拔感兴趣的实体,这个是靠linux内核的通知链机制执行的,事实上,对热插拔cpu的支持主要就是就是注册一条通知链:

int register_cpu_notifier(struct notifier_block *nb)

{

return blocking_notifier_chain_register(&cpu_chain, nb);

}

设计cpu热插拔机制的时候,主要几个要点,最重要的就是不能影响在热插拔cpu上执行的进程,也就是cpu的热插拔对进程应该是透明的,linux的这个实现想想看十分合理,它本质就是利用idle进程的无用性来完成不对别的进程影响的,而且将cpu状态设置为dead状态可以避免在load_balance新的进程重新调度到这个cpu上,cpu的dead状态有cpu_online_map来体现。

有网友说linux在suspend的时候重启别的cpu而不恢复别的cpu原因有两点:1.suspend的时候不要太注重效率;2.停掉别的cpu会更有效率。仅供参考,其实不用按cpu保存状态而是按照进程保存状态,体现了cpu只是一个服务者的思想,只要能保存进程状态就可以了,cpu对用户是透明的,用户关注他们运行了什么进程可是不会管用几个cpu来运行。



 本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1274019

相关文章
|
2月前
|
缓存 Linux 开发者
Linux内核中的并发控制机制
本文深入探讨了Linux操作系统中用于管理多线程和进程的并发控制的关键技术,包括原子操作、锁机制、自旋锁、互斥量以及信号量。通过详细分析这些技术的原理和应用,旨在为读者提供一个关于如何有效利用Linux内核提供的并发控制工具以优化系统性能和稳定性的综合视角。
|
21天前
|
存储 编译器 Linux
动态链接的魔法:Linux下动态链接库机制探讨
本文将深入探讨Linux系统中的动态链接库机制,这其中包括但不限于全局符号介入、延迟绑定以及地址无关代码等内容。
281 22
|
28天前
|
监控 算法 Linux
Linux内核锁机制深度剖析与实践优化####
本文作为一篇技术性文章,深入探讨了Linux操作系统内核中锁机制的工作原理、类型及其在并发控制中的应用,旨在为开发者提供关于如何有效利用这些工具来提升系统性能和稳定性的见解。不同于常规摘要的概述性质,本文将直接通过具体案例分析,展示在不同场景下选择合适的锁策略对于解决竞争条件、死锁问题的重要性,以及如何根据实际需求调整锁的粒度以达到最佳效果,为读者呈现一份实用性强的实践指南。 ####
|
1月前
|
消息中间件 安全 Linux
深入探索Linux操作系统的内核机制
本文旨在为读者提供一个关于Linux操作系统内核机制的全面解析。通过探讨Linux内核的设计哲学、核心组件、以及其如何高效地管理硬件资源和系统操作,本文揭示了Linux之所以成为众多开发者和组织首选操作系统的原因。不同于常规摘要,此处我们不涉及具体代码或技术细节,而是从宏观的角度审视Linux内核的架构和功能,为对Linux感兴趣的读者提供一个高层次的理解框架。
|
2月前
|
缓存 监控 Linux
|
2月前
|
算法 Linux 开发者
Linux内核中的锁机制:保障并发控制的艺术####
本文深入探讨了Linux操作系统内核中实现的多种锁机制,包括自旋锁、互斥锁、读写锁等,旨在揭示这些同步原语如何高效地解决资源竞争问题,保证系统的稳定性和性能。通过分析不同锁机制的工作原理及应用场景,本文为开发者提供了在高并发环境下进行有效并发控制的实用指南。 ####
|
2月前
|
缓存 Linux 开发者
Linux内核中的并发控制机制:深入理解与应用####
【10月更文挑战第21天】 本文旨在为读者提供一个全面的指南,探讨Linux操作系统中用于实现多线程和进程间同步的关键技术——并发控制机制。通过剖析互斥锁、自旋锁、读写锁等核心概念及其在实际场景中的应用,本文将帮助开发者更好地理解和运用这些工具来构建高效且稳定的应用程序。 ####
48 5
|
2月前
|
算法 Unix Linux
深入理解Linux内核调度器:原理与优化
本文探讨了Linux操作系统的心脏——内核调度器(Scheduler)的工作原理,以及如何通过参数调整和代码优化来提高系统性能。不同于常规摘要仅概述内容,本摘要旨在激发读者对Linux内核调度机制深层次运作的兴趣,并简要介绍文章将覆盖的关键话题,如调度算法、实时性增强及节能策略等。
|
2月前
|
Linux 数据库
Linux内核中的锁机制:保障并发操作的数据一致性####
【10月更文挑战第29天】 在多线程编程中,确保数据一致性和防止竞争条件是至关重要的。本文将深入探讨Linux操作系统中实现的几种关键锁机制,包括自旋锁、互斥锁和读写锁等。通过分析这些锁的设计原理和使用场景,帮助读者理解如何在实际应用中选择合适的锁机制以优化系统性能和稳定性。 ####
66 6
|
2月前
|
安全 Linux 数据安全/隐私保护
深入探索Linux操作系统的多用户管理机制
【10月更文挑战第21天】 本文将详细解析Linux操作系统中的多用户管理机制,包括用户账户的创建与管理、权限控制以及用户组的概念和应用。通过具体实例和命令操作,帮助读者理解并掌握Linux在多用户环境下如何实现有效的资源分配和安全管理。