From patchwork Wed Sep 16 07:53:01 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Uvarov X-Patchwork-Id: 53719 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f71.google.com (mail-la0-f71.google.com [209.85.215.71]) by patches.linaro.org (Postfix) with ESMTPS id 13ED622A0D for ; Wed, 16 Sep 2015 07:55:03 +0000 (UTC) Received: by lanb10 with SMTP id b10sf70843931lan.3 for ; Wed, 16 Sep 2015 00:55:02 -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:in-reply-to:references: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=jROuykG/l2fBlExOwLcNvyRfCA5wD9FLSv1qF1nUokw=; b=G+4Aa0S5Edv82X+06T+EbyS4dcvmKfBvNtvAdmntCozGueSSnZlRp1zz/W4AYQE4QS zw3XV3kgTiMJewiscteyH0TX4ZoZeYGNZzSIkfZQxlh9K9FGitF5+FSx+Ud80zIiLka+ 2ZNFK7Qb0HePl9qSAI63+IwCEqPbDdRnqufUOGGb7yhSmsbUqQLpkDFlwF6mg8AfaaVs FM1ufOJaYLGT/mu8xucLWFKLPQiBaHZEkx8T0xbyu6AGD74Az03TRxQ2xIdQxAR8tIdW 21eY0iH1029Eomu9Wi5m4f8CKJohOBR9bbB2Ha/Z38vdBu/0oUM17E1fCw5mGJ5IY55U fFPg== X-Gm-Message-State: ALoCoQkkyh5rXAke6OvxLWawZxFzGmCPM0z3GcZnyXrcFKTG1oOkk3K9qv10PQdQHaeEFmGqVpF6 X-Received: by 10.152.26.5 with SMTP id h5mr1437874lag.5.1442390102050; Wed, 16 Sep 2015 00:55:02 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.29.194 with SMTP id m2ls693578lah.4.gmail; Wed, 16 Sep 2015 00:55:01 -0700 (PDT) X-Received: by 10.112.62.232 with SMTP id b8mr27211977lbs.27.1442390101887; Wed, 16 Sep 2015 00:55:01 -0700 (PDT) Received: from mail-la0-f41.google.com (mail-la0-f41.google.com. [209.85.215.41]) by mx.google.com with ESMTPS id dv2si17348770lac.156.2015.09.16.00.55.01 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Sep 2015 00:55:01 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.41 as permitted sender) client-ip=209.85.215.41; Received: by lagj9 with SMTP id j9so125207391lag.2 for ; Wed, 16 Sep 2015 00:55:01 -0700 (PDT) X-Received: by 10.112.166.106 with SMTP id zf10mr27302406lbb.36.1442390101762; Wed, 16 Sep 2015 00:55:01 -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 w3csp2270224lbq; Wed, 16 Sep 2015 00:55:00 -0700 (PDT) X-Received: by 10.140.18.196 with SMTP id 62mr38888311qgf.79.1442390100851; Wed, 16 Sep 2015 00:55:00 -0700 (PDT) Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id n16si20840736qhb.34.2015.09.16.00.54.59; Wed, 16 Sep 2015 00:55:00 -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 8907962D26; Wed, 16 Sep 2015 07:54:59 +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 C18E062D48; Wed, 16 Sep 2015 07:53:44 +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 5C2F0619C5; Wed, 16 Sep 2015 07:53:35 +0000 (UTC) Received: from mail-la0-f50.google.com (mail-la0-f50.google.com [209.85.215.50]) by lists.linaro.org (Postfix) with ESMTPS id 34923619C5 for ; Wed, 16 Sep 2015 07:53:11 +0000 (UTC) Received: by lahg1 with SMTP id g1so94146413lah.1 for ; Wed, 16 Sep 2015 00:53:10 -0700 (PDT) X-Received: by 10.152.29.231 with SMTP id n7mr2756003lah.63.1442389990108; Wed, 16 Sep 2015 00:53:10 -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 v3sm2330971lae.13.2015.09.16.00.53.09 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 16 Sep 2015 00:53:09 -0700 (PDT) From: Maxim Uvarov To: lng-odp@lists.linaro.org Date: Wed, 16 Sep 2015 10:53:01 +0300 Message-Id: <1442389983-17007-3-git-send-email-maxim.uvarov@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1442389983-17007-1-git-send-email-maxim.uvarov@linaro.org> References: <1442389983-17007-1-git-send-email-maxim.uvarov@linaro.org> X-Topics: patch Subject: [lng-odp] [API-NEXT PATCHv3 2/4] linux-generic: 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.41 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 Signed-off-by: Maxim Uvarov --- .../linux-generic/include/odp_buffer_internal.h | 8 ++- .../linux-generic/include/odp_packet_internal.h | 18 ++++++ platform/linux-generic/odp_packet.c | 65 ++++++++++++++++++++-- 3 files changed, 85 insertions(+), 6 deletions(-) diff --git a/platform/linux-generic/include/odp_buffer_internal.h b/platform/linux-generic/include/odp_buffer_internal.h index 4cacca1..7ab53c6 100644 --- a/platform/linux-generic/include/odp_buffer_internal.h +++ b/platform/linux-generic/include/odp_buffer_internal.h @@ -65,7 +65,11 @@ _ODP_STATIC_ASSERT((ODP_CONFIG_PACKET_BUF_LEN_MAX % #define ODP_BUFFER_POOL_BITS ODP_BITSIZE(ODP_CONFIG_POOLS) #define ODP_BUFFER_SEG_BITS ODP_BITSIZE(ODP_BUFFER_MAX_SEG) -#define ODP_BUFFER_INDEX_BITS (32 - ODP_BUFFER_POOL_BITS - ODP_BUFFER_SEG_BITS) +#define ODP_PACKET_REFS_BITS ODP_BITSIZE(ODP_CONFIG_PACKET_REFS) + +#define ODP_BUFFER_INDEX_BITS (32 - ODP_BUFFER_POOL_BITS - \ + ODP_BUFFER_SEG_BITS - \ + ODP_PACKET_REFS_BITS) #define ODP_BUFFER_PREFIX_BITS (ODP_BUFFER_POOL_BITS + ODP_BUFFER_INDEX_BITS) #define ODP_BUFFER_MAX_POOLS (1 << ODP_BUFFER_POOL_BITS) #define ODP_BUFFER_MAX_BUFFERS (1 << ODP_BUFFER_INDEX_BITS) @@ -79,6 +83,7 @@ typedef union odp_buffer_bits_t { uint32_t u32; struct { #if ODP_BYTE_ORDER == ODP_BIG_ENDIAN + uint32_t ref:ODP_PACKET_REFS_BITS; uint32_t pool_id:ODP_BUFFER_POOL_BITS; uint32_t index:ODP_BUFFER_INDEX_BITS; uint32_t seg:ODP_BUFFER_SEG_BITS; @@ -86,6 +91,7 @@ typedef union odp_buffer_bits_t { uint32_t seg:ODP_BUFFER_SEG_BITS; uint32_t index:ODP_BUFFER_INDEX_BITS; uint32_t pool_id:ODP_BUFFER_POOL_BITS; + uint32_t ref:ODP_PACKET_REFS_BITS; #endif }; diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index ba2cd7e..2d6b58f 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -272,12 +272,30 @@ odp_packet_t _odp_packet_alloc(odp_pool_t pool_hdl); int _odp_packet_parse(odp_packet_hdr_t *pkt_hdr); +void _odp_packet_init(odp_packet_t pkt); +void _odp_packet_get(odp_packet_t pkt); +uint32_t _odp_packet_put(odp_packet_t pkt); + /* Convert a packet handle to a buffer handle */ odp_buffer_t _odp_packet_to_buffer(odp_packet_t pkt); /* Convert a buffer handle to a packet handle */ odp_packet_t _odp_packet_from_buffer(odp_buffer_t buf); +/* Internal debug function to check if packet has references + * + * @param pkt Packet handle + * @retval 0 Packet does not have references + * @retval 1 Packet has references +*/ +static inline int _odp_packet_refcheck(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) - 1; +} + #ifdef __cplusplus } #endif diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 209a6e6..f6c5509 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -28,28 +28,34 @@ 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; /* Handle special case for zero-length packets */ if (len == 0) { - odp_packet_t pkt = + pkt = (odp_packet_t)buffer_alloc(pool_hdl, pool->s.params.buf.size); - if (pkt != ODP_PACKET_INVALID) + if (pkt != ODP_PACKET_INVALID) { pull_tail(odp_packet_hdr(pkt), pool->s.params.buf.size); - + _odp_packet_init(pkt); + } return pkt; } - return (odp_packet_t)buffer_alloc(pool_hdl, len); + pkt = (odp_packet_t)buffer_alloc(pool_hdl, len); + if (pkt != ODP_PACKET_INVALID) + _odp_packet_init(pkt); + return pkt; } void odp_packet_free(odp_packet_t pkt) { - odp_buffer_free((odp_buffer_t)pkt); + if (!_odp_packet_put(pkt)) + odp_buffer_free((odp_buffer_t)pkt); } int odp_packet_reset(odp_packet_t pkt, uint32_t len) @@ -85,6 +91,46 @@ odp_event_t odp_packet_to_event(odp_packet_t pkt) return (odp_event_t)pkt; } +void _odp_packet_init(odp_packet_t pkt) +{ + 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, 1); +} + +void _odp_packet_get(odp_packet_t pkt) +{ + odp_buffer_t buf = _odp_packet_to_buffer(pkt); + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); + + odp_atomic_inc_u32(&hdr->ref_count); +} + +uint32_t _odp_packet_put(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_fetch_dec_u32(&hdr->ref_count) - 1; +} + +odp_packet_t odp_packet_create_ref(odp_packet_t pkt) +{ + odp_buffer_t buf = _odp_packet_to_buffer(pkt); + odp_buffer_bits_t handle; + + _odp_packet_get(pkt); + + handle.handle = buf; + if (handle.ref > ODP_CONFIG_PACKET_REFS) + ODP_ABORT("Maximum %d refs exceeded.\n", + ODP_CONFIG_PACKET_REFS); + handle.ref += 1; + + return _odp_packet_from_buffer(handle.handle); +} + /* * * Pointers and lengths @@ -472,6 +518,9 @@ odp_packet_t odp_packet_rem_data(odp_packet_t pkt, uint32_t offset, uint32_t pktlen = pkt_hdr->frame_len; odp_packet_t newpkt; + if (_odp_packet_refcheck(pkt)) + ODP_ABORT("modifying with refcounters is prohibited\n"); + if (offset > pktlen || offset + len > pktlen) return ODP_PACKET_INVALID; @@ -577,6 +626,9 @@ int odp_packet_copydata_in(odp_packet_t pkt, uint32_t offset, const uint8_t *srcaddr = (const uint8_t *)src; odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + if (_odp_packet_refcheck(pkt)) + ODP_ABORT("modifying with refcounters is prohibited\n"); + if (offset + len > pkt_hdr->frame_len) return -1; @@ -679,6 +731,9 @@ int _odp_packet_copy_to_packet(odp_packet_t srcpkt, uint32_t srcoffset, uint32_t srcseglen = 0; /* GCC */ uint32_t dstseglen = 0; /* GCC */ + if (_odp_packet_refcheck(dstpkt)) + ODP_ABORT("copiyng to packet with refcounters is prohibited\n"); + if (srcoffset + len > srchdr->frame_len || dstoffset + len > dsthdr->frame_len) return -1;