Irqbalance处理中断迁移过程
一、Numa架构
Numa架构通过将cpu划分成不同的组(Node),每个Node由一个或多个(物理)cpu组成,并且有独立的本地内存、I/O等资源。在Numa架构中,每个节点都有自己的内存和计算资源,这使得处理器可以更加灵活地分配资源,提高了整体性能和效率。此外,Numa架构还可以通过增加节点数量来扩展处理器的计算和存储能力,这使得它成为一种非常适合大规模并行处理的架构。
numa架构示意图
- irqbalance中断动态迁移过程
1.建立拓扑结构
结构参考示意图:
具体实现过程:
通过遍历/sys/devices/system/node/node[*],决定有多少NODE的对象。
通过遍历/topology/physical_package_id决定有多少PACKAGE的对象。
通过遍历/sys/devices/system/cpu/cpu[*]/cache/index[max]/shared_cpu_map决定有多少CACHE对象。
通过遍历/sys/devices/system/cpu/cpu[*],以及是否online,决定有多少CPU的对象
通过遍历/sys/bus/pci/devices/0000:00:[**].[*]/下irq以及msi,建立各个irq的数据,并结合proc/irq/下文件初始化中断数据结构。这样irqbalance就知道该irq属于哪个node以及smp_affinity.
2.统计所有中断
通过读取/proc/interrupts值解析出各个irq。
3.统计所有cpu负载load(以10秒为一个间隔时间)
cpu负载=硬/软中断累计时间(单位是jiffies)
通过解析/proc/stat获取每个cpu的硬中断和软中断信息得到cpu负载load
由下而上计算整个拓扑结构各个节点的负载:
父节点负载=各孩子节点负载的总和。
4.将上述中断分配到各个节点
由于中断是根据所在的numa node id将中断分配到不同的node 节点上。irqbalance目前的处理方式:对中断不会跨numa 节点迁移的,只能在同一numa node内部进行优化。现在我们可以将关注点放到单一的node拓扑示意图上
- 首先将未分配cpu的中断irq挂载到rebalance_irq_list上,并进行排序:优先按照中断的irq_info.class由大到小排列,如果class相同则按照load由大到小排列。
- 将rebalance_irq_list迁移到node0节点下。
- 自上而下遍历各个拓扑层,对于每一个拓扑层:
遍历该层所有孩子节点,并将其迁移到负载最小的孩子节点上。
- 完成遍历后,就已经将irq分配到各个cpu上了。
5.计算cpu节点和irq的负载(以单个cpu为例)
以cpu0为例,此时cpu0节点下挂载了irq list,每间隔10s会进行一次计算。
- 解析/proc/stat获取各个cpu的load值(硬/软中断累计时间)。
- 解析/proc/interrupts计算各个中断在各个cpu上的中断次数增加值△irq_count。
- 统计cpu0下的中断增加总中断次数(count)。
- 计算单次中断的负载:
load_slice = load/count
- 计算irq list上各个中断的负载:
irq_info.load= load_slice*△irq_count
6.需要迁移的中断的判断及处理
- 统计当前这一层的最小负载min_load
- 找出当前这一层大于min_load的节点,把当前节点的中断的class和负载情况由大到小进行排序.
- 取出当前节点负载adjustment_load和最大中断负载irq_load进行如下计算:(尝试移动当前中断到最小负载所在的节点)
If((min_load + irq_load) < (adjustment_load - irq_load) ) {
修改当前节点负载:adjustment_load -= irq_load;
修改最小负载的值:min_load += irq_load;
将当前irq迁移到rebalance_irq_list
设置irq的moved值为1
}
- 重复上述(2)~(3)步骤
- 循环结束后,所有需要迁移的中断都放到了rebalance_irq_list中。
7.中断在拓扑结构中的迁移过程
- 对rebalance_irq_list的中断按class和load由大到小排列。
- 将rebalance_irq_list迁移到node节点。
- 然后从node->package->cache->cpu
自上而下遍历各个拓扑层,对于每一个拓扑层:
遍历该层所有孩子节点,并将其迁移到负载最小的孩子节点上。
(4)完成遍历后,就已经将irq分配到各个cpu上了。
8.触发irq在cpu间的实际迁移
- 遍历cpu层并查询当前节点下的irq list中的irq的moved标志是否是1。
- 将当前cpu的mask写入到/proc/irq/中断号/smp_affinity
- 写入中断的smp_affinity,后由系统完成cpu的切换。