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...
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控制器在入口处无需任何操作。 * * 原理:检查...
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)间的并发而设计的,它涉及到昂贵的原子操作和可能导致缓存行争用的内存总线流量。...
clocksource
[toc] kernel/time/clocksource.c 时钟源管理(Clocksource Management) 内核时间的原始动力历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术是为了在Linux内核中创建一个统一的、可插拔的硬件时钟源抽象层。内核需要一个可靠的方式来读取时间的流逝,而不同的硬件平台提供了种类繁多的硬件定时器/计数器,例如x86上的TSC和HPET,ARM上的System Counter等。这些硬件在精度、稳定性、访问开销等方面都千差万别。 kernel/time/clocksource.c的诞生就是为了解决这个硬件异构性的问题: 抽象硬件差异:它提供了一个标准的struct clocksource接口,将所有不同硬件定时器的具体实现(如如何读取其计数器)封装起来,为上层的timekeeping子系统提供一个统一的、与硬件无关的视图。 选择最佳时钟源:系统中可能同时存在多个可用的时钟源。内核需要一种机制来评估它们各自的优劣(基于频率、分辨率、稳定性等),并从中自动选择一个最佳的来驱动整个系统的时间。 保证...
hrtimer
[toc] kernel/time/hrtimer.c 高精度定时器(High-Resolution Timers) 纳秒级精度的事件调度历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/time/hrtimer.c 实现了**高精度定时器(High-Resolution Timers)框架,它的诞生是为了解决内核中日益增长的、对亚毫秒级(sub-millisecond)甚至纳秒级(nanosecond)**定时精度的需求。 传统的jiffies定时器(timer_list)虽然开销极低,但其精度受限于系统的心跳频率HZ(通常在4ms到10ms之间)。这对于许多现代应用来说是完全不够的: 用户空间API支持:POSIX标准定义了nanosleep()、clock_nanosleep()和高精度POSIX定时器,这些API要求内核能够提供远超jiffies精度的定时能力。 多媒体与音频:专业的音频应用为了实现低延迟处理,需要在非常精确的时间点(例如每1-2毫秒)被唤醒来填充声卡缓冲区。 网络与金融:高频交易和某些低延迟网络协议需要对超时进行...
time
[TOC] include/linux/ktime.hktime_set 从秒/纳秒值设置ktime_t变量123456789101112131415161718192021222324252627/** * ktime_set - 从秒/纳秒值设置ktime_t变量 * @secs:秒设置 * @nsecs:纳秒设置 * * 返回:值的ktime_t表示形式。 */static inline ktime_t ktime_set(const s64 secs, const unsigned long nsecs){ if (unlikely(secs >= KTIME_SEC_MAX)) return KTIME_MAX; return secs * NSEC_PER_SEC + (s64)nsecs;}/* Subtract two ktime_t variables. rem = lhs -rhs: */#define ktime_sub(lhs, rhs) ((lhs) - (rhs))/* Add two k...
timekeeping
[toc] kernel/time/timekeeping.c 内核时间保持(Kernel Timekeeping) 维护系统时间的核心与灵魂历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术是为了解决操作系统中最基础、最核心的需求之一:以一种精确、稳定、单调的方式来跟踪和维护时间的流逝。 kernel/time/timekeeping.c所管理的时间保持子系统,具体解决了以下几个关键问题: 时间的表示与更新:需要一个核心机制来管理系统的“官方时间”。这包括“墙上时间”(Wall Time,即CLOCK_REALTIME,自1970年Epoch以来的时间,可以被用户或NTP修改),以及“单调时间”(Monotonic Time,即CLOCK_MONOTONIC,从系统启动开始单调递增,不受时间调整影响)。 时钟源的抽象:硬件提供了各种各样的时间源(Clock Sources),例如TSC(CPU的时间戳计数器)、HPET(高精度事件定时器)、ACPI PM Timer等。这些时钟源的精度、稳定性和访问速度各不相同。时间保持子系统需要一个框架来抽...
timer
[toc] kernel/time/timer.c 传统内核定时器(Legacy Kernel Timers) 基于jiffies的通用定时机制历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/time/timer.c 实现了Linux内核中最传统、最通用的低分辨率定时器机制。它的诞生是为了解决内核中一个无处不在的需求:以一种低开销、非阻塞的方式,安排一个函数在未来的某个时间点被执行。 在内核的许多代码路径中,尤其是在与硬件交互时,都需要处理超时。例如: 设备驱动:一个驱动向设备发送一个命令后,不能无限期地等待其响应。它需要设置一个超时,如果在指定时间内没有收到响应,就必须进行错误处理。 网络协议栈:TCP协议在发送一个数据段后,会启动一个重传定时器。如果在规定时间内没有收到对方的确认(ACK),定时器到期后就会重新发送该数据段。 周期性轮询:某些简单的驱动可能需要周期性地检查硬件状态。 timer.c 提供的struct timer_list接口,就是为了满足这些**对精度要求不高(毫秒级)**的通用定时需求而设计的。 它的发展经历了...
jiffies
[toc] kernel/time/jiffies.c 内核心跳(Kernel Heartbeat) 低分辨率定时器的基础历史与背景这项技术是为了解决什么特定问题而诞生的?jiffies 是Linux内核中最古老、最基础的时间测量机制。它的诞生是为了解决内核内部需要一个**简单、廉价、全局统一的“心跳”或“滴答(tick)”**来驱动各种基于时间的活动。 在操作系统内核中,大量活动都不是由外部事件触发,而是需要在一个相对的时间点后发生。例如: 超时(Timeouts):一个网络驱动发送了一个数据包,它需要在一个超时时间(如200毫秒)后检查是否收到了确认。 调度(Scheduling):一个SCHED_RR(轮转)策略的进程,其运行时间片用完后需要被抢占。 周期性任务(Periodic Tasks):某些内核任务需要周期性地运行。 简单的延迟(Delays):代码中需要一个短暂的、非精确的延迟。 jiffies 提供了一个极其简单的解决方案:它是一个在系统启动后不断递增的全局计数器。通过读取这个计数器的值,内核的任何部分都可以获得一个关于“时间流逝”的...
sched_clock
[toc] kernel/time/sched_clock.c 调度器时钟(Scheduler Clock) 高性能的调度与追踪时间戳历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/time/sched_clock.c 提供的核心功能 sched_clock() 是为了解决内核中一个对性能极其敏感的需求:以极低的开销,获取一个高分辨率、单调递增的时间戳。 jiffies 虽然开销低,但其分辨率太差(毫秒级),完全无法满足现代调度器的需求。特别是对于CFS(完全公平调度器),它需要精确地知道一个任务在CPU上到底运行了多少纳秒,以便公平地更新其虚拟运行时间(vruntime)。如果时间测量不准,CFS的公平性就无从谈起。 此外,内核内部的其他高性能子系统也需要类似的时间戳: 性能追踪与分析:像ftrace和perf这样的工具,在记录内核事件时,需要为每个事件打上一个极其精确的时间戳,以便分析微秒甚至纳秒级的性能瓶颈。 锁竞争分析:内核的锁调试器需要精确测量一个任务在等待一个自旋锁上花费了多长时间。 sched_clock() 就是为了满...





