[dpdk-dev] [PATCH 01/10] eal: add and use unaligned integer types

Cyril Chemparathy cchemparathy at ezchip.com
Wed Apr 29 18:15:25 CEST 2015


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.

This is currently unimplemented on ICC and clang, and equivalents will need to
be plugged in.

Signed-off-by: Cyril Chemparathy <cchemparathy at ezchip.com>
---
 app/test-pmd/flowgen.c                     |  4 ++--
 app/test-pmd/txonly.c                      |  2 +-
 app/test/packet_burst_generator.c          |  4 ++--
 app/test/test_mbuf.c                       | 16 ++++++++--------
 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 ++--
 7 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/app/test-pmd/flowgen.c b/app/test-pmd/flowgen.c
index 72016c9..174c003 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/txonly.c b/app/test-pmd/txonly.c
index ca32c85..9e66552 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 b46eed7..06762c6 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_mbuf.c b/app/test/test_mbuf.c
index 5e8a377..d9beb29 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/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index c0ab8b4..3bb97d1 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -61,6 +61,16 @@ extern "C" {
 
 /*********** Macros to eliminate unused variable warnings ********/
 
+#if defined(__GNUC__)
+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
+
 /**
  * short definition to mark a function parameter unused
  */
diff --git a/lib/librte_ether/rte_ether.h b/lib/librte_ether/rte_ether.h
index 49f4576..da25cb3 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 841ac14..279be6c 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.1.2



More information about the dev mailing list