diff mbox

[API-NEXT,PATCHv7,1/5] api: packet: add support for packet references

Message ID 20170111023359.30597-1-bill.fischofer@linaro.org
State New
Headers show

Commit Message

Bill Fischofer Jan. 11, 2017, 2:33 a.m. UTC
From: Petri Savolainen <petri.savolainen@nokia.com>


Introduce new APIs that support efficient sharing of portions of
packets:
 * odp_packet_ref_static() creates a new static reference
   for a packet
 * odp_packet_ref() creates a new dynamic reference to a packet
 * odp_packet_ref_pkt() creates a reference to a packet with
   a supplied header packet
 * odp_packet_has_ref() checks if a packet has multiple
   references to it
 * odp_packet_unshared_len() returns the unshared data length of
   a reference

Signed-off-by: Petri Savolainen <petri.savolainen@nokia.com>

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

--
Changes in v7:
- Rebased on top of Petri's packet header restructure patch v2. This series
  must be applied on top of that patch set until it is merged.
- odp_packet_is_ref() renamed to odp_packet_has_ref()
- API spec reworded by Petri to tighten it, minor implementation changes to
  conform to this tightened spec.
- Bug fix when dealing with dummy packet headers used by the classifier

Changes in v6:
- Miscellaneous formatting corrections
- Minor documentation improvements

Changes in v5:
- Clarified that both input packets to odp_packet_ref_pkt() must be from the
  same pool and results are undefined if they are not.
- Clarified that input(s) to reference create APIs may be references and that
  implementations are free to perform partial or full packet copies if needed
  to support such compound references.
- Removed odp_packet_has_ref() and redefined odp_packet_is_ref() to indicate
  simply whether other handles exist that share bytes with this packet.
- Modified validation tests to reflect the above changes.

Changes in v4:
- Bug fixes
- Expand validation testing to cover extensions on packets with references

Changes in v3:
- Rebased to latest API-NEXT
- Bug fixes
- Eliminate concept of base packets, both references and referenced packets may
  have head extensions as needed
  
 include/odp/api/spec/packet.h | 133 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 132 insertions(+), 1 deletion(-)

-- 
2.9.3
diff mbox

Patch

diff --git a/include/odp/api/spec/packet.h b/include/odp/api/spec/packet.h
index 4a86eba..b6450c1 100644
--- a/include/odp/api/spec/packet.h
+++ b/include/odp/api/spec/packet.h
@@ -795,7 +795,7 @@  uint32_t odp_packet_seg_data_len(odp_packet_t pkt, odp_packet_seg_t seg);
  * data pointers. Otherwise, all old pointers remain valid.
  *
  * The resulting packet is always allocated from the same pool as
- * the destination packet. The source packet may have been allocate from
+ * the destination packet. The source packet may have been allocated from
  * any pool.
  *
  * On failure, both handles remain valid and packets are not modified.
