首先说一下自动IRQ亲和性,在内核配置中可以打开自动IRQ亲和性开关(CONFIG_AUTO_IRQ_AFFINITY)使能此功能。
用户层程序irqbalance(ubuntu等发行版集成此程序)可自动平衡中断irq在各个处理器上,提升系统的性能。irqbalance用到的一个重要的参数hintpolicy用来控制中断平衡的策略,内核会为每一个中断提供一个affinity_hint值,告诉用户层(如irqbalance)此中断倾向的CPU亲和性。 其取值有三个:exact 、subset与ignore,exact表示irqbalance程序会严格按照内核的affinity_hint值进行亲和性平衡;subset表示irqbalance会以affinity_hint的一个子集进行平衡;ignore表示完全忽略内核的affinity_hint。
以运行与双核CPU的ubuntu系统为例,查看网卡ens33的中断号以及中断在两个CPU上的分配情况:
$ cat /proc/interrupts
CPU0 CPU1
19: 477 1058095 IO-APIC 19-fasteoi ens33
看一下proc文件中,中断号irq 19的affinity设置(affinity相关文件按128核心处理器设置)。由smp_affinity的值可见,网卡ens33的19号中断被分配在了CPU1上(0000 0002),smp_affinity_list以数值形式显示了CPU亲和性列表。另外内核未给出irq 19的affinity_hint值。
除去smp_affinity_list的值以外,其它的affinity值都是以bitmap位图的方式表示。
$ cat /proc/irq/19/smp_affinity
00000000,00000000,00000000,00000002
$
$ cat /proc/irq/19/smp_affinity_list
1
$ cat /proc/irq/19/affinity_hint
00000000,00000000,00000000,00000000
$
$ cat /proc/irq/default_smp_affinity
ffffffff,ffffffff,ffffffff,ffffffff
由irq_desc结构可见,PROC系统文件smp_affinity和smp_affinity_list的值对应irq_desc结构体中的成员(irq_common_data->affinity)变量的值;affinity_hint文件的值对应irq_desc的成员affinity_hint,网卡驱动程序(如intel的i40e)通过调用irq_set_affinity_hint函数设置此值。文件default_smp_affinity的值在初始化期间设置为全F。
struct irq_common_data {
cpumask_var_t affinity;
}
struct irq_desc {
struct irq_common_data irq_common_data;
const struct cpumask *affinity_hint;
}
static void __init init_irq_default_affinity(void)
{
if (cpumask_empty(irq_default_affinity))
cpumask_setall(irq_default_affinity);
}
应用层程序irqbalance主要是在系统性能与功耗之间平衡的程序,系统负荷重时把irq分配到多个CPU上,系统空闲时把irq分配在少量CPU保证其它CPU的睡眠状态。用户可收到设置中断的affinity,禁用irqbalance的决策。
内核版本
Linux-4.15