From 7621d6a8d0bdb39b58ee7c4176a0f2e920b8113d Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Mon, 22 Jun 2015 11:34:19 -0700 Subject: [PATCH] eal: add and use unaligned integer types On machines that are strict on pointer alignment, current code breaks on GCC's -Wcast-align checks on casts from narrower to wider types. This patch introduces new unaligned_uint(16|32|64)_t types, which correctly retain alignment in such cases. Strict alignment architectures will need to define CONFIG_RTE_ARCH_STRICT_ALIGN in order to effect these new types. Signed-off-by: Cyril Chemparathy Acked-by: Olivier Matz --- app/test-pmd/flowgen.c | 4 ++-- app/test-pmd/icmpecho.c | 2 +- app/test-pmd/txonly.c | 2 +- app/test/packet_burst_generator.c | 4 ++-- app/test/test_hash_functions.c | 2 +- app/test/test_mbuf.c | 16 ++++++++-------- config/common_bsdapp | 5 +++++ config/common_linuxapp | 5 +++++ drivers/net/bonding/rte_eth_bond_pmd.c | 12 ++++++++---- lib/librte_eal/common/include/rte_common.h | 10 ++++++++++ lib/librte_ether/rte_ether.h | 2 +- lib/librte_ip_frag/rte_ipv4_reassembly.c | 4 ++-- 12 files changed, 46 insertions(+), 22 deletions(-) diff --git a/app/test-pmd/flowgen.c b/app/test-pmd/flowgen.c index 72016c9c77..174c003268 100644 --- a/app/test-pmd/flowgen.c +++ b/app/test-pmd/flowgen.c @@ -101,7 +101,7 @@ tx_mbuf_alloc(struct rte_mempool *mp) static inline uint16_t -ip_sum(const uint16_t *hdr, int hdr_len) +ip_sum(const unaligned_uint16_t *hdr, int hdr_len) { uint32_t sum = 0; @@ -193,7 +193,7 @@ pkt_burst_flow_gen(struct fwd_stream *fs) next_flow); ip_hdr->total_length = RTE_CPU_TO_BE_16(pkt_size - sizeof(*eth_hdr)); - ip_hdr->hdr_checksum = ip_sum((uint16_t *)ip_hdr, + ip_hdr->hdr_checksum = ip_sum((unaligned_uint16_t *)ip_hdr, sizeof(*ip_hdr)); /* Initialize UDP header. */ diff --git a/app/test-pmd/icmpecho.c b/app/test-pmd/icmpecho.c index 29aef71115..e510f9bf37 100644 --- a/app/test-pmd/icmpecho.c +++ b/app/test-pmd/icmpecho.c @@ -282,7 +282,7 @@ ipv4_hdr_cksum(struct ipv4_hdr *ip_h) * Compute the sum of successive 16-bit words of the IPv4 header, * skipping the checksum field of the header. */ - v16_h = (uint16_t *) ip_h; + v16_h = (unaligned_uint16_t *) ip_h; ip_cksum = v16_h[0] + v16_h[1] + v16_h[2] + v16_h[3] + v16_h[4] + v16_h[6] + v16_h[7] + v16_h[8] + v16_h[9]; diff --git a/app/test-pmd/txonly.c b/app/test-pmd/txonly.c index ca32c855ce..9e665524d1 100644 --- a/app/test-pmd/txonly.c +++ b/app/test-pmd/txonly.c @@ -167,7 +167,7 @@ setup_pkt_udp_ip_headers(struct ipv4_hdr *ip_hdr, /* * Compute IP header checksum. */ - ptr16 = (uint16_t*) ip_hdr; + ptr16 = (unaligned_uint16_t*) ip_hdr; ip_cksum = 0; ip_cksum += ptr16[0]; ip_cksum += ptr16[1]; ip_cksum += ptr16[2]; ip_cksum += ptr16[3]; diff --git a/app/test/packet_burst_generator.c b/app/test/packet_burst_generator.c index b46eed70f8..06762c689c 100644 --- a/app/test/packet_burst_generator.c +++ b/app/test/packet_burst_generator.c @@ -154,7 +154,7 @@ initialize_ipv4_header(struct ipv4_hdr *ip_hdr, uint32_t src_addr, uint32_t dst_addr, uint16_t pkt_data_len) { uint16_t pkt_len; - uint16_t *ptr16; + unaligned_uint16_t *ptr16; uint32_t ip_cksum; /* @@ -175,7 +175,7 @@ initialize_ipv4_header(struct ipv4_hdr *ip_hdr, uint32_t src_addr, /* * Compute IP header checksum. */ - ptr16 = (uint16_t *)ip_hdr; + ptr16 = (unaligned_uint16_t *)ip_hdr; ip_cksum = 0; ip_cksum += ptr16[0]; ip_cksum += ptr16[1]; ip_cksum += ptr16[2]; ip_cksum += ptr16[3]; diff --git a/app/test/test_hash_functions.c b/app/test/test_hash_functions.c index df7c909936..8c7cf63a63 100644 --- a/app/test/test_hash_functions.c +++ b/app/test/test_hash_functions.c @@ -223,7 +223,7 @@ verify_jhash_32bits(void) hash = rte_jhash(key, hashtest_key_lens[i], hashtest_initvals[j]); /* Divide key length by 4 in rte_jhash for 32 bits */ - hash32 = rte_jhash_32b((const uint32_t *)key, + hash32 = rte_jhash_32b((const unaligned_uint32_t *)key, hashtest_key_lens[i] >> 2, hashtest_initvals[j]); if (hash != hash32) { diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c index 5d13b374d9..b32bef6224 100644 --- a/app/test/test_mbuf.c +++ b/app/test/test_mbuf.c @@ -333,7 +333,7 @@ testclone_testupdate_testdetach(void) struct rte_mbuf *m = NULL; struct rte_mbuf *clone = NULL; struct rte_mbuf *clone2 = NULL; - uint32_t *data; + unaligned_uint32_t *data; /* alloc a mbuf */ m = rte_pktmbuf_alloc(pktmbuf_pool); @@ -344,7 +344,7 @@ testclone_testupdate_testdetach(void) GOTO_FAIL("Bad length"); rte_pktmbuf_append(m, sizeof(uint32_t)); - data = rte_pktmbuf_mtod(m, uint32_t *); + data = rte_pktmbuf_mtod(m, unaligned_uint32_t *); *data = MAGIC_DATA; /* clone the allocated mbuf */ @@ -352,7 +352,7 @@ testclone_testupdate_testdetach(void) if (clone == NULL) GOTO_FAIL("cannot clone data\n"); - data = rte_pktmbuf_mtod(clone, uint32_t *); + data = rte_pktmbuf_mtod(clone, unaligned_uint32_t *); if (*data != MAGIC_DATA) GOTO_FAIL("invalid data in clone\n"); @@ -369,18 +369,18 @@ testclone_testupdate_testdetach(void) GOTO_FAIL("Next Pkt Null\n"); rte_pktmbuf_append(m->next, sizeof(uint32_t)); - data = rte_pktmbuf_mtod(m->next, uint32_t *); + data = rte_pktmbuf_mtod(m->next, unaligned_uint32_t *); *data = MAGIC_DATA; clone = rte_pktmbuf_clone(m, pktmbuf_pool); if (clone == NULL) GOTO_FAIL("cannot clone data\n"); - data = rte_pktmbuf_mtod(clone, uint32_t *); + data = rte_pktmbuf_mtod(clone, unaligned_uint32_t *); if (*data != MAGIC_DATA) GOTO_FAIL("invalid data in clone\n"); - data = rte_pktmbuf_mtod(clone->next, uint32_t *); + data = rte_pktmbuf_mtod(clone->next, unaligned_uint32_t *); if (*data != MAGIC_DATA) GOTO_FAIL("invalid data in clone->next\n"); @@ -396,11 +396,11 @@ testclone_testupdate_testdetach(void) if (clone2 == NULL) GOTO_FAIL("cannot clone the clone\n"); - data = rte_pktmbuf_mtod(clone2, uint32_t *); + data = rte_pktmbuf_mtod(clone2, unaligned_uint32_t *); if (*data != MAGIC_DATA) GOTO_FAIL("invalid data in clone2\n"); - data = rte_pktmbuf_mtod(clone2->next, uint32_t *); + data = rte_pktmbuf_mtod(clone2->next, unaligned_uint32_t *); if (*data != MAGIC_DATA) GOTO_FAIL("invalid data in clone2->next\n"); diff --git a/config/common_bsdapp b/config/common_bsdapp index 434ba0bfa2..464250bb6d 100644 --- a/config/common_bsdapp +++ b/config/common_bsdapp @@ -73,6 +73,11 @@ CONFIG_RTE_EXEC_ENV_BSDAPP=y # CONFIG_RTE_FORCE_INTRINSICS=n +# +# Machine forces strict alignment constraints. +# +CONFIG_RTE_ARCH_STRICT_ALIGN=n + # # Compile to share library # diff --git a/config/common_linuxapp b/config/common_linuxapp index 724f692792..aae22f4b27 100644 --- a/config/common_linuxapp +++ b/config/common_linuxapp @@ -73,6 +73,11 @@ CONFIG_RTE_EXEC_ENV_LINUXAPP=y # CONFIG_RTE_FORCE_INTRINSICS=n +# +# Machine forces strict alignment constraints. +# +CONFIG_RTE_ARCH_STRICT_ALIGN=n + # # Compile to share library # diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c index 8bad2e18cc..5a2fbef933 100644 --- a/drivers/net/bonding/rte_eth_bond_pmd.c +++ b/drivers/net/bonding/rte_eth_bond_pmd.c @@ -466,8 +466,10 @@ bond_ethdev_tx_burst_active_backup(void *queue, static inline uint16_t ether_hash(struct ether_hdr *eth_hdr) { - uint16_t *word_src_addr = (uint16_t *)eth_hdr->s_addr.addr_bytes; - uint16_t *word_dst_addr = (uint16_t *)eth_hdr->d_addr.addr_bytes; + unaligned_uint16_t *word_src_addr = + (unaligned_uint16_t *)eth_hdr->s_addr.addr_bytes; + unaligned_uint16_t *word_dst_addr = + (unaligned_uint16_t *)eth_hdr->d_addr.addr_bytes; return (word_src_addr[0] ^ word_dst_addr[0]) ^ (word_src_addr[1] ^ word_dst_addr[1]) ^ @@ -483,8 +485,10 @@ ipv4_hash(struct ipv4_hdr *ipv4_hdr) static inline uint32_t ipv6_hash(struct ipv6_hdr *ipv6_hdr) { - uint32_t *word_src_addr = (uint32_t *)&(ipv6_hdr->src_addr[0]); - uint32_t *word_dst_addr = (uint32_t *)&(ipv6_hdr->dst_addr[0]); + unaligned_uint32_t *word_src_addr = + (unaligned_uint32_t *)&(ipv6_hdr->src_addr[0]); + unaligned_uint32_t *word_dst_addr = + (unaligned_uint32_t *)&(ipv6_hdr->dst_addr[0]); return (word_src_addr[0] ^ word_dst_addr[0]) ^ (word_src_addr[1] ^ word_dst_addr[1]) ^ diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h index 0ea1b499cb..3121314654 100644 --- a/lib/librte_eal/common/include/rte_common.h +++ b/lib/librte_eal/common/include/rte_common.h @@ -59,6 +59,16 @@ extern "C" { #define asm __asm__ #endif +#ifdef RTE_ARCH_STRICT_ALIGN +typedef uint64_t unaligned_uint64_t __attribute__ ((aligned(1))); +typedef uint32_t unaligned_uint32_t __attribute__ ((aligned(1))); +typedef uint16_t unaligned_uint16_t __attribute__ ((aligned(1))); +#else +typedef uint64_t unaligned_uint64_t; +typedef uint32_t unaligned_uint32_t; +typedef uint16_t unaligned_uint16_t; +#endif + /*********** Macros to eliminate unused variable warnings ********/ /** diff --git a/lib/librte_ether/rte_ether.h b/lib/librte_ether/rte_ether.h index a14308ecf6..07c17d7e0c 100644 --- a/lib/librte_ether/rte_ether.h +++ b/lib/librte_ether/rte_ether.h @@ -175,7 +175,7 @@ static inline int is_multicast_ether_addr(const struct ether_addr *ea) */ static inline int is_broadcast_ether_addr(const struct ether_addr *ea) { - const uint16_t *ea_words = (const uint16_t *)ea; + const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea; return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF && ea_words[2] == 0xFFFF); diff --git a/lib/librte_ip_frag/rte_ipv4_reassembly.c b/lib/librte_ip_frag/rte_ipv4_reassembly.c index a52f549f7b..dc4d036fde 100644 --- a/lib/librte_ip_frag/rte_ipv4_reassembly.c +++ b/lib/librte_ip_frag/rte_ipv4_reassembly.c @@ -120,7 +120,7 @@ rte_ipv4_frag_reassemble_packet(struct rte_ip_frag_tbl *tbl, { struct ip_frag_pkt *fp; struct ip_frag_key key; - const uint64_t *psd; + const unaligned_uint64_t *psd; uint16_t ip_len; uint16_t flag_offset, ip_ofs, ip_flag; @@ -128,7 +128,7 @@ rte_ipv4_frag_reassemble_packet(struct rte_ip_frag_tbl *tbl, ip_ofs = (uint16_t)(flag_offset & IPV4_HDR_OFFSET_MASK); ip_flag = (uint16_t)(flag_offset & IPV4_HDR_MF_FLAG); - psd = (uint64_t *)&ip_hdr->src_addr; + psd = (unaligned_uint64_t *)&ip_hdr->src_addr; /* use first 8 bytes only */ key.src_dst[0] = psd[0]; key.id = ip_hdr->packet_id; -- 2.20.1