numa node效应对网卡的影响以及解决方式

NUMA的诞生是为了解决SMP架构下不断增多的CPU Core导致的性能问题,NUMA调整了CPU和内存的布局和访问关系。将CPU划分到多个Node节点上,每个Node都有自己独立的内存空间。各个node之间通过高速互联通讯。

CPU访问不同类型节点的内存是不相同的,访问本地节点的速度最快,访问远端节点的速度最慢,即访问速度与节点的距离有关,距离越远访问速度越慢,即非一致。在NUMA系统中,当linux内核收到内存分配请求时,它会优先从发出请求的CPU本地或邻近的内存node中寻找空闲内存,这种方式称为local allocation。

 当网卡PCIe EP、内存、TX&RX CPU 不在同一个Numa上,如果存在数据拷贝,那么就会跨node去访问内存,对于CPU的消耗是比在本node上的消耗多的多的。因此,我们可以尽量使CPU,内存,以及TX&RX CPU均处在一个node上。

1. numa查看

查看网卡处在哪个node的方法如下,如果是-1,表示该主机只有一个node。

cat /sys/bus/pci/devices/0000\:01\:00.0/numa_node

查看node上的cpu以及相应的内存

查看伙伴系统内存,以我所处的服务器为例

 查看硬中断所绑定的CPU。

2.中断绑定 

网卡处理速度很快,如果将中断全部绑定在一个CPU上,就会造成CPU负载压力大,即使全部的时间都在处理中断也可能忙不过来。因此,需要根据网卡中不同的channel(每个channel都有tx和rx中断),而将网卡中断绑定到不同的CPU上。

那么网卡中断可以任意绑定到CPU上吗?答案是当然可以。但是考虑numa node,如果网卡中断绑定到非本numa节点上,那么CPU去处理中断,内存,就会跨node。虽然不影响工作,但性能方面就会受到很大的影响,尤其是当CPU处理速度略差的时候,性能损失的现象会更明显。

因此,我们需要将网卡中断绑定到网卡所在的numa节点上。

将中断绑定在网卡所处的node上的cpu步骤如下:

1.通过dev_to_node函数可以获取网卡所处的numa节点

 priv->num_node = dev_to_node(pdev->dev);

2.申请中断后,设置中断处理的cpu。

        ret = request_irq(priv->tx_irq[i],
                  stmmac_msi_intr_tx,
                  0, int_name, &priv->tx_queue[i]);
        .....
        cpumask_clear(cpu_mask);
        /* assign tx irq to different cpu with rx irq */
        cpumask_set_cpu(cpumask_local_spread(i , priv->num_node), cpu_mask);
        irq_set_affinity_hint(priv->tx_irq[i], cpu_mask);

通过上述步骤,中断就会由网卡所在的numa节点上的cpu处理。

3.内存绑定

网卡内存申请的目标是最好所有的处理都在网卡所在的numa节点上的内存上,这样,CPU能更快速的访问网卡所在的numa节点的内存。那么如何申请网卡所在的内存呢,其实也比较简单。

使用kzalloc函数申请普通内存的时候需要显示指定node节点。

q_vector = kzalloc(struct_size(q_vector, ring, ring_count),
				GFP_KERNEL)
q_vector = kzalloc_node(struct_size(q_vector, ring, ring_count),
				GFP_KERNEL, node);

使用alloc_page申请page的时候同样需要显式指定node节点。不要使用dev_alloc_page申请,而使用alloc_page_node申请最好。

struct page *alloc_pages_node(int nid, gfp_t gfp_mask,
						unsigned int order)

那么申请流式dma或者一致性dma内存时,需要指定numa节点吗,这个不太需要,因为申请该内存的时候,会传入device参数,通过device参数就可以获取相应的numa节点,会倾向于该numa节点上的dma内存。

static inline void *dma_alloc_coherent(struct device *dev, size_t size,
		dma_addr_t *dma_handle, gfp_t gfp)
{
	return dma_alloc_attrs(dev, size, dma_handle, gfp,
			(gfp & __GFP_NOWARN) ? DMA_ATTR_NO_WARN : 0);
}

通过将中断绑定到网卡所处numa节点上的CPU,以及申请内存时申请numa节点上的内存。这样,当网卡插到服务器上不同插槽时,也会避免跨numa节点带来的性能损失。

  • 18
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值