MANA IRQ 亲和性优化
原始问题:详细分析下这个特性:MANA IRQ 亲和性优化 · 2026-07-08
这是一个与Linux内核技术相关的问题,我将深入分析MANA IRQ亲和性优化特性。找到了关键提交。让我深入分析这个特性。—
📋 问题定位
| 维度 | 内容 |
|---|---|
| 所属子系统 | 网卡驱动:MANA (Microsoft Azure Network Adapter) — drivers/net/ethernet/microsoft/mana/gdma_main.c |
| 关键函数 | mana_irq_setup_numa_aware() (原 irq_setup())、mana_irq_setup_linear() (新增)、mana_gd_setup_dyn_irqs() |
| 提交 | 5316394b1752 — Shradha Gupta, June 24, 2026 |
| 修复的提交 | 755391121038 (动态 MSI-X 分配引入的回归) |
| 标签 | Cc: stable@vger.kernel.org |
🎯 问题背景
引入回归的变更
在此之前,MANA 驱动在早期加载阶段静态分配所有 MSI-X 向量。提交 755391121038 将其改为两阶段动态分配:
- 阶段 1 (
mana_gd_setup_hwc_irqs):先分配 1 个向量给 HWC (Hardware Communication Channel),创建 HWC 并用其查询硬件支持的最大 IRQ 数量 - 阶段 2 (
mana_gd_setup_remaining_irqs→mana_gd_setup_dyn_irqs):查询到max_msix后,动态追加剩余的队列 IRQ
两阶段分配带来的问题是:到第二阶段时,系统上已存在其他设备预先分配的 IRQ,导致IRQ 权重在不同 vCPU 上已不均衡。原始的 NUMA 感知亲和性分配逻辑 (irq_setup,即现在的 mana_irq_setup_numa_aware) 依然按 NUMA hop → core 组 → sibling CPU 的层次分配,在 IRQ 数 > vCPU 数的场景下会把多个 MANA 队列 IRQ 挤到同一组 sibling vCPU 上。
具体症状
在 低 vCPU 配置 的 SMP 使能的 VM 上:
4 vCPU (2 cores), 5 MANA IRQ (1 HWC + 4 Queue)
分配结果(补丁前):
IRQ0 (HWC) → vCPU 0
IRQ1 (mana_q1) → vCPU 0 ← 与 HWC 挤在一起
IRQ2 (mana_q2) → vCPU 2
IRQ3 (mana_q3) → vCPU 0 ← 与 HWC 挤在一起
IRQ4 (mana_q4) → vCPU 3
%soft 分布:
vCPU 0: 39% ← 软中断完全集中在 vCPU 0
vCPU 1: 0%
vCPU 2: 24%
vCPU 3: 25%
软中断处理全部压在 vCPU 0 上,多连接 TCP 吞吐量大幅下降。
⚙️ 技术方案与原理剖析
核心变更
补丁引入了两种 IRQ 亲和性分配策略,在 mana_gd_setup_dyn_irqs() 中根据 IRQ 总数与在线 CPU 数的关系 做分支选择:
num_msix_usable (HWC + 队列IRQ) vs num_online_cpus()
│
├── 可用IRQ数 ≤ 在线CPU数 ──→ mana_irq_setup_numa_aware()
│ (NUMA感知,跳过第一个core组给HWC)
│
└── 可用IRQ数 > 在线CPU数 ──→ mana_irq_setup_linear()
(线性分配,忽略NUMA/core拓扑)
策略 1:mana_irq_setup_numa_aware()(原有逻辑增强)
// 遍历NUMA hops,在每个hop内按core组逐级分配
for_each_numa_hop_mask(next, node) {
weight = cpumask_weight_andnot(next, prev);
while (weight > 0) {
cpumask_andnot(cpus, next, prev);
for_each_cpu(cpu, cpus) {
cpumask_andnot(cpus, cpus, topology_sibling_cpumask(cpu));
--weight;
if (unlikely(skip_first_cpu)) {
skip_first_cpu = false; // 跳过HWC已经占用的第一个core组
continue;
}
irq_set_affinity_and_hint(*irqs++, topology_sibling_cpumask(cpu));
}
}
prev = next;
}
机制:按 NUMA 距离分层,在每层内按 core 组(sibling group) 分配,确保同一物理 core 的两个 sibling 不会同时被分配多个 IRQ。对动态分配的队列 IRQ,开启 skip_first_cpu 跳过 HWC 已占用的第一个 core 组。
策略 2:mana_irq_setup_linear()(新增)
```c static void mana_irq
参考来源
⚠️ 免责声明
本站内容均由 AI 基于公开知识辅助生成,仅供学习参考,请勿直接引用作为依据。作者不对信息的准确性、完整性及适用性作保证,亦不对因使用本站内容产生的任何损失承担责任。