linux内核协议栈之网卡发送队列选择

本文详细介绍了Linux内核5.10版本中,针对多队列网卡的发送队列选择过程,包括netdev_pick_tx函数、XPS队列选择get_xps_queue以及哈希选择队列skb_tx_hash。当设备定义自己的队列选择函数或使用默认函数时,会考虑XPS、CPU核心和接收队列等因素来确定合适的发送队列。同时,队列索引的选择还会经过合法性检查,确保不超过网卡的实际队列数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内核版本:5.10

1 netdev_core_pick_tx

对于多队列的网络设备,real_num_tx_queues大于1,如果网络设备定义了自身的队列选择函数(ixgbe_select_queue),使用此函数;否则,使用netdev_pick_tx选择发送队列。最后,队列选择完成之后,将队列索引保存到skb的成员queue_mapping中。

1.1 netdev_pick_tx

首先,获取套接口中保存的队列索引值(sk_tx_queue_mapping),如果此值合法,范围在[0, skb->real_num_tx_queues]之间,并且ooo_okay不为1,意味着不需要重选队列,此时使用套接口中保存的队列索引值。

否则,使用get_xps_queue选择新的队列索引,如果新索引小于零,使用skb_tx_hash选择队列索引。最后,对于完全的套接口,如果路由缓存有效,并且新索引与保存的索引不同,更新套接口中的发送队列索引。

1.1.1 XPS队列选择 get_xps_queue

如果没有定义XPS,此函数返回-1。如果定义了XPS,可通过以下PROC文件配置基于CPU核心的队列选择,或者基于接收队列的发送队列选择:

如果没有XPS相关配置,返回-1,非法队列值。否则,如果基于接收队列的选择(xps_rxqs_needed)没有配置,使用基于CPU核心的队列选择。如果两者同时配置,优先处理xps_rxqs配置。

首先取得接收队列索引值,如果其合法,使用函数__get_xps_queue_idx依据xps_rxqs配置将其转换为发送队列索引。

如果以上取得的发送队列索引值不合法,使用函数__get_xps_queue_idx将发送CPU核心作为参数,依据xps_cpus配置转换为发送队列索引。

对于多优先级Qdisc流控,tci索引到对应的流控类别(Traffic Class),在根据报文优先级取得偏移量。对于其它流控,直接使用tci作为配置表索引,如果表长度为1,直接使用其中的队列值。否则,根据报文五元组索引计算哈希值作为表索引,获得队列值。

合法的队列值不应大于队列总数real_num_tx_queues的值。

1.1.2 哈希选择队列skb_tx_hash

目前对于mqprio和taprio两种具有优先级队列的Qdisc,会设置num_tc相关数值,根据优先级priority,映射到tc类别,再根据tc到txq的映射计算出发送队列的范围。否则,对于其它Qdisc,发送队列的范围固定为[0,real_num_tx_queues]。

如果skb中记录了接收队列的值,确保此值(hash)位于合法的范围内,即(qoffset, qcount)之间。这样最终选择的队列索引(hash+qoffset)不超过队列总数qcount的值。

否则,如果没有接收队列的记录,由函数skb_get_hash通过报文的五元组信息计算hash值,此哈希值不超过qcount,最后,增加qoffset作队列索引值。此处可见,返回的队列索引可能超过队列总数qcount的值。

1.2 队列索引合法检查 netdev_cap_txqueue

如果选择的队列索引超过总的队列数量,返回队列零。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值