From: Georg Sauthoff Date: Sun, 17 Oct 2021 20:37:18 +0000 (+0200) Subject: net: fix aliasing in checksum computation X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=24f1955d1ecd13a3c261a328c72932115732825e;p=dpdk.git net: fix aliasing in checksum computation 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. Fixes: 6006818cfb26 ("net: new checksum functions") Fixes: e079655c41fb ("net: fix build with gcc 4.4.7 and strict aliasing") Cc: stable@dpdk.org Signed-off-by: Georg Sauthoff Reviewed-by: Morten Brørup Acked-by: Olivier Matz --- diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h index 0ef2430607..41d90ca1b9 100644 --- a/lib/net/rte_ip.h +++ b/lib/net/rte_ip.h @@ -154,29 +154,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; }