diff mbox series

[v1,2/2] linux-gen: packet: inline layer pointers

Message ID 1513872010-2747-3-git-send-email-odpbot@yandex.ru
State Superseded
Headers show
Series [v1,1/2] linux-gen: packet: inline layer offsets | expand

Commit Message

Github ODP bot Dec. 21, 2017, 4 p.m. UTC
From: Petri Savolainen <petri.savolainen@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.savolainen@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 mbox series

Patch

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