Linux进程管理 (7)实时调度
关键词:RT、preempt_count、RT patch。
除了CFS调度器之外,还包括重要的实时调度器,有两种RR和FIFO调度策略。本章只是一个简单的介绍。
更详细的介绍参考《Linux进程管理 (9)实时调度类分析,以及FIFO和RR对比实验》。
同时为了提高Linux的实时性,Linux社区还维护了realtime相关的补丁。这些补丁的介绍在《Linux实时补丁及其分析》。
1. 抢占内核
如果Linux内核不支持抢占,那么进程要么主动要求调度,如schedule()或者cond_resched();要么在系统调用、异常处理和中断处理完成返回用户空间前夕。
在支持可抢占内核中,如果唤醒动作发生在系统调用或者异常处理上下文中,在下一次调用preempt_enable()是会检查是否需要抢占调度;
中断处理返回前夕会检查是否要抢占当前进程,注意这里是中断返回而不是不支持抢占情况的用户空间返回。
struct thread_info成员preempt_count计数表示内核是否可以被完全抢占,当preempt_count为0时,表示内核可以被安全抢占;大于0时则禁止抢占。
preempt_count是32bit,低8位用于抢占计数PREEMPT_ACTIVE表示一个很大的抢占计数,通常用于表示抢占调度。
内核提供preempt_disable()来关闭抢占,preempt_count会加1。preempt_enable()函数打开抢占,preempt_count减1后判断是否为0,并检查thread_info的TIF_NEED_RESCHED标志位,如果为0,则用schedule() 完成调度抢占。
#define preempt_disable() \
do { \
preempt_count_inc(); \----------------------------------------对当前current_thread_info()->preempt_count加1
barrier(); \
} while () #define preempt_count_inc() preempt_count_add(1)
#define preempt_count_add(val) __preempt_count_add(val)
static __always_inline void __preempt_count_add(int val)
{
*preempt_count_ptr() += val;
}
#define preempt_enable() \
do { \
barrier(); \
if (unlikely(preempt_count_dec_and_test())) \-----------------prermpt_count减1后为0,且TIF_NEED_RESCHED被置位,则进行schedule()调度抢占。
__preempt_schedule(); \
} while () static __always_inline bool __preempt_count_dec_and_test(void)
{
return !--*preempt_count_ptr() && tif_need_resched();---------对当前preempt_count减1并判断是否为0,如果为0则检查TIF_NEED_RESCHED
} static __always_inline int *preempt_count_ptr(void)
{
return ¤t_thread_info()->preempt_count;
}
#define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED)-----测试TIF_NEED_RESCHED是否置位
#define test_thread_flag(flag) \
test_ti_thread_flag(current_thread_info(), flag) #define __preempt_schedule() preempt_schedule() asmlinkage __visible void __sched notrace preempt_schedule(void)
{
if (likely(!preemptible()))-----------------------------------判断当前preempt_count是否为0,并且irq没有被禁止。
return; preempt_schedule_common();------------------------------------__schedule()调度抢占。
}
# define preemptible() (preempt_count() == 0 && !irqs_disabled())
static void __sched notrace preempt_schedule_common(void)
{
do {
__preempt_count_add(PREEMPT_ACTIVE);
__schedule();
__preempt_count_sub(PREEMPT_ACTIVE); /*
* Check again in case we missed a preemption opportunity
* between schedule and now.
*/
barrier();
} while (need_resched());
}
2. 内核实时进展
Linux在提高实时性方面取得一系列进展,具体如下:
主要功能 | 内核版本 | 说明 |
Preemption suport | 2.5 | |
PI Mutexes | N/A | PI即Priority Inheritance,优先级继承的互斥体 |
HR Timer | 2.6.24 | 高精度定时器 |
Preemptive RCU | 2.6.25 | 可抢占RCU |
IRQ Threads | 2.6.30 | 中断线程化 |
Forced IRQ Threads | 2.6.39 | 强制中断线程化 |
Deadline scheduler | 3.14 | Deadline调度器 |
Full Realtime Preemption support | rt-patches | rt.wiki.kernel.org |
3. 内核延迟调试工具
内核提供了一些接口、工具,使我们得以一窥调度延迟。常用的有个ftrace的调度器preemptirqoff、等,以及工具latencytop、cyclictest等。
3.1 ftrace preemptirqsoff
preemptirqsoff可以跟踪关闭中断并禁止进程抢占代码的延时,同时记录关闭的最大时长。
这些tracer可以在Kernel hacking->Tracers中打开。
查看/sys/kernel/debug/tracing/available_tracers可以知道当前支持的tracer,里面有preemptirqsoff、preemptoff、irqsoff三种。
更详细的解释参照《Linux ftrace框架介绍及运用》。
下面是一个preemptirqsoff实例,可以看出禁止抢占、屏蔽中断的函数排列。以及最大值的进程信息和发生时的栈信息。
# tracer: preemptirqsoff
#
# preemptirqsoff latency trace v1.1.5 on 4.4.-rt155-custom
# --------------------------------------------------------------------
# latency: us, #/, CPU# | (M:preempt VP:, KP:, SP: HP: #P:)
# -----------------
# | task: gnome-shell- (uid: nice: policy: rt_prio:)
# -----------------
# => started at: schedule
# => ended at: migrate_disable
#
#
# _--------=> CPU#
# / _-------=> irqs-off
# | / _------=> need-resched
# || / _-----=> need-resched_lazy
# ||| / _----=> hardirq/softirq
# |||| / _---=> preempt-depth
# ||||| / _--=> preempt-lazy-depth
# |||||| / _-=> migrate-disable
# ||||||| / delay
# cmd pid |||||||| time | caller
# \ / |||||||| \ | /
...
gnome-sh- ..... 41us!: preempt_count_sub <-_raw_spin_unlock_irq
gnome-sh- ..... 627us : pin_current_cpu <-migrate_disable
gnome-sh- .... 628us : preempt_count_sub <-migrate_disable
gnome-sh- .... 628us : migrate_disable <-migrate_disable
gnome-sh- .... 629us+: trace_preempt_on <-migrate_disable
gnome-sh- .... 686us : <stack trace>
=> preempt_count_sub
=> migrate_disable
=> rt_spin_lock
=> add_wait_queue
=> __pollwait
=> unix_poll
=> sock_poll
=> do_sys_poll
=> SyS_poll
=> entry_SYSCALL_64_fastpath
3.2 latencytop
latencytop在内核上下文切换时记录被切换进程的内核栈,然后通过匹配内核栈函数来判断导致上下文切换的原因。
方便判断系统出现哪方面的延迟,还能查看某个进程或者线程的延迟情况。
使用latencytop需要安装libcanberra-gtk-module,并且使能CONFIG_LATENCYTOP(通过Kernel hacking->Latency measuring infrastructure打开)。
执行sudo latencytop,得到如下结果。
整个结果分为三部分,Targets->Cause->Backtrace,分别是进程->问题点->问题点栈回溯。
Linux进程管理 (7)实时调度的更多相关文章
- Linux进程管理 (9)实时调度类分析,以及FIFO和RR对比实验
关键词:rt_sched_class.SCHED_FIFO.SCHED_RR.sched_setscheduler().sched_setaffinity().RR_TIMESLICE. 本文主要关注 ...
- Linux进程管理 (2)CFS调度器
关键词: 目录: Linux进程管理 (1)进程的诞生 Linux进程管理 (2)CFS调度器 Linux进程管理 (3)SMP负载均衡 Linux进程管理 (4)HMP调度器 Linux进程管理 ( ...
- Linux进程管理专题
Linux进程管理 (1)进程的诞生介绍了如何表示进程?进程的生命周期.进程的创建等等? Linux支持多种调度器(deadline/realtime/cfs/idle),其中CFS调度器最常见.Li ...
- Linux进程管理 (1)进程的诞生
专题:Linux进程管理专题 目录: Linux进程管理 (1)进程的诞生 Linux进程管理 (2)CFS调度器 Linux进程管理 (3)SMP负载均衡 Linux进程管理 (4)HMP调度器 L ...
- Linux进程管理与调度-之-目录导航【转】
转自:http://blog.csdn.net/gatieme/article/details/51456569 版权声明:本文为博主原创文章 && 转载请著名出处 @ http:// ...
- Linux进程管理子系统分析【转】
本文转载自:http://blog.csdn.net/coding__madman/article/details/51298732 Linux进程管理: 进程与程序: 程序:存放在磁盘上的一系列代码 ...
- Linux进程管理知识整理
Linux进程管理知识整理 1.进程有哪些状态?什么是进程的可中断等待状态?进程退出后为什么要等待调度器删除其task_struct结构?进程的退出状态有哪些? TASK_RUNNING(可运行状态) ...
- Linux性能及调优指南(翻译)之Linux进程管理
本文为IBM RedBook的Linux Performanceand Tuning Guidelines的1.1节的翻译原文地址:http://www.redbooks.ibm.com/redpap ...
- 《Linux 性能及调优指南》1.1 Linux进程管理
https://blog.csdn.net/ljianhui/article/details/46718835 本文为IBM RedBook的Linux Performanceand Tuning G ...
随机推荐
- 10.Odoo产品分析 (二) – 商业板块(5) –日历(1)
查看Odoo产品分析系列--目录 日历模板也可以理解为一个日历视图,在分析"销售"模块的日历视图时做过介绍.在这里做一下详细的介绍: 从页面上,它横向分为两个部分,左边的80%显 ...
- mysql数据表的基本操作:表结构操作,字段操作
本节介绍: 表结构操作 创建数据表. 查看数据表和查看字段. 修改数据表结构 删除数据表 字段操作 新增字段. 修改字段数据类型.位置或属性. 重命名字段 删除字段 首发时间:2018-02-18 ...
- mac 下 ipython+notebook
python做数据分析相关的工具的安装和配置,以及numpy的入门 为什么要用PYTHON来做数据分析 MATLAB R语言,语法类似C语言,但是它在语义上是函数设计语言,也是开源的. python ...
- python leetcode 字符串相乘
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式. 示例 1: 输入: num1 = "2", num ...
- MySQL 基本语句(1)
一.cmd命令行的常用命令: 当我们使用MySQL 5.5 Command Line Client这个客户端登陆时,只能登陆root用户.如果今后创建了别的用户,就很麻烦了,所以我们不用MySQL 5 ...
- Nginx 出现 403 Forbidden 最终解决
Nginx 出现 403 Forbidden 最终解决 步骤一: 检查目录权限.权限不足的就加个权限吧. 例子:chmod -R 755 / var/www 步骤二: 打开nginx.conf 例子: ...
- 使用SQL Developer生成Oracle数据库的关系模型(ER图)
客户要一张数据库的关系模型图,于是用SQL Developer来做. 一.SQL Developer版本 我在官网下载的最新版本(现在已经到了18.1,Oracle更新的太勤快): 2.如下图所示选择 ...
- ASP.Net上传文件
在做Web项目时,上传文件是经常会碰到的需求.ASP.Net的WebForm开发模式中,封装了FileUpload控件,可以方便的进行文件上传操作.但有时,你可能不希望使用ASP.Net中的服务器控件 ...
- Python3 socket网络编程(一)
Socket的定义 套接字是为特定网络协议(例如TCP/IP,ICMP/IP,UDP/IP等)套件对上的网络应用程序提供者提供当前可移植标准的对象.它们允许程序接受并进行连接,如发送和接受数据.为了建 ...
- php学习----基本介绍及数据类型
php 官方手册:http://php.net/manual/zh/ 1.PHP(全称 Hypertext Preprocessor,超文本预处理器的字母缩写)是一种服务器端脚本语言,它可嵌入到 HT ...