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加1barrier(); \ } while (0)#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 (0)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.138-rt155-custom # -------------------------------------------------------------------- # latency: 628 us, #39/39, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:8) # ----------------- # | task: gnome-shell-1775 (uid:1000 nice:0 policy:0 rt_prio:0) # ----------------- # => 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-1775 0....21. 41us!: preempt_count_sub <-_raw_spin_unlock_irq gnome-sh-1775 0....11. 627us : pin_current_cpu <-migrate_disable gnome-sh-1775 0....111 628us : preempt_count_sub <-migrate_disable gnome-sh-1775 0....111 628us : migrate_disable <-migrate_disable gnome-sh-1775 0....111 629us+: trace_preempt_on <-migrate_disable gnome-sh-1775 0....111 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进程管理专题
Linux进程管理 (1)进程的诞生介绍了如何表示进程?进程的生命周期.进程的创建等等? Linux支持多种调度器(deadline/realtime/cfs/idle),其中CFS调度器最常见.Li ...
- Linux进程管理及作业控制(转)
Linux是一个多任务的操作系统,系统上同时运行着多个进程,正在执行的一个或多个相关进程称为一个作业.使用作业控制,用户可以同时运行多个作业,并在需要时在作业之间进行切换.本章详细介绍进程管理及作业控 ...
- Linux 进程管理与调度
引言 本文整理了 Linux 内核中进程管理与调度的相关知识.更多相关文章和其他文章均收录于贝贝猫的文章目录. 进程管理与调度 现代操作系统都能同时运行多个进程,至少从用户的角度来看是这个样子的.每一 ...
- linux 的 swapper 进程不能sleep,Linux进程管理与调度.ppt
Linux进程管理与调度 关于进程与线程Linux进程实现Linux进程调度策略Linux进程调度实现 1Linux进程与线程 Linux进程Linux线程 进程作为资源分配的基本单位而存在 线程作为 ...
- Linux进程管理与调度-之-目录导航【转】
转自:http://blog.csdn.net/gatieme/article/details/51456569 版权声明:本文为博主原创文章 && 转载请著名出处 @ http:// ...
- Linux—进程管理
1. 进程的概念 Linux是一个多用户多任务的操作系统.多用户是指多个用户可以在同一时间使用同一个linux系统:多任务是指在Linux下可以同时执行多个任务,更详细的说,linux采用了分时管理的 ...
- linux进程管理子系统分析,linux进程管理子系统简要分析
Linux进程管理: 进程与程序: 程序:存放在磁盘上的一系列代码和数据的可执行映像,是一个静止的实体. 进程:是一个执行中的程序,它是动态的实体 进程四要素: 1. 有一段程序供其执行,这段程序不一 ...
- Linux进程管理+内存管理:进程切换的TLB处理(ASID-address space ID、PCID-process context ID)
目录 一.前言 二.单核场景的工作原理 1.block diagram 2.绝对没有问题,但是性能不佳的方案 3.如何提高TLB的性能? 4.特殊情况的考量 4.进一步提升TLB的性能 - ASID( ...
最新文章
- 【硬核书】树与网络上的概率
- 三层架构的原理及实现
- 直击Kafka的心脏——控制器
- 怎么查MATLAB中的newrbf,已经有了输入输出数据,如何在matlab中建立RBF神经网络
- 科维PLC运行时系统ProConOS embedded CLR 2.2 特定应用
- mysql 密码修改时间_Mysql修改密码的方法
- Cron表达式的正则表达式
- HDU-1671 Phone List 暴力版 + 字典树
- 饿了么合并百度外卖,ThinkSNS:产品上线要趁早
- 程序员专属段子集锦 6/10
- 京东店铺怎么运营 掌握这些京东运营知识很有必要!
- 联想台式计算机 不启动u盘,联想电脑没有u盘启动项怎么回事_联想电脑bios没有U盘启动项如何处理-系统城...
- C Primer Plus(6) 中文版 第6章 C控制语句:循环 6.2 while语句
- win10系统安装教程(U盘PE+UEFI安装)
- VUE post请求下载文件
- Organon将收购Forendo Pharma
- Java实现 LeetCode 492 构造矩形
- 可变形卷积系列(三) Deformable Kernels,创意满满的可变形卷积核 | ICLR 2020
- mysql 的capi预处理
- SQL Server 2005 连接到服务器失败解决方案
热门文章
- 英特尔、高通争战物联网芯片 下个霸主会是谁
- smo算法matlab实现
- php 多维数组排序_已迁移
- VMware Workstation 6.0全貌概览
- python popen阻塞_对Python subprocess.Popen子进程管道阻塞详解
- android下载后的app自动安装,Android 7.0 下载APK后自动安装
- Redis之单线程 Reactor 模型
- H5-Dooring可视化搭建平台的新技能
- 回车的ascii码_ASCII码表
- C - Group HDU - 4638[离线+树状数组]