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状态变化机制简介相关推荐

  1. linux磁盘sda1变化,linux系统中sda变成sdb了怎么办

    目前Linux内核对2113于这种磁盘设备的映射5261基本上取决于三个顺序,一是4102磁盘驱动程序的加载:二是主1653机PCI 插槽的监测:三是磁盘本身的监测,先来的当然是a,以此类推.所以,在 ...

  2. linux驱动架构变化,Linux网卡驱动架构分析

    一.网卡驱动架构 由上到下层次依次为:应用程序→系统调用接口→协议无关接口→网络协议栈→设备无关接口→设备驱动. 二.重要数据结构 1.Linux内核中每一个网卡由一个net_device结构来描述. ...

  3. linux目录文件变化,Linux下监测目录或文件的变化---inotify

    二.结构及事件介绍 当有事件发生时,notify文件描述符会变为可读,调用read()可以读取发生的事件,事件的描述结构为inotify_event结构体,定义如下: struct inotify_e ...

  4. linux xmanager使用教程,Xmanager企业版中各软件功能简介

    Xmanager Enterprise是一款小巧.便捷的浏览远端X窗口系统的工具.它包含很多小的软件,每个软件性能又有所不同,本集小编就为大家讲解Xmanager企业版 5中各软件的功能. 图1:xm ...

  5. linux tick异常变化,linux tickGet()

    tickGet()返回的是从系统启动开始tick计数后的总的tick数目. tick是啥,是"滴答",它是一个数值量,本身不能代表时间. 如果说要知道tick增加一个代表多少时间的 ...

  6. 计算机硬件中 cpu 总线,计算机硬件简介——CPU

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 CPU主要部件有算术逻辑单元ALU.寄存器组RS.控制单元.总线. 1.算术逻辑单元ALU(Arithmetic Logic Unit) ALU是运算器核 ...

  7. linux 失能鼠标,Linux内核中CPU主频和电压调整 (一)

    通过动态改变CPU电压,可以调整CPU主频. 通过改变时钟倍数可以动态改变CPU时钟频率. 一些具有CPU主频率时钟倍数可调能力的处理器,能够在不同的主频率和工作电压之间动态切换:而不需要内核或者用户 ...

  8. linux内核 频率,Linux内核中CPU主频和电压调整 (三)

    如何开发一个新的CPUFreq driver 初始化 首先,在一个 __initcall level 7后者以后的函数中检查内核是否运行在正确的CPU和正确的芯片组上面. 如果正确,则通过cpufre ...

  9. Linux内核学习笔记——Linux中的用户组和权限管理(UID是什么?)

    目录 一.背景 进程权限 最小权限原则 二.linux系统安全模型 用户 用户组 用户和组的关系 安全上下文 进程的用户ID 函数setreuid和setregid 函数seteuid和setegid ...

  10. linux内核教学的全套视频,中科大老师全程讲解Linux内核分析视频教程《附加介绍+总结》共23节课...

    中科大老师全程讲解Linux内核分析视频教程<附加介绍+总结>共23节课" F4 u& {+ T) p5 G' W  ]; o% m 2 q: ]. j8 I; q' D ...

最新文章

  1. uniapp(一) 项目架构,封装
  2. C#创建Access
  3. android设置window背景颜色,android – 设置标题背景颜色
  4. 软件工程 团队作业 #9
  5. 01算法 java_蓝桥杯:基础练习 01字串【JAVA算法实现】
  6. leetcode - 638. 大礼包
  7. 串口的输出设置【原创】
  8. textarea选中行删除_Easy Data Transform如何在Excel中删除重复的行?
  9. AWS SageMaker机器学习训练营听课总结
  10. 计算机windows8黑屏怎么办,详解笔记本电脑出现电源拔出就黑屏的win8处理教程
  11. Spring createBean()源码笔记
  12. JavaScript的那些书
  13. java 动态属性_Java 类动态添加属性字段的操作
  14. Android按钮点击控制进度条,Android通过按钮和进度条实现音量调节(AudioManager)...
  15. 黑马java idea (据说是完整的)网盘
  16. win10计算机无访问权限,win10系统提示无internet访问权限怎么办
  17. 迪杰特斯拉算法Python版本
  18. UIAlertController Extention
  19. 微软新版edge浏览器如何开启画中画模式 (微软新版edge)
  20. matlab r2020a例题 2.1节 数据类型(下)

热门文章

  1. 对Object.prototype.toString.call(obj)的理解
  2. 安装MongoDB时弹窗错误,使用时无法启动服务器
  3. axure如何导出原件_AXURE教程:管理后台页面框架
  4. phpcount数组报错_PHPExcel把导入的excel表格转换为数组,然后运行,浏览器什么也不显示,也不报错...
  5. c语言中有123f,C语言库函数(S类字母) - 3
  6. CentOS7安装单机kubernetes和Docker
  7. lock concurrence
  8. ImportError: No module named rospy
  9. 线程协作--wait,notify:经典消费者生产者
  10. 解决 webpack-dev-server 不能自动刷新的问题