news 2026/6/13 11:36:55

Linux irqtime_account_process_tick中断时间计费

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux irqtime_account_process_tick中断时间计费

Linux irqtime_account_process_tick中断时间计费

irqtime_account_process_tick是Linux内核中负责统计中断消耗CPU时间的核心函数,定义在kernel/sched/cputime.c。它精确记录每个CPU在处理硬中断(hardirq)和软中断(softirq)上花费的时间,这些数据通过/proc/stat和task_statm暴露给用户空间,也是调度器进行负载均衡的依据。

函数原型:

```c
static void irqtime_account_process_tick(struct task_struct *p, int user_tick,
struct rq *rq, int ticks)
```

其中p是当前进程,user_tick表示本次tick是否在用户态,rq是当前CPU的运行队列,ticks是统计的tick数量(通常为1)。

核心实现:

```c
static void irqtime_account_process_tick(struct task_struct *p, int user_tick,
struct rq *rq, int ticks)
{
s64 delta;
struct irqtime *irqtime = this_cpu_ptr(&cpu_irqtime);

if (!irqtime->stolen) {
irqtime->stolen = 1;
return;
}

if (irqtime->hardirq_time) {
delta = irqtime->hardirq_time - irqtime->hardirq_start;
if (delta > 0) {
account_steal_time(delta);
irqtime->hardirq_start = irqtime->hardirq_time;
}
}

if (irqtime->softirq_time) {
delta = irqtime->softirq_time - irqtime->softirq_start;
if (delta > 0) {
account_steal_time(delta);
irqtime->softirq_start = irqtime->softirq_time;
}
}

if (user_tick)
account_user_time(p, cputime_one_jiffy, cputime_one_jiffy);
else if ((p != rq->idle) && (irqtime->hardirq_time || irqtime->softirq_time))
account_system_time(p, HARDIRQ_OFFSET, cputime_one_jiffy);
else
account_idle_time(cputime_one_jiffy);
}
```

irqtime机制的核心是per-CPU变量cpu_irqtime,定义如下:

```c
struct irqtime {
u64 hardirq_time;
u64 softirq_time;
u64 hardirq_start;
u64 softirq_start;
int stolen;
};
```

hardirq_time记录了该CPU自系统启动以来累计的硬中断服务时间,由account_system_time在每次中断处理结束后递增。softirq_time同理。这两个计数器通过sched_clock或sched_clock_cpu提供的高精度时间戳累加。

irqtime_account_process_tick在每个tick中断时被调用(通常频率为100Hz或250Hz)。它通过比较当前中断累计时间与上一次tick记录值的差值,计算出该tick内花在中断处理上的时间。delta为正说明该tick至少有一部分时间消耗在中断处理中。

关键路径上的入口函数为account_process_tick:

```c
void account_process_tick(struct task_struct *p, int user_tick)
{
cputime_t one_jiffy = jiffies_to_cputime(1);
struct rq *rq = this_rq();

if (sched_clock_irqtime) {
irqtime_account_process_tick(p, user_tick, rq, 1);
return;
}

if (user_tick)
account_user_time(p, one_jiffy, one_jiffy);
else if ((p != rq->idle) && (irq_count() == HARDIRQ_OFFSET))
account_system_time(p, HARDIRQ_OFFSET, one_jiffy);
else
account_idle_time(one_jiffy);
}
```

当sched_clock_irqtime被配置且体系结构支持时,启用irqtime_account_process_tick的精准路径。否则回退到传统的粗粒度统计:检查irq_count()是否为HARDIRQ_OFFSET来判断当前是否在硬中断上下文。

hardirq_time和softirq_time的更新发生在中断处理的出入口:

```c
void account_system_time(struct task_struct *p, int index, cputime_t cputime)
{
struct irqtime *irqtime = this_cpu_ptr(&cpu_irqtime);

if (index == HARDIRQ_OFFSET) {
irqtime->hardirq_time += cputime;
irqtime->hardirq_start = irqtime->hardirq_time;
} else if (index == SOFTIRQ_OFFSET) {
irqtime->softirq_time += cputime;
irqtime->softirq_start = irqtime->softirq_time;
}
...
}
```

这个函数在update_process_times中被调用,而update_process_times由tick_periodic或tick_sched_handle触发。

