From patchwork Mon Oct 10 15:50:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bill Fischofer X-Patchwork-Id: 77443 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp1249611qge; Mon, 10 Oct 2016 08:55:24 -0700 (PDT) X-Received: by 10.107.198.72 with SMTP id w69mr32437209iof.121.1476114924011; Mon, 10 Oct 2016 08:55:24 -0700 (PDT) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id j97si11398474iod.123.2016.10.10.08.55.23; Mon, 10 Oct 2016 08:55:23 -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 0F39560F1F; Mon, 10 Oct 2016 15:55:23 +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 470C660F15; Mon, 10 Oct 2016 15:51:35 +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 A5BC060F17; Mon, 10 Oct 2016 15:51:25 +0000 (UTC) Received: from mail-oi0-f42.google.com (mail-oi0-f42.google.com [209.85.218.42]) by lists.linaro.org (Postfix) with ESMTPS id 805B760F17 for ; Mon, 10 Oct 2016 15:50:53 +0000 (UTC) Received: by mail-oi0-f42.google.com with SMTP id t73so16824727oie.1 for ; Mon, 10 Oct 2016 08:50:53 -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=Q6ZNgZIecL/4VivJhU7vxoG+jHQ0WCE/smLX4+ypm0o9g/EgttsffQS0SgUqjX6E07 MEwX/l+hz0CziBKQoaTt3KpfnKLFh+Tm6bgq8EEaLg/vxgsNHxw4vrpZFEwnN46xiRkK ycgZrJjqyIR4jPWHqHE17+ZqnUfFkBC9V3zHx4cVRiRQvJq8WB3twRrPwgXIzoOLXzUv 8Bmv5gFwoo0irKkZagFJf4IZY8L88Y4AL7nArfKM7QPfNloRdsGvGrYLTyBR1uXheq71 ZuvBobQKz7/Qws4m9j/y1weF9PktEes3W03bRTiPMtTm5t/Ds54a675+2Cej/BNQ3aK9 76og== X-Gm-Message-State: AA6/9RlCQTYNEUEe0YevuY6KGflugl7P/iX8ifPJEOvpZmZBGEVobpe48b7O97PzkcYTntQH7Qc= X-Received: by 10.157.39.136 with SMTP id c8mr10857483otb.180.1476114653032; Mon, 10 Oct 2016 08:50:53 -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 1sm1740700otb.2.2016.10.10.08.50.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 10 Oct 2016 08:50:52 -0700 (PDT) From: Bill Fischofer To: lng-odp@lists.linaro.org Date: Mon, 10 Oct 2016 10:50:46 -0500 Message-Id: <1476114646-9874-6-git-send-email-bill.fischofer@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1476114646-9874-1-git-send-email-bill.fischofer@linaro.org> References: <1476114646-9874-1-git-send-email-bill.fischofer@linaro.org> X-Topics: patch Subject: [lng-odp] [API-NEXT PATCHv4 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.