From: Petri Savolainen <petri.savolai...@linaro.org>

Inline L2/L3/L4 pointer functions. Packet map function
is exported to backup the unlikely case when offset is not
within the first segment. Always use the inlined version
within the implementation itself.

Signed-off-by: Petri Savolainen <petri.savolai...@linaro.org>
---
/** Email created from pull request 360 (psavol:master-packet-offset-inline)
 ** https://github.com/Linaro/odp/pull/360
 ** Patch: https://github.com/Linaro/odp/pull/360.patch
 ** Base sha: 3c02836d9d9ca16b1277bdd30e523779b9fe8374
 ** Merge commit sha: 8a43dcccb105ee32ad867e39b8763d77c37b331e
 **/
 .../include/odp/api/plat/packet_inlines.h          | 62 ++++++++++++++++++++++
 .../include/odp/api/plat/packet_inlines_api.h      | 15 ++++++
 platform/linux-generic/odp_packet.c                | 40 ++++++--------
 platform/linux-generic/odp_traffic_mngr.c          |  6 +--
 4 files changed, 95 insertions(+), 28 deletions(-)

diff --git a/platform/linux-generic/include/odp/api/plat/packet_inlines.h 
b/platform/linux-generic/include/odp/api/plat/packet_inlines.h
index aa9ba812f..2ace0ca37 100644
--- a/platform/linux-generic/include/odp/api/plat/packet_inlines.h
+++ b/platform/linux-generic/include/odp/api/plat/packet_inlines.h
@@ -18,6 +18,11 @@
 #include <odp/api/packet_io.h>
 #include <odp/api/hints.h>
 
+/** @internal Inline function @param pkt_ptr @param offset @param seg_len
+ *  @param seg_idx @return */
+void *_odp_packet_map(void *pkt_ptr, uint32_t offset, uint32_t *seg_len,
+                     int *seg_idx);
+
 /** @internal Inline function offsets */
 extern const _odp_packet_inline_offset_t _odp_packet_inline;
 
@@ -126,6 +131,63 @@ static inline uint32_t _odp_packet_l4_offset(odp_packet_t 
pkt)
        return _odp_pkt_get(pkt, uint16_t, l4_offset);
 }
 
+/** @internal Inline function @param pkt @param len @return */
+static inline void *_odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len)
+{
+       uint32_t offset  = _odp_packet_l2_offset(pkt);
+       uint32_t seg_len = _odp_packet_seg_len(pkt);
+       uint8_t *data    = (uint8_t *)_odp_packet_data(pkt);
+
+       if (odp_unlikely(offset > seg_len)) {
+               void *pkt_hdr = (void *)pkt;
+
+               return _odp_packet_map(pkt_hdr, offset, len, NULL);
+       }
+
+       if (len)
+               *len = seg_len - offset;
+
+       return data + offset;
+}
+
+/** @internal Inline function @param pkt @param len @return */
+static inline void *_odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len)
+{
+       uint32_t offset  = _odp_packet_l3_offset(pkt);
+       uint32_t seg_len = _odp_packet_seg_len(pkt);
+       uint8_t *data    = (uint8_t *)_odp_packet_data(pkt);
+
+       if (odp_unlikely(offset > seg_len)) {
+               void *pkt_hdr = (void *)pkt;
+
+               return _odp_packet_map(pkt_hdr, offset, len, NULL);
+       }
+
+       if (len)
+               *len = seg_len - offset;
+
+       return data + offset;
+}
+
+/** @internal Inline function @param pkt @param len @return */
+static inline void *_odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len)
+{
+       uint32_t offset  = _odp_packet_l4_offset(pkt);
+       uint32_t seg_len = _odp_packet_seg_len(pkt);
+       uint8_t *data    = (uint8_t *)_odp_packet_data(pkt);
+
+       if (odp_unlikely(offset > seg_len)) {
+               void *pkt_hdr = (void *)pkt;
+
+               return _odp_packet_map(pkt_hdr, offset, len, NULL);
+       }
+
+       if (len)
+               *len = seg_len - offset;
+
+       return data + offset;
+}
+
 /** @internal Inline function @param pkt @return */
 static inline uint32_t _odp_packet_flow_hash(odp_packet_t pkt)
 {
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
index 84b4f08ab..c90a69c52 100644
--- a/platform/linux-generic/include/odp/api/plat/packet_inlines_api.h
+++ b/platform/linux-generic/include/odp/api/plat/packet_inlines_api.h
@@ -83,6 +83,21 @@ _ODP_INLINE uint32_t odp_packet_l4_offset(odp_packet_t pkt)
        return _odp_packet_l4_offset(pkt);
 }
 
