Skip to content

Commit f938dae

Browse files
Gal PressmanSaeed Mahameed
authored andcommitted
net/mlx5e: CHECKSUM_COMPLETE offload for VLAN/QinQ packets
When the VLAN tag is present in the packet buffer (i.e VLAN stripping disabled, QinQ) the driver will currently report CHECKSUM_UNNECESSARY. Instead of using CHECKSUM_COMPLETE offload for packets with first ethertype of IPv4/6, use it for packets with last ethertype of IPv4/6 to cover the former cases as well. The checksum field present in the CQE is calculated from the IP header until the end of the packet. When the first ethertype is different than IPv4/6 (for ex. 802.1Q VLAN) a checksum of the VLAN header/s should be added. The small header/s checksum calculation will allow us to use CHECKSUM_COMPLETE instead of CHECKSUM_UNNECESSARY. Testing bandwidth of one and 8 TCP streams to a single RQ, LRO and VLAN stripping offloads disabled: CPU: Intel(R) Xeon(R) CPU E5-2660 v2 @ 2.20GHz NIC: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] Before: +--------------+--------------------+---------------------+----------------------+ | Traffic type | 1 Stream BW [Mbps] | 8 Streams BW [Mbps] | Checksum offload | +--------------+--------------------+---------------------+----------------------+ | Untagged | 28,247.35 | 24,716.88 | CHECKSUM_COMPLETE | | VLAN | 27,516.69 | 23,752.26 | CHECKSUM_UNNECESSARY | | QinQ | 6,961.30 | 20,667.04 | CHECKSUM_UNNECESSARY | +--------------+--------------------+---------------------+----------------------+ Now: +--------------+--------------------+---------------------+-------------------+ | Traffic type | 1 Stream BW [Mbps] | 8 Streams BW [Mbps] | Checksum offload | +--------------+--------------------+---------------------+-------------------+ | Untagged | 28,521.28 | 24,926.32 | CHECKSUM_COMPLETE | | VLAN | 27,389.37 | 23,715.34 | CHECKSUM_COMPLETE | | QinQ | 6,901.77 | 20,845.73 | CHECKSUM_COMPLETE | +--------------+--------------------+---------------------+-------------------+ No performance degradation observed. Signed-off-by: Gal Pressman <[email protected]> Reviewed-by: Tariq Toukan <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent f24686e commit f938dae

File tree

1 file changed

+14
-3
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core

1 file changed

+14
-3
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_rx.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,6 @@ static void mlx5e_lro_update_hdr(struct sk_buff *skb, struct mlx5_cqe64 *cqe,
563563
u8 tcp_ack = (l4_hdr_type == CQE_L4_HDR_TYPE_TCP_ACK_NO_DATA) ||
564564
(l4_hdr_type == CQE_L4_HDR_TYPE_TCP_ACK_AND_DATA);
565565

566-
skb->mac_len = ETH_HLEN;
567566
proto = __vlan_get_protocol(skb, eth->h_proto, &network_depth);
568567

569568
tot_len = cqe_bcnt - network_depth;
@@ -610,10 +609,11 @@ static inline void mlx5e_skb_set_hash(struct mlx5_cqe64 *cqe,
610609
skb_set_hash(skb, be32_to_cpu(cqe->rss_hash_result), ht);
611610
}
612611

613-
static inline bool is_first_ethertype_ip(struct sk_buff *skb)
612+
static inline bool is_last_ethertype_ip(struct sk_buff *skb, int *network_depth)
614613
{
615614
__be16 ethertype = ((struct ethhdr *)skb->data)->h_proto;
616615

616+
ethertype = __vlan_get_protocol(skb, ethertype, network_depth);
617617
return (ethertype == htons(ETH_P_IP) || ethertype == htons(ETH_P_IPV6));
618618
}
619619

@@ -623,6 +623,8 @@ static inline void mlx5e_handle_csum(struct net_device *netdev,
623623
struct sk_buff *skb,
624624
bool lro)
625625
{
626+
int network_depth = 0;
627+
626628
if (unlikely(!(netdev->features & NETIF_F_RXCSUM)))
627629
goto csum_none;
628630

@@ -632,9 +634,17 @@ static inline void mlx5e_handle_csum(struct net_device *netdev,
632634
return;
633635
}
634636

635-
if (is_first_ethertype_ip(skb)) {
637+
if (is_last_ethertype_ip(skb, &network_depth)) {
636638
skb->ip_summed = CHECKSUM_COMPLETE;
637639
skb->csum = csum_unfold((__force __sum16)cqe->check_sum);
640+
if (network_depth > ETH_HLEN)
641+
/* CQE csum is calculated from the IP header and does
642+
* not cover VLAN headers (if present). This will add
643+
* the checksum manually.
644+
*/
645+
skb->csum = csum_partial(skb->data + ETH_HLEN,
646+
network_depth - ETH_HLEN,
647+
skb->csum);
638648
rq->stats.csum_complete++;
639649
return;
640650
}
@@ -664,6 +674,7 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
664674
struct net_device *netdev = rq->netdev;
665675
int lro_num_seg;
666676

677+
skb->mac_len = ETH_HLEN;
667678
lro_num_seg = be32_to_cpu(cqe->srqn) >> 24;
668679
if (lro_num_seg > 1) {
669680
mlx5e_lro_update_hdr(skb, cqe, cqe_bcnt);

0 commit comments

Comments
 (0)