From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id EFDAAA0501 for ; Thu, 5 May 2022 12:27:46 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B93A44282F; Thu, 5 May 2022 12:27:46 +0200 (CEST) Received: from us-smtp-delivery-74.mimecast.com (us-smtp-delivery-74.mimecast.com [170.10.129.74]) by mails.dpdk.org (Postfix) with ESMTP id 66D5B4283F for ; Thu, 5 May 2022 12:27:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1651746464; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+VSCWAsWs1Wtex/UdC1DCDn5c9HooEfhdBaMGzpHPVA=; b=fgWTsqxFpPhIrBJBe6uGTansxj7C/0oro+5wEeb7sKFgAlLpzAKQ6J5hiI4OM2GfmU0dTi 5Xi4aShq7nyZ1mQTOr+84v8bApoPVO/+gE2hBVpdcU73o9z0DziWhy4hLo2RR62HK3DKsL 4jEUbklLB0XT3/cZerdvzsm06EcUkZg= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-523-X9F1FDn2N2CR44T1ZuVhhQ-1; Thu, 05 May 2022 06:27:44 -0400 X-MC-Unique: X9F1FDn2N2CR44T1ZuVhhQ-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id AAE5E833961; Thu, 5 May 2022 10:27:43 +0000 (UTC) Received: from max-t490s.redhat.com (unknown [10.39.208.18]) by smtp.corp.redhat.com (Postfix) with ESMTP id 73563416157; Thu, 5 May 2022 10:27:42 +0000 (UTC) From: Maxime Coquelin To: dev@dpdk.org, jasowang@redhat.com, chenbo.xia@intel.com, david.marchand@redhat.com, olivier.matz@6wind.com Cc: stable@dpdk.org, Maxime Coquelin Subject: [PATCH 6/6] net/vhost: perform SW checksum in Tx path Date: Thu, 5 May 2022 12:27:29 +0200 Message-Id: <20220505102729.821075-7-maxime.coquelin@redhat.com> In-Reply-To: <20220505102729.821075-1-maxime.coquelin@redhat.com> References: <20220505102729.821075-1-maxime.coquelin@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.85 on 10.11.54.10 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=maxime.coquelin@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Virtio specification supports guest checksum offloading for L4, which is enabled with VIRTIO_NET_F_GUEST_CSUM feature negotiation. However, the Vhost PMD does not advertise Tx checksum offload capabilities. Advertising these offload capabilities at the ethdev level is not enough, because we could still end-up with the application enabling these offloads while the guest not negotiating it. This patch advertizes the Tx checksum offload capabilities, and introduces a compatibility layer to cover the case VIRTIO_NET_F_GUEST_CSUM has not been negotiated but the application does configure the Tx checksum offloads. This function performs the L4 Tx checksum in SW for UDP and TCP. Compared to Rx SW checksum, the Tx SW checksum function needs to compute the pseudo-header checksum, as we cannot knwo whether it was done before. This patch does not advertize SCTP checksum offloading capability for now, but it could be handled later if the need arises. Reported-by: Jason Wang Signed-off-by: Maxime Coquelin --- drivers/net/vhost/rte_eth_vhost.c | 62 +++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c index d5303f7368..52a802de05 100644 --- a/drivers/net/vhost/rte_eth_vhost.c +++ b/drivers/net/vhost/rte_eth_vhost.c @@ -114,6 +114,7 @@ struct pmd_internal { rte_atomic32_t started; bool vlan_strip; bool rx_sw_csum; + bool tx_sw_csum; }; struct internal_list { @@ -370,8 +371,10 @@ vhost_dev_csum_configure(struct rte_eth_dev *eth_dev) { struct pmd_internal *internal = eth_dev->data->dev_private; const struct rte_eth_rxmode *rxmode = ð_dev->data->dev_conf.rxmode; + const struct rte_eth_txmode *txmode = ð_dev->data->dev_conf.txmode; internal->rx_sw_csum = false; + internal->tx_sw_csum = false; /* SW checksum is not compatible with legacy mode */ if (!(internal->flags & RTE_VHOST_USER_NET_COMPLIANT_OL_FLAGS)) @@ -384,6 +387,56 @@ vhost_dev_csum_configure(struct rte_eth_dev *eth_dev) internal->rx_sw_csum = true; } } + + if (!(internal->features & (1ULL << VIRTIO_NET_F_GUEST_CSUM))) { + if (txmode->offloads & + (RTE_ETH_TX_OFFLOAD_UDP_CKSUM | RTE_ETH_TX_OFFLOAD_TCP_CKSUM)) { + VHOST_LOG(NOTICE, "Tx csum will be done in SW, may impact performance."); + internal->tx_sw_csum = true; + } + } +} + +static void +vhost_dev_tx_sw_csum(struct rte_mbuf *mbuf) +{ + uint32_t hdr_len; + uint16_t csum = 0, csum_offset; + + switch (mbuf->ol_flags & RTE_MBUF_F_TX_L4_MASK) { + case RTE_MBUF_F_TX_L4_NO_CKSUM: + return; + case RTE_MBUF_F_TX_TCP_CKSUM: + csum_offset = offsetof(struct rte_tcp_hdr, cksum); + break; + case RTE_MBUF_F_TX_UDP_CKSUM: + csum_offset = offsetof(struct rte_udp_hdr, dgram_cksum); + break; + default: + /* Unsupported packet type. */ + return; + } + + hdr_len = mbuf->l2_len + mbuf->l3_len; + csum_offset += hdr_len; + + /* Prepare the pseudo-header checksum */ + if (rte_net_intel_cksum_prepare(mbuf) < 0) + return; + + if (rte_raw_cksum_mbuf(mbuf, hdr_len, rte_pktmbuf_pkt_len(mbuf) - hdr_len, &csum) < 0) + return; + + csum = ~csum; + /* See RFC768 */ + if (unlikely((mbuf->packet_type & RTE_PTYPE_L4_UDP) && csum == 0)) + csum = 0xffff; + + if (rte_pktmbuf_data_len(mbuf) >= csum_offset + 1) + *rte_pktmbuf_mtod_offset(mbuf, uint16_t *, csum_offset) = csum; + + mbuf->ol_flags &= ~RTE_MBUF_F_TX_L4_MASK; + mbuf->ol_flags |= RTE_MBUF_F_TX_L4_NO_CKSUM; } static void @@ -513,6 +566,10 @@ eth_vhost_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs) } } + if (r->internal->tx_sw_csum) + vhost_dev_tx_sw_csum(m); + + bufs[nb_send] = m; ++nb_send; } @@ -1359,6 +1416,11 @@ eth_dev_info(struct rte_eth_dev *dev, dev_info->tx_offload_capa = RTE_ETH_TX_OFFLOAD_MULTI_SEGS | RTE_ETH_TX_OFFLOAD_VLAN_INSERT; + if (internal->flags & RTE_VHOST_USER_NET_COMPLIANT_OL_FLAGS) { + dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_UDP_CKSUM | + RTE_ETH_TX_OFFLOAD_TCP_CKSUM; + } + dev_info->rx_offload_capa = RTE_ETH_RX_OFFLOAD_VLAN_STRIP; if (internal->flags & RTE_VHOST_USER_NET_COMPLIANT_OL_FLAGS) { dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_UDP_CKSUM | -- 2.35.1