[dpdk-dev,v2,05/10] eal: add and use unaligned integer types
Commit Message
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@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(-)
Comments
2015-06-19 10:34, Cyril Chemparathy:
> 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.
[...]
> +#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
CONFIG_RTE_ARCH_STRICT_ALIGN should be declared (and disabled) in config templates.
On Mon, 22 Jun 2015 11:36:20 +0200
Thomas Monjalon <thomas.monjalon@6wind.com> wrote:
> 2015-06-19 10:34, Cyril Chemparathy:
> > 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.
> [...]
> > +#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
>
> CONFIG_RTE_ARCH_STRICT_ALIGN should be declared (and disabled) in
> config templates.
Sure. Will include in v3. I'm assuming this goes into
common_linuxapp and common_bsdapp, allowing specific architectures to
override if necessary. Correct?
2015-06-22 09:47, Cyril Chemparathy:
> On Mon, 22 Jun 2015 11:36:20 +0200
> Thomas Monjalon <thomas.monjalon@6wind.com> wrote:
>
> > 2015-06-19 10:34, Cyril Chemparathy:
> > > 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.
> > [...]
> > > +#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
> >
> > CONFIG_RTE_ARCH_STRICT_ALIGN should be declared (and disabled) in
> > config templates.
>
> Sure. Will include in v3. I'm assuming this goes into
> common_linuxapp and common_bsdapp, allowing specific architectures to
> override if necessary. Correct?
Yes, thanks
@@ -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. */
@@ -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];
@@ -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];
@@ -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");
@@ -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 ********/
/**
@@ -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);
@@ -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;