From patchwork Sun Oct 17 20:37:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Georg Sauthoff X-Patchwork-Id: 101927 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id E7FEBA0547; Sun, 17 Oct 2021 22:38:16 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C95D840042; Sun, 17 Oct 2021 22:38:16 +0200 (CEST) Received: from turing.lru.li (turing.lru.li [49.12.115.177]) by mails.dpdk.org (Postfix) with ESMTP id C735D4003C for ; Sun, 17 Oct 2021 22:38:15 +0200 (CEST) Received: from dell12.lru.li (unknown [IPv6:2001:1a80:303a:0:faca:b8ff:fe50:d072]) (Authenticated sender: georg) by turing.lru.li (Postfix) with ESMTPSA id 6BAF65EF976; Sun, 17 Oct 2021 20:38:15 +0000 (UTC) Received: by dell12.lru.li (Postfix, from userid 1000) id 0C6781A6F22; Sun, 17 Oct 2021 22:38:15 +0200 (CEST) From: Georg Sauthoff To: =?utf-8?q?Morten_Br=C3=B8rup?= , Olivier Matz , Thomas Monjalon , David Marchand Cc: dev@dpdk.org, Georg Sauthoff Date: Sun, 17 Oct 2021 22:37:18 +0200 Message-Id: <20211017203718.801998-2-mail@gms.tf> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211017203718.801998-1-mail@gms.tf> References: <20211017203718.801998-1-mail@gms.tf> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 1/1] net: fix aliasing issue in checksum computation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" That means a superfluous cast is removed and aliasing through a uint8_t pointer is eliminated. NB: The C standard specifies that a unsigned char pointer may alias while the C standard doesn't include such requirement for uint8_t pointers. Also simplified the loop since a modern C compiler can speed up (i.e. auto-vectorize) it in a similar way. For example, GCC auto-vectorizes it for Haswell using AVX registers while halving the number of instructions in the generated code. Signed-off-by: Georg Sauthoff Reviewed-by: Morten Brørup Acked-by: Olivier Matz --- lib/net/rte_ip.h | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h index 05948b69b7..1b8c6519a9 100644 --- a/lib/net/rte_ip.h +++ b/lib/net/rte_ip.h @@ -141,29 +141,18 @@ rte_ipv4_hdr_len(const struct rte_ipv4_hdr *ipv4_hdr) static inline uint32_t __rte_raw_cksum(const void *buf, size_t len, uint32_t sum) { - /* workaround gcc strict-aliasing warning */ - uintptr_t ptr = (uintptr_t)buf; + /* extend strict-aliasing rules */ typedef uint16_t __attribute__((__may_alias__)) u16_p; - const u16_p *u16_buf = (const u16_p *)ptr; - - while (len >= (sizeof(*u16_buf) * 4)) { - sum += u16_buf[0]; - sum += u16_buf[1]; - sum += u16_buf[2]; - sum += u16_buf[3]; - len -= sizeof(*u16_buf) * 4; - u16_buf += 4; - } - while (len >= sizeof(*u16_buf)) { + const u16_p *u16_buf = (const u16_p *)buf; + const u16_p *end = u16_buf + len / sizeof(*u16_buf); + + for (; u16_buf != end; ++u16_buf) sum += *u16_buf; - len -= sizeof(*u16_buf); - u16_buf += 1; - } - /* if length is in odd bytes */ - if (len == 1) { + /* if length is odd, keeping it byte order independent */ + if (unlikely(len % 2)) { uint16_t left = 0; - *(uint8_t *)&left = *(const uint8_t *)u16_buf; + *(unsigned char*)&left = *(const unsigned char *)end; sum += left; }