irqtime_account_process_tick中的steal字段处理虚拟化场景中的steal time。当hypervisor窃取分配给guest的CPU时间时,stolen标记防止虚报中断时间。在KVM中,steal time通过kvm_steal_clock更新,irqtime检查该字段后跳过已盗用的时间片。

irqtime数据通过/proc/stat的intr行和softirq行暴露:

```c
static int show_stat(struct seq_file *p, void *v)
{
...
for_each_online_cpu(i) {
struct irqtime *irqtime = per_cpu_ptr(&cpu_irqtime, i);
seq_printf(p, "cpu%d ...", i);
seq_printf(p, " ... %llu %llu",
irqtime->hardirq_time,
irqtime->softirq_time);
}
...
}
```

irqtime_account_process_tick也影响调度器的负载均衡决策。当某个CPU大量时间消耗在中断处理中,其irqtime占比高说明该CPU不适合再分配新的计算或IO任务。调度器的find_idlest_cpu在选择目标CPU时会参考该CPU的空闲时间,而irqtime未被正确记录时可能导致CPU被过度分配给中断密集型任务。

CONFIG_IRQ_TIME_ACCOUNTING是使能该功能的编译选项。如果未配置此选项,内核回退到tick级别的粗粒度统计,无法精确区分中断时间和进程时间。在实时内核(RT)中,irqtime是sched_rt_runtime_exceeded检测的关键输入,因为它影响实时任务的运行时间预算计算。

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

Python 爬虫实战:国家统计局宏观经济数据爬取与趋势分析

批量采集GDP、CPI、PMI等核心宏观指标,构建中国经济数据看板,追踪周期波动与政策拐点。 一、项目背景 宏观经济数据是分析经济周期、评估政策效果、预判市场走势的基石。对于投资者、研究员和企业决策者而言,系统性地获取和追踪GDP增长率、居民消费价格指数(CPI)、采购经…

作者头像 李华
网站建设 2026/6/13 11:27:58

Pod 重启 IP 就变——Nacos 上 k8s 的三个致命问题与完整解决方案

Pod 重启 IP 就变——Nacos 上 k8s 的三个致命问题与完整解决方案Deployment 部署 Nacos,重启后集群全员失联 团队决定把 Nacos 迁移到 k8s。我想着"三个 Deployment 不就完了"——结果踩了一串连环坑。 第一版配置: apiVersion: apps/v1 kind…

作者头像 李华
网站建设 2026/6/13 11:27:57

在Azure Pipelines中使用Cypress进行端到端测试的实践

在现代Web开发中,端到端(E2E)测试是确保应用程序功能完整性的关键步骤。特别是在微服务架构和复杂的前后端分离应用中,E2E测试变得尤为重要。本文将介绍如何在Azure Pipelines中配置并运行Cypress测试,以确保.NET Angular应用的质量。 背景介绍 假设我们有一个使用dotne…

作者头像 李华
网站建设 2026/6/13 11:26:52

遗传算法工程落地:编码、适应度与参数调优三重实战

1. 项目概述:为什么第二部分比第一部分更“落地”?“遗传算法入门——第二部分”这个标题乍看平平无奇,但如果你翻过第一部分,就会发现它几乎只讲了生物隐喻:染色体、基因、交叉、变异、适应度……像一本精美的科普插画…

作者头像 李华
网站建设 2026/6/13 11:22:58

前端综合实战:跨域通信、离线存储与 URL 到页面全流程

文章目录前言一、同源策略与跨域1.1 同源定义1.2 跨域解决方案二、跨标签页通信2.1 BroadcastChannel2.2 localStorage 事件2.3 SharedWorker2.4 方案对比三、SSE vs WebSocket3.1 SSE(Server-Sent Events)3.2 WebSocket3.3 区别四、离线存储方案选型4.1…

作者头像 李华
网站建设 2026/6/13 11:15:08

Mythos推理架构:可编程、可审计的门控式高阶推理系统

1. 项目概述:一次被刻意“锁住”的能力跃迁如果你最近关注大模型前沿动态,大概率在技术社区、AI从业者群或邮件列表里见过“TAI #200”这个编号——它不是某篇论文的DOI,也不是某个开源项目的Release Tag,而是The AI Alignment Ne…

作者头像 李华