All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/9] Improve cast alignment for strict aligned machines
@ 2015-06-22 18:34 Cyril Chemparathy
  2015-06-22 18:34 ` [PATCH v4 1/9] mempool: silence -Wcast-align on pointer arithmetic Cyril Chemparathy
                   ` (9 more replies)
  0 siblings, 10 replies; 13+ messages in thread
From: Cyril Chemparathy @ 2015-06-22 18:34 UTC (permalink / raw)
  To: dev

This series contains a few improvements that allow the DPDK code base
to build properly on machines that enforce strict pointer cast
alignment constraints.

When dealing with packet data which could be arbitrarily aligned, we
get the compiler to do the right thing by (a) making sure that header
types are packed, and (b) introducing and using
unaligned_uint(16|32|64)_t types when upcasting from byte pointers.

In a few other instances, we know apriori that the pointer cast cannot
possibly break alignment.  This applies to the changes in mempool,
hash, mbuf, and the ethdev stats code.  Here, we simply silence the
compiler by casting through (void *) using the RTE_PTR_(ADD|SUB)
macros.

Finally, we introduce a new rte_pktmbuf_mtod_offset() helper to return
a type casted pointer to an offset within the packet data.  This
replaces the following commonly used pattern:
	(struct foo *)(rte_pktmbuf_mtod(m, char *) + offset)
with:
	rte_pktmbuf_mtod_offset(m, struct foo *, offset)

To ensure consistency, the above transform was applied throughout the
code base using the coccinelle semantic patching tool.

Changes in this series:
  v2: Fixes based on Olivier's comments.
  v3: Extends unaligned fixes to new code introduced on master.
  v4: Fixes based on Thomas' comments.
      Extends unaligned fixes to new code introduced on master.

Cyril Chemparathy (9):
  mempool: silence -Wcast-align on pointer arithmetic
  mbuf: silence -Wcast-align on pointer arithmetic
  ethdev: silence -Wcast-align on pointer arithmetic
  hash: silence -Wcast-align on pointer arithmetic
  eal: add and use unaligned integer types
  app/test-pmd: pack simple_gre_hdr
  librte_mbuf: Add rte_pktmbuf_mtod_offset()
  librte_mbuf: Add transform for rte_pktmbuf_mtod_offset()
  librte_mbuf: Apply mtod-offset.cocci transform

 app/test-pmd/csumonly.c                    |  2 +-
 app/test-pmd/flowgen.c                     |  4 +-
 app/test-pmd/icmpecho.c                    |  2 +-
 app/test-pmd/ieee1588fwd.c                 |  4 +-
 app/test-pmd/rxonly.c                      | 21 +++++----
 app/test-pmd/txonly.c                      |  6 +--
 app/test/packet_burst_generator.c          |  9 ++--
 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 +++--
 drivers/net/mlx4/mlx4.c                    |  9 ++--
 examples/dpdk_qat/crypto.c                 |  8 ++--
 examples/dpdk_qat/main.c                   |  5 +-
 examples/l3fwd-acl/main.c                  | 20 ++++----
 examples/l3fwd-power/main.c                |  8 ++--
 examples/l3fwd-vf/main.c                   |  4 +-
 examples/l3fwd/main.c                      | 71 ++++++++++++----------------
 examples/load_balancer/runtime.c           |  4 +-
 examples/vhost_xen/main.c                  |  4 +-
 lib/librte_eal/common/include/rte_common.h | 10 ++++
 lib/librte_ether/rte_ethdev.c              | 24 +++++-----
 lib/librte_ether/rte_ether.h               |  2 +-
 lib/librte_hash/rte_hash.c                 | 10 ++--
 lib/librte_ip_frag/rte_ipv4_reassembly.c   |  7 ++-
 lib/librte_ip_frag/rte_ipv6_reassembly.c   |  5 +-
 lib/librte_mbuf/rte_mbuf.h                 | 32 +++++++++----
 lib/librte_mempool/rte_mempool.c           |  2 +-
 lib/librte_mempool/rte_mempool.h           |  6 +--
 lib/librte_port/rte_port_ras.c             |  6 +--
 lib/librte_vhost/vhost_rxtx.c              |  6 +--
 scripts/cocci.sh                           | 64 +++++++++++++++++++++++++
 scripts/cocci/mtod-offset.cocci            | 76 ++++++++++++++++++++++++++++++
 34 files changed, 319 insertions(+), 152 deletions(-)
 create mode 100755 scripts/cocci.sh
 create mode 100644 scripts/cocci/mtod-offset.cocci

-- 
2.1.2

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v4 1/9] mempool: silence -Wcast-align on pointer arithmetic
  2015-06-22 18:34 [PATCH v4 0/9] Improve cast alignment for strict aligned machines Cyril Chemparathy
@ 2015-06-22 18:34 ` Cyril Chemparathy
  2015-06-22 18:34 ` [PATCH v4 2/9] mbuf: " Cyril Chemparathy
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Cyril Chemparathy @ 2015-06-22 18:34 UTC (permalink / raw)
  To: dev

Translating from a mempool object to the mempool pointer does not break
alignment constraints.  However, the compiler is unaware of this fact and
complains on -Wcast-align.  This patch modifies the code to use RTE_PTR_SUB(),
thereby silencing the compiler by casting through (void *).

