chained_irq
[toc] include/linux/irqchip/chained_irq.hchained_irq_enter 链式中断进入123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869/* * 用于链式处理器的入口/出口函数,其中主IRQ芯片可能实现 * fasteoi或电平触发流控。 *//* * 这是一个静态内联函数,作为链式中断处理器的标准入口点。 * @chip: 指向顶层(父)中断的中断控制器芯片结构体。 * @desc: 指向顶层(父)中断的中断描述符。 */static inline void chained_irq_enter(struct irq_chip *chip, struct irq_desc *desc){ /* * 注释:FastEOI控制器在入口处无需任何操作。 * * 原理:检查...
irq_work
[toc] include/linux/irq_work.h__IRQ_WORK_INIT1234567#define __IRQ_WORK_INIT(_func, _flags) (struct irq_work){ \ .node = { .u_flags = (_flags), }, \ .func = (_func), \ .irqwait = __RCUWAIT_INITIALIZER(irqwait), \}#define IRQ_WORK_INIT(_func) __IRQ_WORK_INIT(_func, 0) kernel/irq_work.c IRQ上下文延迟工作(IRQ Context Deferred Work) 在安全时机执行来自中断的紧急任务历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/irq_work.c 实现的irq_work机制是为了解决一个非常特殊且棘手的内核同步问题:如何从一个“硬中断(Hard IRQ)”上下文中,安全地执行一个需要...
interrupt
[TOC] include/linux/interrupt.hor_softirq_pending 软中断待处理状态12345678DEFINE_PER_CPU_ALIGNED(irq_cpustat_t, irq_stat);EXPORT_PER_CPU_SYMBOL(irq_stat);#define local_softirq_pending_ref irq_stat.__softirq_pending#define local_softirq_pending() (__this_cpu_read(local_softirq_pending_ref))#define set_softirq_pending(x) (__this_cpu_write(local_softirq_pending_ref, (x)))#define or_softirq_pending(x) (__this_cpu_or(local_softirq_pending_ref, (x))) raise_timer_softirq 定时器软中断12345678static in...
softirq
[toc] kernel/softirq.c 内核中断下半部(Interrupt Bottom-Half) 核心实现历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/softirq.c 实现的软中断(softirq)机制是为了解决一个操作系统内核设计中的核心矛盾:中断处理程序的执行时间必须极短,但中断所触发的工作任务可能很耗时。 中断处理的紧迫性:硬件中断发生时,CPU会立即暂停当前工作,跳转到中断处理程序(Interrupt Service Routine, ISR,也称“上半部”/“Top Half”)。在执行ISR期间,通常会屏蔽掉当前CPU上的同级甚至所有中断,以保证处理的原子性和快速性。如果ISR执行时间过长,会导致系统无法响应其他新的硬件中断,增加系统延迟(Latency),甚至丢失中断事件。 任务的复杂性:然而,中断事件所触发的后续处理可能很复杂。例如,网卡收到一个数据包的中断,其后续处理包括解析协议栈、将数据包递交给上层应用等,这些都是耗时操作。 软中断机制就是为了将中断处理分割为两个部分而设计的: 上半部(Top H...
debug_locks
[TOC] debug_locks 各种锁的常用调试工具的通用位置: 自旋锁、rwlocks、mutex 和 rwsems。 debug_locks 的介绍debug_locks 是 Linux 内核中用于调试各种锁(如自旋锁、自读写锁、互斥锁和读写信号量)的工具。它提供了一种机制,用于检测锁的使用错误,并在发现问题时记录或报告相关信息。 特点 全局控制:通过全局标志 debug_locks,可以一次性启用或禁用所有锁的调试功能。 静默模式:支持通过 debug_locks_silent 实现“静默失败”,即在检测到锁错误时不打印任何信息到控制台。 原子操作:使用 xchg 等原子操作确保在多线程环境中安全地切换调试状态。 减少噪声:在检测到第一个锁错误后,可以关闭后续的调试输出,避免日志被大量错误信息淹没。 使用场景 锁错误检测: 在开发和调试阶段,用于检测锁的使用错误,例如死锁、锁未正确释放等问题。 适用于调试自旋锁(spinlock)、读写锁(rwlock)、互斥锁(mutex)和读写信号量(rwsem)等。 内核模块开发: 在开发内核模块时,debu...
local_lock
[toc] include/linux/local_lock.h Per-CPU数据锁(Lock for Per-CPU Data) 一种为保护Per-CPU数据而生的超轻量级锁历史与背景这项技术是为了解决什么特定问题而诞生的?local_lock是一种高度特化的、以性能为首要目标的锁,它的诞生是为了解决一个非常具体的问题:如何以最低的开销来保护Per-CPU(每CPU)数据。 Per-CPU数据是指内核为每个CPU都创建了一个独立副本的数据。理论上,一个CPU上的代码应该只访问自己的那份数据副本。在这种理想情况下,并发访问的来源只有两种: 抢占(Preemption):当前任务在访问Per-CPU数据时被一个更高优先级的任务抢占,而这个新任务也访问了同一个Per-CPU变量。 中断(Interrupts):一个硬中断或软中断在当前CPU上发生,其中断处理程序访问了同一个Per-CPU变量。 传统的解决方案是使用spinlock。但是,spinlock是为解决多CPU(SMP)间的并发而设计的,它涉及到昂贵的原子操作和可能导致缓存行争用的内存总线流量。...
mutex
[toc] kernel/locking/mutex.c 互斥锁(Mutex) 内核中基本的睡眠锁实现历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/locking/mutex.c 实现的互斥锁(Mutex,Mutual Exclusion)是为了解决多任务内核中一个最基础、最普遍的并发控制问题:如何确保一段代码(临界区)在任何时刻最多只能被一个执行绪(线程或进程)执行,从而保护共享数据的完整性。 在没有互斥机制的情况下,如果多个CPU上的任务同时访问和修改同一个共享数据(如一个链表),就会导致数据损坏、状态不一致、内存泄漏等各种灾难性的后果。 mutex被设计为一种睡眠锁(Sleeping Lock),专门用于解决**进程上下文(Process Context)**中的互斥问题。它的诞生是为了与另一种锁——**自旋锁(Spinlock)**形成互补: 自旋锁适用于中断上下文或保护极短的、不容许睡眠的临界区。获取不到锁的任务会“自旋”(忙等待),浪费CPU。 如果临界区比较长,或者在临界区内需要调用可能导致睡眠的函数(如kmalloc(...
rwsem
[TOC] kernel/locking/rwsem.c 读写信号量(Read-Write Semaphore) 内核中可睡眠的读写锁历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/locking/rwsem.c 实现的读写信号量(Read-Write Semaphore, rwsem)是为了解决rwlock_t(读写自旋锁)无法解决的一类“读多写少”场景的并发控制问题:当临界区的执行时间较长,或者在临界区内需要睡眠时,如何高效地进行读写并发控制。 rwlock_t是一个自旋锁,它要求临界区必须极短且绝对不能睡眠。然而,在内核的许多路径中(特别是与用户空间交互的系统调用),临界区可能很长,并且包含可能导致睡眠的操作(如copy_from_user、kmalloc(GFP_KERNEL)或等待I/O)。 rwsem正是为了这种可睡眠的、读多写少的场景而设计的。它是一个睡眠锁,提供了与rwlock_t相同的逻辑: 允许多个读者并发进入。 只允许一个写者独占进入。 读者和写者互斥。 当一个任务试图获取一个被占用的rwsem时,它不...
spinlock
[toc] kernel/locking/spinlock.c 自旋锁(Spinlock) 内核中最基础的高性能对称多处理器(SMP)锁历史与背景这项技术是为了解决什么特定问题而诞生的?自旋锁(Spinlock)是为了解决**对称多处理器(SMP)**系统中最基础的并发控制问题而诞生的:如何保护一段极短的、在任何执行上下文中都可能被访问的临界区。 在单处理器(UP)系统中,要保护一段临界区,最简单的方法是禁用本地中断。这样可以确保在执行临界区代码时,不会被中断处理程序打断,从而避免了并发。 然而,在多处理器(SMP)系统中,禁用本地CPU的中断并不能阻止另一个CPU同时执行并访问同一块共享数据。因此,需要一种CPU之间的互斥机制。自旋锁就是为此设计的最底层、最高效的锁。它主要解决: SMP互斥:提供一种在多个CPU之间进行互斥的机制。 原子上下文(Atomic Context)保护:中断处理程序、软中断、tasklet等上下文是不能睡眠的。自旋锁通过“忙等待”而不是“睡眠”来等待锁,因此它是唯一可以在这些原子上下文中安全使用的锁类型。 它的发展经历了...
rcu
[TOC] kernel/rcu Read-Copy Update (RCU) 高性能的内核同步机制历史与背景这项技术是为了解决什么特定问题而诞生的?Read-Copy Update (RCU) 技术的诞生,是为了解决在多核处理器系统中,对**读多写少(Read-mostly)**类型共享数据进行同步时遇到的性能瓶颈问题。 传统的同步机制,如读写锁(Reader-Writer Locks),虽然允许多个读者同时访问数据,但存在以下问题: 读者开销:即使是读取操作,读者也必须获取一个锁(或至少执行原子操作来增加引用计数)。在多核环境下,这会导致缓存行在CPU之间频繁“弹跳”(cache line bouncing),造成严重的性能下降和扩展性问题。 锁争用:当写者需要获取锁时,它可能会被已有的读者阻塞,或者需要等待新的读者完成。反之,写者持有锁时,所有读者都必须等待。这种争用在高并发读取场景下尤为突出。 RCU 的核心目标就是让读者几乎零开销(wait-free)。它允许读者在访问数据时完全不需要获取任何锁、自旋锁或执行原子指令,从而消除了读者端的同步开销和扩展...








