1.开场白 环境: 处理器架构:arm64 内核源码:linux-5.11 ubuntu版本:20.04.1 代码阅读工具:vim+ctags+cscope 我们或许经常听说过内核抢占,可是我们是否真正理解它呢...内核抢占和抢占式内核究竟有什么关系呢?抢占计数器究竟干什么用?... 本文我们就来好好讨论下,关于内核抢占的一些技术细节,力求让大家理解内核抢占。 注:本文主要关注CFS调度类。...# uname -a Linux (none) 5.11.0-g08a3831f3ae1 #1 SMP PREEMPT Fri Apr 30 17:41:53 CST 2021 aarch64 GNU/...Linux 那什么是抢占式内核呢?...(Server)" help ¦ This is the traditional Linux preemption model, geared towards
为了彻底理解是什么使得Linux能正常运行以及其为何能在各种不同的系统中运行良好,你需要深入研究内核最本质的部分。内核处理CPU与外界间的所有交互,并且决定哪些程序将以什么顺序共享处理器时间。...《深入理解Linux内核,第三版》指导你对内核中使用的最重要的数据结构、算法和程序设计诀窍进行一次遍历。通过对表面特性的探究,作者给那些想知道自己机器工作原理的人提供了颇有价值的见解。...然而,本书涵盖的不仅仅是代码的功能,它解释了Linux以自己的方式工作的理论基础。 下载地址:深入理解Linux内核.pdf
用例1:linux系统中,当内存不足时,会唤醒kswapd内核线程来进行异步内存回收,下面我们来看他的创建过程: mm/vmscan.c kswapd_init ->for_each_node_state...(kswapd, pgdat, "kswapd%d", nid) //使用kthread_run结构创建并唤醒创建的内核线程 执行kswapd函数 用例2:Linux软中断是下半部的一种机制,一般对效率要求较高的场景会使用到...内核模块代码:kthread_demo.c #include #include #include #include... #include static struct task_struct *tsk; static int kthread_fn(...= ~/kernel/linux-5.11 obj-m := kthread_demo.o modules: $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules clean
1.开场白 环境: 处理器架构:arm64 内核源码:linux-5.11 ubuntu版本:20.04.1 代码阅读工具:vim+ctags+cscope 在linux系统中, 我们接触最多的莫过于用户空间的任务...,像用户线程或用户进程,因为他们太活跃了,也太耀眼了以至于我们感受不到内核线程的存在,但是内核线程却在背后默默地付出着,如内存回收,脏页回写,处理大量的软中断等,如果没有内核线程那么linux世界是那么的可怕...2.kthreadd的诞生 盘古开天辟地,我们知道linux所有任务的祖先是0号进程,然后0号进程创建了天字第一号的1号init进程,init进程是所有用户任务的祖先,而内核线程同样也有自己的祖先那就是...可以看到,kthread函数用到了一些完成量和睡眠函数,如果单独看这个函数肯定会一头雾水,要理解这个函数需要回答一下几个问题...调用路径如下: include/linux/kthread.h #define kthread_run(threadfn, data, namefmt, ...
1.开场白 环境: 处理器架构:arm64 内核源码:linux-5.10.50 ubuntu版本:20.04.1 代码阅读工具:vim+ctags+cscope 前面文章,我们介绍了进程是如何睡眠,本文来揭开进程唤醒的神秘面纱...进程唤醒主要应用场景如下: fork的时候唤醒子进程 exec的时候唤醒进程 睡眠超时唤醒 睡眠锁释放唤醒 IO读写完成唤醒 其他正常的唤醒路径 注:应用场景在此不再分析,感兴趣的小伙伴可以自行查阅内核源代码...preempt.need_resched = 0),这是因为本地cpu一定不是idle状态(因为本地cpu正在做唤醒操作),而远程cpu可能处于idle状态,需要发生ipi来唤醒远程cpu处理重新调度(在中断处理返回内核态前夕就可以发生调度了...resched_curr主要用于设置重新调度标志和抢占重新调度标志,会考虑是本地cpu还是远程cpu的情况,并不是发生调度,需要等到最近的调度点到来时发生调度(可能是重新开启抢占的时候,也可能是中断返回前夕,见之前讲解到的内核抢占相关文章
【Linux内核锁】二、中断屏蔽 1、中断屏蔽思想 中断屏蔽,正如其名,屏蔽掉CPU的中断响应功能,解决并发引起的竞态问题。 在进入临界区前屏蔽中断,这么做有什么好处,以及有什么弊端?...弊端在于: Linux内核中,除了系统进程调度依赖中断,还有一些异步I/O等众多操作都依赖中断,因此长时间屏蔽中断是很危险的,会对系统造成严重影响,因此也要求临界区代码要简短。...因此,并不能解决SMP多CPU引发的竞态 因此,单独使用中断屏蔽通常不是一种值得推荐的避免竞态的方法 2、Linux内核中断屏蔽的实现 2.1 Linux内核提供的API接口 关于中断屏蔽,Linux内核所提供的接口如下...3、总结 该篇文章,主要了解以下几点: 中断屏蔽的思想 中断屏蔽的好处与不足 Linux内核提供的中断屏蔽接口 中断屏蔽的基本汇编实现
1开场白 环境: 处理器架构:arm64 内核源码:linux-5.10.50 ubuntu版本:20.04.1 代码阅读工具:vim+ctags+cscope 无论是任务处于用户态还是内核态,经常会因为等待某些事件而睡眠...主要讲解以下内容: 睡眠的三种状态 睡眠的内核原理 用户态睡眠 内核态睡眠 总结 2....这里给出被致命信号打断/唤醒的代码路径: include/linux/sched.h #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE...来看下freezable_schedule: //include/linux/freezer.h freezable_schedule ->schedule() ->__schedule(false...5.内核态睡眠 当任务处于内核态时,有时候也需要睡眠一段时间,不像任务处于用户态需要发生系统调用来请求内核进行睡眠,在内核态可以直接调用睡眠函数。
【深入理解Linux内核锁】三、原子操作 1、原子操作思想 原子操作(atomic operation),不可分割的操作。...同时,Linux内核提供了两类原子操作的接口,分别是针对位和整型变量的原子操作。...内核源码4.19,刚看是看的时候,有点摸不着头脑,因为定义的地方和引用的地方较多,不太容易找到,后来才慢慢得窥门径。...:( 原来内核通过各种宏定义将其操作全部管理起来,宏定义在内核中的使用也是非常广泛了。...内核锁的原子操作,原子操作分为两种:整型变量的原子操作和位原子操作。
来看下freezable_schedule: //include/linux/freezer.h freezable_schedule ->schedule() ->__schedule(false...总结:处于用户态的任务,如果想要睡眠一段时间必须向内核请求服务(如调用clock_nanosleep系统调用),内核中会设置一个高精度定时器,来记录要睡眠的任务,然后设置任务状态为可中断的睡眠状态,紧接着发生主动调度...5.内核态睡眠 当任务处于内核态时,有时候也需要睡眠一段时间,不像任务处于用户态需要发生系统调用来请求内核进行睡眠,在内核态可以直接调用睡眠函数。...进程睡眠按照进程所处的特权级别可以分为:用户态进程睡眠和内核态进程睡眠,用户态进程睡眠需要进程通过系统调用陷入内核来发起睡眠请求。...对于进程睡眠,内核主要需要做三大步操作:1.设置任务状态为睡眠状态 2.记录睡眠的任务 3.发起主动调度。
1.开场白 环境: 处理器架构:arm64 内核源码:linux-5.10.50 ubuntu版本:20.04.1 代码阅读工具:vim+ctags+cscope Linux内核由于存在page...脏页跟踪是指内核如何在合适的时机记录文件页为脏,以便内核在进行脏页回写时,知道将哪些页面回写到磁盘。...在Linux内核中,因为跟踪脏页会涉及到文件回写、缺页异常、反向映射等技术,所以本文也重点讲解在Linux内核中如何跟踪脏页。
1开场白 环境: 处理器架构:arm64 内核源码:linux-5.10.50 ubuntu版本:20.04.1 代码阅读工具:vim+ctags+cscope 无论是任务处于用户态还是内核态,经常会因为等待某些事件而睡眠...内核是如何管理睡眠的任务的?我们会结合内核源代码来分析任务的睡眠,力求全方位角度来剖析。 注:由于篇幅问题,文章分为上下两篇,且这里不区分进程和任务,统一使用任务来表示进程。...主要讲解以下内容: 睡眠的三种状态 睡眠的内核原理 用户态睡眠 内核态睡眠 总结 2....这里给出被致命信号打断/唤醒的代码路径: include/linux/sched.h #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE...如延迟睡眠场景,内核将即将睡眠的任务记录在定时器相关的数据结构中;可睡眠的信号量场景中,内核将即将睡眠的任务加入到信号量的相关链表中。
开场白 环境: 处理器架构:arm64 内核源码:linux-6.6.29 ubuntu版本:20.04.1 代码阅读工具:vim+ctags+cscope 本文主要介绍内存管理中的HVO(HugeTLB...本文通过图解结合源代码分析的方式让大家彻底理解HVO的实现原理,且本文主要以2M大小的HugeTLB 页面为例讲解。...2.HVO优化原理及触发场景 2.1 HVO优化原理 下面我们从内核源码角度来看以下HVO优化原理。...2M大小的hugetlb页面,释放掉8页(page0-page7)) ->SetHPageVmemmapOptimized(head) //为hugetlb页面设置HVO优化标记,定义在include/linux...像这些描述尾页的struct page,被成为"伪造的头页",内核中处理如下(page_folio为例): include/linux/page-flags.h page_folio ->_compound_head
1开场白 环境: 处理器架构:arm64 内核源码:linux-5.10.50 ubuntu版本:20.04.1 代码阅读工具:vim+ctags+cscope 本文讲解Linux内核虚拟内存管理中的mmu_gather...2.源代码解读 2.1 重要数据结构体 首先我们先介绍一下,与mmu-gather相关的一些重要结构体,对于理解源码很有帮助。...,不能占用太多的内核栈空间,而多批次由于动态分配批次积聚结构所以每个批次能积聚更多的页面。...2.3 tlb_gather_mmu 这个函数主要是初始化从进程内核栈中传递过来的mmu_gather结构。...内核mmu-gather用于积聚解除映射的相关物理页面,并保证了刷tlb和释放物理页面的顺序。
我们以Read为例,当程序中发起了一个Read请求后,操作系统会将数据从内核缓冲区加载到用户缓冲区,如果内核缓冲区内没有数据,内核会将该次读请求追加到请求队列,当内核将磁盘数据读取到内核缓冲区后,再次执行读请求...[c98d68d5abd1af03f77a0909fa016768.png] NIO底层在JDK1.4版本是用linux的内核函数select()或poll()来实现,跟上面的NioServer代码类似...深入 底层概念解析 select模型 如果要深入分析NIO的底层我们需要逐步的分析,首先,我们需要了解一种叫做select()函数的模型,它是什么呢?...这点比较难理解,注意是将EPFD(Epoll文件描述符)放到Socket的等待队列!...在Linux系统上,AIO的底层实现仍使用Epoll,没有很好实现AIO,因此在性能上没有明显的优势,而且被JDK封装了一层不容易深度优化,Linux上AIO还不够成熟。
1.开场白 环境: 处理器架构:arm64 内核源码:linux-5.11 ubuntu版本:20.04.1 代码阅读工具:vim+ctags+cscope 本文步进到Linux内核进程管理的核心部分,...打开调度器的黑匣子,来看看Linux内核如何调度进程的。...static void __sched notrace __schedule(bool preempt) 我们对注释做出解释,让大家深刻理解调度时机...首先需要知道一点是:内核抢占说的是处于内核态的任务被其他任务所抢占的情况(无论是不是可抢占式内核,处于用户态的任务都可以被抢占,处于内核态的任务是否能被抢占由是否开启内核抢占来决定),当然内核态的任务可以是内核线程也可以是通过系统调用请求内核服务的用户任务...从中断处理器返回到用户空间 可抢占式内核(增加一些抢占点) 重新开启内核抢占 中断返回内核态的时候 3.主调度器调用时机源码窥探 下面给出主要的一些主调度器调用时机源码分析,作为学习参考。
我们以Read为例,当程序中发起了一个Read请求后,操作系统会将数据从内核缓冲区加载到用户缓冲区,如果内核缓冲区内没有数据,内核会将该次读请求追加到请求队列,当内核将磁盘数据读取到内核缓冲区后,再次执行读请求...NIO底层在JDK1.4版本是用linux的内核函数select()或poll()来实现,跟上面的NioServer代码类似,selector每次都会轮询所有的sockchannel看下哪个channel...深入 底层概念解析 select模型 如果要深入分析NIO的底层我们需要逐步的分析,首先,我们需要了解一种叫做select()函数的模型,它是什么呢?...这点比较难理解,注意是将EPFD(Epoll文件描述符)放到Socket的等待队列! ?...在Linux系统上,AIO的底层实现仍使用Epoll,没有很好实现AIO,因此在性能上没有明显的优势,而且被JDK封装了一层不容易深度优化,Linux上AIO还不够成熟。
NIO底层在JDK1.4版本是用linux的内核函数select()或poll()来实现,跟上面的NioServer代码类似,selector每次都会轮询所有的sockchannel看下哪个channel...深入底层源码分析 如果要深入分析NIO的底层我们需要逐步的分析,首先,我们需要了解一种叫做select()函数的模型,它是什么呢?...这是个什么鬼,我来给大家解释一下,文件描述符是linux内核为了高效管理已被打开的文件所创建的索引,用于指向被打开的文件,所有执行I/O操作的系统调用都通过文件描述符;文件描述符是一个简单的非负整数,用以表明每个被进程打开的文件...内核里面的函数了,都已经看到这么底层了,不看到它的这个函数的用法实属不甘心,好在linux是开源的,而我们正好可以通过linux的man命令来查看这个函数的用法 ?...好啦,我们上面分析了这么多,就为了分析Selector.open()方法的作用,那我这里简单总结一下它的作用 它的作用就是在linux的内核创建了个Epoll实例,也就是创建了个多路复用器 那么接下来继续分析第二个核心方法
一,前言本文是“Linux内核分析”系列文章的第一篇,会以内核的核心功能为出发点,描述Linux内核的整体架构,以及架构之下主要的软件子系统。...注:本文和其它的“Linux内核分析”文章都基于如下约定:a) 内核版本为Linux 3.10.29(该版本是一个long term的版本,会被Linux社区持续维护至少2年)。...b) 鉴于嵌入式系统大多使用ARM处理器,因此涉及到体系结构部分的内容,都以ARM为分析对象二,Linux内核的核心功能如下图所示,Linux内核只是Linux操作系统一部分。...所以为了管理这些设备,Linux内核提出了如下的架构。三,Linux内核的整体架构3.1 整体架构和子系统划分 上图说明了Linux内核的整体架构。...四,Linux内核源代码的目录结构Linux内核源代码包括三个主要部分: 1. 内核核心代码,包括第3章所描述的各个子系统和子模块,以及其它的支撑子系统,例如电源管理、Linux初始化等 2.
,如果是则不需要进行地址空间切换(实际上指的是用户地址空间),因为内核线程总是运行在内核态访问的是内核地址空间,而内核地址空间是所有的进程共享的。...在arm64架构中,内核地址空间是通过ttbr1_el1来访问,而它的主内核页表在内核初始化的时候已经填充好了,也就是我们常说的swapper_pg_dir页表,后面所有对内核地址空间的访问,无论是内核线程也好还是用户任务...2.虽然做了这样的切换,但是这个时候并不能访问到next的用户地址空间,因为还处在主调度器上下文中,属于内核态,访问的是内核空间。..., next, prev) -> ((last) = __switch_to((prev), (next))) 这里做处理器状态切换时,传递了两个参数,返回了一个参数: prev和next很好理解就是...总结 主调度器可以说Linux内核进程管理中的核心组件,进程管理的其他部分如抢占、唤醒、睡眠等都是围绕它来运作。
作者简介 韩传华,就职于南京大鱼半导体有限公司,主要从事linux相关系统软件开发工作,负责Soc芯片BringUp及系统软件开发,乐于分享喜欢学习,喜欢专研Linux内核源代码。...本文主要关注进程管理的一个切入点,那就是进程的上下文切换,来理解linux内核是如何进程进程上下文切换的,从而揭开上下文切换的神秘面纱。...(注意:本文以linux-5.0内核源码讲解,采用arm64架构) 1.进程上下文的概念 进程上下文是进程执行活动全过程的静态描述。...实际上linux内核中,进程上下文包括进程的虚拟地址空间和硬件上下文。...switch_mm_irqs_off //进程地址空间切换 ->switch_to //处理器状态切换 2.1 进程地址空间切换 进程地址空间指的是进程所拥有的虚拟地址空间,而这个地址空间是假的,是linux
领取专属 10元无门槛券
手把手带您无忧上云