From patchwork Sun Oct 9 21:58:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bill Fischofer X-Patchwork-Id: 77418 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp987880qge; Sun, 9 Oct 2016 15:03:03 -0700 (PDT) X-Received: by 10.55.166.131 with SMTP id p125mr30590153qke.33.1476050583347; Sun, 09 Oct 2016 15:03:03 -0700 (PDT) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id 58si8116696qtp.96.2016.10.09.15.03.02; Sun, 09 Oct 2016 15:03:03 -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 BD03F60860; Sun, 9 Oct 2016 22:03:02 +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 7032060E9A; Sun, 9 Oct 2016 21:58:54 +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 142ED60E88; Sun, 9 Oct 2016 21:58:48 +0000 (UTC) Received: from mail-oi0-f51.google.com (mail-oi0-f51.google.com [209.85.218.51]) by lists.linaro.org (Postfix) with ESMTPS id F24B260E88 for ; Sun, 9 Oct 2016 21:58:35 +0000 (UTC) Received: by mail-oi0-f51.google.com with SMTP id m72so109730122oik.3 for ; Sun, 09 Oct 2016 14:58:35 -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=iWMSqxne4j6ReUlqu3lZwD5npjd6NEYMSq0rHP8pDCASrv5kezqy2GvFPafvT9HzrX K/z7W8UYn8NyLfqHJYqCtfJdKMf0D+FZr5TdtjsVjAMhX1+ma5b3RR/OK/hckkdfbThx +H1fNM+9cg0XmDFMtQmOnUS/zJK1NlmS3Flbz26u58lWYNftIWTIOHAmaSdFhmOAtjqr 0ax95pi+YHQLr4KqTdYRNDDRUXuJCJiVbPoinLq397LIk778zR9a+HrT4gUEx/t1q+2Q 63UjVopOJgNk1fqtNcR8TvC6ft0OtgtH5y/MBKjgVETlzQ8/d1ldi1jc5URNPdKJQltN IwRw== X-Gm-Message-State: AA6/9RkaqUR8H7gzBEd41ZPiIpJe9yOHeNlLpqHQ1VIb+uO81F2tPqIY2AcEP6S0IJAqHNPJpWE= X-Received: by 10.202.242.9 with SMTP id q9mr18946375oih.140.1476050315267; Sun, 09 Oct 2016 14:58:35 -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 o8sm9786082oia.28.2016.10.09.14.58.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 09 Oct 2016 14:58:34 -0700 (PDT) From: Bill Fischofer To: lng-odp@lists.linaro.org Date: Sun, 9 Oct 2016 16:58:28 -0500 Message-Id: <1476050308-15181-6-git-send-email-bill.fischofer@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1476050308-15181-1-git-send-email-bill.fischofer@linaro.org> References: <1476050308-15181-1-git-send-email-bill.fischofer@linaro.org> X-Topics: patch Subject: [lng-odp] [API-NEXT PATCHv3 5/5] doc: packet: 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.