news 2026/6/13 13:44:08

Linux irq_poll忙轮询中断模式与cap_poll适配

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux irq_poll忙轮询中断模式与cap_poll适配

Linux irq_poll忙轮询中断模式与cap_poll适配

irq_poll是Linux内核提供的一种中断与轮询混合机制,用于在高中断频率场景下降低中断开销。它由include/linux/irq_poll.h和lib/irq_poll.c实现。当设备中断频率超过一定阈值时,irq_poll自动将中断模式切换为轮询模式,避免频繁的硬件中断上下文切换消耗CPU时间。

irq_poll的核心数据结构:

```c
struct irq_poll {
struct list_head list;
unsigned long state;
int (*poll)(struct irq_poll *, int budget);
unsigned int irq;
};
```

state字段使用位操作管理状态,关键标志位如下:

```c
#define IRQ_POLL_F_SCHED 0
#define IRQ_POLL_F_POLLING 1
#define IRQ_POLL_F_DISABLE 2
```

初始化一个irq_poll实例使用irq_poll_init:

```c
void irq_poll_init(struct irq_poll *iop, int irq,
int (*poll)(struct irq_poll *, int))
{
INIT_LIST_HEAD(&iop->list);
iop->state = 0;
iop->irq = irq;
iop->poll = poll;
}
```

irq_poll的核心调度入口是irq_poll_sched,通常在中断处理handler中调用:

```c
void irq_poll_sched(struct irq_poll *iop)
{
if (test_and_set_bit(IRQ_POLL_F_SCHED, &iop->state))
return;

list_add_tail(&iop->list, this_cpu_ptr(&blk_cpu_iopoll));
__raise_softirq_irqoff(IRQ_POLL_SOFTIRQ);
}
```

该函数将irq_poll实例加入per-CPU链表blk_cpu_iopoll,然后触发IRQ_POLL_SOFTIRQ软中断。软中断处理函数irq_poll_softirq在软中断上下文中执行轮询回调:

```c
static void irq_poll_softirq(struct softirq_action *h)
{
int pending = 0, budget = irq_poll_budget;
LIST_HEAD(list);

local_irq_disable();
list_splice_init(this_cpu_ptr(&blk_cpu_iopoll), &list);
local_irq_enable();

while (!list_empty(&list)) {
struct irq_poll *iop;
int work_done;

iop = list_entry(list.next, struct irq_poll, list);
work_done = iop->poll(iop, budget);
budget -= min(budget, work_done);

if (work_done && budget) {
list_move_tail(&iop->list, &list);
pending++;
} else {
list_del_init(&iop->list);
clear_bit(IRQ_POLL_F_SCHED, &iop->state);
if (work_done && budget)
pending++;
}
}

if (pending) {
list_splice_tail_init(&list, this_cpu_ptr(&blk_cpu_iopoll));
__raise_softirq_irqoff(IRQ_POLL_SOFTIRQ);
}

local_irq_disable();
list_splice_tail_init(&list, this_cpu_ptr(&blk_cpu_iopoll));
local_irq_enable();
}
```

轮询回调用budget参数控制本次轮询的处理上限,防止独占CPU。irq_poll_budget默认值为64,表示每次软中断最多处理64个数据包或请求。如果poll返回的工作量等于budget,说明仍有数据待处理,irq_poll_softirq将重新触发软中断继续轮询。如果工作量小于budget,说明设备已空,清除IRQ_POLL_F_SCHED标志返回中断模式。

cap_poll是在网络驱动NAPI poll基础上的IRQ层面扩展。部分设备通过set_irq_poll_cap接口标记自身支持poll能力:

```c
void irq_poll_set_cap(struct irq_poll *iop)
{
set_bit(IRQ_POLL_F_DISABLE, &iop->state);
}
```

将IRQ_POLL_F_DISABLE置位后,irq_poll会在特定条件下禁用自身并退还中断模式。这个自适应切换是irq_poll区别于NAPI的关键点。irq_poll通过统计中断间隔时间动态判断是否切换:

```c
static bool irq_poll_check_poll(struct irq_poll *iop, unsigned int irq_interval)
{
if (irq_interval < irq_poll_timeout)
return true;
return false;
}
```

当连续中断间隔小于irq_poll_timeout(默认200微秒)时,中断频率过高,irq_poll倾向于保持在轮询模式;当间隔变大时,切换回中断模式以节省CPU。

