linux内核怎么变化,Linux内核中CPU状态变化机制简介
1. CPU状态
在Linux内核include/linux/notifier.h文件中,定义了几种CPU状态,如下所示:
#define CPU_ONLINE 0x0002 /* CPU (unsigned)v is up */
#define CPU_UP_PREPARE 0x0003 /* CPU (unsigned)v coming up */
#define CPU_UP_CANCELED 0x0004 /* CPU (unsigned)v NOT coming up */
#define CPU_DOWN_PREPARE 0x0005 /* CPU (unsigned)v going down */
#define CPU_DOWN_FAILED 0x0006 /* CPU (unsigned)v NOT going down */
#define CPU_DEAD 0x0007 /* CPU (unsigned)v dead */
#define CPU_DYING 0x0008 /* CPU (unsigned)v not running any task,
* not handling interrupts, soon dead.
* Called on the dying cpu, interrupts
* are already disabled. Must not
* sleep, must not fail */
#define CPU_POST_DEAD 0x0009 /* CPU (unsigned)v dead, cpu_hotplug lock is dropped */
#define CPU_STARTING 0x000A /* CPU (unsigned)v soon running.
* Called on the new cpu, just before
* enabling interrupts. Must not sleep,
* must not fail */
2. 状态变化通知链
为了让内核中其他模块能觉察到CPU状态的变化,在内核中定义了一个全局链表cpu_chain。需要觉察CPU状态变化的模块,会调用函数register_cpu_notifier,此函数会将模块提供的struct notifier_block结构体变量加入到全局链表cpu_chain中。
具体代码如下所示:
在kernel/cpu.c文件中,定义了全局链表cpu_chain。如下所示:
static RAW_NOTIFIER_HEAD(cpu_chain);
函数register_cpu_notifier实现如下所示:
int __ref register_cpu_notifier(struct notifier_block *nb)
{
int ret;
……;
ret = raw_notifier_chain_register(&cpu_chain, nb);
……;
return ret;
}
在内核其他模块kernel/watchdog.c文件中对函数register_cpu_notifier的调用如下所示:
static int __cpuinit
cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
{
int hotcpu = (unsigned long)hcpu;
switch (action) {
case CPU_UP_PREPARE:
case CPU_UP_PREPARE_FROZEN:
if (watchdog_prepare_cpu(hotcpu))
return NOTIFY_BAD;
break;
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
if (watchdog_enable(hotcpu))
return NOTIFY_BAD;
break;
……
}
return NOTIFY_OK;
}
static struct notifier_block __cpuinitdata cpu_nfb = {
.notifier_call = cpu_callback
};
static int __init spawn_watchdog_task(void)
{
……
register_cpu_notifier(&cpu_nfb);
……
return 0;
}
early_initcall(spawn_watchdog_task);
Linux内核中相关模块为了觉察CPU状态变化注册了相关函数,那么CPU状态变化又是如何通知到这些模块的呢?在kernel/cpu.c文件中,定义了两个函数cpu_notify和__cpu_notify,它们会通过调用其他功能函数来遍历全局链表cpu_chain,遍历过程中会调用其他模块注册的结构体变量notifier_block中的notifier_call函数。
3. CPU状态变化
通过在内核文件中查找cpu_notify函数和此函数调用的__cpu_notify函数,可以得到CPU状态变化的代码段,如下所示:
在kernel/cpu.c文件中,_cpu_up函数如下所示:
static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
{
……
ret = __cpu_notify(CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls);
……
/* Now call notifier in preparation. */
cpu_notify(CPU_ONLINE | mod, hcpu);
out_notify:
if (ret != 0)
__cpu_notify(CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
……;
}
_cpu_down函数如下所示:
static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
{
……
err = __cpu_notify(CPU_DOWN_PREPARE | mod, hcpu, -1, &nr_calls);
if (err) {
__cpu_notify(CPU_DOWN_FAILED | mod, hcpu, nr_calls, NULL);
}
……
/* CPU is completely dead: tell everyone. Too late to complain. */
cpu_notify_nofail(CPU_DEAD | mod, hcpu);
out_release:
if (!err)
cpu_notify_nofail(CPU_POST_DEAD | mod, hcpu);
return err;
}
notify_cpu_starting函数如下所示:
void __cpuinit notify_cpu_starting(unsigned int cpu)
{
unsigned long val = CPU_STARTING;
cpu_notify(val, (void *)(long)cpu);
}
linux内核怎么变化,Linux内核中CPU状态变化机制简介相关推荐
- linux磁盘sda1变化,linux系统中sda变成sdb了怎么办
目前Linux内核对2113于这种磁盘设备的映射5261基本上取决于三个顺序,一是4102磁盘驱动程序的加载:二是主1653机PCI 插槽的监测:三是磁盘本身的监测,先来的当然是a,以此类推.所以,在 ...
- linux驱动架构变化,Linux网卡驱动架构分析
一.网卡驱动架构 由上到下层次依次为:应用程序→系统调用接口→协议无关接口→网络协议栈→设备无关接口→设备驱动. 二.重要数据结构 1.Linux内核中每一个网卡由一个net_device结构来描述. ...
- linux目录文件变化,Linux下监测目录或文件的变化---inotify
二.结构及事件介绍 当有事件发生时,notify文件描述符会变为可读,调用read()可以读取发生的事件,事件的描述结构为inotify_event结构体,定义如下: struct inotify_e ...
- linux xmanager使用教程,Xmanager企业版中各软件功能简介
Xmanager Enterprise是一款小巧.便捷的浏览远端X窗口系统的工具.它包含很多小的软件,每个软件性能又有所不同,本集小编就为大家讲解Xmanager企业版 5中各软件的功能. 图1:xm ...
- linux tick异常变化,linux tickGet()
tickGet()返回的是从系统启动开始tick计数后的总的tick数目. tick是啥,是"滴答",它是一个数值量,本身不能代表时间. 如果说要知道tick增加一个代表多少时间的 ...
- 计算机硬件中 cpu 总线,计算机硬件简介——CPU
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 CPU主要部件有算术逻辑单元ALU.寄存器组RS.控制单元.总线. 1.算术逻辑单元ALU(Arithmetic Logic Unit) ALU是运算器核 ...
- linux 失能鼠标,Linux内核中CPU主频和电压调整 (一)
通过动态改变CPU电压,可以调整CPU主频. 通过改变时钟倍数可以动态改变CPU时钟频率. 一些具有CPU主频率时钟倍数可调能力的处理器,能够在不同的主频率和工作电压之间动态切换:而不需要内核或者用户 ...
- linux内核 频率,Linux内核中CPU主频和电压调整 (三)
如何开发一个新的CPUFreq driver 初始化 首先,在一个 __initcall level 7后者以后的函数中检查内核是否运行在正确的CPU和正确的芯片组上面. 如果正确,则通过cpufre ...
- Linux内核学习笔记——Linux中的用户组和权限管理(UID是什么?)
目录 一.背景 进程权限 最小权限原则 二.linux系统安全模型 用户 用户组 用户和组的关系 安全上下文 进程的用户ID 函数setreuid和setregid 函数seteuid和setegid ...
- linux内核教学的全套视频,中科大老师全程讲解Linux内核分析视频教程《附加介绍+总结》共23节课...
中科大老师全程讲解Linux内核分析视频教程<附加介绍+总结>共23节课" F4 u& {+ T) p5 G' W ]; o% m 2 q: ]. j8 I; q' D ...
最新文章
- uniapp(一) 项目架构,封装
- C#创建Access
- android设置window背景颜色,android – 设置标题背景颜色
- 软件工程 团队作业 #9
- 01算法 java_蓝桥杯:基础练习 01字串【JAVA算法实现】
- leetcode - 638. 大礼包
- 串口的输出设置【原创】
- textarea选中行删除_Easy Data Transform如何在Excel中删除重复的行?
- AWS SageMaker机器学习训练营听课总结
- 计算机windows8黑屏怎么办,详解笔记本电脑出现电源拔出就黑屏的win8处理教程
- Spring createBean()源码笔记
- JavaScript的那些书
- java 动态属性_Java 类动态添加属性字段的操作
- Android按钮点击控制进度条,Android通过按钮和进度条实现音量调节(AudioManager)...
- 黑马java idea (据说是完整的)网盘
- win10计算机无访问权限,win10系统提示无internet访问权限怎么办
- 迪杰特斯拉算法Python版本
- UIAlertController Extention
- 微软新版edge浏览器如何开启画中画模式 (微软新版edge)
- matlab r2020a例题 2.1节 数据类型(下)
热门文章
- 对Object.prototype.toString.call(obj)的理解
- 安装MongoDB时弹窗错误,使用时无法启动服务器
- axure如何导出原件_AXURE教程:管理后台页面框架
- phpcount数组报错_PHPExcel把导入的excel表格转换为数组,然后运行,浏览器什么也不显示,也不报错...
- c语言中有123f,C语言库函数(S类字母) - 3
- CentOS7安装单机kubernetes和Docker
- lock concurrence
- ImportError: No module named rospy
- 线程协作--wait,notify:经典消费者生产者
- 解决 webpack-dev-server 不能自动刷新的问题