linux-dpdk: fix shared library build

Message ID 1477927915-4573-1-git-send-email-matias.elo@nokia.com
State New
Headers show

Commit Message

Elo, Matias (Nokia - FI/Espoo) Oct. 31, 2016, 3:31 p.m.
Currently, the build fails if configuration options enable_abi_compat=0 and
enable_shared=1. Fix this by using precalculated defines for packet offsets
instead of global variables.

Signed-off-by: Matias Elo <matias.elo@nokia.com>
---

Applies on top of 'linux-dpdk: fix invalid ODP_ABI_COMPAT '#if' directives'
patch.

 platform/linux-dpdk/Makefile.am                    |  1 +
 .../include/odp/api/plat/packet_flags_inlines.h    | 14 ++---
 .../include/odp/api/plat/packet_inlines.h          | 38 ++++----------
 .../include/odp_packet_offsets_internal.h          | 40 ++++++++++++++
 platform/linux-dpdk/odp_packet.c                   | 61 ++++++++++++----------
 5 files changed, 87 insertions(+), 67 deletions(-)
 create mode 100644 platform/linux-dpdk/include/odp_packet_offsets_internal.h

Comments

Krishna Garapati Nov. 2, 2016, 3:31 p.m. | #1
Apart from the proposed solution I see that we can fix the issue by simply
doing "#include <odp/api/visibility_begin.h> & #include
<odp/api/visibility_end.h>" which pushes the visibility of the symbol to
global. And since the defined symbols are "const", they are well protected.
Have you tried this ?.

/Krishna

On 31 October 2016 at 16:31, Matias Elo <matias.elo@nokia.com> wrote:

