Skip to content

Commit 89ec1f0

Browse files
jjagielskanguy11
authored andcommitted
i40e: Fix queue-to-TC mapping on Tx
In SW DCB mode the packets sent receive incorrect UP tags. They are constructed correctly and put into tx_ring, but UP is later remapped by HW on the basis of TCTUPR register contents according to Tx queue selected, and BW used is consistent with the new UP values. This is caused by Tx queue selection in kernel not taking into account DCB configuration. This patch fixes the issue by implementing the ndo_select_queue NDO callback. Fixes: fd0a05c ("i40e: transmit, receive, and NAPI") Signed-off-by: Arkadiusz Kubalewski <[email protected]> Signed-off-by: Jedrzej Jagielski <[email protected]> Tested-by: Imam Hassan Reza Biswas <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent dc614c4 commit 89ec1f0

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13271,6 +13271,7 @@ static const struct net_device_ops i40e_netdev_ops = {
1327113271
.ndo_poll_controller = i40e_netpoll,
1327213272
#endif
1327313273
.ndo_setup_tc = __i40e_setup_tc,
13274+
.ndo_select_queue = i40e_lan_select_queue,
1327413275
.ndo_set_features = i40e_set_features,
1327513276
.ndo_set_vf_mac = i40e_ndo_set_vf_mac,
1327613277
.ndo_set_vf_vlan = i40e_ndo_set_vf_port_vlan,

drivers/net/ethernet/intel/i40e/i40e_txrx.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3631,6 +3631,56 @@ static inline int i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
36313631
return -1;
36323632
}
36333633

3634+
static u16 i40e_swdcb_skb_tx_hash(struct net_device *dev,
3635+
const struct sk_buff *skb,
3636+
u16 num_tx_queues)
3637+
{
3638+
u32 jhash_initval_salt = 0xd631614b;
3639+
u32 hash;
3640+
3641+
if (skb->sk && skb->sk->sk_hash)
3642+
hash = skb->sk->sk_hash;
3643+
else
3644+
hash = (__force u16)skb->protocol ^ skb->hash;
3645+
3646+
hash = jhash_1word(hash, jhash_initval_salt);
3647+
3648+
return (u16)(((u64)hash * num_tx_queues) >> 32);
3649+
}
3650+
3651+
u16 i40e_lan_select_queue(struct net_device *netdev,
3652+
struct sk_buff *skb,
3653+
struct net_device __always_unused *sb_dev)
3654+
{
3655+
struct i40e_netdev_priv *np = netdev_priv(netdev);
3656+
struct i40e_vsi *vsi = np->vsi;
3657+
struct i40e_hw *hw;
3658+
u16 qoffset;
3659+
u16 qcount;
3660+
u8 tclass;
3661+
u16 hash;
3662+
u8 prio;
3663+
3664+
/* is DCB enabled at all? */
3665+
if (vsi->tc_config.numtc == 1)
3666+
return i40e_swdcb_skb_tx_hash(netdev, skb,
3667+
netdev->real_num_tx_queues);
3668+
3669+
prio = skb->priority;
3670+
hw = &vsi->back->hw;
3671+
tclass = hw->local_dcbx_config.etscfg.prioritytable[prio];
3672+
/* sanity check */
3673+
if (unlikely(!(vsi->tc_config.enabled_tc & BIT(tclass))))
3674+
tclass = 0;
3675+
3676+
/* select a queue assigned for the given TC */
3677+
qcount = vsi->tc_config.tc_info[tclass].qcount;
3678+
hash = i40e_swdcb_skb_tx_hash(netdev, skb, qcount);
3679+
3680+
qoffset = vsi->tc_config.tc_info[tclass].qoffset;
3681+
return qoffset + hash;
3682+
}
3683+
36343684
/**
36353685
* i40e_xmit_xdp_ring - transmits an XDP buffer to an XDP Tx ring
36363686
* @xdpf: data to transmit

drivers/net/ethernet/intel/i40e/i40e_txrx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,8 @@ static inline unsigned int i40e_rx_pg_order(struct i40e_ring *ring)
451451

452452
bool i40e_alloc_rx_buffers(struct i40e_ring *rxr, u16 cleaned_count);
453453
netdev_tx_t i40e_lan_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
454+
u16 i40e_lan_select_queue(struct net_device *netdev, struct sk_buff *skb,
455+
struct net_device *sb_dev);
454456
void i40e_clean_tx_ring(struct i40e_ring *tx_ring);
455457
void i40e_clean_rx_ring(struct i40e_ring *rx_ring);
456458
int i40e_setup_tx_descriptors(struct i40e_ring *tx_ring);

0 commit comments

Comments
 (0)