[API-NEXT,PATCHv3,4/5] linux-gen: packet: inline functions

Message ID 20170209115352.16271-5-bill.fischofer@linaro.org
State New
Headers show
Series
  • Packet function inline
Related show

Commit Message

Bill Fischofer Feb. 9, 2017, 11:53 a.m.
From: Petri Savolainen <petri.savolainen@linaro.org>


Added first inlined packet functions. Functions are allways used
inlined within the implementation. Applications see inlined
versions only when ABI compatibility is disabled.

Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>

Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>

---
 platform/linux-generic/Makefile.am                 |   2 +
 platform/linux-generic/include/odp/api/packet.h    |  11 +-
 .../include/odp/api/plat/packet_inlines.h          | 156 +++++++++++++++++++++
 .../include/odp/api/plat/packet_inlines_api.h      |  97 +++++++++++++
 .../include/odp/api/plat/packet_types.h            |  41 ++++++
 .../linux-generic/include/odp_packet_internal.h    |  19 ++-
 platform/linux-generic/odp_packet.c                | 127 ++++-------------
 platform/linux-generic/pktio/dpdk.c                |   5 +-
 platform/linux-generic/pktio/netmap.c              |   5 +-
 test/common_plat/performance/Makefile.am           |   4 +
 10 files changed, 350 insertions(+), 117 deletions(-)
 create mode 100644 platform/linux-generic/include/odp/api/plat/packet_inlines.h
 create mode 100644 platform/linux-generic/include/odp/api/plat/packet_inlines_api.h

-- 
2.11.0.295.gd7dffce

Patch

diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index 63d5cbc0..a782b28c 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -82,6 +82,8 @@  odpapiplatinclude_HEADERS = \
 		  $(srcdir)/include/odp/api/plat/event_types.h \
 		  $(srcdir)/include/odp/api/plat/init_types.h \
 		  $(srcdir)/include/odp/api/plat/ipsec_types.h \
+		  $(srcdir)/include/odp/api/plat/packet_inlines.h \
+		  $(srcdir)/include/odp/api/plat/packet_inlines_api.h \
 		  $(srcdir)/include/odp/api/plat/packet_types.h \
 		  $(srcdir)/include/odp/api/plat/packet_io_types.h \
 		  $(srcdir)/include/odp/api/plat/pool_types.h \
