网卡驱动中是否需要xmit的锁

结论:不需要,dev_hard_start_xmit时,存在HARD_TX_LOCK/HARD_TX_UNLOCK的自璇锁,该锁为txq粒度,因此网卡驱动中针对txq的资源不存在保序需求。

版本:linux-4.1.19,sch_generic.c 、netdevice.h

网卡驱动中是否需要xmit的锁_第1张图片

如上图在iperf3打流过程中抓取的协议栈调用栈,最终调用的函数为sch_direct_xmit->dev_hard_start_xmit,搜索该函数附近可见,调用硬件发送函数dev_hard_start_xmit时,存在HARD_TX_LOCK/HARD_TX_UNLOCK的锁。

bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
		     struct net_device *dev, struct netdev_queue *txq,
		     spinlock_t *root_lock, bool validate)
{
...
	if (likely(skb)) {
		HARD_TX_LOCK(dev, txq, smp_processor_id());
		if (!netif_xmit_frozen_or_stopped(txq))
			skb = dev_hard_start_xmit(skb, dev, txq, &ret);

		HARD_TX_UNLOCK(dev, txq);
	} 
...
}

netdevice.h:

#define HARD_TX_LOCK(dev, txq, cpu) {			\
	if ((dev->features & NETIF_F_LLTX) == 0) {	\
		__netif_tx_lock(txq, cpu);		\
	} else {					\
		__netif_tx_acquire(txq);		\
	}						\
}

static inline void __netif_tx_lock(struct netdev_queue *txq, int cpu)
{
	spin_lock(&txq->_xmit_lock);
	txq->xmit_lock_owner = cpu;
}

static inline bool __netif_tx_acquire(struct netdev_queue *txq)
{
	__acquire(&txq->_xmit_lock);
	return true;
}

#define __acquire(x)
#define __acquires(x)
#define __release(x)
#define __releases(x)

赋值有NETIF_F_LLTX标志的是linux内核的一些虚拟设备,入bond、geneve/gre、vlan和tun等,传统厂商intel/cisco/huwei等设备并没有使用该标志,因此通用网卡并不需要赋值该标志。

__netif_tx_lock函数中使用了txq->_xmit_lock锁进行保序,粒度为txq,因此后续在网卡的驱动程序中并不需要增加txq多线程保序锁。

你可能感兴趣的:(linux-路由系统,linux,运维,服务器)