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 <cchemparathy@ezchip.com> Acked-by: Olivier Matz <olivier.matz@6wind.com>
This commit is contained in:
parent
0052d53df4
commit
7621d6a8d0
@ -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. */
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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]) ^
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user