自旋锁 spin_lock、 spin_lock_irq 以及 spin_lock_irqsave 的区别

能够停留下来认真读这篇文章的人大部分都已经了解了什么是自旋锁,至少知道自旋锁就是不停的询问资源有没有准备好的一把锁,这个从概念上很容易理解,当然他的内在也是很容易实现。 目录 为什么需要自旋锁 很多时候我们并不能采用其他的锁,比如读写锁、互斥锁、信号量等。一方面这些锁会发生上下文切换,他的时间是不可…

Linux 通用块层之拥塞控制

目录 为什么需要拥塞控制 前面已经介绍了 Linux 操作系统通用块层中作为数据流动的关键因素 BIO,从软件的角度来讲,只要代码执行得够快,理论上就可以不停的下发数据让后端去执行。当然,都知道这是不可能的,首先局限于底层的硬件限制,磁盘速率一般也不超过 300MB/s,换成 SSD 的话会更快一下…

Linux 通用块层 bio 详解

Linux Block 层在 Linux 内核设计之初就作为几大子系统存在,当然这也是得益于他的前辈 Unix 等优秀的设计。作为 IO 子系统的中间层,他为上层输出接口,为下层提供数据,像个勤劳的小蜜蜂,本文介绍通用块层中的最具传奇色彩的 bio,他就像是一个原子,是在整个 block 层的最小单…

Linux 内核驱动模块强制卸载

Linux 内核尽管是一个大而全的宏内核,包括驱动、文件系统以及内存管理等都打包带走,但是其引以为豪的模块化设计也让他吸收到了微内核所带来的模块化设计思想。这里我们不讨论到底宏内核所带来的高性能和微内核带来的高稳定性等问题,仅仅从技术的角度探讨如何强制卸载一个已经不能通过正常手段卸载的 Linux …

devm_kmalloc 实现与使用

Linux 为驱动开发提供了专门的内存申请函数 kmalloc/kfree,但是偶尔有时候在内存申请完成之后或者设备卸载之后,这一段内存并没有被释放掉,从而导致内存泄露。或者在某些时候内存申请失败时,需要通过多个 goto 来保证不内存泄露,你一定见过类似的代码: int *data, *resou…

实现简单的 Linux 内核模块

Linux 内核包含了许多的驱动,这些驱动都是由一个个模块组合而成,那么怎么编写一个简单的内核驱动模块? 模块源码框架 内核的模块需要按照一定的框架进行搭建,通常情况下都需要模块入口和模块出口1。我们来演示一下怎么编写一个 Hello World 的模块。 #include <linux/mo…

ARM64 的 memcpy 优化与实现

如何优化 memcpy 函数 Linux 内核用到了许多方式来加强性能以及稳定性,本文探讨的 memcpy 的汇编实现方式就是其中的一种,memcpy 的性能是否强大,拷贝延迟是否足够低都直接影响着整个系统性能。通过对拷贝函数的理解可以加深对整个系统设计的一个理解,同时提升自身技术实力。 罗马不是一…

Linux 内核 Buddy 系统

Linux 的内存管理部分很复杂,涉及到了方方面面的原理,众所周知 Linux 内核由全世界各个地区的优秀工程师集智而成,所以这里面包含了许许多多的令人赞叹的设计,今天我们要来学习的伙伴系统就是这其中的臻品之一。在内核初始化完成之后,所有的内存申请与释放都交给了伙伴系统来完成,他就像是一个厨师,总是…

ARM64 芯片的 Jiffies 更新流程

最近在调试 arm64 机器时遇到了一个比较蛋疼的时钟问题,这个时钟问题会导致在部分机器类型上导致无法启动,为了深入了解并解决掉这个问题,特定决定研究一下整个 jiffies 的更新逻辑过程,本篇文章写于 site 上传之前的半年前,所以可能存在某些纰漏,检查也不够细致但是希望能够为后来者多少提供 …