Change-Id: I4a67c9aa1bf012a0bf860d21bb8105db89062c76
Signed-off-by: Cyril Chemparathy <cchemparathy@ezchip.com>
---
 lib/librte_mempool/rte_mempool.c | 2 +-
 lib/librte_mempool/rte_mempool.h | 6 ++----
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index f592dc7..002d3a8 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -136,7 +136,7 @@ mempool_add_elem(struct rte_mempool *mp, void *obj, uint32_t obj_idx,
 	obj = (char *)obj + mp->header_size;
 
 	/* set mempool ptr in header */
-	hdr = (struct rte_mempool_objhdr *)((char *)obj - sizeof(*hdr));
+	hdr = RTE_PTR_SUB(obj, sizeof(*hdr));
 	hdr->mp = mp;
 
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
index a8054e1..380d60b 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -262,15 +262,13 @@ struct rte_mempool {
 /* return the header of a mempool object (internal) */
 static inline struct rte_mempool_objhdr *__mempool_get_header(void *obj)
 {
-	return (struct rte_mempool_objhdr *)((char *)obj -
-		sizeof(struct rte_mempool_objhdr));
+	return RTE_PTR_SUB(obj, sizeof(struct rte_mempool_objhdr));
 }
 
 /* return the trailer of a mempool object (internal) */
 static inline struct rte_mempool_objtlr *__mempool_get_trailer(void *obj)
 {
-	return (struct rte_mempool_objtlr *)((char *)obj -
-		sizeof(struct rte_mempool_objtlr));
+	return RTE_PTR_SUB(obj, sizeof(struct rte_mempool_objtlr));
 }
 
 /**
-- 
2.1.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 2/9] mbuf: silence -Wcast-align on pointer arithmetic
  2015-06-22 18:34 [PATCH v4 0/9] Improve cast alignment for strict aligned machines Cyril Chemparathy
  2015-06-22 18:34 ` [PATCH v4 1/9] mempool: silence -Wcast-align on pointer arithmetic Cyril Chemparathy
@ 2015-06-22 18:34 ` Cyril Chemparathy
  2015-06-22 18:34 ` [PATCH v4 3/9] ethdev: " Cyril Chemparathy
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Cyril Chemparathy @ 2015-06-22 18:34 UTC (permalink / raw)
  To: dev

Translating from an mbuf element to the mbuf pointer does not break alignment
constraints.  However, the compiler is unaware of this fact and complains on
-Wcast-align.  This patch modifies the code to use RTE_PTR_SUB(), thereby
silencing the compiler by casting through (void *).

Change-Id: I60d9b7a9205ff0befb8dbb4cdcb1df6f9d9d0250
Signed-off-by: Cyril Chemparathy <cchemparathy@ezchip.com>
---
 lib/librte_mbuf/rte_mbuf.h | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 6c9cfd6..6efd2b5 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -347,13 +347,7 @@ static inline uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp);
 static inline struct rte_mbuf *
 rte_mbuf_from_indirect(struct rte_mbuf *mi)
 {
-	struct rte_mbuf *md;
-
-	/* mi->buf_addr and mi->priv_size correspond to buffer and
-	 * private size of the direct mbuf */
-	md = (struct rte_mbuf *)((char *)mi->buf_addr - sizeof(*mi) -
-		mi->priv_size);
-	return md;
+	return RTE_PTR_SUB(mi->buf_addr, sizeof(*mi) + mi->priv_size);
 }
 
 /**
-- 
2.1.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 3/9] ethdev: silence -Wcast-align on pointer arithmetic
  2015-06-22 18:34 [PATCH v4 0/9] Improve cast alignment for strict aligned machines Cyril Chemparathy
  2015-06-22 18:34 ` [PATCH v4 1/9] mempool: silence -Wcast-align on pointer arithmetic Cyril Chemparathy
  2015-06-22 18:34 ` [PATCH v4 2/9] mbuf: " Cyril Chemparathy
@ 2015-06-22 18:34 ` Cyril Chemparathy
  2015-06-22 18:34 ` [PATCH v4 4/9] hash: " Cyril Chemparathy
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Cyril Chemparathy @ 2015-06-22 18:34 UTC (permalink / raw)
  To: dev

Statistics offsets in the rte_stats_strings[] array are always 64-bit aligned.
However, the compiler is unaware of this fact and complains on -Wcast-align.
This patch modifies the code to use RTE_PTR_ADD(), thereby silencing the
compiler by casting through (void *).

Change-Id: I6460b4b84b89dce6ac0b7b20e7002d53bcbd22db
Signed-off-by: Cyril Chemparathy <cchemparathy@ezchip.com>
---
 lib/librte_ether/rte_ethdev.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index e13fde5..02cd07f 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1742,8 +1742,7 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 	struct rte_eth_stats eth_stats;
 	struct rte_eth_dev *dev;
 	unsigned count, i, q;
-	uint64_t val;
-	char *stats_ptr;
+	uint64_t val, *stats_ptr;
 
 	if (!rte_eth_dev_is_valid_port(port_id)) {
 		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
@@ -1770,8 +1769,9 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 
 	/* global stats */
 	for (i = 0; i < RTE_NB_STATS; i++) {
-		stats_ptr = (char *)&eth_stats + rte_stats_strings[i].offset;
-		val = *(uint64_t *)stats_ptr;
+		stats_ptr = RTE_PTR_ADD(&eth_stats,
+					rte_stats_strings[i].offset);
+		val = *stats_ptr;
 		snprintf(xstats[count].name, sizeof(xstats[count].name),
 			"%s", rte_stats_strings[i].name);
 		xstats[count++].value = val;
@@ -1780,10 +1780,10 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 	/* per-rxq stats */
 	for (q = 0; q < dev->data->nb_rx_queues; q++) {
 		for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
-			stats_ptr = (char *)&eth_stats;
-			stats_ptr += rte_rxq_stats_strings[i].offset;
-			stats_ptr += q * sizeof(uint64_t);
-			val = *(uint64_t *)stats_ptr;
+			stats_ptr = RTE_PTR_ADD(&eth_stats,
+					rte_rxq_stats_strings[i].offset +
+					q * sizeof(uint64_t));
+			val = *stats_ptr;
 			snprintf(xstats[count].name, sizeof(xstats[count].name),
 				"rx_queue_%u_%s", q,
 				rte_rxq_stats_strings[i].name);
@@ -1794,10 +1794,10 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 	/* per-txq stats */
 	for (q = 0; q < dev->data->nb_tx_queues; q++) {
 		for (i = 0; i < RTE_NB_TXQ_STATS; i++) {
-			stats_ptr = (char *)&eth_stats;
-			stats_ptr += rte_txq_stats_strings[i].offset;
-			stats_ptr += q * sizeof(uint64_t);
-			val = *(uint64_t *)stats_ptr;
+			stats_ptr = RTE_PTR_ADD(&eth_stats,
+					rte_txq_stats_strings[i].offset +
+					q * sizeof(uint64_t));
+			val = *stats_ptr;
 			snprintf(xstats[count].name, sizeof(xstats[count].name),
 				"tx_queue_%u_%s", q,
 				rte_txq_stats_strings[i].name);
-- 
2.1.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 4/9] hash: silence -Wcast-align on pointer arithmetic
  2015-06-22 18:34 [PATCH v4 0/9] Improve cast alignment for strict aligned machines Cyril Chemparathy
                   ` (2 preceding siblings ...)
  2015-06-22 18:34 ` [PATCH v4 3/9] ethdev: " Cyril Chemparathy
@ 2015-06-22 18:34 ` Cyril Chemparathy
  2015-06-22 18:34 ` [PATCH v4 5/9] eal: add and use unaligned integer types Cyril Chemparathy
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Cyril Chemparathy @ 2015-06-22 18:34 UTC (permalink / raw)
  To: dev

Since sig_tbl_bucket_size and key_tbl_key_size are explicitly aligned
at initialization, offset dereferences in the hash table code cannot
possibly be unaligned.  However, the compiler is unaware of this fact
and complains on -Wcast-align.  This patch modifies the code to use
RTE_PTR_ADD(), thereby silencing the compiler by casting through (void
*).

Change-Id: Ia7102cf3f870752743cfe9f4443a3e53cd99bac1
Signed-off-by: Cyril Chemparathy <cchemparathy@ezchip.com>
---
 lib/librte_hash/rte_hash.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/librte_hash/rte_hash.c b/lib/librte_hash/rte_hash.c
index 9245716..67dff5b 100644
--- a/lib/librte_hash/rte_hash.c
+++ b/lib/librte_hash/rte_hash.c
@@ -96,23 +96,23 @@ EAL_REGISTER_TAILQ(rte_hash_tailq)
 static inline hash_sig_t *
 get_sig_tbl_bucket(const struct rte_hash *h, uint32_t bucket_index)
 {
-	return (hash_sig_t *)
-			&(h->sig_tbl[bucket_index * h->sig_tbl_bucket_size]);
+	return RTE_PTR_ADD(h->sig_tbl, (bucket_index *
+					h->sig_tbl_bucket_size));
 }
 
 /* Returns a pointer to the first key in specified bucket. */
 static inline uint8_t *
 get_key_tbl_bucket(const struct rte_hash *h, uint32_t bucket_index)
 {
-	return (uint8_t *) &(h->key_tbl[bucket_index * h->bucket_entries *
-				     h->key_tbl_key_size]);
+	return RTE_PTR_ADD(h->key_tbl, (bucket_index * h->bucket_entries *
+					h->key_tbl_key_size));
 }
 
 /* Returns a pointer to a key at a specific position in a specified bucket. */
 static inline void *
 get_key_from_bucket(const struct rte_hash *h, uint8_t *bkt, uint32_t pos)
 {
-	return (void *) &bkt[pos * h->key_tbl_key_size];
+	return RTE_PTR_ADD(bkt, pos * h->key_tbl_key_size);
 }
 
 /* Does integer division with rounding-up of result. */
-- 
2.1.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 5/9] eal: add and use unaligned integer types
  2015-06-22 18:34 [PATCH v4 0/9] Improve cast alignment for strict aligned machines Cyril Chemparathy
                   ` (3 preceding siblings ...)
  2015-06-22 18:34 ` [PATCH v4 4/9] hash: " Cyril Chemparathy
@ 2015-06-22 18:34 ` Cyril Chemparathy
  2015-06-22 18:34 ` [PATCH v4 6/9] app/test-pmd: pack simple_gre_hdr Cyril Chemparathy
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Cyril Chemparathy @ 2015-06-22 18:34 UTC (permalink / raw)
  To: dev

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.

Change-Id: I6f7c429fc14233c991287d065ecf2a09dbd65ebb
Signed-off-by: Cyril Chemparathy <cchemparathy@ezchip.com>
---
 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 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/icmpecho.c b/app/test-pmd/icmpecho.c
index 29aef71..e510f9b 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 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_hash_functions.c b/app/test/test_hash_functions.c
index df7c909..8c7cf63 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 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/config/common_bsdapp b/config/common_bsdapp
index 0b169c8..3af59d9 100644
--- a/config/common_bsdapp
+++ b/config/common_bsdapp
@@ -74,6 +74,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
 #
 CONFIG_RTE_BUILD_SHARED_LIB=n
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 5deb55a..a0b37d8 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -74,6 +74,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
 #
 CONFIG_RTE_BUILD_SHARED_LIB=n
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 8bad2e1..5a2fbef 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 c6e076b..dcff889 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 a14308e..07c17d7 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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 6/9] app/test-pmd: pack simple_gre_hdr
  2015-06-22 18:34 [PATCH v4 0/9] Improve cast alignment for strict aligned machines Cyril Chemparathy
                   ` (4 preceding siblings ...)
  2015-06-22 18:34 ` [PATCH v4 5/9] eal: add and use unaligned integer types Cyril Chemparathy
@ 2015-06-22 18:34 ` Cyril Chemparathy
  2015-06-22 18:34 ` [PATCH v4 7/9] librte_mbuf: Add rte_pktmbuf_mtod_offset() Cyril Chemparathy
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Cyril Chemparathy @ 2015-06-22 18:34 UTC (permalink / raw)
  To: dev

Not packing this causes -Wcast-align breakage on machines that are
strict on alignment.  This patch fixes this bug.

Acked-by: Olivier Matz <olivier.matz@6wind.com>
Change-Id: I7feab9ea4fc33c4ebdf3503ca67477ca0809bb7e
Signed-off-by: Cyril Chemparathy <cchemparathy@ezchip.com>
---
 app/test-pmd/csumonly.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index 950ea82..4287940 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -108,7 +108,7 @@ struct testpmd_offload_info {
 struct simple_gre_hdr {
 	uint16_t flags;
 	uint16_t proto;
-};
+} __attribute__((__packed__));
 
 static uint16_t
 get_psd_sum(void *l3_hdr, uint16_t ethertype, uint64_t ol_flags)
-- 
2.1.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 7/9] librte_mbuf: Add rte_pktmbuf_mtod_offset()
  2015-06-22 18:34 [PATCH v4 0/9] Improve cast alignment for strict aligned machines Cyril Chemparathy
                   ` (5 preceding siblings ...)
  2015-06-22 18:34 ` [PATCH v4 6/9] app/test-pmd: pack simple_gre_hdr Cyril Chemparathy
@ 2015-06-22 18:34 ` Cyril Chemparathy
  2015-06-22 18:34 ` [PATCH v4 8/9] librte_mbuf: Add transform for rte_pktmbuf_mtod_offset() Cyril Chemparathy
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Cyril Chemparathy @ 2015-06-22 18:34 UTC (permalink / raw)
  To: dev

There are a number of instances in the code where rte_pktmbuf_mtod()
is used to get the mbuf data pointer, only to add an offset before
casting the result to some other header type.  This patch adds a new
rte_pktmbuf_mtod_offset() macro to eliminate these awful double cast
situations.

Change-Id: I4dec35a15e44a7b8c767559a8d3b294177f39552
Signed-off-by: Cyril Chemparathy <cchemparathy@ezchip.com>
---
 lib/librte_mbuf/rte_mbuf.h | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 6efd2b5..396963c 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -54,6 +54,7 @@
  */
 
 #include <stdint.h>
+#include <rte_common.h>
 #include <rte_mempool.h>
 #include <rte_memory.h>
 #include <rte_atomic.h>
@@ -1080,18 +1081,35 @@ static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m)
 }
 
 /**
+ * A macro that points to an offset into the data in the mbuf.
+ *
+ * The returned pointer is cast to type t. Before using this
+ * function, the user must ensure that the first segment is large
+ * enough to accomodate its data.
+ *
+ * @param m
+ *   The packet mbuf.
+ * @param o
+ *   The offset into the mbuf data.
+ * @param t
+ *   The type to cast the result into.
+ */
+#define rte_pktmbuf_mtod_offset(m, t, o)	\
+	((t)((char *)(m)->buf_addr + (m)->data_off + (o)))
+
+/**
  * A macro that points to the start of the data in the mbuf.
  *
  * The returned pointer is cast to type t. Before using this
- * function, the user must ensure that m_headlen(m) is large enough to
- * read its data.
+ * function, the user must ensure that the first segment is large
+ * enough to accomodate its data.
  *
  * @param m
  *   The packet mbuf.
  * @param t
  *   The type to cast the result into.
  */
