From patchwork Mon Oct 10 19:31:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bill Fischofer X-Patchwork-Id: 77463 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp65916qge; Mon, 10 Oct 2016 12:35:22 -0700 (PDT) X-Received: by 10.55.143.134 with SMTP id r128mr35898750qkd.161.1476128122899; Mon, 10 Oct 2016 12:35:22 -0700 (PDT) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id y124si16810681qkc.181.2016.10.10.12.35.20; Mon, 10 Oct 2016 12:35:22 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 1933060F53; Mon, 10 Oct 2016 19:35:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 7356760F50; Mon, 10 Oct 2016 19:31:48 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 9773160F4C; Mon, 10 Oct 2016 19:31:32 +0000 (UTC) Received: from mail-oi0-f54.google.com (mail-oi0-f54.google.com [209.85.218.54]) by lists.linaro.org (Postfix) with ESMTPS id EB65E60F22 for ; Mon, 10 Oct 2016 19:31:27 +0000 (UTC) Received: by mail-oi0-f54.google.com with SMTP id y2so60361306oie.0 for ; Mon, 10 Oct 2016 12:31:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=casr6j6mjZ4KXYfwV42Uod9754ybx0NEivDFZic73gg=; b=XrULhPEJW5Qi/1dpazKGFsujKPpLfzgoGc9JpfPYFAoWP1GQyQqNkCDx+z3V9nAvWX gsA2aTF1fj6/BOZY+6UcB2D78e2zSPoq3fUXEcEgB4RTaZWO8bEZD+NwZdcdic/omr59 hsD9RmZgkr4/Z7ro9StJDHQCXrrdBDzi5V8FopWr/zcgLp80DPeUcPHdP3rMZRE3DZ4s ptHbFkA9R1Gt5is7/2vTyPDH11hC3Rm6trs1ESV1lI+Bglw8OIy9DQDdo3UOAMOjo/Y9 tAXSkfYY1pEmbJUPOcLKMsCFApMbqIBRMpmmLAbYwtJmg242GHFXZu0WRCn32J+nBaUo 0rNA== X-Gm-Message-State: AA6/9RnTk4JST9Zg9TJvfZ/EKkAjbcQF84oatmheW3wNo3AOsuJkpAzdH+fRKhj2TxDYUgFkAGU= X-Received: by 10.157.56.110 with SMTP id r43mr8734535otd.66.1476127887328; Mon, 10 Oct 2016 12:31:27 -0700 (PDT) Received: from localhost.localdomain (cpe-70-121-83-241.austin.res.rr.com. [70.121.83.241]) by smtp.gmail.com with ESMTPSA id t7sm2198305otb.25.2016.10.10.12.31.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 10 Oct 2016 12:31:26 -0700 (PDT) From: Bill Fischofer To: lng-odp@lists.linaro.org Date: Mon, 10 Oct 2016 14:31:16 -0500 Message-Id: <1476127876-5214-6-git-send-email-bill.fischofer@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1476127876-5214-1-git-send-email-bill.fischofer@linaro.org> References: <1476127876-5214-1-git-send-email-bill.fischofer@linaro.org> X-Topics: patch Subject: [lng-odp] [API-NEXT PATCHv5 5/5] doc: userguide: add user documentation for packet splice/reference APIs X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" Signed-off-by: Bill Fischofer --- doc/users-guide/users-guide-packet.adoc | 118 ++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) -- 2.7.4 diff --git a/doc/users-guide/users-guide-packet.adoc b/doc/users-guide/users-guide-packet.adoc index e3be23c..82836d0 100644 --- a/doc/users-guide/users-guide-packet.adoc +++ b/doc/users-guide/users-guide-packet.adoc @@ -282,3 +282,121 @@ larger than the underlying segment size. The call may also fail if the requested alignment is too high. Alignment limits will vary among different ODP implementations, however ODP requires that all implementations support requested alignments of at least 32 bytes. + +==== Packet Splices and References +To support efficient multicast, retransmit, and related processing, ODP +supports two additional types of packet manipulation: _splices_ and +_references_. + +===== Splices +A _splice_ is formed by connecting a _header packet_ to a _base packet_ at a +specified byte offset into the base packet using the API: + +[source,c] +----- +spliced_pkt = odp_packet_splice(hdr_pkt, base_pkt, offset); +----- + +If the splice fails, `ODP_PACKET_INVALID` is returned and both `hdr_pkt` and +`base_pkt` are unchanged. Otherwise the `hdr_pkt` is replaced by the returned +`spliced_pkt`, which should be used to refer to the splice. The basic splice +operation is show below: + +.Packet Splicing +image::splice.svg[align="center"] + +Note that the original `base_pkt` is still valid and viewable independent of +the splice. However, when viewed through the returned splice packet handle the +bytes contained in `base_pkt` prior to the splice offset are invisible. + +A splice thus creates a "view" on a base packet that consists of a unique +_prefix_ followed by a shared _payload_. This is important because multiple +headers can be spliced onto a single base packet: + +[source,c] +----- +splice1 = odp_packet_splice(hdr_pkt1, base_pkt, offset1); +splice2 = odp_packet_splice(hdr_pkt2, base_pkt, offset2); +----- +The result of these two calls is shown here: + +.Payload Sharing via Splicing +image::doublesplice.svg[align="center"] + +Here two separate header packets are spliced onto the same base packet, each +at their own specified offset, which may or may not be the same. The result is +three packets visible to the application: + +* The original `base_pkt`, which can still be accessed directly. +* The first splice, which consists of `hdr_pkt1` followed by bytes contained in +`base_pkt` starting at `offset1`. +* The second splice, which consists of `hdr_pkt2` followed by bytes contained +in `base_pkt` starting at `offset2`. + +Only a single copy of the bytes in `base_pkt` that are common to the two +splices exist. Splices therefore permit multiple headers to be attached to a +shared payload in an efficient manner. + +Once spliced, the `base_pkt` may be freed via a call to `odp_packet_free()`, +however the bytes that are part of `base_pkt` that are visible through any +splices are retained until the splice packets are themselves freed. Splices +can thus be used to retain a copy of a packet after it (or another splice +based on it) has been transmitted or otherwise consumed. + +===== References +A _packet reference_ is a special type of splice with a null header. For +convenience, a separate API is provided for creating packet references: + +[source,c] +----- +ref_pkt = odp_packet_ref(base_pkt, offset); +----- +Again, if the reference fails `ODP_PACKET_INVALID` is returned and no other +effect is seen. A successful call results in the following behavior: + +.Packet Reference +image::pktref.svg[align="center"] + +Similar to a splice, a reference permits the creation of multiple views on +a base packet that can be processed or freed independently. The only +difference is that a reference does not have an application-supplied header +prefixed to it. + +===== Data Sharing with Splices and References +Because a `base_pkt` is a shared object in both splices and references, +applications must observe certain disciplines when working with them. +In partiular, any change to a `base_pkt` following the creation of a splice +or reference will be visible through any splice/reference handles to them, +and this can lead to unpredictable behavior. For best portability and +consistency, it is recommended that a `base_pkt` be treated as read only once +it has been successfully spliced. + +To assist applications in working with splices, ODP provides two additional +APIs: + +[source,c] +----- +int odp_packet_is_a_splice(odp_packet_t pkt); + +int odp_packet_is_spliced(odp_packet_t pkt); +----- +The `odp_packet_is_a_splice()` API says whether a packet was created via a call +to `odp_packet_splice()` or `odp_packet_ref()`. The `odp_packet_is_spliced()` +API says whether a packet has had a splice created on it, _i.e.,_ if it is a +`base_pkt` for some other splice. + +Note that architecturally, ODP does not limit splicing and so it is possible that +a splice may be used as a `base_pkt` for creating another splice. Such +_compound splices_ may or may not be supported by individual ODP implementations +so for best portability it is recommended that applications restrict themselves +to using simple splices. + +Note also that a packet may not be spliced to itself, nor may circular splice +relationships be formed, _e.g.,_ packet A is spliced onto packet B and B is +spliced onto A. Results are undefined if such circular relationships are attempted. + +The intent of splices and references is to permit easy and efficient manipulation +of packets that consist of unique headers and shared payloads. This means that +normal headroom manipulation (`odp_packet_push_head()`, etc.) affects only the +data unique to an individual splice or reference, allowing customized headers to +be attached to shared payloads.