diff --git a/platform/linux-generic/include/odp/api/packet.h b/platform/linux-generic/include/odp/api/packet.h
index ebbeaf1b..eff40803 100644
--- a/platform/linux-generic/include/odp/api/packet.h
+++ b/platform/linux-generic/include/odp/api/packet.h
@@ -24,13 +24,10 @@  extern "C" {
 #include <odp/api/plat/buffer_types.h>
 #include <odp/api/plat/pool_types.h>
 
-/** @ingroup odp_packet
- *  @{
- */
-
-/**
- * @}
- */
+#include <odp/api/plat/static_inline.h>
+#if ODP_ABI_COMPAT == 0
+#include <odp/api/plat/packet_inlines.h>
+#endif
 
 #include <odp/api/spec/packet.h>
 
diff --git a/platform/linux-generic/include/odp/api/plat/packet_inlines.h b/platform/linux-generic/include/odp/api/plat/packet_inlines.h
new file mode 100644
index 00000000..8bfd85fe
--- /dev/null
+++ b/platform/linux-generic/include/odp/api/plat/packet_inlines.h
@@ -0,0 +1,156 @@ 
+/* Copyright (c) 2017, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * Packet inline functions
+ */
+
+#ifndef _ODP_PLAT_PACKET_INLINES_H_
+#define _ODP_PLAT_PACKET_INLINES_H_
+
+#include <odp/api/plat/packet_types.h>
+#include <odp/api/pool.h>
+#include <odp/api/packet_io.h>
+#include <odp/api/hints.h>
+
+/** @internal Packet field accessor */
+#define _odp_pkt_get(pkt, cast, field) \
+	(*(cast *)(uintptr_t)((uint8_t *)pkt + _odp_packet_inline.field))
+
+/** @internal Inline function offsets */
+extern const _odp_packet_inline_offset_t _odp_packet_inline;
+
+/** @internal Inline function @param pkt @return */
+static inline void *_odp_packet_data(odp_packet_t pkt)
+{
+	return _odp_pkt_get(pkt, void *, data);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline uint32_t _odp_packet_seg_len(odp_packet_t pkt)
+{
+	return _odp_pkt_get(pkt, uint32_t, seg_len);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline uint32_t _odp_packet_len(odp_packet_t pkt)
+{
+	uint32_t pkt_len = _odp_pkt_get(pkt, uint32_t, frame_len);
+	void *ref_nxt    = _odp_pkt_get(pkt, void *, ref_hdr);
+	void *ref_pkt    = (void *)pkt;
+
+	while (ref_nxt) {
+		pkt_len += _odp_pkt_get(ref_pkt, uint32_t, ref_len) -
+			_odp_pkt_get(ref_pkt, uint32_t, ref_offset);
+
+		ref_pkt = ref_nxt;
+		ref_nxt = _odp_pkt_get(ref_nxt, void *, ref_hdr);
+	}
+
+	return pkt_len;
+}
+
+/** @internal Inline function @param pkt @return */
+static inline uint32_t _odp_packet_headroom(odp_packet_t pkt)
+{
+	return _odp_pkt_get(pkt, uint32_t, headroom);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline uint32_t _odp_packet_tailroom(odp_packet_t pkt)
+{
+	return _odp_pkt_get(pkt, uint32_t, tailroom);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline odp_pool_t _odp_packet_pool(odp_packet_t pkt)
+{
+	return _odp_pkt_get(pkt, odp_pool_t, pool);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline odp_pktio_t _odp_packet_input(odp_packet_t pkt)
+{
+	return _odp_pkt_get(pkt, odp_pktio_t, input);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline void *_odp_packet_user_ptr(odp_packet_t pkt)
+{
+	return _odp_pkt_get(pkt, void *, user_ptr);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline void *_odp_packet_user_area(odp_packet_t pkt)
+{
+	return _odp_pkt_get(pkt, void *, user_area);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline uint32_t _odp_packet_user_area_size(odp_packet_t pkt)
+{
+	return _odp_pkt_get(pkt, uint32_t, user_area_size);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline uint32_t _odp_packet_flow_hash(odp_packet_t pkt)
+{
+	return _odp_pkt_get(pkt, uint32_t, flow_hash);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline odp_time_t _odp_packet_ts(odp_packet_t pkt)
+{
+	return _odp_pkt_get(pkt, odp_time_t, timestamp);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline void *_odp_packet_head(odp_packet_t pkt)
+{
+	return (uint8_t *)_odp_packet_data(pkt) - _odp_packet_headroom(pkt);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline int _odp_packet_is_segmented(odp_packet_t pkt)
+{
+	return _odp_pkt_get(pkt, uint8_t, segcount) > 1 ||
+		_odp_pkt_get(pkt, void *, ref_hdr) != NULL;
+}
+
+/** @internal Inline function @param pkt @return */
+static inline odp_packet_seg_t _odp_packet_first_seg(odp_packet_t pkt)
+{
+	(void)pkt;
+
+	return 0;
+}
+
+/** @internal Inline function @param pkt @param offset @param len */
+static inline void _odp_packet_prefetch(odp_packet_t pkt, uint32_t offset,
+					uint32_t len)
+{
+	(void)pkt; (void)offset; (void)len;
+}
+
+/* Include inlined versions of API functions */
+#include <odp/api/plat/static_inline.h>
+#if ODP_ABI_COMPAT == 0
+
+/** @ingroup odp_packet
+ *  @{
+ */
+
+#include <odp/api/plat/packet_inlines_api.h>
+
+/**
+ * @}
+ */
+
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp/api/plat/packet_inlines_api.h b/platform/linux-generic/include/odp/api/plat/packet_inlines_api.h
new file mode 100644
index 00000000..f818f820
--- /dev/null
+++ b/platform/linux-generic/include/odp/api/plat/packet_inlines_api.h
@@ -0,0 +1,97 @@ 
+/* Copyright (c) 2017, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * Packet inline functions
+ */
+
+#ifndef _ODP_PLAT_PACKET_INLINES_API_H_
+#define _ODP_PLAT_PACKET_INLINES_API_H_
+
+_ODP_INLINE void *odp_packet_data(odp_packet_t pkt)
+{
+	return _odp_packet_data(pkt);
+}
+
+_ODP_INLINE uint32_t odp_packet_seg_len(odp_packet_t pkt)
+{
+	return _odp_packet_seg_len(pkt);
+}
+
+_ODP_INLINE uint32_t odp_packet_len(odp_packet_t pkt)
+{
+	return _odp_packet_len(pkt);
+}
+
+_ODP_INLINE uint32_t odp_packet_headroom(odp_packet_t pkt)
+{
+	return _odp_packet_headroom(pkt);
+}
+
+_ODP_INLINE uint32_t odp_packet_tailroom(odp_packet_t pkt)
+{
+	return _odp_packet_tailroom(pkt);
+}
+
+_ODP_INLINE odp_pool_t odp_packet_pool(odp_packet_t pkt)
+{
+	return _odp_packet_pool(pkt);
+}
+
+_ODP_INLINE odp_pktio_t odp_packet_input(odp_packet_t pkt)
+{
+	return _odp_packet_input(pkt);
+}
+
+_ODP_INLINE void *odp_packet_user_ptr(odp_packet_t pkt)
+{
+	return _odp_packet_user_ptr(pkt);
+}
+
+_ODP_INLINE void *odp_packet_user_area(odp_packet_t pkt)
+{
+	return _odp_packet_user_area(pkt);
+}
+
+_ODP_INLINE uint32_t odp_packet_user_area_size(odp_packet_t pkt)
+{
+	return _odp_packet_user_area_size(pkt);
+}
+
+_ODP_INLINE uint32_t odp_packet_flow_hash(odp_packet_t pkt)
+{
+	return _odp_packet_flow_hash(pkt);
+}
+
+_ODP_INLINE odp_time_t odp_packet_ts(odp_packet_t pkt)
+{
+	return _odp_packet_ts(pkt);
+}
+
+_ODP_INLINE void *odp_packet_head(odp_packet_t pkt)
+{
+	return _odp_packet_head(pkt);
+}
+
+_ODP_INLINE int odp_packet_is_segmented(odp_packet_t pkt)
+{
+	return _odp_packet_is_segmented(pkt);
+}
+
+_ODP_INLINE odp_packet_seg_t odp_packet_first_seg(odp_packet_t pkt)
+{
+	return _odp_packet_first_seg(pkt);
+}
+
+_ODP_INLINE void odp_packet_prefetch(odp_packet_t pkt, uint32_t offset,
+				     uint32_t len)
+{
+	return _odp_packet_prefetch(pkt, offset, len);
+}
+
+#endif
diff --git a/platform/linux-generic/include/odp/api/plat/packet_types.h b/platform/linux-generic/include/odp/api/plat/packet_types.h
index 999130ec..9efb5165 100644
--- a/platform/linux-generic/include/odp/api/plat/packet_types.h
+++ b/platform/linux-generic/include/odp/api/plat/packet_types.h
@@ -18,6 +18,8 @@ 
 extern "C" {
 #endif
 
+#include <stddef.h>
+
 #include <odp/api/plat/static_inline.h>
 #if ODP_ABI_COMPAT == 1
 #include <odp/api/abi/packet.h>
@@ -55,6 +57,45 @@  typedef enum {
 
 #endif
 
+/** @internal Packet header field offsets for inline functions */
+typedef struct _odp_packet_inline_offset_t {
+	/** @internal field offset */
+	size_t data;
+	/** @internal field offset */
+	size_t seg_len;
+	/** @internal field offset */
+	size_t frame_len;
+	/** @internal field offset */
+	size_t headroom;
+	/** @internal field offset */
+	size_t tailroom;
+	/** @internal field offset */
+	size_t unshared_len;
+	/** @internal field offset */
+	size_t ref_hdr;
+	/** @internal field offset */
+	size_t ref_offset;
+	/** *internal field offset */
+	size_t ref_len;
+	/** @internal field offset */
+	size_t pool;
+	/** @internal field offset */
+	size_t input;
+	/** @internal field offset */
+	size_t segcount;
+	/** @internal field offset */
+	size_t user_ptr;
+	/** @internal field offset */
+	size_t user_area;
+	/** @internal field offset */
+	size_t user_area_size;
+	/** @internal field offset */
+	size_t flow_hash;
+	/** @internal field offset */
+	size_t timestamp;
+
+} _odp_packet_inline_offset_t;
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h
index d1c6d456..875c376a 100644
--- a/platform/linux-generic/include/odp_packet_internal.h
+++ b/platform/linux-generic/include/odp_packet_internal.h
@@ -292,17 +292,14 @@  static inline void pull_tail(odp_packet_hdr_t *pkt_hdr, uint32_t len)
 
 static inline uint32_t packet_len(odp_packet_hdr_t *pkt_hdr)
 {
-	uint32_t pkt_len = 0;
-	uint32_t offset  = 0;
-
-	do {
-		pkt_len += pkt_hdr->frame_len - offset;
-		offset   = pkt_hdr->ref_offset;
-		if (pkt_hdr->ref_hdr)
-			offset += (pkt_hdr->ref_hdr->frame_len -
-				   pkt_hdr->ref_len);
-		pkt_hdr  = pkt_hdr->ref_hdr;
-	} while (pkt_hdr);
+	uint32_t pkt_len = pkt_hdr->frame_len;
+	odp_packet_hdr_t *ref_hdr = pkt_hdr->ref_hdr;
+
+	while (ref_hdr) {
+		pkt_len += pkt_hdr->ref_offset - pkt_hdr->ref_len;
+		pkt_hdr = ref_hdr;
+		ref_hdr = ref_hdr->ref_hdr;
+	}
 
 	return pkt_len;
 }
diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c
index cfed3d9b..a925e722 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -4,6 +4,7 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
+#include <odp/api/plat/packet_inlines.h>
 #include <odp/api/packet.h>
 #include <odp_packet_internal.h>
 #include <odp_debug_internal.h>
@@ -23,6 +24,27 @@ 
 /* Initial packet segment data length */
 #define BASE_LEN  CONFIG_PACKET_MAX_SEG_LEN
 
+/* Fill in packet header field offsets for inline functions */
+const _odp_packet_inline_offset_t _odp_packet_inline ODP_ALIGNED_CACHE = {
+	.data           = offsetof(odp_packet_hdr_t, buf_hdr.seg[0].data),
+	.seg_len        = offsetof(odp_packet_hdr_t, buf_hdr.seg[0].len),
+	.frame_len      = offsetof(odp_packet_hdr_t, frame_len),
+	.headroom       = offsetof(odp_packet_hdr_t, headroom),
+	.tailroom       = offsetof(odp_packet_hdr_t, tailroom),
+	.unshared_len   = offsetof(odp_packet_hdr_t, unshared_len),
+	.ref_hdr        = offsetof(odp_packet_hdr_t, ref_hdr),
+	.ref_offset     = offsetof(odp_packet_hdr_t, ref_offset),
+	.ref_len        = offsetof(odp_packet_hdr_t, ref_len),
+	.pool           = offsetof(odp_packet_hdr_t, buf_hdr.pool_hdl),
+	.input          = offsetof(odp_packet_hdr_t, input),
+	.segcount       = offsetof(odp_packet_hdr_t, buf_hdr.segcount),
+	.user_ptr       = offsetof(odp_packet_hdr_t, buf_hdr.buf_ctx),
+	.user_area      = offsetof(odp_packet_hdr_t, buf_hdr.uarea_addr),
+	.user_area_size = offsetof(odp_packet_hdr_t, buf_hdr.uarea_size),
+	.flow_hash      = offsetof(odp_packet_hdr_t, flow_hash),
+	.timestamp      = offsetof(odp_packet_hdr_t, timestamp)
+};
+
 static inline odp_packet_hdr_t *packet_hdr(odp_packet_t pkt)
 {
 	return (odp_packet_hdr_t *)(uintptr_t)pkt;
@@ -775,13 +797,6 @@  odp_event_t odp_packet_to_event(odp_packet_t pkt)
  *
  */
 
-void *odp_packet_head(odp_packet_t pkt)
-{
-	odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
-
-	return pkt_hdr->buf_hdr.seg[0].data - pkt_hdr->headroom;
-}
-
 uint32_t odp_packet_buf_len(odp_packet_t pkt)
 {
 	odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
@@ -795,25 +810,6 @@  uint32_t odp_packet_buf_len(odp_packet_t pkt)
 	return buf_len;
 }
 
-void *odp_packet_data(odp_packet_t pkt)
-{
-	odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
-
-	return packet_map(pkt_hdr, 0, NULL, NULL);
-}
-
-uint32_t odp_packet_seg_len(odp_packet_t pkt)
-{
-	odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
-
-	return packet_first_seg_len(pkt_hdr);
-}
-
-uint32_t odp_packet_len(odp_packet_t pkt)
-{
-	return packet_len(packet_hdr(pkt));
-}
-
 uint32_t odp_packet_unshared_len(odp_packet_t pkt)
 {
 	odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
@@ -839,16 +835,6 @@  uint32_t odp_packet_unshared_len(odp_packet_t pkt)
 	return pkt_len;
 }
 
-uint32_t odp_packet_headroom(odp_packet_t pkt)
-{
-	return packet_hdr(pkt)->headroom;
-}
-
-uint32_t odp_packet_tailroom(odp_packet_t pkt)
-{
-	return packet_last_hdr(pkt, NULL)->tailroom;
-}
-
 void *odp_packet_tail(odp_packet_t pkt)
 {
 	odp_packet_hdr_t *pkt_hdr = packet_last_hdr(pkt, NULL);
@@ -1452,13 +1438,6 @@  void *odp_packet_offset(odp_packet_t pkt, uint32_t offset, uint32_t *len,
 	return addr;
 }
 
-/* This function is a no-op */
-void odp_packet_prefetch(odp_packet_t pkt ODP_UNUSED,
-			 uint32_t offset ODP_UNUSED,
-			 uint32_t len ODP_UNUSED)
-{
-}
-
 /*
  *
  * Meta-data
@@ -1466,41 +1445,16 @@  void odp_packet_prefetch(odp_packet_t pkt ODP_UNUSED,
  *
  */
 
-odp_pool_t odp_packet_pool(odp_packet_t pkt)
-{
-	return packet_hdr(pkt)->buf_hdr.pool_hdl;
-}
-
-odp_pktio_t odp_packet_input(odp_packet_t pkt)
-{
-	return packet_hdr(pkt)->input;
-}
-
 int odp_packet_input_index(odp_packet_t pkt)
 {
 	return odp_pktio_index(packet_hdr(pkt)->input);
 }
 
-void *odp_packet_user_ptr(odp_packet_t pkt)
-{
-	return packet_hdr(pkt)->buf_hdr.buf_ctx;
-}
-
 void odp_packet_user_ptr_set(odp_packet_t pkt, const void *ctx)
 {
 	packet_hdr(pkt)->buf_hdr.buf_cctx = ctx;
 }
 
-void *odp_packet_user_area(odp_packet_t pkt)
-{
-	return packet_hdr(pkt)->buf_hdr.uarea_addr;
-}
-
-uint32_t odp_packet_user_area_size(odp_packet_t pkt)
-{
-	return packet_hdr(pkt)->buf_hdr.uarea_size;
-}
-
 void *odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len)
 {
 	odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
@@ -1593,13 +1547,6 @@  int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset)
 	return 0;
 }
 
-uint32_t odp_packet_flow_hash(odp_packet_t pkt)
-{
-	odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
-
-	return pkt_hdr->flow_hash;
-}
-
 void odp_packet_flow_hash_set(odp_packet_t pkt, uint32_t flow_hash)
 {
 	odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
@@ -1608,13 +1555,6 @@  void odp_packet_flow_hash_set(odp_packet_t pkt, uint32_t flow_hash)
 	pkt_hdr->p.input_flags.flow_hash = 1;
 }
 
-odp_time_t odp_packet_ts(odp_packet_t pkt)
-{
-	odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
-
-	return pkt_hdr->timestamp;
-}
-
 void odp_packet_ts_set(odp_packet_t pkt, odp_time_t timestamp)
 {
 	odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
@@ -1623,13 +1563,6 @@  void odp_packet_ts_set(odp_packet_t pkt, odp_time_t timestamp)
 	pkt_hdr->p.input_flags.timestamp = 1;
 }
 
-int odp_packet_is_segmented(odp_packet_t pkt)
-{
-	odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
-
-	return pkt_hdr->buf_hdr.segcount > 1 || pkt_hdr->ref_hdr != NULL;
-}
-
 int odp_packet_num_segs(odp_packet_t pkt)
 {
 	odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
@@ -1654,11 +1587,6 @@  int odp_packet_num_segs(odp_packet_t pkt)
 	return segcount;
 }
 
-odp_packet_seg_t odp_packet_first_seg(odp_packet_t pkt ODP_UNUSED)
-{
-	return 0;
-}
-
 odp_packet_seg_t odp_packet_last_seg(odp_packet_t pkt)
 {
 	return (odp_packet_seg_t)(odp_packet_num_segs(pkt) - 1);
@@ -1836,7 +1764,7 @@  int odp_packet_align(odp_packet_t *pkt, uint32_t offset, uint32_t len,
 		return rc;
 
 	(void)odp_packet_move_data(*pkt, 0, shift,
-				   odp_packet_len(*pkt) - shift);
+				   _odp_packet_len(*pkt) - shift);
 
 	(void)odp_packet_trunc_tail(pkt, shift, NULL, NULL);
 	return 1;
@@ -1884,7 +1812,7 @@  int odp_packet_concat(odp_packet_t *dst, odp_packet_t src)
 
 int odp_packet_split(odp_packet_t *pkt, uint32_t len, odp_packet_t *tail)
 {
-	uint32_t pktlen = odp_packet_len(*pkt);
+	uint32_t pktlen = _odp_packet_len(*pkt);
 
 	if (len >= pktlen || tail == NULL)
 		return -1;
@@ -2028,7 +1956,7 @@  odp_packet_t odp_packet_copy(odp_packet_t pkt, odp_pool_t pool)
 odp_packet_t odp_packet_copy_part(odp_packet_t pkt, uint32_t offset,
 				  uint32_t len, odp_pool_t pool)
 {
-	uint32_t pktlen = odp_packet_len(pkt);
+	uint32_t pktlen = _odp_packet_len(pkt);
 	odp_packet_t newpkt;
 
 	if (offset >= pktlen || offset + len > pktlen)
@@ -2651,3 +2579,8 @@  uint64_t odp_packet_seg_to_u64(odp_packet_seg_t hdl)
 {
 	return _odp_pri(hdl);
 }
+
+/* Include non-inlined versions of API functions */
+#if ODP_ABI_COMPAT == 1
+#include <odp/api/plat/packet_inlines_api.h>
+#endif
diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c
index 9a9f7a4e..1922109a 100644
--- a/platform/linux-generic/pktio/dpdk.c
+++ b/platform/linux-generic/pktio/dpdk.c
@@ -14,6 +14,9 @@ 
 
 #include <odp/api/cpumask.h>
 
+#include <odp/api/plat/packet_inlines.h>
+#include <odp/api/packet.h>
+
 #include <odp_packet_io_internal.h>
 #include <odp_classification_internal.h>
 #include <odp_packet_dpdk.h>
@@ -836,7 +839,7 @@  static inline int pkt_to_mbuf(pktio_entry_t *pktio_entry,
 		return 0;
 	}
 	for (i = 0; i < num; i++) {
-		pkt_len = odp_packet_len(pkt_table[i]);
+		pkt_len = _odp_packet_len(pkt_table[i]);
 
 		if (pkt_len > pkt_dpdk->mtu) {
 			if (i == 0)
diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c
index 208984b6..ae3db34d 100644
--- a/platform/linux-generic/pktio/netmap.c
+++ b/platform/linux-generic/pktio/netmap.c
@@ -8,6 +8,9 @@ 
 
 #include <odp_posix_extensions.h>
 
+#include <odp/api/plat/packet_inlines.h>
+#include <odp/api/packet.h>
+
 #include <odp_packet_io_internal.h>
 #include <odp_packet_netmap.h>
 #include <odp_packet_socket.h>
@@ -806,7 +809,7 @@  static int netmap_send(pktio_entry_t *pktio_entry, int index,
 
 	for (nb_tx = 0; nb_tx < num; nb_tx++) {
 		pkt = pkt_table[nb_tx];
-		pkt_len = odp_packet_len(pkt);
+		pkt_len = _odp_packet_len(pkt);
 
 		if (pkt_len > pkt_nm->mtu) {
 			if (nb_tx == 0)
diff --git a/test/common_plat/performance/Makefile.am b/test/common_plat/performance/Makefile.am
index 1074ade8..9111c0c2 100644
--- a/test/common_plat/performance/Makefile.am
+++ b/test/common_plat/performance/Makefile.am
@@ -28,6 +28,10 @@  odp_bench_packet_LDFLAGS = $(AM_LDFLAGS) -static
 odp_bench_packet_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test
 odp_crypto_LDFLAGS = $(AM_LDFLAGS) -static
 odp_crypto_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test
+odp_pktio_perf_LDFLAGS = $(AM_LDFLAGS) -static
+odp_pktio_perf_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test
+odp_l2fwd_LDFLAGS = $(AM_LDFLAGS) -static
+odp_l2fwd_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test
 odp_pktio_ordered_LDFLAGS = $(AM_LDFLAGS) -static
 odp_pktio_ordered_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test
 odp_sched_latency_LDFLAGS = $(AM_LDFLAGS) -static