《深入Linux内核架构》第2章 进程管理和调度 (6)

 目录

 2.8 调度器增强

2.8.1 SMP调度

2.8.2 调度域和控制组

2.8.3 内核抢占和低延迟相关工作

2.9 小结


本专栏文章将有70篇左右,欢迎+关注,订阅后续文章。

2.8 调度器增强

2.8.1 SMP调度

进程迁移:

        含义:把进程从一个CPU就绪队列迁移至另一个CPU就绪队列。

        作用:CPU负荷均衡。

        缺点:缓存失效,危害性能。

设置进程的亲和力affinity,控制进程可在哪些CPU上运行。

对应系统调用:

        long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)

                最终设置task_struct->cpus_allowed成员。

CPU就绪队列中SMP部分:

struct rq {#ifdef CONFIG_SMPstruct sched_domain *sd;                   //调度域int active_balance;                       //是否正在进行负载均衡int push_cpu;                             //迁移目标CPUint cpu;                                  //当前就绪队列所在CPUstruct task_struct *migration_thread;     //执行迁移的线程struct list_head migration_queue;         //迁移请求链表#endif}

调度类中SMP相关函数指针:

struct sched_class {  void (*set_cpus_allowed)(struct task_struct *p, struct cpumask *newmask);//设置进程CPU 亲和力(affinity),即确定进程可运行在哪些CPU。void (*migrate_task_rq)(struct task_struct *p, int next_cpu);     //将进程迁移到指定的CPU上运行。int (*select_task_rq)(struct task_struct *p, int sd_flag, int flags);//根据进程亲和性,系统负载平衡策略等为进程选择一个合适的CPU运行队列。}

周期调度中关于SMP部分:

void scheduler_tick(void){#ifdef CONFIG_SMPrq->idle_balance = idle_cpu(cpu);trigger_load_balance(rq, cpu);     //每次时钟中断都进行CPU负载均衡#endif}void trigger_load_balance(struct rq *rq, int cpu){raise_softirq(SCHED_SOFTIRQ);}//open_softirq(SCHED_SOFTIRQ, run_rebalance_domains);//SCHED_SOFTIRQ软中断处理函数run_rebalance_domains:static void run_rebalance_domains(struct softirq_action *h)
{rebalance_domains(this_cpu, idle);}//进行调度域内部CPU之间的负载均衡。

然后调用rebalance_domains -> load_balance,进行负载均衡操作。

load_balance:

        比较struct rq的进程总负荷,寻找最忙CPU,执行对应调度类的load_balance函数。

刚exec启动新进程时,适合跨CPU迁移,此时缓存影响小。

已运行的进程不适合迁移,因为刚准备的缓存立马失效,降低性能。

根据进程的亲和力决定迁移目标CPU。

2.8.2 调度域和控制组

调度域:

        含义:将所有CPU分为若干调度域,每个调度域管理一组CPU。

        特点:同一调度域的所有CPU具有相同属性和调度策略。

调度域分组依据:物理距离,共享cache,拓扑结构,亲和性等。

        如物理临近或共享cache的CPU组成一个调度域。

不同调度域是树状结构,顶层调度域包含所有CPU,而下层调度域是对CPU子集的分组。

五个调度域层级:

        All NUMA Domain

        NUMA Domain

        Phy Domain

        Core Domain

        CPU Domain(SMT Domain)

 对应树形结构:

如一个CPU被分到两个调度域,每个调度域有自己的调度策略。

对应有两个目录:

        1. /proc/sys/kernel/sched_domain/cpuX/domain0/

        2. /proc/sys/kernel/sched_domain/cpuX/domain1/

       两个目录下有多个参数,包括:

                两次负载均衡最大/最小间隔, 调度域是否繁忙,最小不平衡值等

#cat /proc/sys/kernel/sched_domain/cpu9/domain0/name

        MC //MC域,即Multi-Core

#cat /proc/sys/kernel/sched_domain/cpu9/domain1/name

        NUMA //NUMA域

进程迁移时,优先在调度域内部迁移,应减少跨NUMA迁移。

控制组:cgroup

        管理一组进程的使用资源。如CPU,内存,磁盘IO,网络带宽等。

        cgroup可把进程按用户分组, 也可任意进程组合分组。

2.8.3 内核抢占和低延迟相关工作

内核抢占:

        内核任务执行时被更高优先级的任务打断,从而允许更高优先级的任务立即执行。

并不是任意时候都可以抢占当前内核任务。

禁止内核抢占时机:

        当前任务处于关键时机,不能被中断。如:

        ​1、访问 Per-CPU数据时 。(防止smp_processor_id改变)

        ​2、访问CPU state。

        3、持有spinlock时。(如果允许内核抢占可能造成死锁。)

内核中如何判断当前任务是否可被抢占?

        进程struct thread_info中preempt_count:

                等于0,可被抢占。(退出最后一个临界区后为0)

                大于0,禁止抢占。(可嵌套递归进入多个临界区)

void __raw_spin_lock(raw_spinlock_t *lock)

{

        preempt_disable(); //进入临界区后,将preempt_count+1,实现禁止内核抢占。

        ...

}

void __raw_spin_unlock(raw_spinlock_t *lock)

{

        ...

        preempt_enable(); //释放锁后,将preempt_count-1,允许内核抢占。

}

#define preempt_enable() \do { \preempt_enable_no_resched(); //将preempt_count - 1barrier(); \preempt_check_resched(); \         //定义如下} while (0)#define preempt_check_resched() \do { \if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \preempt_schedule(); \      //执行抢占,让出CPU,调度其他进程。} while (0)

thread_info中flag的TIF_NEED_RESCHED标志:

        用于指示当前进程需要被抢占,让出CPU,让其他进程执行。

什么时候设置当前进程的TIF_NEED_RESCHED标志?

        1、进程被唤醒时,若有更高优先级进程需要执行。

        ​2、创建新进程时,若新进程优先级高于当前进程。

        ​3、进程修改进程的nice值时,导致优先级高于当前进程。

执行内核抢占前,都检查TIF_NEED_RESCHED标志。若置位,调用对应适用的抢占函数。

抢占时机总结:

        ​ 1. 中断处理程序返回内核态时:

                preempt_schedule_irq执行抢占。

        2. ​调用preempt_enable允许抢占时。

                调用preempt_schedule()执行抢占。

        ​3. 显式调用schedule函数。

        ​4. 阻塞/睡眠时。

preempt_schedule_irq和preempt_schedule函数都最终调用_schedule()

访问per-CPU变量时,也需要禁止内核抢占,防止一个CPU读时,另一个CPU写。

#define get_cpu()         ({ preempt_disable(); __smp_processor_id(); })#define put_cpu()         preempt_enable()

获取当前运行进程所在CPU

#define raw_smp_processor_id()  (current_thread_info()->cpu)

int preempt_count,32位。

preempt_count中的bit 27就是PREEMPT_ACTIVE值。

PREEMPT_ACTIVE:

        表明内核抢占已被激活。即使preempt_count的其他部分大于0。(例如,进入一个不可抢占的区域),内核仍然可以响应更高优先级的任务或信号。

2.9 小结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/623395.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BCLinux8U6系统基线加固致无法su的问题分析

本文对BCLinux8U6系统进行基线加固致无法su的问题分析。 一、问题现象 对BCLinux8U6系统进行基线加固,su切换用户失败,报错信息如下: [ABCDlocalhost ~]$ su - 密码: su: 模块未知 二、问题分析 1、错误排查 出错前&#xf…

CubelMX点灯

工程配置 开发板led引脚图 工程io配置 配置PB5 为输出 配置 PE5 为输出 时钟配置 写测试代码 配置工程,下载运行。 参考链接 STM32入门教程-1.点灯_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1dC41147eL/?spm_id_from333.788&vd_sourcee821a225c7b…

为什么需要网络切片?

网络切片是电信领域的一个突破性概念,它允许将物理网络基础设施划分为多个虚拟网络,称为切片。每个切片作为一个独立的网络运行,拥有自己的专用资源和定制的特性,满足不同应用、行业或用户的特定需求。 将网络切片视为在共享物理…

Redis-键值设计

Redis-键值设计 1.设置key的规范 遵循基本格式:【业务名称】:【数据名】:【id】 可读性强,在客户端的情况下使用:如果前缀相同会分目录层级长度不超过44字节 string数据结构的三种类型,在44字节之内是embstring 内存…

栈的解释和实现

目录 1.栈的基本概念: 2. 栈的基本功能: 3.栈的实现: 3.1 存储结构:(顺序表) 3.2 初始化:(void StackInit(stack*tmp)) 3.3 栈的销毁:(void …

ObjectiveC-第一部分-基础入门-学习导航

专题地址:MacOS一站式程序开发系列专题 第一部分:基础入门学习导航 OSX-01-Mac OS应用开发概述:简单介绍下MacOS生态、Xcode使用以及使用Xcode创建app的方法OSX-02-Mac OS应用开发系列课程大纲和章节内容设计:介绍下此系列专题的文章内容组织形式以及此系列专题的覆盖内容…

Midjourney简明教程 - 合集

Midjourney简明教程(一):有关Midjourney的基本信息 AI绘画 绘画是人类一门很古老的艺术门类,人类通过实体的器具、画笔、颜色、颜料等反映客观世界和表达主观世界。 而AI绘画则是通过借助就计算机机器学习算法和模型来生成绘画…

Docker篇(三)— Docker的基本操作

目录 镜像操作镜像名称镜像命令案例1-拉取、查看镜像案例2-保存、导入镜像 镜像操作 镜像名称 首先来看下镜像的名称组成: 镜名称一般分两部分组成:[repository]:[tag]。在没有指定tag时,默认是latest,代表最新版本的镜像 如图…

便宜的ov ssl证书推荐

SSL证书是由正规证书颁发机构(CA)颁发的数字证书产品,它可以为网络中明文传输的数据增加一个安全套接层,佳明传输信息,还能对服务器身份进行认证,防止信息传输对象错误。OV企业型SSL证书是一种受到广泛认可的证书类型,…

代码随想录阅读笔记-回溯【分割回文串】

题目 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。 返回 s 所有可能的分割方案。 示例: 输入: "aab" 输出: [ ["aa","b"], ["a","a","b"] ] 思路 本题这涉及到两个关…

OLAP引擎优缺点简单对比

总结: 数据压缩率Clickhouse好;ClickHouse单表查询性能优势巨大;Join查询两者各有优劣,数据量小情况下Clickhouse好,数据量大Doris好;Doris对SQL支持情况要好;

PHP婚恋小程序开发源码支持微信+公众号+APP

随着社会的发展和人们生活节奏的加快,传统的相亲方式已经不能满足现代人的需求。在此背景下,有人想到通过线上小程序的方式来满足更多的人进行相亲,所以在此情况下,婚恋相亲小程序由此出现。婚恋相亲小程序的功能有会员功能&#…