+_ODP_INLINE void *odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len)
+{
+       return _odp_packet_l2_ptr(pkt, len);
+}
+
+_ODP_INLINE void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len)
+{
+       return _odp_packet_l3_ptr(pkt, len);
+}
+
+_ODP_INLINE void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len)
+{
+       return _odp_packet_l4_ptr(pkt, len);
+}
+
 _ODP_INLINE uint32_t odp_packet_flow_hash(odp_packet_t pkt)
 {
        return _odp_packet_flow_hash(pkt);
diff --git a/platform/linux-generic/odp_packet.c 
b/platform/linux-generic/odp_packet.c
index 3f0d764f6..0f4d32818 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -278,11 +278,12 @@ static inline void packet_seg_copy_md(odp_packet_hdr_t 
*dst,
         */
 }
 
-static inline void *packet_map(odp_packet_hdr_t *pkt_hdr,
-                              uint32_t offset, uint32_t *seg_len, int *seg_idx)
+static inline void *packet_map(void *pkt_ptr, uint32_t offset,
+                              uint32_t *seg_len, int *seg_idx)
 {
        void *addr;
        uint32_t len;
+       odp_packet_hdr_t *pkt_hdr = pkt_ptr;
        int seg_id = 0;
        int seg_count = pkt_hdr->buf_hdr.segcount;
 
@@ -323,6 +324,18 @@ static inline void *packet_map(odp_packet_hdr_t *pkt_hdr,
        return addr;
 }
 
+#include <odp/visibility_begin.h>
+
+/* This file uses the inlined version directly. Inlined API calls use this when
+ * packet seg_len < offset. */
+void *_odp_packet_map(void *pkt_ptr, uint32_t offset, uint32_t *seg_len,
+                     int *seg_idx)
+{
+       return packet_map(pkt_ptr, offset, seg_len, seg_idx);
+}
+
+#include <odp/visibility_end.h>
+
 void packet_parse_reset(odp_packet_hdr_t *pkt_hdr)
 {
        /* Reset parser metadata before new parse */
@@ -1207,15 +1220,6 @@ void odp_packet_user_ptr_set(odp_packet_t pkt, const 
void *ctx)
        packet_hdr(pkt)->buf_hdr.buf_cctx = ctx;
 }
 
-void *odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len)
-{
-       odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
-
-       if (!packet_hdr_has_l2(pkt_hdr))
-               return NULL;
-       return packet_map(pkt_hdr, pkt_hdr->p.l2_offset, len, NULL);
-}
-
 int odp_packet_l2_offset_set(odp_packet_t pkt, uint32_t offset)
 {
        odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
@@ -1228,13 +1232,6 @@ int odp_packet_l2_offset_set(odp_packet_t pkt, uint32_t 
offset)
        return 0;
 }
 
-void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len)
-{
-       odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
-
-       return packet_map(pkt_hdr, pkt_hdr->p.l3_offset, len, NULL);
-}
-
 int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset)
 {
        odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
@@ -1246,13 +1243,6 @@ int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t 
offset)
        return 0;
 }
 
-void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len)
-{
-       odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
-
-       return packet_map(pkt_hdr, pkt_hdr->p.l4_offset, len, NULL);
-}
-
 int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset)
 {
        odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
diff --git a/platform/linux-generic/odp_traffic_mngr.c 
b/platform/linux-generic/odp_traffic_mngr.c
index e22a33f29..556b2a1f2 100644
--- a/platform/linux-generic/odp_traffic_mngr.c
+++ b/platform/linux-generic/odp_traffic_mngr.c
@@ -1928,7 +1928,7 @@ static void egress_vlan_marking(tm_vlan_marking_t 
*vlan_marking,
        uint32_t        hdr_len;
        uint16_t        old_tci, new_tci;
 
-       ether_hdr_ptr = odp_packet_l2_ptr(odp_pkt, &hdr_len);
+       ether_hdr_ptr = _odp_packet_l2_ptr(odp_pkt, &hdr_len);
        vlan_hdr_ptr  = (_odp_vlanhdr_t *)(ether_hdr_ptr + 1);
 
        /* If the split_hdr variable below is TRUE, then this indicates that
@@ -1968,7 +1968,7 @@ static void egress_ipv4_tos_marking(tm_tos_marking_t 
*tos_marking,
        uint8_t        old_tos, new_tos, ecn;
 
        l3_offset    = _odp_packet_l3_offset(odp_pkt);
-       ipv4_hdr_ptr = odp_packet_l3_ptr(odp_pkt, &hdr_len);
+       ipv4_hdr_ptr = _odp_packet_l3_ptr(odp_pkt, &hdr_len);
 
        /* If the split_hdr variable below is TRUE, then this indicates that
         * for this odp (output) packet the IPv4 header is not all in the same
@@ -2034,7 +2034,7 @@ static void egress_ipv6_tc_marking(tm_tos_marking_t 
*tos_marking,
        uint8_t        old_tc, new_tc, ecn;
 
        l3_offset    = _odp_packet_l3_offset(odp_pkt);
-       ipv6_hdr_ptr = odp_packet_l3_ptr(odp_pkt, &hdr_len);
+       ipv6_hdr_ptr = _odp_packet_l3_ptr(odp_pkt, &hdr_len);
 
        /* If the split_hdr variable below is TRUE, then this indicates that
         * for this odp (output) packet the IPv6 header is not all in the same

Reply via email to