-#define rte_pktmbuf_mtod(m, t) ((t)((char *)(m)->buf_addr + (m)->data_off))
+#define rte_pktmbuf_mtod(m, t) rte_pktmbuf_mtod_offset(m, t, 0)
 
 /**
  * A macro that returns the length of the packet.
-- 
2.1.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 8/9] librte_mbuf: Add transform for rte_pktmbuf_mtod_offset()
  2015-06-22 18:34 [PATCH v4 0/9] Improve cast alignment for strict aligned machines Cyril Chemparathy
                   ` (6 preceding siblings ...)
  2015-06-22 18:34 ` [PATCH v4 7/9] librte_mbuf: Add rte_pktmbuf_mtod_offset() Cyril Chemparathy
@ 2015-06-22 18:34 ` Cyril Chemparathy
  2015-06-22 18:34 ` [PATCH v4 9/9] librte_mbuf: Apply mtod-offset.cocci transform Cyril Chemparathy
  2015-06-23 15:36 ` [PATCH v4 0/9] Improve cast alignment for strict aligned machines Olivier MATZ
  9 siblings, 0 replies; 13+ messages in thread
From: Cyril Chemparathy @ 2015-06-22 18:34 UTC (permalink / raw)
  To: dev

This patch adds a coccinelle (see http://coccinelle.lip6.fr/)
transform to use the newly added rte_pktmbuf_mtod_offset() helper.  In
addition, we add a simple script to apply all available transforms to
a codebase.

Acked-by: Olivier Matz <olivier.matz@6wind.com>
Change-Id: Ie1a82c48210098dd7bece81cc77cd5ea2da4148d
Signed-off-by: Cyril Chemparathy <cchemparathy@ezchip.com>
---
 scripts/cocci.sh                | 64 ++++++++++++++++++++++++++++++++++
 scripts/cocci/mtod-offset.cocci | 76 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+)
 create mode 100755 scripts/cocci.sh
 create mode 100644 scripts/cocci/mtod-offset.cocci

diff --git a/scripts/cocci.sh b/scripts/cocci.sh
new file mode 100755
index 0000000..7acc256
--- /dev/null
+++ b/scripts/cocci.sh
@@ -0,0 +1,64 @@
+#! /bin/sh
+
+# BSD LICENSE
+#
+# Copyright 2015 EZchip Semiconductor Ltd.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#   * Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#   * Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in
+#     the documentation and/or other materials provided with the
+#     distribution.
+#   * Neither the name of EZchip Semiconductor nor the names of its
+#     contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Apply coccinelle transforms.
+
+SRCTREE=$(readlink -f $(dirname $0)/..)
+COCCI=$SRCTREE/scripts/cocci
+[ -n "$SPATCH" ] || SPATCH=$(which spatch)
+
+PATCH_LIST="$@"
+[ -n "$PATCH_LIST" ] || PATCH_LIST=$(echo $COCCI/*.cocci)
+
+[ -x "$SPATCH" ] || (
+	echo "Coccinelle tools not installed."
+	exit 1
+)
+
+tmp=$(mktemp)
+
+for c in $PATCH_LIST; do
+	while true; do
+		echo -n "Applying $c..."
+		$SPATCH --sp-file $c -c --linux-spacing --very-quiet	\
+			--include-headers --preprocess			\
+			--in-place --dir $SRCTREE > $tmp
+		if [ -s $tmp ]; then
+			echo " changes applied, retrying."
+		else
+			echo " no change."
+			break;
+		fi
+	done
+done
+
+rm -f $tmp
diff --git a/scripts/cocci/mtod-offset.cocci b/scripts/cocci/mtod-offset.cocci
new file mode 100644
index 0000000..13134e9
--- /dev/null
+++ b/scripts/cocci/mtod-offset.cocci
@@ -0,0 +1,76 @@
+//
+// Replace explicit packet offset computations with rte_pktmbuf_mtod_offset().
+//
+@disable paren@
+typedef uint8_t;
+expression M, O;
+@@
+(
+- rte_pktmbuf_mtod(M, char *) + O
++ rte_pktmbuf_mtod_offset(M, char *, O)
+|
+- rte_pktmbuf_mtod(M, char *) - O
++ rte_pktmbuf_mtod_offset(M, char *, -O)
+|
+- rte_pktmbuf_mtod(M, unsigned char *) + O
++ rte_pktmbuf_mtod_offset(M, unsigned char *, O)
+|
+- rte_pktmbuf_mtod(M, unsigned char *) - O
++ rte_pktmbuf_mtod_offset(M, unsigned char *, -O)
+|
+- rte_pktmbuf_mtod(M, uint8_t *) + O
++ rte_pktmbuf_mtod_offset(M, uint8_t *, O)
+|
+- rte_pktmbuf_mtod(M, uint8_t *) - O
++ rte_pktmbuf_mtod_offset(M, uint8_t *, -O)
+)
+
+
+//
+// Fold subsequent offset terms into pre-existing offset used in
+// rte_pktmbuf_mtod_offset().
+//
+@disable paren@
+expression M, O1, O2;
+@@
+(
+- rte_pktmbuf_mtod_offset(M, char *, O1) + O2
++ rte_pktmbuf_mtod_offset(M, char *, O1 + O2)
+|
+- rte_pktmbuf_mtod_offset(M, char *, O1) - O2
++ rte_pktmbuf_mtod_offset(M, char *, O1 - O2)
+|
+- rte_pktmbuf_mtod_offset(M, unsigned char *, O1) + O2
++ rte_pktmbuf_mtod_offset(M, unsigned char *, O1 + O2)
+|
+- rte_pktmbuf_mtod_offset(M, unsigned char *, O1) - O2
++ rte_pktmbuf_mtod_offset(M, unsigned char *, O1 - O2)
+|
+- rte_pktmbuf_mtod_offset(M, uint8_t *, O1) + O2
++ rte_pktmbuf_mtod_offset(M, uint8_t *, O1 + O2)
+|
+- rte_pktmbuf_mtod_offset(M, uint8_t *, O1) - O2
++ rte_pktmbuf_mtod_offset(M, uint8_t *, O1 - O2)
+)
+
+
+//
+// Cleanup rules.  Fold in double casts, remove unnecessary paranthesis, etc.
+//
+@disable paren@
+expression M, O;
+type C, T;
+@@
+(
+- (C)rte_pktmbuf_mtod_offset(M, T, O)
++ rte_pktmbuf_mtod_offset(M, C, O)
+|
+- (rte_pktmbuf_mtod_offset(M, T, O))
++ rte_pktmbuf_mtod_offset(M, T, O)
+|
+- (C)rte_pktmbuf_mtod(M, T)
++ rte_pktmbuf_mtod(M, C)
+|
+- (rte_pktmbuf_mtod(M, T))
++ rte_pktmbuf_mtod(M, T)
+)
-- 
2.1.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 9/9] librte_mbuf: Apply mtod-offset.cocci transform
  2015-06-22 18:34 [PATCH v4 0/9] Improve cast alignment for strict aligned machines Cyril Chemparathy
                   ` (7 preceding siblings ...)
  2015-06-22 18:34 ` [PATCH v4 8/9] librte_mbuf: Add transform for rte_pktmbuf_mtod_offset() Cyril Chemparathy
@ 2015-06-22 18:34 ` Cyril Chemparathy
  2015-06-23 15:36 ` [PATCH v4 0/9] Improve cast alignment for strict aligned machines Olivier MATZ
  9 siblings, 0 replies; 13+ messages in thread
From: Cyril Chemparathy @ 2015-06-22 18:34 UTC (permalink / raw)
  To: dev

This patch simply applies the transform previously committed in
scripts/cocci/mtod-offset.cocci.  No other modifications have been
made here.

This patch applies on commit 960e8a22fc6d9373e37dd1454131e91f082bb8bc.
This patch may need to be regenerated by rerunning scripts/cocci.sh
instead of simply merging in the change.

Acked-by: Olivier Matz <olivier.matz@6wind.com>
Change-Id: I1cdc4fe6f7954cebb520e495a9454cb586cace54
Signed-off-by: Cyril Chemparathy <cchemparathy@ezchip.com>
---
 app/test-pmd/ieee1588fwd.c               |  4 +-
 app/test-pmd/rxonly.c                    | 21 ++++++----
 app/test-pmd/txonly.c                    |  4 +-
 app/test/packet_burst_generator.c        |  5 ++-
 drivers/net/mlx4/mlx4.c                  |  9 ++--
 examples/dpdk_qat/crypto.c               |  8 ++--
 examples/dpdk_qat/main.c                 |  5 ++-
 examples/l3fwd-acl/main.c                | 20 ++++-----
 examples/l3fwd-power/main.c              |  8 ++--
 examples/l3fwd-vf/main.c                 |  4 +-
 examples/l3fwd/main.c                    | 71 ++++++++++++++------------------
 examples/load_balancer/runtime.c         |  4 +-
 examples/vhost_xen/main.c                |  4 +-
 lib/librte_ip_frag/rte_ipv4_reassembly.c |  3 +-
 lib/librte_ip_frag/rte_ipv6_reassembly.c |  5 +--
 lib/librte_port/rte_port_ras.c           |  6 +--
 lib/librte_vhost/vhost_rxtx.c            |  6 +--
 17 files changed, 90 insertions(+), 97 deletions(-)

diff --git a/app/test-pmd/ieee1588fwd.c b/app/test-pmd/ieee1588fwd.c
index 84237c1..dfbb185 100644
--- a/app/test-pmd/ieee1588fwd.c
+++ b/app/test-pmd/ieee1588fwd.c
@@ -573,8 +573,8 @@ ieee1588_packet_fwd(struct fwd_stream *fs)
 	 * Check that the received PTP packet is a PTP V2 packet of type
 	 * PTP_SYNC_MESSAGE.
 	 */
