From patchwork Tue Mar 31 19:23:00 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olivier Matz X-Patchwork-Id: 4206 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 73DB87EEF; Tue, 31 Mar 2015 21:23:32 +0200 (CEST) Received: from mail-wi0-f169.google.com (mail-wi0-f169.google.com [209.85.212.169]) by dpdk.org (Postfix) with ESMTP id A47FD7E6A for ; Tue, 31 Mar 2015 21:23:29 +0200 (CEST) Received: by wibgn9 with SMTP id gn9so38800550wib.1 for ; Tue, 31 Mar 2015 12:23:29 -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=nCI0AtoTTYzeyCNeyLXYd5qkZZkJpHy7IEAlbj05Ko0=; b=ZQXxwAAokSAAWFtELkb7JYaylHh30VBD1L3MWKzF9yDJzGg2bp11aGPndEQ3m0bQTv KoObNMKP0CqCEHYXR44xy0ikziXcMQPbka/tK2aCPIyrtWocbPwPkJOd8tg0ogIjeyF2 Gt++mvuzmbKNHYdJfYm3JGkD1Jbq06GffMdygVs+cItjY9buYnTdsis2ryZjRWkGIJiZ SBmCZhmhHilA2fZ+fM5/7GhoZrIEaGYTDlAiUx9t9Ju4ZWrb25fd0SAJXI9XP60BCo/5 UXyn2cGUrF7AHPFAwifjkUum6mvDosZ4u/iZNNSuNhHLYWdE4Wf2+NN4CtC/GaIGGJmT YuAA== X-Gm-Message-State: ALoCoQn/v0BYWii0MTrnbwyZjxQSxDT5evuUBJMQjta+CTnY3ULVJkuDGjjx5JvZ85Myzpyw8MC5 X-Received: by 10.194.174.164 with SMTP id bt4mr78074090wjc.155.1427829809368; Tue, 31 Mar 2015 12:23:29 -0700 (PDT) Received: from localhost.localdomain ([185.65.185.242]) by mx.google.com with ESMTPSA id g2sm25966892wib.1.2015.03.31.12.23.27 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 31 Mar 2015 12:23:28 -0700 (PDT) From: Olivier Matz X-Google-Original-From: Olivier Matz To: dev@dpdk.org Date: Tue, 31 Mar 2015 21:23:00 +0200 Message-Id: <1427829784-12323-2-git-send-email-zer0@droids-corp.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1427829784-12323-1-git-send-email-zer0@droids-corp.org> References: <1427385595-15011-1-git-send-email-olivier.matz@6wind.com> <1427829784-12323-1-git-send-email-zer0@droids-corp.org> Subject: [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Olivier Matz Add a new private_size field in mbuf structure that should be initialized at mbuf pool creation. This field contains the size of the application private data in mbufs. Introduce new static inline functions rte_mbuf_from_indirect() and rte_mbuf_to_baddr() to replace the existing macros, which take the private size in account when attaching and detaching mbufs. Signed-off-by: Olivier Matz Reviewed-by: Zoltan Kiss Acked-by: Neil Horman Acked-by: Konstantin Ananyev --- app/test-pmd/testpmd.c | 1 + examples/vhost/main.c | 4 +-- lib/librte_mbuf/rte_mbuf.c | 1 + lib/librte_mbuf/rte_mbuf.h | 77 +++++++++++++++++++++++++++++++++++----------- 4 files changed, 63 insertions(+), 20 deletions(-) diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 3057791..c5a195a 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -425,6 +425,7 @@ testpmd_mbuf_ctor(struct rte_mempool *mp, mb->tx_offload = 0; mb->vlan_tci = 0; mb->hash.rss = 0; + mb->priv_size = 0; } static void diff --git a/examples/vhost/main.c b/examples/vhost/main.c index c3fcb80..e44e82f 100644 --- a/examples/vhost/main.c +++ b/examples/vhost/main.c @@ -139,7 +139,7 @@ /* Number of descriptors per cacheline. */ #define DESC_PER_CACHELINE (RTE_CACHE_LINE_SIZE / sizeof(struct vring_desc)) -#define MBUF_EXT_MEM(mb) (RTE_MBUF_FROM_BADDR((mb)->buf_addr) != (mb)) +#define MBUF_EXT_MEM(mb) (rte_mbuf_from_indirect(mb) != (mb)) /* mask of enabled ports */ static uint32_t enabled_port_mask = 0; @@ -1550,7 +1550,7 @@ attach_rxmbuf_zcp(struct virtio_net *dev) static inline void pktmbuf_detach_zcp(struct rte_mbuf *m) { const struct rte_mempool *mp = m->pool; - void *buf = RTE_MBUF_TO_BADDR(m); + void *buf = rte_mbuf_to_baddr(m); uint32_t buf_ofs; uint32_t buf_len = mp->elt_size - sizeof(*m); m->buf_physaddr = rte_mempool_virt2phy(mp, m) + sizeof(*m); diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c index 526b18d..e095999 100644 --- a/lib/librte_mbuf/rte_mbuf.c +++ b/lib/librte_mbuf/rte_mbuf.c @@ -125,6 +125,7 @@ rte_pktmbuf_init(struct rte_mempool *mp, m->pool = mp; m->nb_segs = 1; m->port = 0xff; + m->priv_size = 0; } /* do some sanity checks on a mbuf: panic if it fails */ diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index 17ba791..932fe58 100644 --- a/lib/librte_mbuf/rte_mbuf.h +++ b/lib/librte_mbuf/rte_mbuf.h @@ -317,18 +317,51 @@ struct rte_mbuf { /* uint64_t unused:8; */ }; }; + + /** Size of the application private data. In case of an indirect + * mbuf, it stores the direct mbuf private data size. */ + uint16_t priv_size; } __rte_cache_aligned; /** - * Given the buf_addr returns the pointer to corresponding mbuf. + * Return the mbuf owning the data buffer address of an indirect mbuf. + * + * @param mi + * The pointer to the indirect mbuf. + * @return + * The address of the direct mbuf corresponding to buffer_addr. */ -#define RTE_MBUF_FROM_BADDR(ba) (((struct rte_mbuf *)(ba)) - 1) +static inline struct rte_mbuf * +rte_mbuf_from_indirect(struct rte_mbuf *mi) +{ + struct rte_mbuf *md; + + /* mi->buf_addr and mi->priv_size correspond to buffer and + * private size of the direct mbuf */ + md = (struct rte_mbuf *)((char *)mi->buf_addr - sizeof(*mi) - + mi->priv_size); + return md; +} /** - * Given the pointer to mbuf returns an address where it's buf_addr - * should point to. + * Return the buffer address embedded in the given mbuf. + * + * The user must ensure that m->priv_size corresponds to the + * private size of this mbuf, which is not the case for indirect + * mbufs. + * + * @param md + * The pointer to the mbuf. + * @return + * The address of the data buffer owned by the mbuf. */ -#define RTE_MBUF_TO_BADDR(mb) (((struct rte_mbuf *)(mb)) + 1) +static inline char * +rte_mbuf_to_baddr(struct rte_mbuf *md) +{ + char *buffer_addr; + buffer_addr = (char *)md + sizeof(*md) + md->priv_size; + return buffer_addr; +} /** * Returns TRUE if given mbuf is indirect, or FALSE otherwise. @@ -688,6 +721,7 @@ static inline struct rte_mbuf *rte_pktmbuf_alloc(struct rte_mempool *mp) /** * Attach packet mbuf to another packet mbuf. + * * After attachment we refer the mbuf we attached as 'indirect', * while mbuf we attached to as 'direct'. * Right now, not supported: @@ -701,7 +735,6 @@ static inline struct rte_mbuf *rte_pktmbuf_alloc(struct rte_mempool *mp) * @param md * The direct packet mbuf. */ - static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) { RTE_MBUF_ASSERT(RTE_MBUF_DIRECT(md) && @@ -712,6 +745,7 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) mi->buf_physaddr = md->buf_physaddr; mi->buf_addr = md->buf_addr; mi->buf_len = md->buf_len; + mi->priv_size = md->priv_size; mi->next = md->next; mi->data_off = md->data_off; @@ -732,7 +766,8 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) } /** - * Detach an indirect packet mbuf - + * Detach an indirect packet mbuf. + * * - restore original mbuf address and length values. * - reset pktmbuf data and data_len to their default values. * All other fields of the given packet mbuf will be left intact. @@ -740,22 +775,28 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) * @param m * The indirect attached packet mbuf. */ - static inline void rte_pktmbuf_detach(struct rte_mbuf *m) { - const struct rte_mempool *mp = m->pool; - void *buf = RTE_MBUF_TO_BADDR(m); - uint32_t buf_len = mp->elt_size - sizeof(*m); - m->buf_physaddr = rte_mempool_virt2phy(mp, m) + sizeof (*m); - + struct rte_pktmbuf_pool_private *mbp_priv; + struct rte_mempool *mp = m->pool; + void *buf; + unsigned mhdr_size; + + /* first, restore the priv_size, this is needed before calling + * rte_mbuf_to_baddr() */ + mbp_priv = rte_mempool_get_priv(mp); + m->priv_size = mp->elt_size - RTE_PKTMBUF_HEADROOM - + mbp_priv->mbuf_data_room_size - + sizeof(struct rte_mbuf); + + buf = rte_mbuf_to_baddr(m); + mhdr_size = (char *)buf - (char *)m; + m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mhdr_size; m->buf_addr = buf; - m->buf_len = (uint16_t)buf_len; - + m->buf_len = (uint16_t)(mp->elt_size - mhdr_size); m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ? RTE_PKTMBUF_HEADROOM : m->buf_len; - m->data_len = 0; - m->ol_flags = 0; } @@ -774,7 +815,7 @@ __rte_pktmbuf_prefree_seg(struct rte_mbuf *m) * - free attached mbuf segment */ if (RTE_MBUF_INDIRECT(m)) { - struct rte_mbuf *md = RTE_MBUF_FROM_BADDR(m->buf_addr); + struct rte_mbuf *md = rte_mbuf_from_indirect(m); rte_pktmbuf_detach(m); if (rte_mbuf_refcnt_update(md, -1) == 0) __rte_mbuf_raw_free(md);