From patchwork Wed Jan 11 02:33:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bill Fischofer X-Patchwork-Id: 90797 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp913029qgi; Tue, 10 Jan 2017 18:34:18 -0800 (PST) X-Received: by 10.107.150.10 with SMTP id y10mr5825202iod.221.1484102058764; Tue, 10 Jan 2017 18:34:18 -0800 (PST) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id z128si3676354itg.85.2017.01.10.18.34.18; Tue, 10 Jan 2017 18:34:18 -0800 (PST) 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 sp=NONE dis=NONE) header.from=linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id CE5EF60C2E; Wed, 11 Jan 2017 02:34:17 +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, URIBL_BLOCKED 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 4BCD36099D; Wed, 11 Jan 2017 02:34:11 +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 93072607AC; Wed, 11 Jan 2017 02:34:05 +0000 (UTC) Received: from mail-oi0-f50.google.com (mail-oi0-f50.google.com [209.85.218.50]) by lists.linaro.org (Postfix) with ESMTPS id 35DC7607AC for ; Wed, 11 Jan 2017 02:34:04 +0000 (UTC) Received: by mail-oi0-f50.google.com with SMTP id u143so162121181oif.3 for ; Tue, 10 Jan 2017 18:34:04 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=Jd66oIUuEA+asWeNyEZ03KHhZD45U1M+rqt4gVHDSY8=; b=fAhRi3vG324wVSQlvZk/4mWHuL0ZWH3/Fk8Z46I1rd5kM+lRUXnE2WR4jFc852pxA7 /5ayUK8dPtJqcMY/SUq8cTrlWGSZvsViT6BruezOU/u6hAYy2UknWvYfmCAKUHopr0Gc tDsEMPiQu/qKX02aHJFZfBrpeFDlV5csSQJRKAUVe/NUyEqmeXwOnYK3ywTBBE+ICk1q 6oK+bDN4sp8P2Uzmlp/KZ9Jtya27L2F+RRLnReV8mMi/9+1E8j+Z2ktIJHiKK34tCNvf BXB+Gr5yEX6xwj759sdMZPVwtTqFEIg+UmPBuWPurNw1t3ZgJ1TqaIc7SLxFKFVS0mwM C9xA== X-Gm-Message-State: AIkVDXKHEFFFy7mMpnRDyETRC1iwK9AWpAWVIQ6NNEwYfW5CLSvrdOtLhMKJOFzRO4LvbCES+g4= X-Received: by 10.202.81.66 with SMTP id f63mr2829980oib.184.1484102043530; Tue, 10 Jan 2017 18:34:03 -0800 (PST) Received: from localhost.localdomain (cpe-70-121-83-241.austin.res.rr.com. [70.121.83.241]) by smtp.gmail.com with ESMTPSA id u191sm1841930oiu.7.2017.01.10.18.34.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 10 Jan 2017 18:34:02 -0800 (PST) From: Bill Fischofer To: lng-odp@lists.linaro.org Date: Tue, 10 Jan 2017 20:33:55 -0600 Message-Id: <20170111023359.30597-1-bill.fischofer@linaro.org> X-Mailer: git-send-email 2.9.3 Cc: Petri Savolainen Subject: [lng-odp] [API-NEXT PATCHv7 1/5] api: packet: add support for packet references 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" From: Petri Savolainen 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 Signed-off-by: Bill Fischofer -- 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 --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 * ******************************************************** *