-	ptp_hdr = (struct ptpv2_msg *) (rte_pktmbuf_mtod(mb, char *) +
-					sizeof(struct ether_hdr));
+	ptp_hdr = rte_pktmbuf_mtod_offset(mb, struct ptpv2_msg *,
+					  sizeof(struct ether_hdr));
 	if (ptp_hdr->version != 0x02) {
 		printf("Port %u Received PTP V2 Ethernet frame with wrong PTP"
 		       " protocol version 0x%x (should be 0x02)\n",
diff --git a/app/test-pmd/rxonly.c b/app/test-pmd/rxonly.c
index ac56090..b8e35ab 100644
--- a/app/test-pmd/rxonly.c
+++ b/app/test-pmd/rxonly.c
@@ -175,22 +175,25 @@ pkt_burst_receive(struct fwd_stream *fs)
 			 /* Do not support ipv4 option field */
 			if (ol_flags & PKT_RX_TUNNEL_IPV4_HDR) {
 				l3_len = sizeof(struct ipv4_hdr);
-				ipv4_hdr = (struct ipv4_hdr *) (rte_pktmbuf_mtod(mb,
-						unsigned char *) + l2_len);
+				ipv4_hdr = rte_pktmbuf_mtod_offset(mb,
+								   struct ipv4_hdr *,
+								   l2_len);
 				l4_proto = ipv4_hdr->next_proto_id;
 			} else {
 				l3_len = sizeof(struct ipv6_hdr);
-				ipv6_hdr = (struct ipv6_hdr *) (rte_pktmbuf_mtod(mb,
-						unsigned char *) + l2_len);
+				ipv6_hdr = rte_pktmbuf_mtod_offset(mb,
+								   struct ipv6_hdr *,
+								   l2_len);
 				l4_proto = ipv6_hdr->proto;
 			}
 			if (l4_proto == IPPROTO_UDP) {
-				udp_hdr = (struct udp_hdr *) (rte_pktmbuf_mtod(mb,
-						unsigned char *) + l2_len + l3_len);
+				udp_hdr = rte_pktmbuf_mtod_offset(mb,
+								  struct udp_hdr *,
+								  l2_len + l3_len);
 				l4_len = sizeof(struct udp_hdr);
-				vxlan_hdr = (struct vxlan_hdr *) (rte_pktmbuf_mtod(mb,
-						unsigned char *) + l2_len + l3_len
-						 + l4_len);
+				vxlan_hdr = rte_pktmbuf_mtod_offset(mb,
+								    struct vxlan_hdr *,
+								    l2_len + l3_len + l4_len);
 
 				printf(" - VXLAN packet: packet type =%d, "
 					"Destination UDP port =%d, VNI = %d",
diff --git a/app/test-pmd/txonly.c b/app/test-pmd/txonly.c
index 9e66552..f8027f1 100644
--- a/app/test-pmd/txonly.c
+++ b/app/test-pmd/txonly.c
@@ -110,7 +110,7 @@ copy_buf_to_pkt_segs(void* buf, unsigned len, struct rte_mbuf *pkt,
 		seg = seg->next;
 	}
 	copy_len = seg->data_len - offset;
-	seg_buf = (rte_pktmbuf_mtod(seg, char *) + offset);
+	seg_buf = rte_pktmbuf_mtod_offset(seg, char *, offset);
 	while (len > copy_len) {
 		rte_memcpy(seg_buf, buf, (size_t) copy_len);
 		len -= copy_len;
@@ -125,7 +125,7 @@ static inline void
 copy_buf_to_pkt(void* buf, unsigned len, struct rte_mbuf *pkt, unsigned offset)
 {
 	if (offset + len <= pkt->data_len) {
-		rte_memcpy((rte_pktmbuf_mtod(pkt, char *) + offset),
+		rte_memcpy(rte_pktmbuf_mtod_offset(pkt, char *, offset),
 			buf, (size_t) len);
 		return;
 	}
diff --git a/app/test/packet_burst_generator.c b/app/test/packet_burst_generator.c
index 06762c6..28d9e25 100644
--- a/app/test/packet_burst_generator.c
+++ b/app/test/packet_burst_generator.c
@@ -59,7 +59,7 @@ copy_buf_to_pkt_segs(void *buf, unsigned len, struct rte_mbuf *pkt,
 		seg = seg->next;
 	}
 	copy_len = seg->data_len - offset;
-	seg_buf = rte_pktmbuf_mtod(seg, char *) + offset;
+	seg_buf = rte_pktmbuf_mtod_offset(seg, char *, offset);
 	while (len > copy_len) {
 		rte_memcpy(seg_buf, buf, (size_t) copy_len);
 		len -= copy_len;
@@ -74,7 +74,8 @@ static inline void
 copy_buf_to_pkt(void *buf, unsigned len, struct rte_mbuf *pkt, unsigned offset)
 {
 	if (offset + len <= pkt->data_len) {
-		rte_memcpy(rte_pktmbuf_mtod(pkt, char *) + offset, buf, (size_t) len);
+		rte_memcpy(rte_pktmbuf_mtod_offset(pkt, char *, offset), buf,
+			   (size_t) len);
 		return;
 	}
 	copy_buf_to_pkt_segs(buf, len, pkt, offset);
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index fde23e1..5391b7a 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -1104,10 +1104,10 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 			linearize = 1;
 		}
 		/* Set WR fields. */
-		assert(((uintptr_t)rte_pktmbuf_mtod(buf, char *) -
+		assert((rte_pktmbuf_mtod(buf, uintptr_t) -
 			(uintptr_t)buf) <= 0xffff);
 		WR_ID(wr->wr_id).offset =
-			((uintptr_t)rte_pktmbuf_mtod(buf, char *) -
+			(rte_pktmbuf_mtod(buf, uintptr_t) -
 			 (uintptr_t)buf);
 		wr->num_sge = segs;
 		/* Register segments as SGEs. */
@@ -1142,7 +1142,7 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 			assert(sge->length == 0);
 			assert(sge->lkey == 0);
 			/* Update SGE. */
-			sge->addr = (uintptr_t)rte_pktmbuf_mtod(buf, char *);
+			sge->addr = rte_pktmbuf_mtod(buf, uintptr_t);
 			if (txq->priv->vf)
 				rte_prefetch0((volatile void *)
 					(uintptr_t)sge->addr);
@@ -1593,8 +1593,7 @@ rxq_alloc_elts_sp(struct rxq *rxq, unsigned int elts_n,
 			assert(sizeof(sge->addr) >= sizeof(uintptr_t));
 			if (j == 0) {
 				/* The first SGE keeps its headroom. */
-				sge->addr = (uintptr_t)rte_pktmbuf_mtod(buf,
-									char *);
+				sge->addr = rte_pktmbuf_mtod(buf, uintptr_t);
 				sge->length = (buf->buf_len -
 					       RTE_PKTMBUF_HEADROOM);
 			} else {
diff --git a/examples/dpdk_qat/crypto.c b/examples/dpdk_qat/crypto.c
index 00e0eb5..c03ea78 100644
--- a/examples/dpdk_qat/crypto.c
+++ b/examples/dpdk_qat/crypto.c
@@ -772,8 +772,8 @@ enum crypto_result
 crypto_encrypt(struct rte_mbuf *rte_buff, enum cipher_alg c, enum hash_alg h)
 {
 	CpaCySymDpOpData *opData =
-			(CpaCySymDpOpData *) (rte_pktmbuf_mtod(rte_buff, char *)
-					+ CRYPTO_OFFSET_TO_OPDATA);
+			rte_pktmbuf_mtod_offset(rte_buff, CpaCySymDpOpData *,
+						CRYPTO_OFFSET_TO_OPDATA);
 	uint32_t lcore_id;
 
 	if (unlikely(c >= NUM_CRYPTO || h >= NUM_HMAC))
@@ -847,8 +847,8 @@ enum crypto_result
 crypto_decrypt(struct rte_mbuf *rte_buff, enum cipher_alg c, enum hash_alg h)
 {
 
-	CpaCySymDpOpData *opData = (void*) (rte_pktmbuf_mtod(rte_buff, char *)
-			+ CRYPTO_OFFSET_TO_OPDATA);
+	CpaCySymDpOpData *opData = rte_pktmbuf_mtod_offset(rte_buff, void *,
+							   CRYPTO_OFFSET_TO_OPDATA);
 	uint32_t lcore_id;
 
 	if (unlikely(c >= NUM_CRYPTO || h >= NUM_HMAC))
diff --git a/examples/dpdk_qat/main.c b/examples/dpdk_qat/main.c
index c66a8cc..dc68989 100644
--- a/examples/dpdk_qat/main.c
+++ b/examples/dpdk_qat/main.c
@@ -325,8 +325,9 @@ main_loop(__attribute__((unused)) void *dummy)
 			continue;
 		/* Send packet to either QAT encrypt, QAT decrypt or NIC TX */
 		if (pkt_from_nic_rx) {
-			struct ipv4_hdr *ip  = (struct ipv4_hdr *) (rte_pktmbuf_mtod(pkt, unsigned char *) +
-					sizeof(struct ether_hdr));
+			struct ipv4_hdr *ip  = rte_pktmbuf_mtod_offset(pkt,
+								       struct ipv4_hdr *,
+								       sizeof(struct ether_hdr));
 			if (ip->src_addr & rte_cpu_to_be_32(ACTION_ENCRYPT)) {
 				if (CRYPTO_RESULT_FAIL == crypto_encrypt(pkt,
 					(enum cipher_alg)((ip->src_addr >> 16) & 0xFF),
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index a5d4f25..29cb25e 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -216,9 +216,9 @@ send_single_packet(struct rte_mbuf *m, uint8_t port);
 #define OFF_IPV42PROTO (offsetof(struct ipv4_hdr, next_proto_id))
 #define OFF_IPV62PROTO (offsetof(struct ipv6_hdr, proto))
 #define MBUF_IPV4_2PROTO(m)	\
-	(rte_pktmbuf_mtod((m), uint8_t *) + OFF_ETHHEAD + OFF_IPV42PROTO)
+	rte_pktmbuf_mtod_offset((m), uint8_t *, OFF_ETHHEAD + OFF_IPV42PROTO)
 #define MBUF_IPV6_2PROTO(m)	\
-	(rte_pktmbuf_mtod((m), uint8_t *) + OFF_ETHHEAD + OFF_IPV62PROTO)
+	rte_pktmbuf_mtod_offset((m), uint8_t *, OFF_ETHHEAD + OFF_IPV62PROTO)
 
 #define GET_CB_FIELD(in, fd, base, lim, dlm)	do {            \
 	unsigned long val;                                      \
@@ -564,9 +564,9 @@ dump_acl4_rule(struct rte_mbuf *m, uint32_t sig)
 {
 	uint32_t offset = sig & ~ACL_DENY_SIGNATURE;
 	unsigned char a, b, c, d;
-	struct ipv4_hdr *ipv4_hdr = (struct ipv4_hdr *)
-					(rte_pktmbuf_mtod(m, unsigned char *) +
-					sizeof(struct ether_hdr));
+	struct ipv4_hdr *ipv4_hdr = rte_pktmbuf_mtod_offset(m,
+							    struct ipv4_hdr *,
+							    sizeof(struct ether_hdr));
 
 	uint32_t_to_char(rte_bswap32(ipv4_hdr->src_addr), &a, &b, &c, &d);
 	printf("Packet Src:%hhu.%hhu.%hhu.%hhu ", a, b, c, d);
@@ -588,9 +588,9 @@ dump_acl6_rule(struct rte_mbuf *m, uint32_t sig)
 {
 	unsigned i;
 	uint32_t offset = sig & ~ACL_DENY_SIGNATURE;
-	struct ipv6_hdr *ipv6_hdr = (struct ipv6_hdr *)
-					(rte_pktmbuf_mtod(m, unsigned char *) +
-					sizeof(struct ether_hdr));
+	struct ipv6_hdr *ipv6_hdr = rte_pktmbuf_mtod_offset(m,
+							    struct ipv6_hdr *,
+							    sizeof(struct ether_hdr));
 
 	printf("Packet Src");
 	for (i = 0; i < RTE_DIM(ipv6_hdr->src_addr); i += sizeof(uint16_t))
@@ -649,8 +649,8 @@ prepare_one_packet(struct rte_mbuf **pkts_in, struct acl_search_t *acl,
 
 	if (type == PKT_RX_IPV4_HDR) {
 
-		ipv4_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(pkt,
-			unsigned char *) + sizeof(struct ether_hdr));
+		ipv4_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv4_hdr *,
+						   sizeof(struct ether_hdr));
 
 		/* Check to make sure the packet is valid (RFC1812) */
 		if (is_valid_ipv4_pkt(ipv4_hdr, pkt->pkt_len) >= 0) {
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 6057059..d4eba1a 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -638,8 +638,8 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid,
 	if (m->ol_flags & PKT_RX_IPV4_HDR) {
 		/* Handle IPv4 headers.*/
 		ipv4_hdr =
-			(struct ipv4_hdr *)(rte_pktmbuf_mtod(m, unsigned char*)
-						+ sizeof(struct ether_hdr));
+			rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
+						sizeof(struct ether_hdr));
 
 #ifdef DO_RFC_1812_CHECKS
 		/* Check to make sure the packet is valid (RFC1812) */
@@ -677,8 +677,8 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid,
 		struct ipv6_hdr *ipv6_hdr;
 
 		ipv6_hdr =
-			(struct ipv6_hdr *)(rte_pktmbuf_mtod(m, unsigned char*)
-						+ sizeof(struct ether_hdr));
+			rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *,
+						sizeof(struct ether_hdr));
 
 		dst_port = get_ipv6_dst_port(ipv6_hdr, portid,
 					qconf->ipv6_lookup_struct);
diff --git a/examples/l3fwd-vf/main.c b/examples/l3fwd-vf/main.c
index 6e56cfb..ccbb02f 100644
--- a/examples/l3fwd-vf/main.c
+++ b/examples/l3fwd-vf/main.c
@@ -459,8 +459,8 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, lookup_struct_t * l3fwd
 
 	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
 
-	ipv4_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(m, unsigned char *) +
-				sizeof(struct ether_hdr));
+	ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
+					   sizeof(struct ether_hdr));
 
 #ifdef DO_RFC_1812_CHECKS
 	/* Check to make sure the packet is valid (RFC1812) */
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 7e4bbfd..5c22ed1 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -753,14 +753,14 @@ simple_ipv4_fwd_4pkts(struct rte_mbuf* m[4], uint8_t portid, struct lcore_conf *
 	eth_hdr[3] = rte_pktmbuf_mtod(m[3], struct ether_hdr *);
 
 	/* Handle IPv4 headers.*/
-	ipv4_hdr[0] = (struct ipv4_hdr *)(rte_pktmbuf_mtod(m[0], unsigned char *) +
-			sizeof(struct ether_hdr));
-	ipv4_hdr[1] = (struct ipv4_hdr *)(rte_pktmbuf_mtod(m[1], unsigned char *) +
-			sizeof(struct ether_hdr));
-	ipv4_hdr[2] = (struct ipv4_hdr *)(rte_pktmbuf_mtod(m[2], unsigned char *) +
-			sizeof(struct ether_hdr));
-	ipv4_hdr[3] = (struct ipv4_hdr *)(rte_pktmbuf_mtod(m[3], unsigned char *) +
-			sizeof(struct ether_hdr));
+	ipv4_hdr[0] = rte_pktmbuf_mtod_offset(m[0], struct ipv4_hdr *,
+					      sizeof(struct ether_hdr));
+	ipv4_hdr[1] = rte_pktmbuf_mtod_offset(m[1], struct ipv4_hdr *,
+					      sizeof(struct ether_hdr));
+	ipv4_hdr[2] = rte_pktmbuf_mtod_offset(m[2], struct ipv4_hdr *,
+					      sizeof(struct ether_hdr));
+	ipv4_hdr[3] = rte_pktmbuf_mtod_offset(m[3], struct ipv4_hdr *,
+					      sizeof(struct ether_hdr));
 
 #ifdef DO_RFC_1812_CHECKS
 	/* Check to make sure the packet is valid (RFC1812) */
@@ -796,14 +796,10 @@ simple_ipv4_fwd_4pkts(struct rte_mbuf* m[4], uint8_t portid, struct lcore_conf *
 	}
 #endif // End of #ifdef DO_RFC_1812_CHECKS
 
-	data[0] = _mm_loadu_si128((__m128i*)(rte_pktmbuf_mtod(m[0], unsigned char *) +
-		sizeof(struct ether_hdr) + offsetof(struct ipv4_hdr, time_to_live)));
-	data[1] = _mm_loadu_si128((__m128i*)(rte_pktmbuf_mtod(m[1], unsigned char *) +
-		sizeof(struct ether_hdr) + offsetof(struct ipv4_hdr, time_to_live)));
-	data[2] = _mm_loadu_si128((__m128i*)(rte_pktmbuf_mtod(m[2], unsigned char *) +
-		sizeof(struct ether_hdr) + offsetof(struct ipv4_hdr, time_to_live)));
-	data[3] = _mm_loadu_si128((__m128i*)(rte_pktmbuf_mtod(m[3], unsigned char *) +
-		sizeof(struct ether_hdr) + offsetof(struct ipv4_hdr, time_to_live)));
+	data[0] = _mm_loadu_si128(rte_pktmbuf_mtod_offset(m[0], __m128i *, sizeof(struct ether_hdr) + offsetof(struct ipv4_hdr, time_to_live)));
+	data[1] = _mm_loadu_si128(rte_pktmbuf_mtod_offset(m[1], __m128i *, sizeof(struct ether_hdr) + offsetof(struct ipv4_hdr, time_to_live)));
+	data[2] = _mm_loadu_si128(rte_pktmbuf_mtod_offset(m[2], __m128i *, sizeof(struct ether_hdr) + offsetof(struct ipv4_hdr, time_to_live)));
+	data[3] = _mm_loadu_si128(rte_pktmbuf_mtod_offset(m[3], __m128i *, sizeof(struct ether_hdr) + offsetof(struct ipv4_hdr, time_to_live)));
 
 	key[0].xmm = _mm_and_si128(data[0], mask0);
 	key[1].xmm = _mm_and_si128(data[1], mask0);
@@ -860,14 +856,9 @@ simple_ipv4_fwd_4pkts(struct rte_mbuf* m[4], uint8_t portid, struct lcore_conf *
 static inline void get_ipv6_5tuple(struct rte_mbuf* m0, __m128i mask0, __m128i mask1,
 				 union ipv6_5tuple_host * key)
 {
-        __m128i tmpdata0 = _mm_loadu_si128((__m128i*)(rte_pktmbuf_mtod(m0, unsigned char *)
-			+ sizeof(struct ether_hdr) + offsetof(struct ipv6_hdr, payload_len)));
-        __m128i tmpdata1 = _mm_loadu_si128((__m128i*)(rte_pktmbuf_mtod(m0, unsigned char *)
-			+ sizeof(struct ether_hdr) + offsetof(struct ipv6_hdr, payload_len)
-			+  sizeof(__m128i)));
-        __m128i tmpdata2 = _mm_loadu_si128((__m128i*)(rte_pktmbuf_mtod(m0, unsigned char *)
-			+ sizeof(struct ether_hdr) + offsetof(struct ipv6_hdr, payload_len)
-			+ sizeof(__m128i) + sizeof(__m128i)));
+        __m128i tmpdata0 = _mm_loadu_si128(rte_pktmbuf_mtod_offset(m0, __m128i *, sizeof(struct ether_hdr) + offsetof(struct ipv6_hdr, payload_len)));
+        __m128i tmpdata1 = _mm_loadu_si128(rte_pktmbuf_mtod_offset(m0, __m128i *, sizeof(struct ether_hdr) + offsetof(struct ipv6_hdr, payload_len) + sizeof(__m128i)));
+        __m128i tmpdata2 = _mm_loadu_si128(rte_pktmbuf_mtod_offset(m0, __m128i *, sizeof(struct ether_hdr) + offsetof(struct ipv6_hdr, payload_len) + sizeof(__m128i) + sizeof(__m128i)));
         key->xmm[0] = _mm_and_si128(tmpdata0, mask0);
         key->xmm[1] = tmpdata1;
         key->xmm[2] = _mm_and_si128(tmpdata2, mask1);
@@ -889,14 +880,14 @@ simple_ipv6_fwd_4pkts(struct rte_mbuf* m[4], uint8_t portid, struct lcore_conf *
 	eth_hdr[3] = rte_pktmbuf_mtod(m[3], struct ether_hdr *);
 
 	/* Handle IPv6 headers.*/
-	ipv6_hdr[0] = (struct ipv6_hdr *)(rte_pktmbuf_mtod(m[0], unsigned char *) +
-			sizeof(struct ether_hdr));
-	ipv6_hdr[1] = (struct ipv6_hdr *)(rte_pktmbuf_mtod(m[1], unsigned char *) +
-			sizeof(struct ether_hdr));
-	ipv6_hdr[2] = (struct ipv6_hdr *)(rte_pktmbuf_mtod(m[2], unsigned char *) +
-			sizeof(struct ether_hdr));
-	ipv6_hdr[3] = (struct ipv6_hdr *)(rte_pktmbuf_mtod(m[3], unsigned char *) +
-			sizeof(struct ether_hdr));
+	ipv6_hdr[0] = rte_pktmbuf_mtod_offset(m[0], struct ipv6_hdr *,
+					      sizeof(struct ether_hdr));
+	ipv6_hdr[1] = rte_pktmbuf_mtod_offset(m[1], struct ipv6_hdr *,
+					      sizeof(struct ether_hdr));
+	ipv6_hdr[2] = rte_pktmbuf_mtod_offset(m[2], struct ipv6_hdr *,
+					      sizeof(struct ether_hdr));
+	ipv6_hdr[3] = rte_pktmbuf_mtod_offset(m[3], struct ipv6_hdr *,
+					      sizeof(struct ether_hdr));
 
 	get_ipv6_5tuple(m[0], mask1, mask2, &key[0]);
 	get_ipv6_5tuple(m[1], mask1, mask2, &key[1]);
@@ -950,8 +941,8 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, struct lcore_conf *qcon
 
 	if (m->ol_flags & PKT_RX_IPV4_HDR) {
 		/* Handle IPv4 headers.*/
-		ipv4_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(m, unsigned char *) +
-				sizeof(struct ether_hdr));
+		ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
+						   sizeof(struct ether_hdr));
 
 #ifdef DO_RFC_1812_CHECKS
 		/* Check to make sure the packet is valid (RFC1812) */
@@ -984,8 +975,8 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, struct lcore_conf *qcon
 		/* Handle IPv6 headers.*/
 		struct ipv6_hdr *ipv6_hdr;
 
-		ipv6_hdr = (struct ipv6_hdr *)(rte_pktmbuf_mtod(m, unsigned char *) +
-				sizeof(struct ether_hdr));
+		ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *,
+						   sizeof(struct ether_hdr));
 
 		dst_port = get_ipv6_dst_port(ipv6_hdr, portid, qconf->ipv6_lookup_struct);
 
@@ -1174,10 +1165,10 @@ processx4_step3(struct rte_mbuf *pkt[FWDSTEP], uint16_t dst_port[FWDSTEP])
 	__m128i ve[FWDSTEP];
 	__m128i *p[FWDSTEP];
 
-	p[0] = (rte_pktmbuf_mtod(pkt[0], __m128i *));
-	p[1] = (rte_pktmbuf_mtod(pkt[1], __m128i *));
-	p[2] = (rte_pktmbuf_mtod(pkt[2], __m128i *));
-	p[3] = (rte_pktmbuf_mtod(pkt[3], __m128i *));
+	p[0] = rte_pktmbuf_mtod(pkt[0], __m128i *);
+	p[1] = rte_pktmbuf_mtod(pkt[1], __m128i *);
+	p[2] = rte_pktmbuf_mtod(pkt[2], __m128i *);
+	p[3] = rte_pktmbuf_mtod(pkt[3], __m128i *);
 
 	ve[0] = val_eth[dst_port[0]];
 	te[0] = _mm_load_si128(p[0]);
diff --git a/examples/load_balancer/runtime.c b/examples/load_balancer/runtime.c
index adec4ba..2b265c2 100644
--- a/examples/load_balancer/runtime.c
+++ b/examples/load_balancer/runtime.c
@@ -535,7 +535,9 @@ app_lcore_worker(
 			}
 
 			pkt = lp->mbuf_in.array[j];
-			ipv4_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(pkt, unsigned char *) + sizeof(struct ether_hdr));
+			ipv4_hdr = rte_pktmbuf_mtod_offset(pkt,
+							   struct ipv4_hdr *,
+							   sizeof(struct ether_hdr));
 			ipv4_dst = rte_be_to_cpu_32(ipv4_hdr->dst_addr);
 
 			if (unlikely(rte_lpm_lookup(lp->lpm_table, ipv4_dst, &port) != 0)) {
diff --git a/examples/vhost_xen/main.c b/examples/vhost_xen/main.c
index 9e6f18e..5d20700 100644
--- a/examples/vhost_xen/main.c
+++ b/examples/vhost_xen/main.c
@@ -873,8 +873,8 @@ virtio_tx_route(struct virtio_net* dev, struct rte_mbuf *m, struct rte_mempool *
 	vlan_hdr->h_vlan_TCI = htons(vlan_tag);
 
 	/* Copy the remaining packet contents to the mbuf. */
-	rte_memcpy((void *)(rte_pktmbuf_mtod(mbuf, uint8_t *) + VLAN_ETH_HLEN),
-		(const void *)(rte_pktmbuf_mtod(m, uint8_t *) + ETH_HLEN),
+	rte_memcpy(rte_pktmbuf_mtod_offset(mbuf, void *, VLAN_ETH_HLEN),
+		rte_pktmbuf_mtod_offset(m, const void *, ETH_HLEN),
 		(m->data_len - ETH_HLEN));
 	tx_q->m_table[len] = mbuf;
 	len++;
diff --git a/lib/librte_ip_frag/rte_ipv4_reassembly.c b/lib/librte_ip_frag/rte_ipv4_reassembly.c
index 279be6c..14bab91 100644
--- a/lib/librte_ip_frag/rte_ipv4_reassembly.c
+++ b/lib/librte_ip_frag/rte_ipv4_reassembly.c
@@ -85,8 +85,7 @@ ipv4_frag_reassemble(const struct ip_frag_pkt *fp)
 	m->ol_flags |= PKT_TX_IP_CKSUM;
 
 	/* update ipv4 header for the reassmebled packet */
-	ip_hdr = (struct ipv4_hdr*)(rte_pktmbuf_mtod(m, uint8_t *) +
-		m->l2_len);
+	ip_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *, m->l2_len);
 
 	ip_hdr->total_length = rte_cpu_to_be_16((uint16_t)(fp->total_size +
 		m->l3_len));
diff --git a/lib/librte_ip_frag/rte_ipv6_reassembly.c b/lib/librte_ip_frag/rte_ipv6_reassembly.c
index 71cf721..1f1c172 100644
--- a/lib/librte_ip_frag/rte_ipv6_reassembly.c
+++ b/lib/librte_ip_frag/rte_ipv6_reassembly.c
@@ -108,8 +108,7 @@ ipv6_frag_reassemble(const struct ip_frag_pkt *fp)
 	m->ol_flags |= PKT_TX_IP_CKSUM;
 
 	/* update ipv6 header for the reassembled datagram */
-	ip_hdr = (struct ipv6_hdr *) (rte_pktmbuf_mtod(m, uint8_t *) +
-								  m->l2_len);
+	ip_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *, m->l2_len);
 
 	ip_hdr->payload_len = rte_cpu_to_be_16(payload_len);
 
@@ -124,7 +123,7 @@ ipv6_frag_reassemble(const struct ip_frag_pkt *fp)
 	frag_hdr = (struct ipv6_extension_fragment *) (ip_hdr + 1);
 	ip_hdr->proto = frag_hdr->next_header;
 
-	ip_frag_memmove(rte_pktmbuf_mtod(m, char*) + sizeof(*frag_hdr),
+	ip_frag_memmove(rte_pktmbuf_mtod_offset(m, char *, sizeof(*frag_hdr)),
 			rte_pktmbuf_mtod(m, char*), move_len);
 
 	rte_pktmbuf_adj(m, sizeof(*frag_hdr));
diff --git a/lib/librte_port/rte_port_ras.c b/lib/librte_port/rte_port_ras.c
index 5eb627a..d2edc6a 100644
--- a/lib/librte_port/rte_port_ras.c
+++ b/lib/librte_port/rte_port_ras.c
@@ -163,8 +163,7 @@ static void
 process_ipv4(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt)
 {
 	/* Assume there is no ethernet header */
-	struct ipv4_hdr *pkt_hdr = (struct ipv4_hdr *)
-			(rte_pktmbuf_mtod(pkt, unsigned char *));
+	struct ipv4_hdr *pkt_hdr = rte_pktmbuf_mtod(pkt, struct ipv4_hdr *);
 
 	/* Get "Do not fragment" flag and fragment offset */
 	uint16_t frag_field = rte_be_to_cpu_16(pkt_hdr->fragment_offset);
@@ -193,8 +192,7 @@ static void
 process_ipv6(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt)
 {
 	/* Assume there is no ethernet header */
-	struct ipv6_hdr *pkt_hdr = (struct ipv6_hdr *)
-			(rte_pktmbuf_mtod(pkt, unsigned char *));
+	struct ipv6_hdr *pkt_hdr = rte_pktmbuf_mtod(pkt, struct ipv6_hdr *);
 
 	struct ipv6_extension_fragment *frag_hdr;
 	frag_hdr = rte_ipv6_frag_get_ipv6_fragment_header(pkt_hdr);
diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 151d781..0d07338 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -152,7 +152,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
 		while (total_copied < pkt_len) {
 			/* Copy mbuf data to buffer */
 			rte_memcpy((void *)(uintptr_t)(buff_addr + vb_offset),
-				(const void *)(rte_pktmbuf_mtod(buff, const char *) + offset),
+				rte_pktmbuf_mtod_offset(buff, const void *, offset),
 				len_to_cpy);
 			PRINT_PACKET(dev, (uintptr_t)(buff_addr + vb_offset),
 				len_to_cpy, 0);
@@ -318,7 +318,7 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint16_t res_base_idx,
 	while (cpy_len > 0) {
 		/* Copy mbuf data to vring buffer */
 		rte_memcpy((void *)(uintptr_t)(vb_addr + vb_offset),
-			(const void *)(rte_pktmbuf_mtod(pkt, char*) + seg_offset),
+			rte_pktmbuf_mtod_offset(pkt, const void *, seg_offset),
 			cpy_len);
 
 		PRINT_PACKET(dev,
@@ -648,7 +648,7 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
 		cur = m;
 		prev = m;
 		while (cpy_len != 0) {
-			rte_memcpy((void *)(rte_pktmbuf_mtod(cur, char *) + seg_offset),
+			rte_memcpy(rte_pktmbuf_mtod_offset(cur, void *, seg_offset),
 				(void *)((uintptr_t)(vb_addr + vb_offset)),
 				cpy_len);
 
-- 
2.1.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 0/9] Improve cast alignment for strict aligned machines
  2015-06-22 18:34 [PATCH v4 0/9] Improve cast alignment for strict aligned machines Cyril Chemparathy
                   ` (8 preceding siblings ...)
  2015-06-22 18:34 ` [PATCH v4 9/9] librte_mbuf: Apply mtod-offset.cocci transform Cyril Chemparathy
@ 2015-06-23 15:36 ` Olivier MATZ
  2015-06-23 17:36   ` Cyril Chemparathy
  2015-06-24 10:04   ` Thomas Monjalon
  9 siblings, 2 replies; 13+ messages in thread
From: Olivier MATZ @ 2015-06-23 15:36 UTC (permalink / raw)
  To: Cyril Chemparathy, dev

Hi Cyril,

On 06/22/2015 08:34 PM, Cyril Chemparathy wrote:
> This series contains a few improvements that allow the DPDK code base
> to build properly on machines that enforce strict pointer cast
> alignment constraints.
>
> When dealing with packet data which could be arbitrarily aligned, we
> get the compiler to do the right thing by (a) making sure that header
> types are packed, and (b) introducing and using
> unaligned_uint(16|32|64)_t types when upcasting from byte pointers.
>
> In a few other instances, we know apriori that the pointer cast cannot
> possibly break alignment.  This applies to the changes in mempool,
> hash, mbuf, and the ethdev stats code.  Here, we simply silence the
> compiler by casting through (void *) using the RTE_PTR_(ADD|SUB)
> macros.
>
> Finally, we introduce a new rte_pktmbuf_mtod_offset() helper to return
> a type casted pointer to an offset within the packet data.  This
> replaces the following commonly used pattern:
> 	(struct foo *)(rte_pktmbuf_mtod(m, char *) + offset)
> with:
> 	rte_pktmbuf_mtod_offset(m, struct foo *, offset)
>
> To ensure consistency, the above transform was applied throughout the
> code base using the coccinelle semantic patching tool.

Series
Acked-by: Olivier Matz <olivier.matz@6wind.com>



>
> Changes in this series:
>    v2: Fixes based on Olivier's comments.
>    v3: Extends unaligned fixes to new code introduced on master.
>    v4: Fixes based on Thomas' comments.
>        Extends unaligned fixes to new code introduced on master.
>
> Cyril Chemparathy (9):
>    mempool: silence -Wcast-align on pointer arithmetic
>    mbuf: silence -Wcast-align on pointer arithmetic
>    ethdev: silence -Wcast-align on pointer arithmetic
>    hash: silence -Wcast-align on pointer arithmetic
>    eal: add and use unaligned integer types
>    app/test-pmd: pack simple_gre_hdr
>    librte_mbuf: Add rte_pktmbuf_mtod_offset()
>    librte_mbuf: Add transform for rte_pktmbuf_mtod_offset()
>    librte_mbuf: Apply mtod-offset.cocci transform
>
>   app/test-pmd/csumonly.c                    |  2 +-
>   app/test-pmd/flowgen.c                     |  4 +-
>   app/test-pmd/icmpecho.c                    |  2 +-
>   app/test-pmd/ieee1588fwd.c                 |  4 +-
>   app/test-pmd/rxonly.c                      | 21 +++++----
>   app/test-pmd/txonly.c                      |  6 +--
>   app/test/packet_burst_generator.c          |  9 ++--
>   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 +++--
>   drivers/net/mlx4/mlx4.c                    |  9 ++--
>   examples/dpdk_qat/crypto.c                 |  8 ++--
>   examples/dpdk_qat/main.c                   |  5 +-
>   examples/l3fwd-acl/main.c                  | 20 ++++----
>   examples/l3fwd-power/main.c                |  8 ++--
>   examples/l3fwd-vf/main.c                   |  4 +-
>   examples/l3fwd/main.c                      | 71 ++++++++++++----------------
>   examples/load_balancer/runtime.c           |  4 +-
>   examples/vhost_xen/main.c                  |  4 +-
>   lib/librte_eal/common/include/rte_common.h | 10 ++++
>   lib/librte_ether/rte_ethdev.c              | 24 +++++-----
>   lib/librte_ether/rte_ether.h               |  2 +-
>   lib/librte_hash/rte_hash.c                 | 10 ++--
>   lib/librte_ip_frag/rte_ipv4_reassembly.c   |  7 ++-
>   lib/librte_ip_frag/rte_ipv6_reassembly.c   |  5 +-
>   lib/librte_mbuf/rte_mbuf.h                 | 32 +++++++++----
>   lib/librte_mempool/rte_mempool.c           |  2 +-
>   lib/librte_mempool/rte_mempool.h           |  6 +--
>   lib/librte_port/rte_port_ras.c             |  6 +--
>   lib/librte_vhost/vhost_rxtx.c              |  6 +--
>   scripts/cocci.sh                           | 64 +++++++++++++++++++++++++
>   scripts/cocci/mtod-offset.cocci            | 76 ++++++++++++++++++++++++++++++
>   34 files changed, 319 insertions(+), 152 deletions(-)
>   create mode 100755 scripts/cocci.sh
>   create mode 100644 scripts/cocci/mtod-offset.cocci
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 0/9] Improve cast alignment for strict aligned machines
  2015-06-23 15:36 ` [PATCH v4 0/9] Improve cast alignment for strict aligned machines Olivier MATZ
@ 2015-06-23 17:36   ` Cyril Chemparathy
  2015-06-24 10:04   ` Thomas Monjalon
  1 sibling, 0 replies; 13+ messages in thread
From: Cyril Chemparathy @ 2015-06-23 17:36 UTC (permalink / raw)
  To: Olivier MATZ; +Cc: dev

On Tue, 23 Jun 2015 17:36:40 +0200
Olivier MATZ <olivier.matz@6wind.com> wrote:

> Series
> Acked-by: Olivier Matz <olivier.matz@6wind.com>
> 

Thanks Olivier.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 0/9] Improve cast alignment for strict aligned machines
  2015-06-23 15:36 ` [PATCH v4 0/9] Improve cast alignment for strict aligned machines Olivier MATZ
  2015-06-23 17:36   ` Cyril Chemparathy
@ 2015-06-24 10:04   ` Thomas Monjalon
  1 sibling, 0 replies; 13+ messages in thread
From: Thomas Monjalon @ 2015-06-24 10:04 UTC (permalink / raw)
  To: Cyril Chemparathy; +Cc: dev

2015-06-23 17:36, Olivier MATZ:
> On 06/22/2015 08:34 PM, Cyril Chemparathy wrote:
> > This series contains a few improvements that allow the DPDK code base
> > to build properly on machines that enforce strict pointer cast
> > alignment constraints.
> >
> > When dealing with packet data which could be arbitrarily aligned, we
> > get the compiler to do the right thing by (a) making sure that header
> > types are packed, and (b) introducing and using
> > unaligned_uint(16|32|64)_t types when upcasting from byte pointers.
> >
> > In a few other instances, we know apriori that the pointer cast cannot
> > possibly break alignment.  This applies to the changes in mempool,
> > hash, mbuf, and the ethdev stats code.  Here, we simply silence the
> > compiler by casting through (void *) using the RTE_PTR_(ADD|SUB)
> > macros.
> >
> > Finally, we introduce a new rte_pktmbuf_mtod_offset() helper to return
> > a type casted pointer to an offset within the packet data.  This
> > replaces the following commonly used pattern:
> > 	(struct foo *)(rte_pktmbuf_mtod(m, char *) + offset)
> > with:
> > 	rte_pktmbuf_mtod_offset(m, struct foo *, offset)
> >
> > To ensure consistency, the above transform was applied throughout the
> > code base using the coccinelle semantic patching tool.
> 
> Series
> Acked-by: Olivier Matz <olivier.matz@6wind.com>

Applied, thanks

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2015-06-24 10:05 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-22 18:34 [PATCH v4 0/9] Improve cast alignment for strict aligned machines Cyril Chemparathy
2015-06-22 18:34 ` [PATCH v4 1/9] mempool: silence -Wcast-align on pointer arithmetic Cyril Chemparathy
2015-06-22 18:34 ` [PATCH v4 2/9] mbuf: " Cyril Chemparathy
2015-06-22 18:34 ` [PATCH v4 3/9] ethdev: " Cyril Chemparathy
2015-06-22 18:34 ` [PATCH v4 4/9] hash: " Cyril Chemparathy
2015-06-22 18:34 ` [PATCH v4 5/9] eal: add and use unaligned integer types Cyril Chemparathy
2015-06-22 18:34 ` [PATCH v4 6/9] app/test-pmd: pack simple_gre_hdr Cyril Chemparathy
2015-06-22 18:34 ` [PATCH v4 7/9] librte_mbuf: Add rte_pktmbuf_mtod_offset() Cyril Chemparathy
2015-06-22 18:34 ` [PATCH v4 8/9] librte_mbuf: Add transform for rte_pktmbuf_mtod_offset() Cyril Chemparathy
2015-06-22 18:34 ` [PATCH v4 9/9] librte_mbuf: Apply mtod-offset.cocci transform Cyril Chemparathy
2015-06-23 15:36 ` [PATCH v4 0/9] Improve cast alignment for strict aligned machines Olivier MATZ
2015-06-23 17:36   ` Cyril Chemparathy
2015-06-24 10:04   ` Thomas Monjalon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.