From patchwork Wed Sep 9 11:41:49 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Uvarov X-Patchwork-Id: 53315 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f199.google.com (mail-wi0-f199.google.com [209.85.212.199]) by patches.linaro.org (Postfix) with ESMTPS id 3C05922B05 for ; Wed, 9 Sep 2015 11:42:09 +0000 (UTC) Received: by wicgb1 with SMTP id gb1sf5846061wic.3 for ; Wed, 09 Sep 2015 04:42:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:delivered-to:from:to:date :message-id:subject:precedence:list-id:list-unsubscribe:list-archive :list-post:list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=EqgPClAGEgbfzaavKuysGwPnaldX/dDH51boGw5YIgc=; b=kIuuBaTN48vWyX31f9O90zsPUfsi40RKNuF42H6F1nsyqAkwrjuUJ3yRcMzlix0gOw 6BlJUYs8Fq1FqxBBH41J/l38+dGwcPZpw/v4b7/nZRelO9A+B5uzQ5Z/71EWX6AFGfew /h1Mu3su68O7qKQtgCn+75AlLwJ2hOLlFq6Rz9wppYPssIdzXpgnXAA3Io6DH8+nGBfc xtr7LlJCHm8k3RnAhMHKd8MZMu6nWuQtC/FQ237fNZVc9sXLYLJCcXAY33sOqB2DoZu+ 7GZG+Smz88nuiFCU8kul1hw85C6wNVkH792+SPIcGJ8eMkteIX2xFbATmAcwWmaSaIRK dKig== X-Gm-Message-State: ALoCoQndokuTGiAG8MGd9vYTAPvKkaKLxpmJwCBMUFCPvdqWkjeb4WuBCbEuf6YQWYpN4JLwGyK0 X-Received: by 10.180.77.105 with SMTP id r9mr8109771wiw.0.1441798928568; Wed, 09 Sep 2015 04:42:08 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.27.168 with SMTP id u8ls34310lag.63.gmail; Wed, 09 Sep 2015 04:42:08 -0700 (PDT) X-Received: by 10.152.27.70 with SMTP id r6mr8678032lag.67.1441798928394; Wed, 09 Sep 2015 04:42:08 -0700 (PDT) Received: from mail-la0-f46.google.com (mail-la0-f46.google.com. [209.85.215.46]) by mx.google.com with ESMTPS id w1si6439269laa.17.2015.09.09.04.42.08 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 09 Sep 2015 04:42:08 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.46 as permitted sender) client-ip=209.85.215.46; Received: by lagj9 with SMTP id j9so4879514lag.2 for ; Wed, 09 Sep 2015 04:42:08 -0700 (PDT) X-Received: by 10.152.26.41 with SMTP id i9mr222690lag.36.1441798928165; Wed, 09 Sep 2015 04:42:08 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp277009lbq; Wed, 9 Sep 2015 04:42:07 -0700 (PDT) X-Received: by 10.50.28.48 with SMTP id y16mr11850763igg.10.1441798926946; Wed, 09 Sep 2015 04:42:06 -0700 (PDT) Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id o9si1906044igw.14.2015.09.09.04.42.05; Wed, 09 Sep 2015 04:42:06 -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; Received: by lists.linaro.org (Postfix, from userid 109) id 3EB2A61D8E; Wed, 9 Sep 2015 11:42:05 +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=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, 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 CBCAE61CC2; Wed, 9 Sep 2015 11:41:59 +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 6E70C61CC5; Wed, 9 Sep 2015 11:41:57 +0000 (UTC) Received: from mail-la0-f54.google.com (mail-la0-f54.google.com [209.85.215.54]) by lists.linaro.org (Postfix) with ESMTPS id 294E661BFD for ; Wed, 9 Sep 2015 11:41:56 +0000 (UTC) Received: by lagj9 with SMTP id j9so4876043lag.2 for ; Wed, 09 Sep 2015 04:41:55 -0700 (PDT) X-Received: by 10.152.28.229 with SMTP id e5mr28358563lah.110.1441798914996; Wed, 09 Sep 2015 04:41:54 -0700 (PDT) Received: from localhost.localdomain (ppp91-76-161-180.pppoe.mtu-net.ru. [91.76.161.180]) by smtp.gmail.com with ESMTPSA id dk7sm788295lad.14.2015.09.09.04.41.53 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 09 Sep 2015 04:41:54 -0700 (PDT) From: Maxim Uvarov To: lng-odp@lists.linaro.org Date: Wed, 9 Sep 2015 14:41:49 +0300 Message-Id: <1441798909-5379-1-git-send-email-maxim.uvarov@linaro.org> X-Mailer: git-send-email 1.9.1 X-Topics: patch Subject: [lng-odp] [API-NEXT PATCH] api: packet reference count support X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: maxim.uvarov@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.46 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 Add api for buffer reference count support. Which is useful in case: - multicast support - TCP retransmission - traffic generator odp_packet_free() function should relay on reference count and do not free packet with reference count > 1. Implementation for pktio send() function should be also adjusted to not free packet on sending. If platform can not directly support reference count for packet it should clone packet before send inside it's implementation. Signed-off-by: Maxim Uvarov --- include/odp/api/packet.h | 45 ++++++++++++++- .../linux-generic/include/odp_buffer_inlines.h | 26 --------- platform/linux-generic/odp_packet.c | 64 +++++++++++++++++++--- 3 files changed, 98 insertions(+), 37 deletions(-) diff --git a/include/odp/api/packet.h b/include/odp/api/packet.h index 5d46b7b..bf0da17 100644 --- a/include/odp/api/packet.h +++ b/include/odp/api/packet.h @@ -62,7 +62,8 @@ extern "C" { * Pool must have been created with ODP_POOL_PACKET type. The * packet is initialized with data pointers and lengths set according to the * specified len, and the default headroom and tailroom length settings. All - * other packet metadata are set to their default values. + * other packet metadata are set to their default values, packet reference count + * set to 1. * * @param pool Pool handle * @param len Packet data length @@ -79,7 +80,8 @@ odp_packet_t odp_packet_alloc(odp_pool_t pool, uint32_t len); /** * Free packet * - * Frees the packet into the buffer pool it was allocated from. + * Decrement packet reference count and free the packet back into the buffer + * pool it was allocated from if reference count reaches 0. * * @param pkt Packet handle */ @@ -125,6 +127,45 @@ odp_packet_t odp_packet_from_event(odp_event_t ev); */ odp_event_t odp_packet_to_event(odp_packet_t pkt); +/** + * Get packet reference count + * + * @param buf Packet handle + * @return Value of packet reference count + */ +uint32_t odp_packet_refcount(odp_packet_t pkt); + +/** + * Set packet reference count + * + * @param pkt Packet handle + * @param val New value of packet reference count + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_packet_refcount_set(odp_packet_t pkt, uint32_t val); + +/** + * Increment packet reference count on val + * + * @param pkt Packet handle + * @param val Value to add to current packet reference count + * + * @return New value of reference count + */ +uint32_t odp_packet_refcount_inc(odp_packet_t pkt, uint32_t val); + +/** + * Decrement event reference count on val + * + * @param pkt Packet handle + * @param val Value to subtract from current packet reference count + * + * @return New value of reference count + */ +uint32_t odp_packet_refcount_dec(odp_packet_t pkt, uint32_t val); + /* * * Pointers and lengths diff --git a/platform/linux-generic/include/odp_buffer_inlines.h b/platform/linux-generic/include/odp_buffer_inlines.h index 3f4d9fd..da5693d 100644 --- a/platform/linux-generic/include/odp_buffer_inlines.h +++ b/platform/linux-generic/include/odp_buffer_inlines.h @@ -56,32 +56,6 @@ static inline odp_buffer_hdr_t *odp_buf_to_hdr(odp_buffer_t buf) (pool->pool_mdata_addr + (index * ODP_CACHE_LINE_SIZE)); } -static inline uint32_t odp_buffer_refcount(odp_buffer_hdr_t *buf) -{ - return odp_atomic_load_u32(&buf->ref_count); -} - -static inline uint32_t odp_buffer_incr_refcount(odp_buffer_hdr_t *buf, - uint32_t val) -{ - return odp_atomic_fetch_add_u32(&buf->ref_count, val) + val; -} - -static inline uint32_t odp_buffer_decr_refcount(odp_buffer_hdr_t *buf, - uint32_t val) -{ - uint32_t tmp; - - tmp = odp_atomic_fetch_sub_u32(&buf->ref_count, val); - - if (tmp < val) { - odp_atomic_fetch_add_u32(&buf->ref_count, val - tmp); - return 0; - } else { - return tmp - val; - } -} - static inline odp_buffer_hdr_t *validate_buf(odp_buffer_t buf) { odp_buffer_bits_t handle; diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 209a6e6..f86b3f3 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -28,27 +28,33 @@ odp_packet_t odp_packet_alloc(odp_pool_t pool_hdl, uint32_t len) { pool_entry_t *pool = odp_pool_to_entry(pool_hdl); + odp_packet_t pkt = ODP_PACKET_INVALID; if (pool->s.params.type != ODP_POOL_PACKET) - return ODP_PACKET_INVALID; + return pkt; - /* Handle special case for zero-length packets */ - if (len == 0) { - odp_packet_t pkt = - (odp_packet_t)buffer_alloc(pool_hdl, - pool->s.params.buf.size); + if (!len) { + /* Handle special case for zero-length packets */ + pkt = (odp_packet_t)buffer_alloc(pool_hdl, + pool->s.params.buf.size); if (pkt != ODP_PACKET_INVALID) pull_tail(odp_packet_hdr(pkt), pool->s.params.buf.size); - - return pkt; + } else { + pkt = (odp_packet_t)buffer_alloc(pool_hdl, len); } - return (odp_packet_t)buffer_alloc(pool_hdl, len); + if (pkt != ODP_PACKET_INVALID) + odp_packet_refcount_set(pkt, 1); + + return pkt; } void odp_packet_free(odp_packet_t pkt) { + if (odp_packet_refcount_dec(pkt, 1) > 1) + return; + odp_buffer_free((odp_buffer_t)pkt); } @@ -85,6 +91,46 @@ odp_event_t odp_packet_to_event(odp_packet_t pkt) return (odp_event_t)pkt; } +uint32_t odp_packet_refcount(odp_packet_t pkt) +{ + odp_buffer_t buf = _odp_packet_to_buffer(pkt); + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); + + return odp_atomic_load_u32(&hdr->ref_count); +} + +int odp_packet_refcount_set(odp_packet_t pkt, uint32_t val) +{ + odp_buffer_t buf = _odp_packet_to_buffer(pkt); + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); + + odp_atomic_store_u32(&hdr->ref_count, val); + return 0; +} + +uint32_t odp_packet_refcount_inc(odp_packet_t pkt, uint32_t val) +{ + odp_buffer_t buf = _odp_packet_to_buffer(pkt); + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); + + return odp_atomic_fetch_add_u32(&hdr->ref_count, val) + val; +} + +uint32_t odp_packet_refcount_dec(odp_packet_t pkt, uint32_t val) +{ + uint32_t tmp; + odp_buffer_t buf = _odp_packet_to_buffer(pkt); + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); + + tmp = odp_atomic_fetch_sub_u32(&hdr->ref_count, val); + if (tmp < val) { + odp_atomic_fetch_add_u32(&hdr->ref_count, val - tmp); + return 0; + } else { + return tmp - val; + } +} + /* * * Pointers and lengths