@@ -848,6 +848,137 @@  int odp_packet_split(odp_packet_t *pkt, uint32_t len, odp_packet_t *tail);
 
 /*
  *
+ * References
+ * ********************************************************
+ *
+ */
+
+/**
+ * Create a static reference to a packet
+ *
+ * A static reference is used to obtain an additional handle for referring to
+ * the entire packet as it is. As long as a packet has multiple (static)
+ * references, any of the references (including 'pkt') must not be used to
+ * modify the packet in any way - both data and metadata must remain static.
+ * The packet may be modified again when there is a single reference left.
+ * Static and dynamic references must not be mixed. Results are undefined if
+ * these restrictions are not observed.
+ *
+ * While static references are inflexible they offer efficient way to do,
+ * e.g., packet retransmissions. Use odp_packet_ref() or odp_packet_ref_pkt()
+ * for more flexible, dynamic references.
+ *
+ * Packet is not modified on failure.
+ *
+ * @param pkt    Handle of the packet for which a static reference is
+ *               to be created.
+ *
+ * @return Static reference to the packet
+ * @retval ODP_PACKET_INVALID  On failure
+ */
+odp_packet_t odp_packet_ref_static(odp_packet_t pkt);
+
+/**
+ * Create a reference to a packet
+ *
+ * Returns a new (dynamic) reference to a packet starting the shared part of
+ * the data at a specified byte offset. Metadata and data before the offset
+ * are not shared with other references of the packet. The rest of the data is
+ * shared and must be treated as read only. Initially the returned reference
+ * has metadata initialized to default values and does not contain unshared
+ * data.  Packet (head) manipulation functions may be used normally to, e.g.,
+ * add a unique header onto the shared payload. The shared part of the packet
+ * may be modified again when there is a single reference left. Static and
+ * dynamic references must not be mixed. Results are undefined if these
+ * restrictions are not observed.
+ *
+ * odp_packet_unshared_len() may be used to determine the number of bytes
+ * starting at offset zero that are unique to a packet handle.
+ *
+ * The packet handle 'pkt' may itself by a (dynamic) reference to a packet.
+ *
+ * If the caller does not intend to modify either the packet or the new
+ * reference to it, odp_packet_ref_static() may be used to create
+ * a static reference that is more optimized for that use case.
+ *
+ * Packet is not modified on failure.
+ *
+ * @param pkt    Handle of the packet for which a reference is to be
+ *               created.
+ *
+ * @param offset Byte offset in the packet at which the shared part is to
+ *               begin. This must be in the range 0 ... odp_packet_len(pkt)-1.
+ *
+ * @return New reference to the packet
+ * @retval ODP_PACKET_INVALID On failure
+ */
+odp_packet_t odp_packet_ref(odp_packet_t pkt, uint32_t offset);
+
+/**
+ * Create a reference to a packet with a header packet
+ *
+ * This operation is otherwise identical to odp_packet_ref(), but it prepends
+ * a supplied 'hdr' packet as the head of the new reference. The resulting
+ * packet consists metadata and data of the 'hdr' packet, followed by the
+ * shared part of packet 'pkt'.
+ *
+ * The packet handle ('pkt') may itself by a (dynamic) reference to a packet,
+ * but the header packet handle ('hdr') must be unique. Both packets must be
+ * have been allocated from the same pool and the handles must not refer to
+ * the same packet. Results are undefined if these restrictions are not
+ * observed.
+ *
+ * Packets are not modified on failure. The header packet 'hdr' is consumed
+ * on success.
+ *
+ * @param pkt    Handle of the packet for which a reference is to be
+ *               created.
+ *
+ * @param offset Byte offset in 'pkt' at which the shared part is to
+ *               begin. Must be in the range 0 ... odp_packet_len(pkt)-1.
+ *
+ * @param hdr    Handle of the header packet to be prefixed onto the new
+ *               reference. Must be a unique reference.
+ *
+ * @return New reference the reference packet
+ * @retval ODP_PACKET_INVALID On failure
+ */
+odp_packet_t odp_packet_ref_pkt(odp_packet_t pkt, uint32_t offset,
+				odp_packet_t hdr);
+
+/**
+ * Packet unshared data length
+ *
+ * When a packet has multiple references, packet data is divided into two
+ * parts: unshared and shared. The unshared part always precedes the shared
+ * part. This call returns number of bytes in the unshared part.  When a
+ * packet has only a single reference, all packet data is unshared and
+ * unshared length equals the packet length (odp_packet_len()).
+ *
+ * Application may modify only the unshared part, the rest of the packet data
+ * must be treated as read only.
+ *
+ * @param pkt  Packet handle
+ *
+ * @return Packet unshared data length
+ */
+uint32_t odp_packet_unshared_len(odp_packet_t pkt);
+
+/**
+ * Test if packet has multiple references
+ *
+ * A packet that has multiple references shares data and possibly metadata
+ * with other packets. Shared part must be treated as read only.
+ *
+ * @param pkt Packet handle
+ *
+ * @retval 0  This is the single reference to the packet
+ * @retval 1  Packet has multiple references
+ */
+int odp_packet_has_ref(odp_packet_t pkt);
+
+/*
+ *
  * Copy
  * ********************************************************
  *