@@ -78,6 +78,8 @@ odpapiplatinclude_HEADERS = \
$(srcdir)/include/odp/api/plat/crypto_types.h \
$(srcdir)/include/odp/api/plat/event_types.h \
$(srcdir)/include/odp/api/plat/init_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 \
@@ -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>
new file mode 100644
@@ -0,0 +1,173 @@
+/* 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 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 *(void **)(uintptr_t)((uint8_t *)pkt + _odp_packet_inline.data);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline uint32_t _odp_packet_seg_len(odp_packet_t pkt)
+{
+ return *(uint32_t *)(uintptr_t)((uint8_t *)pkt +
+ _odp_packet_inline.seg_len);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline uint32_t _odp_packet_len(odp_packet_t pkt)
+{
+ return *(uint32_t *)(uintptr_t)((uint8_t *)pkt +
+ _odp_packet_inline.frame_len);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline uint32_t _odp_packet_headroom(odp_packet_t pkt)
+{
+ return *(uint32_t *)(uintptr_t)((uint8_t *)pkt +
+ _odp_packet_inline.headroom);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline uint32_t _odp_packet_tailroom(odp_packet_t pkt)
+{
+ return *(uint32_t *)(uintptr_t)((uint8_t *)pkt +
+ _odp_packet_inline.tailroom);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline odp_pool_t _odp_packet_pool(odp_packet_t pkt)
+{
+ return *(odp_pool_t *)(uintptr_t)((uint8_t *)pkt +
+ _odp_packet_inline.pool);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline odp_pktio_t _odp_packet_input(odp_packet_t pkt)
+{
+ return *(odp_pktio_t *)(uintptr_t)((uint8_t *)pkt +
+ _odp_packet_inline.input);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline int _odp_packet_num_segs(odp_packet_t pkt)
+{
+ return *(uint8_t *)(uintptr_t)((uint8_t *)pkt +
+ _odp_packet_inline.segcount);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline void *_odp_packet_user_ptr(odp_packet_t pkt)
+{
+ return *(void **)(uintptr_t)((uint8_t *)pkt +
+ _odp_packet_inline.user_ptr);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline void *_odp_packet_user_area(odp_packet_t pkt)
+{
+ return *(void **)(uintptr_t)((uint8_t *)pkt +
+ _odp_packet_inline.user_area);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline uint32_t _odp_packet_user_area_size(odp_packet_t pkt)
+{
+ return *(uint32_t *)(uintptr_t)((uint8_t *)pkt +
+ _odp_packet_inline.user_area_size);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline uint32_t _odp_packet_flow_hash(odp_packet_t pkt)
+{
+ return *(uint32_t *)(uintptr_t)((uint8_t *)pkt +
+ _odp_packet_inline.flow_hash);
+}
+
+/** @internal Inline function @param pkt @return */
+static inline odp_time_t _odp_packet_ts(odp_packet_t pkt)
+{
+ return *(odp_time_t *)(uintptr_t)((uint8_t *)pkt +
+ _odp_packet_inline.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_packet_num_segs(pkt) > 1;
+}
+
+/** @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 @return */
+static inline odp_packet_seg_t _odp_packet_last_seg(odp_packet_t pkt)
+{
+ return _odp_packet_num_segs(pkt) - 1;
+}
+
+/** @internal Inline function @param pkt @param seg @return */
+static inline odp_packet_seg_t _odp_packet_next_seg(odp_packet_t pkt,
+ odp_packet_seg_t seg)
+{
+ if (odp_unlikely(seg >= _odp_packet_last_seg(pkt)))
+ return ODP_PACKET_SEG_INVALID;
+
+ return seg + 1;
+}
+
+/** @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
new file mode 100644
@@ -0,0 +1,113 @@
+/* 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 int odp_packet_num_segs(odp_packet_t pkt)
+{
+ return _odp_packet_num_segs(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 odp_packet_seg_t odp_packet_last_seg(odp_packet_t pkt)
+{
+ return _odp_packet_last_seg(pkt);
+}
+
+_ODP_INLINE odp_packet_seg_t odp_packet_next_seg(odp_packet_t pkt,
+ odp_packet_seg_t seg)
+{
+ return _odp_packet_next_seg(pkt, seg);
+}
+
+_ODP_INLINE void odp_packet_prefetch(odp_packet_t pkt, uint32_t offset,
+ uint32_t len)
+{
+ return _odp_packet_prefetch(pkt, offset, len);
+}
+
+#endif
@@ -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,37 @@ 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 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
@@ -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,23 @@
/* 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),
+ .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;
@@ -655,13 +673,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);
@@ -669,35 +680,6 @@ uint32_t odp_packet_buf_len(odp_packet_t pkt)
return pkt_hdr->buf_hdr.size * pkt_hdr->buf_hdr.segcount;
}
-void *odp_packet_data(odp_packet_t pkt)
-{
- odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
-
- return packet_data(pkt_hdr);
-}
-
-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_hdr(pkt)->frame_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_hdr(pkt)->tailroom;
-}
-
void *odp_packet_tail(odp_packet_t pkt)
{
odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
@@ -1207,13 +1189,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
@@ -1221,41 +1196,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);
@@ -1348,13 +1298,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);
@@ -1363,13 +1306,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);
@@ -1378,42 +1314,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)
-{
- return packet_hdr(pkt)->buf_hdr.segcount > 1;
-}
-
-int odp_packet_num_segs(odp_packet_t pkt)
-{
- odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
-
- return pkt_hdr->buf_hdr.segcount;
-}
-
-odp_packet_seg_t odp_packet_first_seg(odp_packet_t pkt)
-{
- (void)pkt;
-
- return 0;
-}
-
-odp_packet_seg_t odp_packet_last_seg(odp_packet_t pkt)
-{
- odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
-
- return packet_last_seg(pkt_hdr);
-}
-
-odp_packet_seg_t odp_packet_next_seg(odp_packet_t pkt, odp_packet_seg_t seg)
-{
- odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
-
- if (odp_unlikely(seg >= (odp_packet_seg_t)packet_last_seg(pkt_hdr)))
- return ODP_PACKET_SEG_INVALID;
-
- return seg + 1;
-}
-
/*
*
* Segment level
@@ -1542,7 +1442,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;
@@ -1586,7 +1486,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;
@@ -1627,7 +1527,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)
@@ -2246,3 +2146,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
@@ -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)
@@ -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)
@@ -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
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> --- platform/linux-generic/Makefile.am | 2 + platform/linux-generic/include/odp/api/packet.h | 11 +- .../include/odp/api/plat/packet_inlines.h | 173 +++++++++++++++++++++ .../include/odp/api/plat/packet_inlines_api.h | 113 ++++++++++++++ .../include/odp/api/plat/packet_types.h | 33 ++++ platform/linux-generic/odp_packet.c | 147 ++++------------- platform/linux-generic/pktio/dpdk.c | 5 +- platform/linux-generic/pktio/netmap.c | 5 +- test/common_plat/performance/Makefile.am | 4 + 9 files changed, 363 insertions(+), 130 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.8.1