与NAPI相比,irq_poll的差异在于:

1. irq_poll工作在软中断IRQ_POLL_SOFTIRQ中,NAPI使用NET_RX_SOFTIRQ,两者优先级不同。
2. irq_poll的poll回调在软中断上下文每次被调用时最多执行budget次,NAPI的poll在每次被调用时有固定的budget配额。
3. irq_poll不需要像NAPI那样禁用设备的RX中断,它仅通过IRQ_POLL_F_SCHED标志控制调度,中断handler依然简短地记录状态。

irq_poll与线程化中断的使用场景对比:中断频率较低时,线程化中断将处理推入进程上下文节省CPU;中断频率极高(如万兆网卡)时,线程化导致频繁唤醒和调度,此时irq_poll在软中断中轮询更高效。

```c
static int example_irq_handler(int irq, void *dev_id)
{
struct my_device *dev = dev_id;

/* Quick hardware check */
if (!readl(dev->regs + INT_STATUS))
return IRQ_NONE;

/* Schedule irq_poll instead of processing all data */
irq_poll_sched(&dev->iop);
return IRQ_HANDLED;
}

static int my_device_poll(struct irq_poll *iop, int budget)
{
struct my_device *dev = container_of(iop, struct my_device, iop);
int work = 0;

while (work < budget) {
u32 status = readl(dev->regs + RX_STATUS);
if (!(status & RX_READY))
break;
/* Process one packet */
work++;
}

if (work < budget) {
/* No more data, re-enable interrupts */
writel(INT_ENABLE, dev->regs + INT_MASK);
}

return work;
}
```

在这个示例中,IRQ handler仅检查状态并调用irq_poll_sched,实际数据收发在poll回调中轮询完成。这种设计将高频率中断转换为有节制的轮询,兼顾了延迟和吞吐量。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/13 13:42:52

两天实训,跑通P600无人机开发

5月28日-29日&#xff0c;阿木实验室 P600无人机培训课在成都顺利开展。本次培训围绕 P600无人机平台展开&#xff0c;课程内容覆盖无人机基础知识、MAVROS 控制接口、Prometheus 软件框架、理论仿真以及多项实飞演示&#xff0c;帮助学员从系统原理到实际操作&#xff0c;更完…

作者头像 李华
网站建设 2026/6/13 13:38:55

M68040总线监听机制:多主系统缓存一致性硬件实现详解

1. 多主系统缓存一致性的核心挑战与M68040的应对之道在嵌入式系统和早期的多处理器架构设计中&#xff0c;一个核心且棘手的问题就是缓存一致性。想象一下&#xff0c;在一个系统中&#xff0c;有多个“大脑”&#xff08;处理器或DMA控制器等总线主设备&#xff09;都能独立地…

作者头像 李华
网站建设 2026/6/13 13:37:51

多维聚合实战:从SQL GROUP BY到OLAP立方体的数据变形术

1. 这不是简单的“加总求平均”——多维聚合中的数据变形术到底在解决什么问题&#xff1f;如果你正在处理销售报表、用户行为宽表、IoT设备时序快照&#xff0c;或者哪怕只是Excel里一张带地区、月份、产品线、渠道四个维度的汇总表&#xff0c;那你大概率已经踩进过这个坑&am…

作者头像 李华
网站建设 2026/6/13 13:35:53

NXP DSP56720/56721 GPIO与ESAI接口配置实战指南

1. 项目概述与核心价值如果你正在开发基于Freescale&#xff08;现NXP&#xff09;Symphony DSP56720或DSP56721的音频处理系统&#xff0c;那么对GPIO和ESAI接口的深入理解和精准配置&#xff0c;绝对是项目成败的关键一步。这两颗芯片作为经典的多核音频DSP&#xff0c;在专业…

作者头像 李华
网站建设 2026/6/13 13:34:49

AlienFX Tools终极指南:免费快速解决Alienware灯光控制失效问题

AlienFX Tools终极指南&#xff1a;免费快速解决Alienware灯光控制失效问题 【免费下载链接】alienfx-tools Alienware systems lights, fans, and power control tools and apps 项目地址: https://gitcode.com/gh_mirrors/al/alienfx-tools AlienFX Tools是一款专为Al…

作者头像 李华