> Currently, the build fails if configuration options enable_abi_compat=0 and
> enable_shared=1. Fix this by using precalculated defines for packet offsets
> instead of global variables.
>
> Signed-off-by: Matias Elo <matias.elo@nokia.com>
> ---
>
> Applies on top of 'linux-dpdk: fix invalid ODP_ABI_COMPAT '#if' directives'
> patch.
>
>  platform/linux-dpdk/Makefile.am                    |  1 +
>  .../include/odp/api/plat/packet_flags_inlines.h    | 14 ++---
>  .../include/odp/api/plat/packet_inlines.h          | 38 ++++----------
>  .../include/odp_packet_offsets_internal.h          | 40 ++++++++++++++
>  platform/linux-dpdk/odp_packet.c                   | 61
> ++++++++++++----------
>  5 files changed, 87 insertions(+), 67 deletions(-)
>  create mode 100644 platform/linux-dpdk/include/
> odp_packet_offsets_internal.h
>
> diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/
> Makefile.am
> index 488f2c0..f9e4530 100644
> --- a/platform/linux-dpdk/Makefile.am
> +++ b/platform/linux-dpdk/Makefile.am
> @@ -130,6 +130,7 @@ noinst_HEADERS = \
>                   ${top_srcdir}/platform/linux-
> generic/include/odp_packet_io_ipc_internal.h \
>                   ${top_srcdir}/platform/linux-
> generic/include/odp_packet_io_queue.h \
>                   ${top_srcdir}/platform/linux-
> generic/include/odp_packet_io_ring_internal.h \
> +                 ${srcdir}/include/odp_packet_offsets_internal.h \
>                   ${top_srcdir}/platform/linux-generic/include/odp_packet_socket.h
> \
>                   ${top_srcdir}/platform/linux-
> generic/include/odp_pkt_queue_internal.h \
>                   ${srcdir}/include/odp_pool_internal.h \
> diff --git a/platform/linux-dpdk/include/odp/api/plat/packet_flags_inlines.h
> b/platform/linux-dpdk/include/odp/api/plat/packet_flags_inlines.h
> index 7d2464e..58d8573 100644
> --- a/platform/linux-dpdk/include/odp/api/plat/packet_flags_inlines.h
> +++ b/platform/linux-dpdk/include/odp/api/plat/packet_flags_inlines.h
> @@ -17,24 +17,16 @@
>  extern "C" {
>  #endif
>
> -extern const unsigned int ol_flags_offset;
> -extern const uint64_t rss_flag;
> +#include <odp_packet_offsets_internal.h>
>
> -/*
> - * NOTE: These functions are inlined because they are on a performance
> hot path.
> - * As we can't force the application to directly include DPDK headers we
> have to
> - * export these fields through constants calculated compile time in
> - * odp_packet.c, where we can see the DPDK definitions.
> - *
> - */
>  _STATIC int odp_packet_has_flow_hash(odp_packet_t pkt)
>  {
> -       return *(uint64_t *)((char *)pkt + ol_flags_offset) & rss_flag;
> +       return *(uint64_t *)((char *)pkt + _OL_FLAGS_OFFSET) &
> _RX_RSS_FLAG;
>  }
>
>  _STATIC void odp_packet_has_flow_hash_clr(odp_packet_t pkt)
>  {
> -       *(uint64_t *)((char *)pkt + ol_flags_offset) &= ~rss_flag;
> +       *(uint64_t *)((char *)pkt + _OL_FLAGS_OFFSET) &= ~_RX_RSS_FLAG;
>  }
>
>  #ifdef __cplusplus
> diff --git a/platform/linux-dpdk/include/odp/api/plat/packet_inlines.h
> b/platform/linux-dpdk/include/odp/api/plat/packet_inlines.h
> index 45ef1a2..12a345d 100644
> --- a/platform/linux-dpdk/include/odp/api/plat/packet_inlines.h
> +++ b/platform/linux-dpdk/include/odp/api/plat/packet_inlines.h
> @@ -17,64 +17,46 @@
>  extern "C" {
>  #endif
>
> -#if ODP_ABI_COMPAT == 0
> +#include <odp_packet_offsets_internal.h>
>
> -extern const unsigned int buf_addr_offset;
> -extern const unsigned int data_off_offset;
> -extern const unsigned int pkt_len_offset;
> -extern const unsigned int seg_len_offset;
> -extern const unsigned int udata_len_offset;
> -extern const unsigned int udata_offset;
> -extern const unsigned int rss_offset;
> -extern const unsigned int ol_flags_offset;
> -extern const uint64_t rss_flag;
> -
> -#endif /* ODP_ABI_COMPAT */
> -/*
> - * NOTE: These functions are inlined because they are on a performance
> hot path.
> - * As we can't force the application to directly include DPDK headers we
> have to
> - * export these fields through constants calculated compile time in
> - * odp_packet.c, where we can see the DPDK definitions.
> - *
> - */
>  _STATIC uint32_t odp_packet_len(odp_packet_t pkt)
>  {
> -       return *(uint32_t *)(void *)((char *)pkt + pkt_len_offset);
> +       return *(uint32_t *)(void *)((char *)pkt + _PKT_LEN_OFFSET);
>  }
>
>  _STATIC uint32_t odp_packet_seg_len(odp_packet_t pkt)
>  {
> -       return *(uint16_t *)(void *)((char *)pkt + seg_len_offset);
> +       return *(uint16_t *)(void *)((char *)pkt + _SEG_LEN_OFFSET);
>  }
>
>  _STATIC void *odp_packet_user_area(odp_packet_t pkt)
>  {
> -       return (void *)((char *)pkt + udata_offset);
> +       return (void *)((char *)pkt + _UDATA_OFFSET);
>  }
>
>  _STATIC uint32_t odp_packet_user_area_size(odp_packet_t pkt)
>  {
> -       return *(uint32_t *)(void *)((char *)pkt + udata_len_offset);
> +       return *(uint32_t *)(void *)((char *)pkt + _UDATA_LEN_OFFSET);
>  }
>
>  _STATIC void *odp_packet_data(odp_packet_t pkt)
>  {
> -       char **buf_addr = (char **)(void *)((char *)pkt + buf_addr_offset);
> +       char **buf_addr = (char **)(void *)((char *)pkt +
> _BUF_ADDR_OFFSET);
>         uint16_t data_off =
> -               *(uint16_t *)(void *)((char *)pkt + data_off_offset);
> +               *(uint16_t *)(void *)((char *)pkt + _DATA_OFF_OFFSET);
>
>         return (void *)(*buf_addr + data_off);
>  }
>
>  _STATIC uint32_t odp_packet_flow_hash(odp_packet_t pkt)
>  {
> -       return *(uint32_t *)(void *)((char *)pkt + rss_offset);
> +       return *(uint32_t *)(void *)((char *)pkt + _HASH_RSS_OFFSET);
>  }
>
>  _STATIC void odp_packet_flow_hash_set(odp_packet_t pkt, uint32_t
> flow_hash)
>  {
> -       *(uint32_t *)(void *)((char *)pkt + rss_offset) = flow_hash;
> -       *(uint64_t *)(void *)((char *)pkt + ol_flags_offset) |= rss_flag;
> +       *(uint32_t *)(void *)((char *)pkt + _HASH_RSS_OFFSET) = flow_hash;
> +       *(uint64_t *)(void *)((char *)pkt + _OL_FLAGS_OFFSET) |=
> _RX_RSS_FLAG;
>  }
>
>  #ifdef __cplusplus
> diff --git a/platform/linux-dpdk/include/odp_packet_offsets_internal.h
> b/platform/linux-dpdk/include/odp_packet_offsets_internal.h
> new file mode 100644
> index 0000000..92cce76
> --- /dev/null
> +++ b/platform/linux-dpdk/include/odp_packet_offsets_internal.h
> @@ -0,0 +1,40 @@
> +/* Copyright (c) 2016, Linaro Limited
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier: BSD-3-Clause
> + */
> +
> +/**
> + * @file
> + *
> + * Internal packet offset defines
> + */
> +
> +#ifndef ODP_PACKET_OFFSETS_INTERNAL_H_
> +#define ODP_PACKET_OFFSETS_INTERNAL_H_
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/**
> + * As we can't force the application to directly include DPDK headers we
> export
> + * these fields through precalculated defines. These defines are
> validated at
> + * compile time in odp_packet.c, where we can see the DPDK definitions.
> + */
> +#define _BUF_ADDR_OFFSET  0
> +#define _DATA_OFF_OFFSET  18
> +#define _PKT_LEN_OFFSET   36
> +#define _SEG_LEN_OFFSET   40
> +#define _UDATA_LEN_OFFSET 440
> +#define _UDATA_OFFSET     512
> +#define _HASH_RSS_OFFSET  44
> +#define _OL_FLAGS_OFFSET  24
> +
> +#define _RX_RSS_FLAG      (1ULL << 1)
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* ODP_PACKET_OFFSETS_INTERNAL_H_ */
> diff --git a/platform/linux-dpdk/odp_packet.c b/platform/linux-dpdk/odp_
> packet.c
> index 7cb294e..2aa6ad9 100644
> --- a/platform/linux-dpdk/odp_packet.c
> +++ b/platform/linux-dpdk/odp_packet.c
> @@ -20,35 +20,44 @@
>  #include <stddef.h>
>  #include <inttypes.h>
>
> -/* These are the offsets for packet accessors for inlining. */
> -const unsigned int buf_addr_offset = offsetof(odp_packet_hdr_t, buf_hdr) +
> -                                    offsetof(struct odp_buffer_hdr_t, mb)
> +
> -                                    offsetof(struct rte_mbuf, buf_addr);
> -const unsigned int data_off_offset = offsetof(odp_packet_hdr_t, buf_hdr) +
> -                                    offsetof(struct odp_buffer_hdr_t, mb)
> +
> -                                    offsetof(struct rte_mbuf, data_off);
> +#if ODP_ABI_COMPAT == 1
> +#include <odp/api/plat/packet_inlines.h>
> +#endif
>
> +/* Validate the precalculated packet offset defines. */
> +ODP_STATIC_ASSERT(_BUF_ADDR_OFFSET == (offsetof(odp_packet_hdr_t,
> buf_hdr) +
> +                 offsetof(struct odp_buffer_hdr_t, mb) +
> +                 offsetof(struct rte_mbuf, buf_addr)),
> +                 "_BUF_ADDR_OFFSET__ERROR\n");
> +ODP_STATIC_ASSERT(_DATA_OFF_OFFSET == (offsetof(odp_packet_hdr_t,
> buf_hdr) +
> +                 offsetof(struct odp_buffer_hdr_t, mb) +
> +                 offsetof(struct rte_mbuf, data_off)),
> +                 "_DATA_OFF_OFFSET__ERROR\n");
> +ODP_STATIC_ASSERT(_PKT_LEN_OFFSET == (offsetof(odp_packet_hdr_t,
> buf_hdr) +
> +                 offsetof(struct odp_buffer_hdr_t, mb) +
> +                 (size_t)&rte_pktmbuf_pkt_len((struct rte_mbuf *)0)),
> +                 "_PKT_LEN_OFFSET__ERROR\n");
> +ODP_STATIC_ASSERT(_SEG_LEN_OFFSET == (offsetof(odp_packet_hdr_t,
> buf_hdr) +
> +                 offsetof(struct odp_buffer_hdr_t, mb) +
> +                 (size_t)&rte_pktmbuf_data_len((struct rte_mbuf *)0)),
> +                 "_SEG_LEN_OFFSET__ERROR\n");
> +ODP_STATIC_ASSERT(_UDATA_LEN_OFFSET == offsetof(odp_packet_hdr_t,
> uarea_size),
> +                 "_UDATA_LEN_OFFSET__ERROR\n");
> +ODP_STATIC_ASSERT(_UDATA_OFFSET == sizeof(odp_packet_hdr_t),
> +                 "_UDATA_OFFSET__ERROR\n");
> +ODP_STATIC_ASSERT(_HASH_RSS_OFFSET == (offsetof(odp_packet_hdr_t,
> buf_hdr) +
> +                 offsetof(struct odp_buffer_hdr_t, mb) +
> +                 offsetof(struct rte_mbuf, hash.rss)),
> +                 "_HASH_RSS_OFFSET__ERROR\n");
> +ODP_STATIC_ASSERT(_OL_FLAGS_OFFSET == (offsetof(odp_packet_hdr_t,
> buf_hdr) +
> +                 offsetof(struct odp_buffer_hdr_t, mb) +
> +                 offsetof(struct rte_mbuf, ol_flags)),
> +                 "_OL_FLAGS_OFFSET__ERROR\n");
> +ODP_STATIC_ASSERT(_RX_RSS_FLAG == PKT_RX_RSS_HASH,
> "_RX_RSS_FLAG__ERROR\n");
>  /* The last bit is an expanded version of offsetof(), to make sure that if
>   * rte_pktmbuf_[pkt|data]_len() changes, we will either adapt
> automatically, or
>   * throw a compile failure
>   */
> -const unsigned int pkt_len_offset = offsetof(odp_packet_hdr_t, buf_hdr) +
> -                                   offsetof(struct odp_buffer_hdr_t, mb) +
> -                                   (size_t)&rte_pktmbuf_pkt_len((struct
> rte_mbuf *)0);
> -const unsigned int seg_len_offset = offsetof(odp_packet_hdr_t, buf_hdr) +
> -                                   offsetof(struct odp_buffer_hdr_t, mb) +
> -                                   (size_t)&rte_pktmbuf_data_len((struct
> rte_mbuf *)0);
> -
> -const unsigned int udata_len_offset = offsetof(odp_packet_hdr_t,
> uarea_size);
> -const unsigned int udata_offset = sizeof(odp_packet_hdr_t);
> -const unsigned int rss_offset = offsetof(odp_packet_hdr_t, buf_hdr) +
> -                               offsetof(struct odp_buffer_hdr_t, mb) +
> -                               offsetof(struct rte_mbuf, hash.rss);
> -const unsigned int ol_flags_offset = offsetof(odp_packet_hdr_t, buf_hdr) +
> -                                    offsetof(struct odp_buffer_hdr_t, mb)
> +
> -                                    offsetof(struct rte_mbuf, ol_flags);
> -const uint64_t rss_flag = PKT_RX_RSS_HASH;
> -
>  struct rte_mbuf dummy;
>  ODP_STATIC_ASSERT(sizeof(dummy.data_off) == sizeof(uint16_t),
>                   "data_off should be uint16_t");
> @@ -61,10 +70,6 @@ ODP_STATIC_ASSERT(sizeof(dummy.hash.rss) ==
> sizeof(uint32_t),
>  ODP_STATIC_ASSERT(sizeof(dummy.ol_flags) == sizeof(uint64_t),
>                   "ol_flags should be uint64_t");
>
> -#if ODP_ABI_COMPAT == 1
> -#include <odp/api/plat/packet_inlines.h>
> -#endif
> -
>  /*
>   *
>   * Alloc and free
> --
> 2.7.4
>
> _______________________________________________
> lng-odp-dpdk mailing list
> lng-odp-dpdk@lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/lng-odp-dpdk
>
Elo, Matias (Nokia - FI/Espoo) Nov. 9, 2016, 1:21 p.m. | #2
> On 2 Nov 2016, at 17:31, Krishna Garapati <balakrishna.garapati@linaro.org> wrote:
> 
> Apart from the proposed solution I see that we can fix the issue by simply doing "#include <odp/api/visibility_begin.h> & #include <odp/api/visibility_end.h>" which pushes the visibility of the symbol to global. And since the defined symbols are "const", they are well protected. Have you tried this ?. 
>  
> /Krishna

Hi Krishna,

I tested your suggestion and everything seems to work. Your solution is much simpler than the patch I sent earlier, so I propose we go with your suggestion. Will you send a patch so I can review it?

-Matias
Krishna Garapati Nov. 9, 2016, 1:43 p.m. | #3
On 9 November 2016 at 14:21, Elo, Matias (Nokia - FI/Espoo) <
matias.elo@nokia-bell-labs.com> wrote:

>
> > On 2 Nov 2016, at 17:31, Krishna Garapati <balakrishna.garapati@linaro.
> org> wrote:
> >
> > Apart from the proposed solution I see that we can fix the issue by
> simply doing "#include <odp/api/visibility_begin.h> & #include
> <odp/api/visibility_end.h>" which pushes the visibility of the symbol to
> global. And since the defined symbols are "const", they are well protected.
> Have you tried this ?.
> >
> > /Krishna
>
> Hi Krishna,
>
> I tested your suggestion and everything seems to work. Your solution is
> much simpler than the patch I sent earlier, so I propose we go with your
> suggestion. Will you send a patch so I can review it?
>
 Ya sure I will send a patch for review.
/Krishna

>
> -Matias
>
>

Patch hide | download patch | download mbox

diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/Makefile.am
index 488f2c0..f9e4530 100644
--- a/platform/linux-dpdk/Makefile.am
+++ b/platform/linux-dpdk/Makefile.am
@@ -130,6 +130,7 @@  noinst_HEADERS = \
 		  ${top_srcdir}/platform/linux-generic/include/odp_packet_io_ipc_internal.h \
 		  ${top_srcdir}/platform/linux-generic/include/odp_packet_io_queue.h \
 		  ${top_srcdir}/platform/linux-generic/include/odp_packet_io_ring_internal.h \
+		  ${srcdir}/include/odp_packet_offsets_internal.h \
 		  ${top_srcdir}/platform/linux-generic/include/odp_packet_socket.h \
 		  ${top_srcdir}/platform/linux-generic/include/odp_pkt_queue_internal.h \
 		  ${srcdir}/include/odp_pool_internal.h \
diff --git a/platform/linux-dpdk/include/odp/api/plat/packet_flags_inlines.h b/platform/linux-dpdk/include/odp/api/plat/packet_flags_inlines.h
index 7d2464e..58d8573 100644
--- a/platform/linux-dpdk/include/odp/api/plat/packet_flags_inlines.h
+++ b/platform/linux-dpdk/include/odp/api/plat/packet_flags_inlines.h
@@ -17,24 +17,16 @@ 
 extern "C" {
 #endif
 
-extern const unsigned int ol_flags_offset;
-extern const uint64_t rss_flag;
+#include <odp_packet_offsets_internal.h>
 
-/*
- * NOTE: These functions are inlined because they are on a performance hot path.
- * As we can't force the application to directly include DPDK headers we have to
- * export these fields through constants calculated compile time in
- * odp_packet.c, where we can see the DPDK definitions.
- *
- */
 _STATIC int odp_packet_has_flow_hash(odp_packet_t pkt)
 {
-	return *(uint64_t *)((char *)pkt + ol_flags_offset) & rss_flag;
+	return *(uint64_t *)((char *)pkt + _OL_FLAGS_OFFSET) & _RX_RSS_FLAG;
 }
 
 _STATIC void odp_packet_has_flow_hash_clr(odp_packet_t pkt)
 {
-	*(uint64_t *)((char *)pkt + ol_flags_offset) &= ~rss_flag;
+	*(uint64_t *)((char *)pkt + _OL_FLAGS_OFFSET) &= ~_RX_RSS_FLAG;
 }
 
 #ifdef __cplusplus
diff --git a/platform/linux-dpdk/include/odp/api/plat/packet_inlines.h b/platform/linux-dpdk/include/odp/api/plat/packet_inlines.h
index 45ef1a2..12a345d 100644
--- a/platform/linux-dpdk/include/odp/api/plat/packet_inlines.h
+++ b/platform/linux-dpdk/include/odp/api/plat/packet_inlines.h
@@ -17,64 +17,46 @@ 
 extern "C" {
 #endif
 
-#if ODP_ABI_COMPAT == 0
+#include <odp_packet_offsets_internal.h>
 
-extern const unsigned int buf_addr_offset;
-extern const unsigned int data_off_offset;
-extern const unsigned int pkt_len_offset;
-extern const unsigned int seg_len_offset;
-extern const unsigned int udata_len_offset;
-extern const unsigned int udata_offset;
-extern const unsigned int rss_offset;
-extern const unsigned int ol_flags_offset;
-extern const uint64_t rss_flag;
-
-#endif /* ODP_ABI_COMPAT */
-/*
- * NOTE: These functions are inlined because they are on a performance hot path.
- * As we can't force the application to directly include DPDK headers we have to
- * export these fields through constants calculated compile time in
- * odp_packet.c, where we can see the DPDK definitions.
- *
- */
 _STATIC uint32_t odp_packet_len(odp_packet_t pkt)
 {
-	return *(uint32_t *)(void *)((char *)pkt + pkt_len_offset);
+	return *(uint32_t *)(void *)((char *)pkt + _PKT_LEN_OFFSET);
 }
 
 _STATIC uint32_t odp_packet_seg_len(odp_packet_t pkt)
 {
-	return *(uint16_t *)(void *)((char *)pkt + seg_len_offset);
+	return *(uint16_t *)(void *)((char *)pkt + _SEG_LEN_OFFSET);
 }
 
 _STATIC void *odp_packet_user_area(odp_packet_t pkt)
 {
-	return (void *)((char *)pkt + udata_offset);
+	return (void *)((char *)pkt + _UDATA_OFFSET);
 }
 
 _STATIC uint32_t odp_packet_user_area_size(odp_packet_t pkt)
 {
-	return *(uint32_t *)(void *)((char *)pkt + udata_len_offset);
+	return *(uint32_t *)(void *)((char *)pkt + _UDATA_LEN_OFFSET);
 }
 
 _STATIC void *odp_packet_data(odp_packet_t pkt)
 {
-	char **buf_addr = (char **)(void *)((char *)pkt + buf_addr_offset);
+	char **buf_addr = (char **)(void *)((char *)pkt + _BUF_ADDR_OFFSET);
 	uint16_t data_off =
-		*(uint16_t *)(void *)((char *)pkt + data_off_offset);
+		*(uint16_t *)(void *)((char *)pkt + _DATA_OFF_OFFSET);
 
 	return (void *)(*buf_addr + data_off);
 }
 
 _STATIC uint32_t odp_packet_flow_hash(odp_packet_t pkt)
 {
-	return *(uint32_t *)(void *)((char *)pkt + rss_offset);
+	return *(uint32_t *)(void *)((char *)pkt + _HASH_RSS_OFFSET);
 }
 
 _STATIC void odp_packet_flow_hash_set(odp_packet_t pkt, uint32_t flow_hash)
 {
-	*(uint32_t *)(void *)((char *)pkt + rss_offset) = flow_hash;
-	*(uint64_t *)(void *)((char *)pkt + ol_flags_offset) |= rss_flag;
+	*(uint32_t *)(void *)((char *)pkt + _HASH_RSS_OFFSET) = flow_hash;
+	*(uint64_t *)(void *)((char *)pkt + _OL_FLAGS_OFFSET) |= _RX_RSS_FLAG;
 }
 
 #ifdef __cplusplus
diff --git a/platform/linux-dpdk/include/odp_packet_offsets_internal.h b/platform/linux-dpdk/include/odp_packet_offsets_internal.h
new file mode 100644
index 0000000..92cce76
--- /dev/null
+++ b/platform/linux-dpdk/include/odp_packet_offsets_internal.h
@@ -0,0 +1,40 @@ 
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * Internal packet offset defines
+ */
+
+#ifndef ODP_PACKET_OFFSETS_INTERNAL_H_
+#define ODP_PACKET_OFFSETS_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * As we can't force the application to directly include DPDK headers we export
+ * these fields through precalculated defines. These defines are validated at
+ * compile time in odp_packet.c, where we can see the DPDK definitions.
+ */
+#define _BUF_ADDR_OFFSET  0
+#define _DATA_OFF_OFFSET  18
+#define _PKT_LEN_OFFSET   36
+#define _SEG_LEN_OFFSET   40
+#define _UDATA_LEN_OFFSET 440
+#define _UDATA_OFFSET     512
+#define _HASH_RSS_OFFSET  44
+#define _OL_FLAGS_OFFSET  24
+
+#define _RX_RSS_FLAG      (1ULL << 1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ODP_PACKET_OFFSETS_INTERNAL_H_ */
diff --git a/platform/linux-dpdk/odp_packet.c b/platform/linux-dpdk/odp_packet.c
index 7cb294e..2aa6ad9 100644
--- a/platform/linux-dpdk/odp_packet.c
+++ b/platform/linux-dpdk/odp_packet.c
@@ -20,35 +20,44 @@ 
 #include <stddef.h>
 #include <inttypes.h>
 
-/* These are the offsets for packet accessors for inlining. */
-const unsigned int buf_addr_offset = offsetof(odp_packet_hdr_t, buf_hdr) +
-				     offsetof(struct odp_buffer_hdr_t, mb) +
-				     offsetof(struct rte_mbuf, buf_addr);
-const unsigned int data_off_offset = offsetof(odp_packet_hdr_t, buf_hdr) +
-				     offsetof(struct odp_buffer_hdr_t, mb) +
-				     offsetof(struct rte_mbuf, data_off);
+#if ODP_ABI_COMPAT == 1
+#include <odp/api/plat/packet_inlines.h>
+#endif
 
+/* Validate the precalculated packet offset defines. */
+ODP_STATIC_ASSERT(_BUF_ADDR_OFFSET == (offsetof(odp_packet_hdr_t, buf_hdr) +
+		  offsetof(struct odp_buffer_hdr_t, mb) +
+		  offsetof(struct rte_mbuf, buf_addr)),
+		  "_BUF_ADDR_OFFSET__ERROR\n");
+ODP_STATIC_ASSERT(_DATA_OFF_OFFSET == (offsetof(odp_packet_hdr_t, buf_hdr) +
+		  offsetof(struct odp_buffer_hdr_t, mb) +
+		  offsetof(struct rte_mbuf, data_off)),
+		  "_DATA_OFF_OFFSET__ERROR\n");
+ODP_STATIC_ASSERT(_PKT_LEN_OFFSET == (offsetof(odp_packet_hdr_t, buf_hdr) +
+		  offsetof(struct odp_buffer_hdr_t, mb) +
+		  (size_t)&rte_pktmbuf_pkt_len((struct rte_mbuf *)0)),
+		  "_PKT_LEN_OFFSET__ERROR\n");
+ODP_STATIC_ASSERT(_SEG_LEN_OFFSET == (offsetof(odp_packet_hdr_t, buf_hdr) +
+		  offsetof(struct odp_buffer_hdr_t, mb) +
+		  (size_t)&rte_pktmbuf_data_len((struct rte_mbuf *)0)),
+		  "_SEG_LEN_OFFSET__ERROR\n");
+ODP_STATIC_ASSERT(_UDATA_LEN_OFFSET == offsetof(odp_packet_hdr_t, uarea_size),
+		  "_UDATA_LEN_OFFSET__ERROR\n");
+ODP_STATIC_ASSERT(_UDATA_OFFSET == sizeof(odp_packet_hdr_t),
+		  "_UDATA_OFFSET__ERROR\n");
+ODP_STATIC_ASSERT(_HASH_RSS_OFFSET == (offsetof(odp_packet_hdr_t, buf_hdr) +
+		  offsetof(struct odp_buffer_hdr_t, mb) +
+		  offsetof(struct rte_mbuf, hash.rss)),
+		  "_HASH_RSS_OFFSET__ERROR\n");
+ODP_STATIC_ASSERT(_OL_FLAGS_OFFSET == (offsetof(odp_packet_hdr_t, buf_hdr) +
+		  offsetof(struct odp_buffer_hdr_t, mb) +
+		  offsetof(struct rte_mbuf, ol_flags)),
+		  "_OL_FLAGS_OFFSET__ERROR\n");
+ODP_STATIC_ASSERT(_RX_RSS_FLAG == PKT_RX_RSS_HASH, "_RX_RSS_FLAG__ERROR\n");
 /* The last bit is an expanded version of offsetof(), to make sure that if
  * rte_pktmbuf_[pkt|data]_len() changes, we will either adapt automatically, or
  * throw a compile failure
  */
-const unsigned int pkt_len_offset = offsetof(odp_packet_hdr_t, buf_hdr) +
-				    offsetof(struct odp_buffer_hdr_t, mb) +
-				    (size_t)&rte_pktmbuf_pkt_len((struct rte_mbuf *)0);
-const unsigned int seg_len_offset = offsetof(odp_packet_hdr_t, buf_hdr) +
-				    offsetof(struct odp_buffer_hdr_t, mb) +
-				    (size_t)&rte_pktmbuf_data_len((struct rte_mbuf *)0);
-
-const unsigned int udata_len_offset = offsetof(odp_packet_hdr_t, uarea_size);
-const unsigned int udata_offset = sizeof(odp_packet_hdr_t);
-const unsigned int rss_offset = offsetof(odp_packet_hdr_t, buf_hdr) +
-				offsetof(struct odp_buffer_hdr_t, mb) +
-				offsetof(struct rte_mbuf, hash.rss);
-const unsigned int ol_flags_offset = offsetof(odp_packet_hdr_t, buf_hdr) +
-				     offsetof(struct odp_buffer_hdr_t, mb) +
-				     offsetof(struct rte_mbuf, ol_flags);
-const uint64_t rss_flag = PKT_RX_RSS_HASH;
-
 struct rte_mbuf dummy;
 ODP_STATIC_ASSERT(sizeof(dummy.data_off) == sizeof(uint16_t),
 		  "data_off should be uint16_t");
@@ -61,10 +70,6 @@  ODP_STATIC_ASSERT(sizeof(dummy.hash.rss) == sizeof(uint32_t),
 ODP_STATIC_ASSERT(sizeof(dummy.ol_flags) == sizeof(uint64_t),
 		  "ol_flags should be uint64_t");
 
-#if ODP_ABI_COMPAT == 1
-#include <odp/api/plat/packet_inlines.h>
-#endif
-
 /*
  *
  * Alloc and free