DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/5] mbuf: enhancements of mbuf clones
@ 2015-03-25 17:00 Olivier Matz
  2015-03-25 17:00 ` [dpdk-dev] [PATCH 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
                   ` (5 more replies)
  0 siblings, 6 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-25 17:00 UTC (permalink / raw)
  To: dev

This series fixes the support of indirect mbufs when the application
reserves a private area in mbufs. This is done adding a new field
in each mbuf storing the size of this private area. Another option
would have been to store that in the mbuf pool private info, but
as we have enough room in mbuf, it's faster to have it in the mbuf.

The series also removes the limitation that rte_pktmbuf_clone() is
only allowed on direct (non-cloned) mbufs.

Olivier Matz (5):
  mbuf: fix clone support when application uses private mbuf data
  mbuf: allow to clone an indirect mbuf
  test/mbuf: rename mc variable in m
  test/mbuf: enhance mbuf refcnt test
  test/mbuf: verify that cloning a clone works properly

 app/test-pmd/testpmd.c     |  1 +
 app/test/test_mbuf.c       | 88 ++++++++++++++++++++++++++++++++++++++-------
 examples/vhost/main.c      |  6 ++--
 lib/librte_mbuf/rte_mbuf.c |  1 +
 lib/librte_mbuf/rte_mbuf.h | 90 +++++++++++++++++++++++++++++++---------------
 5 files changed, 140 insertions(+), 46 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-25 17:00 [dpdk-dev] [PATCH 0/5] mbuf: enhancements of mbuf clones Olivier Matz
@ 2015-03-25 17:00 ` Olivier Matz
  2015-03-26 13:35   ` Bruce Richardson
  2015-03-25 17:00 ` [dpdk-dev] [PATCH 2/5] mbuf: allow to clone an indirect mbuf Olivier Matz
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 101+ messages in thread
From: Olivier Matz @ 2015-03-25 17:00 UTC (permalink / raw)
  To: dev

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_baddr()
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 <olivier.matz@6wind.com>
---
 app/test-pmd/testpmd.c     |  1 +
 examples/vhost/main.c      |  6 ++----
 lib/librte_mbuf/rte_mbuf.c |  1 +
 lib/librte_mbuf/rte_mbuf.h | 44 +++++++++++++++++++++++++++++++++++---------
 4 files changed, 39 insertions(+), 13 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..050f3ac 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -139,8 +139,6 @@
 /* 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))
-
 /* mask of enabled ports */
 static uint32_t enabled_port_mask = 0;
 
@@ -1590,7 +1588,7 @@ txmbuf_clean_zcp(struct virtio_net *dev, struct vpool *vpool)
 
 	for (index = 0; index < mbuf_count; index++) {
 		mbuf = __rte_mbuf_raw_alloc(vpool->pool);
-		if (likely(MBUF_EXT_MEM(mbuf)))
+		if (likely(RTE_MBUF_INDIRECT(mbuf)))
 			pktmbuf_detach_zcp(mbuf);
 		rte_ring_sp_enqueue(vpool->ring, mbuf);
 
@@ -1653,7 +1651,7 @@ static void mbuf_destroy_zcp(struct vpool *vpool)
 	for (index = 0; index < mbuf_count; index++) {
 		mbuf = __rte_mbuf_raw_alloc(vpool->pool);
 		if (likely(mbuf != NULL)) {
-			if (likely(MBUF_EXT_MEM(mbuf)))
+			if (likely(RTE_MBUF_INDIRECT(mbuf)))
 				pktmbuf_detach_zcp(mbuf);
 			rte_ring_sp_enqueue(vpool->ring, (void *)mbuf);
 		}
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..4ced6d3 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -268,7 +268,7 @@ struct rte_mbuf {
 	uint16_t data_len;        /**< Amount of data in segment buffer. */
 	uint32_t pkt_len;         /**< Total pkt len: sum of all segments. */
 	uint16_t vlan_tci;        /**< VLAN Tag Control Identifier (CPU order) */
-	uint16_t reserved;
+	uint16_t priv_size;       /**< size of the application private data */
 	union {
 		uint32_t rss;     /**< RSS hash result if RSS enabled */
 		struct {
@@ -320,15 +320,38 @@ struct rte_mbuf {
 } __rte_cache_aligned;
 
 /**
- * Given the buf_addr returns the pointer to corresponding mbuf.
+ * Return the mbuf owning the given data buffer address.
+ *
+ * @param mi
+ *   The pointer to the indirect mbuf.
+ * @param buffer_addr
+ *   The address of the data buffer of the direct 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_baddr(struct rte_mbuf *mi, char *buffer_addr)
+{
+       struct rte_mbuf *md;
+       md = (struct rte_mbuf *)(buffer_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.
+ *
+ * @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.
@@ -744,9 +767,11 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md)
 static inline void rte_pktmbuf_detach(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_len = mp->elt_size - sizeof(*m);
-	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + sizeof (*m);
+
+	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + sizeof (*m) +
+		m->priv_size;
 
 	m->buf_addr = buf;
 	m->buf_len = (uint16_t)buf_len;
@@ -774,7 +799,8 @@ __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_baddr(m, (char *)m->buf_addr);
 			rte_pktmbuf_detach(m);
 			if (rte_mbuf_refcnt_update(md, -1) == 0)
 				__rte_mbuf_raw_free(md);
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH 2/5] mbuf: allow to clone an indirect mbuf
  2015-03-25 17:00 [dpdk-dev] [PATCH 0/5] mbuf: enhancements of mbuf clones Olivier Matz
  2015-03-25 17:00 ` [dpdk-dev] [PATCH 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
@ 2015-03-25 17:00 ` Olivier Matz
  2015-03-25 17:00 ` [dpdk-dev] [PATCH 3/5] test/mbuf: rename mc variable in m Olivier Matz
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-25 17:00 UTC (permalink / raw)
  To: dev

Remove one limitation of rte_pktmbuf_attach(): "mbuf we're attaching to
must be direct".

Now, when we attach to an indirect mbuf:
- copy the all relevant fields (addr, len, offload, ...) as before
- get the pointer to the mbuf that embeds the data buffer (direct mbuf),
  and increase the reference counter of this one.

When detaching the mbuf, we can retrieve this direct mbuf as the pointer
is determined from the buffer address.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_mbuf/rte_mbuf.h | 46 ++++++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 20 deletions(-)

diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 4ced6d3..3dc12cb 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -714,44 +714,50 @@ static inline struct rte_mbuf *rte_pktmbuf_alloc(struct rte_mempool *mp)
  * After attachment we refer the mbuf we attached as 'indirect',
  * while mbuf we attached to as 'direct'.
  * Right now, not supported:
- *  - attachment to indirect mbuf (e.g. - md  has to be direct).
  *  - attachment for already indirect mbuf (e.g. - mi has to be direct).
  *  - mbuf we trying to attach (mi) is used by someone else
  *    e.g. it's reference counter is greater then 1.
  *
  * @param mi
  *   The indirect packet mbuf.
- * @param md
- *   The direct packet mbuf.
+ * @param m
+ *   The packet mbuf we're attaching to.
  */
 
-static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md)
+static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
 {
-	RTE_MBUF_ASSERT(RTE_MBUF_DIRECT(md) &&
-	    RTE_MBUF_DIRECT(mi) &&
+	struct rte_mbuf *md;
+
+	RTE_MBUF_ASSERT(RTE_MBUF_DIRECT(mi) &&
 	    rte_mbuf_refcnt_read(mi) == 1);
 
+	/* if m is not direct, get the mbuf that embeds the data */
+	if (RTE_MBUF_DIRECT(m))
+		md = m;
+	else
+		md = rte_mbuf_from_baddr(m, (char *)m->buf_addr);
+
 	rte_mbuf_refcnt_update(md, 1);
-	mi->buf_physaddr = md->buf_physaddr;
-	mi->buf_addr = md->buf_addr;
-	mi->buf_len = md->buf_len;
-
-	mi->next = md->next;
-	mi->data_off = md->data_off;
-	mi->data_len = md->data_len;
-	mi->port = md->port;
-	mi->vlan_tci = md->vlan_tci;
-	mi->tx_offload = md->tx_offload;
-	mi->hash = md->hash;
+	mi->buf_physaddr = m->buf_physaddr;
+	mi->buf_addr = m->buf_addr;
+	mi->buf_len = m->buf_len;
+
+	mi->next = m->next;
+	mi->data_off = m->data_off;
+	mi->data_len = m->data_len;
+	mi->port = m->port;
+	mi->vlan_tci = m->vlan_tci;
+	mi->tx_offload = m->tx_offload;
+	mi->hash = m->hash;
 
 	mi->next = NULL;
 	mi->pkt_len = mi->data_len;
 	mi->nb_segs = 1;
-	mi->ol_flags = md->ol_flags | IND_ATTACHED_MBUF;
-	mi->packet_type = md->packet_type;
+	mi->ol_flags = m->ol_flags | IND_ATTACHED_MBUF;
+	mi->packet_type = m->packet_type;
 
 	__rte_mbuf_sanity_check(mi, 1);
-	__rte_mbuf_sanity_check(md, 0);
+	__rte_mbuf_sanity_check(m, 0);
 }
 
 /**
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH 3/5] test/mbuf: rename mc variable in m
  2015-03-25 17:00 [dpdk-dev] [PATCH 0/5] mbuf: enhancements of mbuf clones Olivier Matz
  2015-03-25 17:00 ` [dpdk-dev] [PATCH 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
  2015-03-25 17:00 ` [dpdk-dev] [PATCH 2/5] mbuf: allow to clone an indirect mbuf Olivier Matz
@ 2015-03-25 17:00 ` Olivier Matz
  2015-03-25 17:00 ` [dpdk-dev] [PATCH 4/5] test/mbuf: enhance mbuf refcnt test Olivier Matz
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-25 17:00 UTC (permalink / raw)
  To: dev

It's better to name the mbuf 'm' instead of 'mc' as it's not a clone.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 1ff66cb..9a3cf8f 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -321,43 +321,42 @@ fail:
 static int
 testclone_testupdate_testdetach(void)
 {
-	struct rte_mbuf *mc = NULL;
+	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
 
 	/* alloc a mbuf */
-
-	mc = rte_pktmbuf_alloc(pktmbuf_pool);
-	if (mc == NULL)
+	m = rte_pktmbuf_alloc(pktmbuf_pool);
+	if (m == NULL)
 		GOTO_FAIL("ooops not allocating mbuf");
 
-	if (rte_pktmbuf_pkt_len(mc) != 0)
+	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("Bad length");
 
 
 	/* clone the allocated mbuf */
-	clone = rte_pktmbuf_clone(mc, pktmbuf_pool);
+	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 	rte_pktmbuf_free(clone);
 
-	mc->next = rte_pktmbuf_alloc(pktmbuf_pool);
-	if(mc->next == NULL)
+	m->next = rte_pktmbuf_alloc(pktmbuf_pool);
+	if (m->next == NULL)
 		GOTO_FAIL("Next Pkt Null\n");
 
-	clone = rte_pktmbuf_clone(mc, pktmbuf_pool);
+	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 
 	/* free mbuf */
-	rte_pktmbuf_free(mc);
+	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
-	mc = NULL;
+	m = NULL;
 	clone = NULL;
 	return 0;
 
 fail:
-	if (mc)
-		rte_pktmbuf_free(mc);
+	if (m)
+		rte_pktmbuf_free(m);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH 4/5] test/mbuf: enhance mbuf refcnt test
  2015-03-25 17:00 [dpdk-dev] [PATCH 0/5] mbuf: enhancements of mbuf clones Olivier Matz
                   ` (2 preceding siblings ...)
  2015-03-25 17:00 ` [dpdk-dev] [PATCH 3/5] test/mbuf: rename mc variable in m Olivier Matz
@ 2015-03-25 17:00 ` Olivier Matz
  2015-03-25 17:00 ` [dpdk-dev] [PATCH 5/5] test/mbuf: verify that cloning a clone works properly Olivier Matz
  2015-03-26 15:59 ` [dpdk-dev] [PATCH v2 0/5] mbuf: enhancements of mbuf clones Olivier Matz
  5 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-25 17:00 UTC (permalink / raw)
  To: dev

Check that the data in the cloned mbuf is the same than in the
reference mbuf.
Check that the reference counter is incremented for each segment.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 9a3cf8f..9d8ee4e 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -76,6 +76,8 @@
 #define REFCNT_MBUF_SIZE        (sizeof (struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
 #define REFCNT_RING_SIZE        (REFCNT_MBUF_NUM * REFCNT_MAX_REF)
 
+#define MAGIC_DATA              0x42424242
+
 #define MAKE_STRING(x)          # x
 
 static struct rte_mempool *pktmbuf_pool = NULL;
@@ -323,6 +325,7 @@ testclone_testupdate_testdetach(void)
 {
 	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
+	uint32_t *data;
 
 	/* alloc a mbuf */
 	m = rte_pktmbuf_alloc(pktmbuf_pool);
@@ -332,21 +335,53 @@ testclone_testupdate_testdetach(void)
 	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("Bad length");
 
+	rte_pktmbuf_append(m, sizeof(uint32_t));
+	data = rte_pktmbuf_mtod(m, uint32_t *);
+	*data = MAGIC_DATA;
 
 	/* clone the allocated mbuf */
 	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
+
+	data = rte_pktmbuf_mtod(clone, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone\n");
+
+	if (rte_mbuf_refcnt_read(m) != 2)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	/* free the clone */
 	rte_pktmbuf_free(clone);
+	clone = NULL;
 
+	/* same test with a chained mbuf */
 	m->next = rte_pktmbuf_alloc(pktmbuf_pool);
 	if (m->next == NULL)
 		GOTO_FAIL("Next Pkt Null\n");
 
+	rte_pktmbuf_append(m->next, sizeof(uint32_t));
+	data = rte_pktmbuf_mtod(m->next, uint32_t *);
+	*data = MAGIC_DATA;
+
 	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 
+	data = rte_pktmbuf_mtod(clone, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone\n");
+
+	data = rte_pktmbuf_mtod(clone->next, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone->next\n");
+
+	if (rte_mbuf_refcnt_read(m) != 2)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	if (rte_mbuf_refcnt_read(m->next) != 2)
+		GOTO_FAIL("invalid refcnt in m->next\n");
+
 	/* free mbuf */
 	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
@@ -357,6 +392,8 @@ testclone_testupdate_testdetach(void)
 fail:
 	if (m)
 		rte_pktmbuf_free(m);
+	if (clone)
+		rte_pktmbuf_free(clone);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH 5/5] test/mbuf: verify that cloning a clone works properly
  2015-03-25 17:00 [dpdk-dev] [PATCH 0/5] mbuf: enhancements of mbuf clones Olivier Matz
                   ` (3 preceding siblings ...)
  2015-03-25 17:00 ` [dpdk-dev] [PATCH 4/5] test/mbuf: enhance mbuf refcnt test Olivier Matz
@ 2015-03-25 17:00 ` Olivier Matz
  2015-03-26  8:48   ` Olivier MATZ
  2015-03-26 15:59 ` [dpdk-dev] [PATCH v2 0/5] mbuf: enhancements of mbuf clones Olivier Matz
  5 siblings, 1 reply; 101+ messages in thread
From: Olivier Matz @ 2015-03-25 17:00 UTC (permalink / raw)
  To: dev

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 9d8ee4e..68cd4de 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -325,6 +325,7 @@ testclone_testupdate_testdetach(void)
 {
 	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
+	struct rte_mbuf *clone2 = NULL;
 	uint32_t *data;
 
 	/* alloc a mbuf */
@@ -382,11 +383,34 @@ testclone_testupdate_testdetach(void)
 	if (rte_mbuf_refcnt_read(m->next) != 2)
 		GOTO_FAIL("invalid refcnt in m->next\n");
 
+	/* try to clone the clone */
+
+	clone2 = rte_pktmbuf_clone(clone, pktmbuf_pool);
+	if (clone2 == NULL)
+		GOTO_FAIL("cannot clone the clone\n");
+
+	data = rte_pktmbuf_mtod(clone2, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone2\n");
+
+	data = rte_pktmbuf_mtod(clone2->next, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone2->next\n");
+
+	if (rte_mbuf_refcnt_read(m) != 3)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	if (rte_mbuf_refcnt_read(m->next) != 3)
+		GOTO_FAIL("invalid refcnt in m->next\n");
+
 	/* free mbuf */
 	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
+	rte_pktmbuf_free(clone2);
+
 	m = NULL;
 	clone = NULL;
+	clone2 = NULL;
 	return 0;
 
 fail:
@@ -394,6 +418,8 @@ fail:
 		rte_pktmbuf_free(m);
 	if (clone)
 		rte_pktmbuf_free(clone);
+	if (clone2)
+		rte_pktmbuf_free(clone);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH 5/5] test/mbuf: verify that cloning a clone works properly
  2015-03-25 17:00 ` [dpdk-dev] [PATCH 5/5] test/mbuf: verify that cloning a clone works properly Olivier Matz
@ 2015-03-26  8:48   ` Olivier MATZ
  0 siblings, 0 replies; 101+ messages in thread
From: Olivier MATZ @ 2015-03-26  8:48 UTC (permalink / raw)
  To: dev

On 03/25/2015 06:00 PM, Olivier Matz wrote:
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> ---
>   app/test/test_mbuf.c | 26 ++++++++++++++++++++++++++
>   1 file changed, 26 insertions(+)
>
> [...]
>
> @@ -394,6 +418,8 @@ fail:
>   		rte_pktmbuf_free(m);
>   	if (clone)
>   		rte_pktmbuf_free(clone);
> +	if (clone2)
> +		rte_pktmbuf_free(clone);
>   	return -1;
>   }
>   #undef GOTO_FAIL
>

Self-nak on this one, it should of course be rte_pktmbuf_free(clone2)

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-25 17:00 ` [dpdk-dev] [PATCH 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
@ 2015-03-26 13:35   ` Bruce Richardson
  2015-03-26 15:30     ` Olivier MATZ
  0 siblings, 1 reply; 101+ messages in thread
From: Bruce Richardson @ 2015-03-26 13:35 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

On Wed, Mar 25, 2015 at 06:00:34PM +0100, Olivier Matz wrote:
> 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_baddr()
> 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 <olivier.matz@6wind.com>
> ---
>  app/test-pmd/testpmd.c     |  1 +
>  examples/vhost/main.c      |  6 ++----
>  lib/librte_mbuf/rte_mbuf.c |  1 +
>  lib/librte_mbuf/rte_mbuf.h | 44 +++++++++++++++++++++++++++++++++++---------
>  4 files changed, 39 insertions(+), 13 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..050f3ac 100644
> --- a/examples/vhost/main.c
> +++ b/examples/vhost/main.c
> @@ -139,8 +139,6 @@
>  /* 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))
> -
>  /* mask of enabled ports */
>  static uint32_t enabled_port_mask = 0;
>  
> @@ -1590,7 +1588,7 @@ txmbuf_clean_zcp(struct virtio_net *dev, struct vpool *vpool)
>  
>  	for (index = 0; index < mbuf_count; index++) {
>  		mbuf = __rte_mbuf_raw_alloc(vpool->pool);
> -		if (likely(MBUF_EXT_MEM(mbuf)))
> +		if (likely(RTE_MBUF_INDIRECT(mbuf)))
>  			pktmbuf_detach_zcp(mbuf);
>  		rte_ring_sp_enqueue(vpool->ring, mbuf);
>  
> @@ -1653,7 +1651,7 @@ static void mbuf_destroy_zcp(struct vpool *vpool)
>  	for (index = 0; index < mbuf_count; index++) {
>  		mbuf = __rte_mbuf_raw_alloc(vpool->pool);
>  		if (likely(mbuf != NULL)) {
> -			if (likely(MBUF_EXT_MEM(mbuf)))
> +			if (likely(RTE_MBUF_INDIRECT(mbuf)))
>  				pktmbuf_detach_zcp(mbuf);
>  			rte_ring_sp_enqueue(vpool->ring, (void *)mbuf);
>  		}
> 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..4ced6d3 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -268,7 +268,7 @@ struct rte_mbuf {
>  	uint16_t data_len;        /**< Amount of data in segment buffer. */
>  	uint32_t pkt_len;         /**< Total pkt len: sum of all segments. */
>  	uint16_t vlan_tci;        /**< VLAN Tag Control Identifier (CPU order) */
> -	uint16_t reserved;
> +	uint16_t priv_size;       /**< size of the application private data */
>  	union {
>  		uint32_t rss;     /**< RSS hash result if RSS enabled */
>  		struct {
> @@ -320,15 +320,38 @@ struct rte_mbuf {

Why does this new field need to go in cache line zero? New fields should go
by default in cache line 1, where there is more space, unless there is a compelling
reason not to. Space in cache line 0 is at a premium.

/Bruce

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-26 13:35   ` Bruce Richardson
@ 2015-03-26 15:30     ` Olivier MATZ
  0 siblings, 0 replies; 101+ messages in thread
From: Olivier MATZ @ 2015-03-26 15:30 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: dev

Hi Bruce,

On 03/26/2015 02:35 PM, Bruce Richardson wrote:
> On Wed, Mar 25, 2015 at 06:00:34PM +0100, Olivier Matz wrote:
>> 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_baddr()
>> and rte_mbuf_to_baddr() to replace the existing macros, which
>> take the private size in account when attaching and detaching
>> mbufs.
>>
>> [...]
>
> Why does this new field need to go in cache line zero? New fields should go
> by default in cache line 1, where there is more space, unless there is a compelling
> reason not to. Space in cache line 0 is at a premium.

You are right, having this in the second cache line makes
more sense, I'll change that in the v2.

Thanks for your review,
Olivier

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v2 0/5] mbuf: enhancements of mbuf clones
  2015-03-25 17:00 [dpdk-dev] [PATCH 0/5] mbuf: enhancements of mbuf clones Olivier Matz
                   ` (4 preceding siblings ...)
  2015-03-25 17:00 ` [dpdk-dev] [PATCH 5/5] test/mbuf: verify that cloning a clone works properly Olivier Matz
@ 2015-03-26 15:59 ` Olivier Matz
  2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
                     ` (5 more replies)
  5 siblings, 6 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-26 15:59 UTC (permalink / raw)
  To: dev; +Cc: zoltan.kiss

This series fixes the support of indirect mbufs when the application
reserves a private area in mbufs. This is done adding a new field
in each mbuf storing the size of this private area. Another option
would have been to store that in the mbuf pool private info, but
as we have enough room in mbuf, it's faster to have it in the mbuf.

The series also removes the limitation that rte_pktmbuf_clone() is
only allowed on direct (non-cloned) mbufs.

Changes in v2:
- do not change the use of MBUF_EXT_MEM() in vhost
- change rte_mbuf_from_baddr() to rte_mbuf_from_indirect(), removing
  one parameter
- fix and rework rte_pktmbuf_detach()
- move m->priv_size in second mbuf cache line
- fix mbuf free in test error case

Olivier Matz (5):
  mbuf: fix clone support when application uses private mbuf data
  mbuf: allow to clone an indirect mbuf
  test/mbuf: rename mc variable in m
  test/mbuf: enhance mbuf refcnt test
  test/mbuf: verify that cloning a clone works properly

 app/test-pmd/testpmd.c     |  1 +
 app/test/test_mbuf.c       | 88 ++++++++++++++++++++++++++++++++++++++-------
 examples/vhost/main.c      |  2 +-
 lib/librte_mbuf/rte_mbuf.c |  1 +
 lib/librte_mbuf/rte_mbuf.h | 90 ++++++++++++++++++++++++++++++----------------
 5 files changed, 138 insertions(+), 44 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-26 15:59 ` [dpdk-dev] [PATCH v2 0/5] mbuf: enhancements of mbuf clones Olivier Matz
@ 2015-03-26 15:59   ` Olivier Matz
  2015-03-26 17:13     ` Zoltan Kiss
  2015-03-27  0:24     ` Ananyev, Konstantin
  2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 2/5] mbuf: allow to clone an indirect mbuf Olivier Matz
                     ` (4 subsequent siblings)
  5 siblings, 2 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-26 15:59 UTC (permalink / raw)
  To: dev; +Cc: zoltan.kiss

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 <olivier.matz@6wind.com>
---
 app/test-pmd/testpmd.c     |  1 +
 examples/vhost/main.c      |  2 +-
 lib/librte_mbuf/rte_mbuf.c |  1 +
 lib/librte_mbuf/rte_mbuf.h | 44 ++++++++++++++++++++++++++++++++++----------
 4 files changed, 37 insertions(+), 11 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..d542461 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;
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..45ac948 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -317,18 +317,42 @@ struct rte_mbuf {
 			/* uint64_t unused:8; */
 		};
 	};
+
+	uint16_t priv_size;       /**< size of the application private data */
 } __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;
+       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.
+ *
+ * @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.
@@ -744,12 +768,12 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md)
 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);
+	void *buf = rte_mbuf_to_baddr(m);
+	unsigned 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;
@@ -774,7 +798,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);
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v2 2/5] mbuf: allow to clone an indirect mbuf
  2015-03-26 15:59 ` [dpdk-dev] [PATCH v2 0/5] mbuf: enhancements of mbuf clones Olivier Matz
  2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
@ 2015-03-26 15:59   ` Olivier Matz
  2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 3/5] test/mbuf: rename mc variable in m Olivier Matz
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-26 15:59 UTC (permalink / raw)
  To: dev; +Cc: zoltan.kiss

Remove one limitation of rte_pktmbuf_attach(): "mbuf we're attaching to
must be direct".

Now, when we attach to an indirect mbuf:
- copy the all relevant fields (addr, len, offload, ...) as before
- get the pointer to the mbuf that embeds the data buffer (direct mbuf),
  and increase the reference counter of this one.

When detaching the mbuf, we can retrieve this direct mbuf as the pointer
is determined from the buffer address.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_mbuf/rte_mbuf.h | 46 ++++++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 20 deletions(-)

diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 45ac948..be635f0 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -715,44 +715,50 @@ static inline struct rte_mbuf *rte_pktmbuf_alloc(struct rte_mempool *mp)
  * After attachment we refer the mbuf we attached as 'indirect',
  * while mbuf we attached to as 'direct'.
  * Right now, not supported:
- *  - attachment to indirect mbuf (e.g. - md  has to be direct).
  *  - attachment for already indirect mbuf (e.g. - mi has to be direct).
  *  - mbuf we trying to attach (mi) is used by someone else
  *    e.g. it's reference counter is greater then 1.
  *
  * @param mi
  *   The indirect packet mbuf.
- * @param md
- *   The direct packet mbuf.
+ * @param m
+ *   The packet mbuf we're attaching to.
  */
 
-static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md)
+static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
 {
-	RTE_MBUF_ASSERT(RTE_MBUF_DIRECT(md) &&
-	    RTE_MBUF_DIRECT(mi) &&
+	struct rte_mbuf *md;
+
+	RTE_MBUF_ASSERT(RTE_MBUF_DIRECT(mi) &&
 	    rte_mbuf_refcnt_read(mi) == 1);
 
+	/* if m is not direct, get the mbuf that embeds the data */
+	if (RTE_MBUF_DIRECT(m))
+		md = m;
+	else
+		md = rte_mbuf_from_indirect(m);
+
 	rte_mbuf_refcnt_update(md, 1);
-	mi->buf_physaddr = md->buf_physaddr;
-	mi->buf_addr = md->buf_addr;
-	mi->buf_len = md->buf_len;
-
-	mi->next = md->next;
-	mi->data_off = md->data_off;
-	mi->data_len = md->data_len;
-	mi->port = md->port;
-	mi->vlan_tci = md->vlan_tci;
-	mi->tx_offload = md->tx_offload;
-	mi->hash = md->hash;
+	mi->buf_physaddr = m->buf_physaddr;
+	mi->buf_addr = m->buf_addr;
+	mi->buf_len = m->buf_len;
+
+	mi->next = m->next;
+	mi->data_off = m->data_off;
+	mi->data_len = m->data_len;
+	mi->port = m->port;
+	mi->vlan_tci = m->vlan_tci;
+	mi->tx_offload = m->tx_offload;
+	mi->hash = m->hash;
 
 	mi->next = NULL;
 	mi->pkt_len = mi->data_len;
 	mi->nb_segs = 1;
-	mi->ol_flags = md->ol_flags | IND_ATTACHED_MBUF;
-	mi->packet_type = md->packet_type;
+	mi->ol_flags = m->ol_flags | IND_ATTACHED_MBUF;
+	mi->packet_type = m->packet_type;
 
 	__rte_mbuf_sanity_check(mi, 1);
-	__rte_mbuf_sanity_check(md, 0);
+	__rte_mbuf_sanity_check(m, 0);
 }
 
 /**
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v2 3/5] test/mbuf: rename mc variable in m
  2015-03-26 15:59 ` [dpdk-dev] [PATCH v2 0/5] mbuf: enhancements of mbuf clones Olivier Matz
  2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
  2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 2/5] mbuf: allow to clone an indirect mbuf Olivier Matz
@ 2015-03-26 15:59   ` Olivier Matz
  2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 4/5] test/mbuf: enhance mbuf refcnt test Olivier Matz
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-26 15:59 UTC (permalink / raw)
  To: dev; +Cc: zoltan.kiss

It's better to name the mbuf 'm' instead of 'mc' as it's not a clone.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 1ff66cb..9a3cf8f 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -321,43 +321,42 @@ fail:
 static int
 testclone_testupdate_testdetach(void)
 {
-	struct rte_mbuf *mc = NULL;
+	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
 
 	/* alloc a mbuf */
-
-	mc = rte_pktmbuf_alloc(pktmbuf_pool);
-	if (mc == NULL)
+	m = rte_pktmbuf_alloc(pktmbuf_pool);
+	if (m == NULL)
 		GOTO_FAIL("ooops not allocating mbuf");
 
-	if (rte_pktmbuf_pkt_len(mc) != 0)
+	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("Bad length");
 
 
 	/* clone the allocated mbuf */
-	clone = rte_pktmbuf_clone(mc, pktmbuf_pool);
+	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 	rte_pktmbuf_free(clone);
 
-	mc->next = rte_pktmbuf_alloc(pktmbuf_pool);
-	if(mc->next == NULL)
+	m->next = rte_pktmbuf_alloc(pktmbuf_pool);
+	if (m->next == NULL)
 		GOTO_FAIL("Next Pkt Null\n");
 
-	clone = rte_pktmbuf_clone(mc, pktmbuf_pool);
+	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 
 	/* free mbuf */
-	rte_pktmbuf_free(mc);
+	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
-	mc = NULL;
+	m = NULL;
 	clone = NULL;
 	return 0;
 
 fail:
-	if (mc)
-		rte_pktmbuf_free(mc);
+	if (m)
+		rte_pktmbuf_free(m);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v2 4/5] test/mbuf: enhance mbuf refcnt test
  2015-03-26 15:59 ` [dpdk-dev] [PATCH v2 0/5] mbuf: enhancements of mbuf clones Olivier Matz
                     ` (2 preceding siblings ...)
  2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 3/5] test/mbuf: rename mc variable in m Olivier Matz
@ 2015-03-26 15:59   ` Olivier Matz
  2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 5/5] test/mbuf: verify that cloning a clone works properly Olivier Matz
  2015-03-31 19:22   ` [dpdk-dev] [PATCH v3 0/5] mbuf: enhancements of mbuf clones Olivier Matz
  5 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-26 15:59 UTC (permalink / raw)
  To: dev; +Cc: zoltan.kiss

Check that the data in the cloned mbuf is the same than in the
reference mbuf.
Check that the reference counter is incremented for each segment.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 9a3cf8f..9d8ee4e 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -76,6 +76,8 @@
 #define REFCNT_MBUF_SIZE        (sizeof (struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
 #define REFCNT_RING_SIZE        (REFCNT_MBUF_NUM * REFCNT_MAX_REF)
 
+#define MAGIC_DATA              0x42424242
+
 #define MAKE_STRING(x)          # x
 
 static struct rte_mempool *pktmbuf_pool = NULL;
@@ -323,6 +325,7 @@ testclone_testupdate_testdetach(void)
 {
 	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
+	uint32_t *data;
 
 	/* alloc a mbuf */
 	m = rte_pktmbuf_alloc(pktmbuf_pool);
@@ -332,21 +335,53 @@ testclone_testupdate_testdetach(void)
 	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("Bad length");
 
+	rte_pktmbuf_append(m, sizeof(uint32_t));
+	data = rte_pktmbuf_mtod(m, uint32_t *);
+	*data = MAGIC_DATA;
 
 	/* clone the allocated mbuf */
 	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
+
+	data = rte_pktmbuf_mtod(clone, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone\n");
+
+	if (rte_mbuf_refcnt_read(m) != 2)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	/* free the clone */
 	rte_pktmbuf_free(clone);
+	clone = NULL;
 
+	/* same test with a chained mbuf */
 	m->next = rte_pktmbuf_alloc(pktmbuf_pool);
 	if (m->next == NULL)
 		GOTO_FAIL("Next Pkt Null\n");
 
+	rte_pktmbuf_append(m->next, sizeof(uint32_t));
+	data = rte_pktmbuf_mtod(m->next, uint32_t *);
+	*data = MAGIC_DATA;
+
 	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 
+	data = rte_pktmbuf_mtod(clone, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone\n");
+
+	data = rte_pktmbuf_mtod(clone->next, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone->next\n");
+
+	if (rte_mbuf_refcnt_read(m) != 2)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	if (rte_mbuf_refcnt_read(m->next) != 2)
+		GOTO_FAIL("invalid refcnt in m->next\n");
+
 	/* free mbuf */
 	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
@@ -357,6 +392,8 @@ testclone_testupdate_testdetach(void)
 fail:
 	if (m)
 		rte_pktmbuf_free(m);
+	if (clone)
+		rte_pktmbuf_free(clone);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v2 5/5] test/mbuf: verify that cloning a clone works properly
  2015-03-26 15:59 ` [dpdk-dev] [PATCH v2 0/5] mbuf: enhancements of mbuf clones Olivier Matz
                     ` (3 preceding siblings ...)
  2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 4/5] test/mbuf: enhance mbuf refcnt test Olivier Matz
@ 2015-03-26 15:59   ` Olivier Matz
  2015-03-31 19:22   ` [dpdk-dev] [PATCH v3 0/5] mbuf: enhancements of mbuf clones Olivier Matz
  5 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-26 15:59 UTC (permalink / raw)
  To: dev; +Cc: zoltan.kiss

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 9d8ee4e..e59aedc 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -325,6 +325,7 @@ testclone_testupdate_testdetach(void)
 {
 	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
+	struct rte_mbuf *clone2 = NULL;
 	uint32_t *data;
 
 	/* alloc a mbuf */
@@ -382,11 +383,34 @@ testclone_testupdate_testdetach(void)
 	if (rte_mbuf_refcnt_read(m->next) != 2)
 		GOTO_FAIL("invalid refcnt in m->next\n");
 
+	/* try to clone the clone */
+
+	clone2 = rte_pktmbuf_clone(clone, pktmbuf_pool);
+	if (clone2 == NULL)
+		GOTO_FAIL("cannot clone the clone\n");
+
+	data = rte_pktmbuf_mtod(clone2, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone2\n");
+
+	data = rte_pktmbuf_mtod(clone2->next, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone2->next\n");
+
+	if (rte_mbuf_refcnt_read(m) != 3)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	if (rte_mbuf_refcnt_read(m->next) != 3)
+		GOTO_FAIL("invalid refcnt in m->next\n");
+
 	/* free mbuf */
 	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
+	rte_pktmbuf_free(clone2);
+
 	m = NULL;
 	clone = NULL;
+	clone2 = NULL;
 	return 0;
 
 fail:
@@ -394,6 +418,8 @@ fail:
 		rte_pktmbuf_free(m);
 	if (clone)
 		rte_pktmbuf_free(clone);
+	if (clone2)
+		rte_pktmbuf_free(clone2);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
@ 2015-03-26 17:13     ` Zoltan Kiss
  2015-03-27  0:24     ` Ananyev, Konstantin
  1 sibling, 0 replies; 101+ messages in thread
From: Zoltan Kiss @ 2015-03-26 17:13 UTC (permalink / raw)
  To: Olivier Matz, dev



On 26/03/15 15:59, Olivier Matz wrote:
> 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 <olivier.matz@6wind.com>
> ---
>   app/test-pmd/testpmd.c     |  1 +
>   examples/vhost/main.c      |  2 +-
>   lib/librte_mbuf/rte_mbuf.c |  1 +
>   lib/librte_mbuf/rte_mbuf.h | 44 ++++++++++++++++++++++++++++++++++----------
>   4 files changed, 37 insertions(+), 11 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..d542461 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;
You would need to fix pktmbuf_detach_zcp as well, but see my reply to 
Konstantin.

> 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..45ac948 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -317,18 +317,42 @@ struct rte_mbuf {
>   			/* uint64_t unused:8; */
>   		};
>   	};
> +
> +	uint16_t priv_size;       /**< size of the application private data */
>   } __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;
> +       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.
> + *
> + * @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.
> @@ -744,12 +768,12 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md)
>   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);
> +	void *buf = rte_mbuf_to_baddr(m);
> +	unsigned mhdr_size = (char *)buf - (char *)m;
Minor nit: I think "sizeof(*m) + m->priv_size" would be much more clear, 
like you did above. In fact, this might worth its own inline function, 
and then you can substitute mhdr_size below.

>
> +	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;
> @@ -774,7 +798,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);
>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
  2015-03-26 17:13     ` Zoltan Kiss
@ 2015-03-27  0:24     ` Ananyev, Konstantin
  2015-03-27  9:07       ` Olivier MATZ
  1 sibling, 1 reply; 101+ messages in thread
From: Ananyev, Konstantin @ 2015-03-27  0:24 UTC (permalink / raw)
  To: Olivier Matz, dev

Hi Olivier,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Olivier Matz
> Sent: Thursday, March 26, 2015 4:00 PM
> To: dev@dpdk.org
> Cc: zoltan.kiss@linaro.org
> Subject: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
> 
> 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 <olivier.matz@6wind.com>
> ---
>  app/test-pmd/testpmd.c     |  1 +
>  examples/vhost/main.c      |  2 +-
>  lib/librte_mbuf/rte_mbuf.c |  1 +
>  lib/librte_mbuf/rte_mbuf.h | 44 ++++++++++++++++++++++++++++++++++----------
>  4 files changed, 37 insertions(+), 11 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..d542461 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;
> 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..45ac948 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -317,18 +317,42 @@ struct rte_mbuf {
>  			/* uint64_t unused:8; */
>  		};
>  	};
> +
> +	uint16_t priv_size;       /**< size of the application private data */
>  } __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;
> +       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.
> + *
> + * @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;
> +}
> 

I am a bit puzzled here, so for indirect mbuf, what value priv_size should hold?
Is that priv_size of indirect mfuf, or priv_size of direct mbuf, that mbuf is attached to?
If it is first one, then your changes in __rte_pktmbuf_prefree_seg() wouldn't work properly,
If second one then  changes in rte_pktmbuf_detach() looks wrong to me.
Unless, of course priv_size for all mbufs in the system should always be the same value.
But I suppose, that's not what your intention was, otherwise we don't need priv_size inside mbuf at all -
just a new macro in config file seems enough, plus it would be easier and faster.

I think that to support ability to setup priv_size on a mempool basis,
and reserve private space between struct rte_mbuf and rte_mbuf. buf_addr,
we need to: 

1. Store priv_size both inside the mempool and inside the mbuf.

2. rte_pktmbuf_attach() should change the value of priv_size to the priv_size of the direct mbuf we are going to attach to:
rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) {... mi->priv_size = md->priv_size; ...}

3. rte_pktmbuf_detach() should restore original value of mbuf's priv_size:
rte_pktmbuf_detach(struct rte_mbuf *m) 
{
  ...
   m->priv_size = rte_mempool_get_privsize(m->pool);
   m->buf _addr= rte_mbuf_to_baddr(m);
   ...
}

Also I think we need to provide a way to specify priv_size for all mbufs of the mepool at init time:
- either force people to specify it at rte_mempool_create() time (probably use init_arg for that),
- or provide separate function that could be called straight after rte_mempool_create() , that
would setup priv_size for the  pool and for all its mbufs.
- or some sort of combination of these 2 approaches - introduce a wrapper function 
(rte_mbuf_pool_create() or something) that would take priv_size as parameter, 
create a new mempool and then setup priv_size.

Though, I still think that the better approach is to reserve private space before struct rte_mbuf, not after.
In that case, user got his private space, and we keep buf_addr straight after  rte_mbuf, without any whole.
So we don't need steps 2 and 3, above,
plus we don't need rte_mbuf_to_baddr() and rte_mbuf_from_indirect() - 
RTE_MBUF_TO_BADDR/ RTE_MBUF_FROM_BADDR would keep working correctly.
In fact, with this scheme - we don't even need priv_size for mbuf management (attach/detach/free).

Wonder did you try that approach?
Thanks
Konstantin


>  /**
>   * Returns TRUE if given mbuf is indirect, or FALSE otherwise.
> @@ -744,12 +768,12 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md)
>  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);
> +	void *buf = rte_mbuf_to_baddr(m);
> +	unsigned 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;
> @@ -774,7 +798,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);
> --
> 2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-27  0:24     ` Ananyev, Konstantin
@ 2015-03-27  9:07       ` Olivier MATZ
  2015-03-27 13:56         ` Olivier MATZ
  0 siblings, 1 reply; 101+ messages in thread
From: Olivier MATZ @ 2015-03-27  9:07 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

Thank you for your comments.

On 03/27/2015 01:24 AM, Ananyev, Konstantin wrote:
> Hi Olivier,
> 
>> -----Original Message-----
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Olivier Matz
>> Sent: Thursday, March 26, 2015 4:00 PM
>> To: dev@dpdk.org
>> Cc: zoltan.kiss@linaro.org
>> Subject: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
>>
>> 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 <olivier.matz@6wind.com>
>> ---
>>  app/test-pmd/testpmd.c     |  1 +
>>  examples/vhost/main.c      |  2 +-
>>  lib/librte_mbuf/rte_mbuf.c |  1 +
>>  lib/librte_mbuf/rte_mbuf.h | 44 ++++++++++++++++++++++++++++++++++----------
>>  4 files changed, 37 insertions(+), 11 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..d542461 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;
>> 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..45ac948 100644
>> --- a/lib/librte_mbuf/rte_mbuf.h
>> +++ b/lib/librte_mbuf/rte_mbuf.h
>> @@ -317,18 +317,42 @@ struct rte_mbuf {
>>  			/* uint64_t unused:8; */
>>  		};
>>  	};
>> +
>> +	uint16_t priv_size;       /**< size of the application private data */
>>  } __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;
>> +       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.
>> + *
>> + * @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;
>> +}
>>
> 
> I am a bit puzzled here, so for indirect mbuf, what value priv_size should hold?
> Is that priv_size of indirect mfuf, or priv_size of direct mbuf, that mbuf is attached to?
> If it is first one, then your changes in __rte_pktmbuf_prefree_seg() wouldn't work properly,
> If second one then  changes in rte_pktmbuf_detach() looks wrong to me.
> Unless, of course priv_size for all mbufs in the system should always be the same value.
> But I suppose, that's not what your intention was, otherwise we don't need priv_size inside mbuf at all -
> just a new macro in config file seems enough, plus it would be easier and faster.

Yes, my assumption was that the priv_size isi the same on all mbufs
of a pool, and probably in most cases all mbufs of the system.
To me, a config macro is not th best solution because it prevents the
application to choose the proper size at run-time, especially if the
dpdk is distributed in binary format.

That's why I decided to have priv_size in mbufs, although having it in
the mempool private area is possible but it adds an additional
indirection (see the cover letter).

> I think that to support ability to setup priv_size on a mempool basis,
> and reserve private space between struct rte_mbuf and rte_mbuf. buf_addr,
> we need to: 
> 
> 1. Store priv_size both inside the mempool and inside the mbuf.
> 
> 2. rte_pktmbuf_attach() should change the value of priv_size to the priv_size of the direct mbuf we are going to attach to:
> rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) {... mi->priv_size = md->priv_size; ...}
> 
> 3. rte_pktmbuf_detach() should restore original value of mbuf's priv_size:
> rte_pktmbuf_detach(struct rte_mbuf *m) 
> {
>   ...
>    m->priv_size = rte_mempool_get_privsize(m->pool);
>    m->buf _addr= rte_mbuf_to_baddr(m);
>    ...
> }
> 
> Also I think we need to provide a way to specify priv_size for all mbufs of the mepool at init time:
> - either force people to specify it at rte_mempool_create() time (probably use init_arg for that),
> - or provide separate function that could be called straight after rte_mempool_create() , that
> would setup priv_size for the  pool and for all its mbufs.
> - or some sort of combination of these 2 approaches - introduce a wrapper function 
> (rte_mbuf_pool_create() or something) that would take priv_size as parameter, 
> create a new mempool and then setup priv_size.

Your solution looks good to me, and even if I'm not absolutely
convinced that there is a use case where a packet is attached to
another one with a different priv_size, it's stronger from an
API perspective to support this. Maybe it could happen in a
virtualization or secondary process context where there are 2
different mbuf pools.

The mbuf_priv_size could go in struct rte_pktmbuf_pool_private, but
it can already be deducted from what we have today without changing
anything:

priv_size = pool->elt_size - RTE_PKTMBUF_HEADROOM -
	pool_private->mbuf_data_room_size -
	sizeof(rte_mbuf)

Introducing rte_mbuf_pool_create() seems a good idea to me, it
would hide 'rte_pktmbuf_pool_private' from the user and force
to initialize all the required fields (mbuf_data_room_size only
today, and maybe mbuf_priv_size).

The API would be:

struct rte_mempool *
rte_mbuf_pool_create(const char *name, unsigned n, unsigned elt_size,
	unsigned cache_size, size_t mbuf_priv_size,
	rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg,
	int socket_id, unsigned flags)

I can give it a try and send a patch for this.

> Though, I still think that the better approach is to reserve private space before struct rte_mbuf, not after.
> In that case, user got his private space, and we keep buf_addr straight after  rte_mbuf, without any whole.
> So we don't need steps 2 and 3, above,
> plus we don't need rte_mbuf_to_baddr() and rte_mbuf_from_indirect() - 
> RTE_MBUF_TO_BADDR/ RTE_MBUF_FROM_BADDR would keep working correctly.
> In fact, with this scheme - we don't even need priv_size for mbuf management (attach/detach/free).
> 
> Wonder did you try that approach?

Yes, I though about this approach too. But I think it would require
more changes. When an application or a driver allocate a mbuf with
mempool_get(), it expects that the returned pointer is the rte_mbuf *.

With this solution, there are 2 options:
- no mempool modification, so each application/driver has to add
  priv_size bytes to the object to get the mbuf pointer. This does not
  look feasible.
- change the mempool to support private area before each object. I
  think mempool API is already quite complex, and I think it's not
  the role of the mempool library to provide such features.

In any case, I think it would require more modifications (in terms of
lines of code, but also in terms of "allocation logic"). At the end,
the patch I suggested does not break any paradygm and just add ~10 lines
of code.

Regards,
Olivier

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-27  9:07       ` Olivier MATZ
@ 2015-03-27 13:56         ` Olivier MATZ
  2015-03-27 14:25           ` Ananyev, Konstantin
  0 siblings, 1 reply; 101+ messages in thread
From: Olivier MATZ @ 2015-03-27 13:56 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

On 03/27/2015 10:07 AM, Olivier MATZ wrote:
>> I think that to support ability to setup priv_size on a mempool basis,
>> and reserve private space between struct rte_mbuf and rte_mbuf. buf_addr,
>> we need to: 
>>
>> 1. Store priv_size both inside the mempool and inside the mbuf.
>>
>> 2. rte_pktmbuf_attach() should change the value of priv_size to the priv_size of the direct mbuf we are going to attach to:
>> rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) {... mi->priv_size = md->priv_size; ...}
>>
>> 3. rte_pktmbuf_detach() should restore original value of mbuf's priv_size:
>> rte_pktmbuf_detach(struct rte_mbuf *m) 
>> {
>>   ...
>>    m->priv_size = rte_mempool_get_privsize(m->pool);
>>    m->buf _addr= rte_mbuf_to_baddr(m);
>>    ...
>> }
>>
>> Also I think we need to provide a way to specify priv_size for all mbufs of the mepool at init time:
>> - either force people to specify it at rte_mempool_create() time (probably use init_arg for that),
>> - or provide separate function that could be called straight after rte_mempool_create() , that
>> would setup priv_size for the  pool and for all its mbufs.
>> - or some sort of combination of these 2 approaches - introduce a wrapper function 
>> (rte_mbuf_pool_create() or something) that would take priv_size as parameter, 
>> create a new mempool and then setup priv_size.

I though a bit more about this solution, and I realized that doing
mi->priv_size = md->priv_size in rte_pktmbuf_attach() is probably not
a good idea, as there is no garantee that the size of mi is large enough
to store the priv of md.

Having the same priv_size for mi and md is maybe a good constraint.
I can add this in the API comments and assertions in the code to
check this condition, what do you think?


> Introducing rte_mbuf_pool_create() seems a good idea to me, it
> would hide 'rte_pktmbuf_pool_private' from the user and force
> to initialize all the required fields (mbuf_data_room_size only
> today, and maybe mbuf_priv_size).
> 
> The API would be:
> 
> struct rte_mempool *
> rte_mbuf_pool_create(const char *name, unsigned n, unsigned elt_size,
> 	unsigned cache_size, size_t mbuf_priv_size,
> 	rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg,
> 	int socket_id, unsigned flags)
> 
> I can give it a try and send a patch for this.

About this, it is not required anymore for this patch series if we
agree with my comment above.

I'll send a separate patch for that. It's probably a good occasion
to get rid of the pointer casted into an integer for
mbuf_data_room_size.

Regards,
Olivier

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-27 13:56         ` Olivier MATZ
@ 2015-03-27 14:25           ` Ananyev, Konstantin
  2015-03-27 15:17             ` Olivier MATZ
  0 siblings, 1 reply; 101+ messages in thread
From: Ananyev, Konstantin @ 2015-03-27 14:25 UTC (permalink / raw)
  To: Olivier MATZ, dev

Hi Olivier,

> -----Original Message-----
> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> Sent: Friday, March 27, 2015 1:56 PM
> To: Ananyev, Konstantin; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
> 
> Hi Konstantin,
> 
> On 03/27/2015 10:07 AM, Olivier MATZ wrote:
> >> I think that to support ability to setup priv_size on a mempool basis,
> >> and reserve private space between struct rte_mbuf and rte_mbuf. buf_addr,
> >> we need to:
> >>
> >> 1. Store priv_size both inside the mempool and inside the mbuf.
> >>
> >> 2. rte_pktmbuf_attach() should change the value of priv_size to the priv_size of the direct mbuf we are going to attach to:
> >> rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) {... mi->priv_size = md->priv_size; ...}
> >>
> >> 3. rte_pktmbuf_detach() should restore original value of mbuf's priv_size:
> >> rte_pktmbuf_detach(struct rte_mbuf *m)
> >> {
> >>   ...
> >>    m->priv_size = rte_mempool_get_privsize(m->pool);
> >>    m->buf _addr= rte_mbuf_to_baddr(m);
> >>    ...
> >> }
> >>
> >> Also I think we need to provide a way to specify priv_size for all mbufs of the mepool at init time:
> >> - either force people to specify it at rte_mempool_create() time (probably use init_arg for that),
> >> - or provide separate function that could be called straight after rte_mempool_create() , that
> >> would setup priv_size for the  pool and for all its mbufs.
> >> - or some sort of combination of these 2 approaches - introduce a wrapper function
> >> (rte_mbuf_pool_create() or something) that would take priv_size as parameter,
> >> create a new mempool and then setup priv_size.
> 
> I though a bit more about this solution, and I realized that doing
> mi->priv_size = md->priv_size in rte_pktmbuf_attach() is probably not
> a good idea, as there is no garantee that the size of mi is large enough
> to store the priv of md.
> 
> Having the same priv_size for mi and md is maybe a good constraint.
> I can add this in the API comments and assertions in the code to
> check this condition, what do you think?

Probably we have a different concepts of what is mbuf's  private space in mind.
>From my point, even indirect buffer should use it's own private space and
leave contents of direct mbuf it attached to unmodified.  
After attach() operation, only contents of the buffer are shared between mbufs,
but not the mbuf's metadata. 
Otherwise on detach(), you'll have to copy contents of private space back, from direct to indirect mbuf? 
Again how to deal with the case, when 2 or more mbufs will attach to the same direct one?

So let say, if we'll have a macro:

#define RTE_MBUF_PRIV_PTR(mb)	((void *)((struct rte_mbuf *)(mb)) + 1))

No matter is mb  a direct or indirect mbuf.
Do you have something else in mind here?

> 
> 
> > Introducing rte_mbuf_pool_create() seems a good idea to me, it
> > would hide 'rte_pktmbuf_pool_private' from the user and force
> > to initialize all the required fields (mbuf_data_room_size only
> > today, and maybe mbuf_priv_size).
> >
> > The API would be:
> >
> > struct rte_mempool *
> > rte_mbuf_pool_create(const char *name, unsigned n, unsigned elt_size,
> > 	unsigned cache_size, size_t mbuf_priv_size,
> > 	rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg,
> > 	int socket_id, unsigned flags)
> >
> > I can give it a try and send a patch for this.
> 
> About this, it is not required anymore for this patch series if we
> agree with my comment above.

I still think we need some way to setup priv_size on a per-mempool basis.
Doing that in rte_mbuf_pool_create() seems like a good thing to me.
Not sure, why you decided to drop it?

Konstantin

> 
> I'll send a separate patch for that. It's probably a good occasion
> to get rid of the pointer casted into an integer for
> mbuf_data_room_size.
> 
> Regards,
> Olivier

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-27 14:25           ` Ananyev, Konstantin
@ 2015-03-27 15:17             ` Olivier MATZ
  2015-03-27 18:11               ` Zoltan Kiss
  2015-03-30 12:34               ` Ananyev, Konstantin
  0 siblings, 2 replies; 101+ messages in thread
From: Olivier MATZ @ 2015-03-27 15:17 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

On 03/27/2015 03:25 PM, Ananyev, Konstantin wrote:
> Hi Olivier,
> 
>> -----Original Message-----
>> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
>> Sent: Friday, March 27, 2015 1:56 PM
>> To: Ananyev, Konstantin; dev@dpdk.org
>> Subject: Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
>>
>> Hi Konstantin,
>>
>> On 03/27/2015 10:07 AM, Olivier MATZ wrote:
>>>> I think that to support ability to setup priv_size on a mempool basis,
>>>> and reserve private space between struct rte_mbuf and rte_mbuf. buf_addr,
>>>> we need to:
>>>>
>>>> 1. Store priv_size both inside the mempool and inside the mbuf.
>>>>
>>>> 2. rte_pktmbuf_attach() should change the value of priv_size to the priv_size of the direct mbuf we are going to attach to:
>>>> rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) {... mi->priv_size = md->priv_size; ...}
>>>>
>>>> 3. rte_pktmbuf_detach() should restore original value of mbuf's priv_size:
>>>> rte_pktmbuf_detach(struct rte_mbuf *m)
>>>> {
>>>>   ...
>>>>    m->priv_size = rte_mempool_get_privsize(m->pool);
>>>>    m->buf _addr= rte_mbuf_to_baddr(m);
>>>>    ...
>>>> }
>>>>
>>>> Also I think we need to provide a way to specify priv_size for all mbufs of the mepool at init time:
>>>> - either force people to specify it at rte_mempool_create() time (probably use init_arg for that),
>>>> - or provide separate function that could be called straight after rte_mempool_create() , that
>>>> would setup priv_size for the  pool and for all its mbufs.
>>>> - or some sort of combination of these 2 approaches - introduce a wrapper function
>>>> (rte_mbuf_pool_create() or something) that would take priv_size as parameter,
>>>> create a new mempool and then setup priv_size.
>>
>> I though a bit more about this solution, and I realized that doing
>> mi->priv_size = md->priv_size in rte_pktmbuf_attach() is probably not
>> a good idea, as there is no garantee that the size of mi is large enough
>> to store the priv of md.
>>
>> Having the same priv_size for mi and md is maybe a good constraint.
>> I can add this in the API comments and assertions in the code to
>> check this condition, what do you think?
> 
> Probably we have a different concepts of what is mbuf's  private space in mind.
> From my point, even indirect buffer should use it's own private space and
> leave contents of direct mbuf it attached to unmodified.  
> After attach() operation, only contents of the buffer are shared between mbufs,
> but not the mbuf's metadata. 

Sorry if it was not clear in my previous messages, but I agree
with your description. When attaching a mbuf, only data, not
metadata should be shared.

In the solution you are suggesting (quoted above), you say we need
to set mi->priv_size to md->priv_size in rte_pktmbuf_attach(). I felt
this was not possible, but it depends on the meaning we give to
priv_size:

1. If the meaning is "the size of the private data embedded in this
   mbuf", which is the most logical meaning, we cannot do this
   affectation

2. If the meaning is "the size of the private data embedded in the
   mbuf the buf_addr is pointing to" (which is harder to get), the
   affectation makes sense.

>From what I understand, you feel we should use 2/ as priv_size
definition. Is it correct?

In my previous message, the definition of m->priv_size was 1/,
so that's why I felt assigning mi->priv_size to md->priv_size was
not possible.

I agree 2/ is probably a good choice, as it would allow to attach
to a mbuf with a different priv_size. It may require some additional
comments above the field in the structure to explain that.


> Otherwise on detach(), you'll have to copy contents of private space back, from direct to indirect mbuf? 
> Again how to deal with the case, when 2 or more mbufs will attach to the same direct one?
> 
> So let say, if we'll have a macro:
> 
> #define RTE_MBUF_PRIV_PTR(mb)	((void *)((struct rte_mbuf *)(mb)) + 1))
> 
> No matter is mb  a direct or indirect mbuf.
> Do you have something else in mind here?

I completely agree with this macro. We should consider the private data
as an extension of the mbuf structure.


>>> Introducing rte_mbuf_pool_create() seems a good idea to me, it
>>> would hide 'rte_pktmbuf_pool_private' from the user and force
>>> to initialize all the required fields (mbuf_data_room_size only
>>> today, and maybe mbuf_priv_size).
>>>
>>> The API would be:
>>>
>>> struct rte_mempool *
>>> rte_mbuf_pool_create(const char *name, unsigned n, unsigned elt_size,
>>> 	unsigned cache_size, size_t mbuf_priv_size,
>>> 	rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg,
>>> 	int socket_id, unsigned flags)
>>>
>>> I can give it a try and send a patch for this.
>>
>> About this, it is not required anymore for this patch series if we
>> agree with my comment above.
> 
> I still think we need some way to setup priv_size on a per-mempool basis.
> Doing that in rte_mbuf_pool_create() seems like a good thing to me.
> Not sure, why you decided to drop it?

I think we can already do it without changing the API by providing
our own rte_pktmbuf_init and rte_pktmbuf_pool_init.

rte_pktmbuf_init() has to set:
  m->buf_len = mp->elt_size - sizeof(struct mbuf);
  m->priv_size = sizeof(struct mbuf) - sizeof(struct rte_mbuf);

rte_pktmbuf_pool_init() has to set:
  /* we can use the default function */
  mbp_priv->mbuf_data_room_size = MBUF_RXDATA_SIZE +
  	RTE_PKTMBUF_HEADROOM;

In this case, it is possible to calculate the mbuf_priv_size only
from the pool object:

  mbuf_priv_size = pool->elt_size - RTE_PKTMBUF_HEADROOM -
	pool_private->mbuf_data_room_size -
	sizeof(rte_mbuf)


I agree it's not ideal, but I think the mbuf pool initialization
is another problem. That's why I suggested to change this in a
separate series that will add rte_mbuf_pool_create() with the
API described above. Thoughts?


Thanks,
Olivier


> 
> Konstantin
> 
>>
>> I'll send a separate patch for that. It's probably a good occasion
>> to get rid of the pointer casted into an integer for
>> mbuf_data_room_size.
>>
>> Regards,
>> Olivier

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-27 15:17             ` Olivier MATZ
@ 2015-03-27 18:11               ` Zoltan Kiss
  2015-03-28 21:19                 ` Olivier MATZ
  2015-03-30 12:34               ` Ananyev, Konstantin
  1 sibling, 1 reply; 101+ messages in thread
From: Zoltan Kiss @ 2015-03-27 18:11 UTC (permalink / raw)
  To: Olivier MATZ, Ananyev, Konstantin, dev



On 27/03/15 15:17, Olivier MATZ wrote:
> Hi Konstantin,
>
> On 03/27/2015 03:25 PM, Ananyev, Konstantin wrote:
>> Hi Olivier,
>>
>>> -----Original Message-----
>>> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
>>> Sent: Friday, March 27, 2015 1:56 PM
>>> To: Ananyev, Konstantin; dev@dpdk.org
>>> Subject: Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
>>>
>>> Hi Konstantin,
>>>
>>> On 03/27/2015 10:07 AM, Olivier MATZ wrote:
>>>>> I think that to support ability to setup priv_size on a mempool basis,
>>>>> and reserve private space between struct rte_mbuf and rte_mbuf. buf_addr,
>>>>> we need to:
>>>>>
>>>>> 1. Store priv_size both inside the mempool and inside the mbuf.
>>>>>
>>>>> 2. rte_pktmbuf_attach() should change the value of priv_size to the priv_size of the direct mbuf we are going to attach to:
>>>>> rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) {... mi->priv_size = md->priv_size; ...}
>>>>>
>>>>> 3. rte_pktmbuf_detach() should restore original value of mbuf's priv_size:
>>>>> rte_pktmbuf_detach(struct rte_mbuf *m)
>>>>> {
>>>>>    ...
>>>>>     m->priv_size = rte_mempool_get_privsize(m->pool);
>>>>>     m->buf _addr= rte_mbuf_to_baddr(m);
>>>>>     ...
>>>>> }
>>>>>
>>>>> Also I think we need to provide a way to specify priv_size for all mbufs of the mepool at init time:
>>>>> - either force people to specify it at rte_mempool_create() time (probably use init_arg for that),
>>>>> - or provide separate function that could be called straight after rte_mempool_create() , that
>>>>> would setup priv_size for the  pool and for all its mbufs.
>>>>> - or some sort of combination of these 2 approaches - introduce a wrapper function
>>>>> (rte_mbuf_pool_create() or something) that would take priv_size as parameter,
>>>>> create a new mempool and then setup priv_size.
>>>
>>> I though a bit more about this solution, and I realized that doing
>>> mi->priv_size = md->priv_size in rte_pktmbuf_attach() is probably not
>>> a good idea, as there is no garantee that the size of mi is large enough
>>> to store the priv of md.
>>>
>>> Having the same priv_size for mi and md is maybe a good constraint.
>>> I can add this in the API comments and assertions in the code to
>>> check this condition, what do you think?
>>
>> Probably we have a different concepts of what is mbuf's  private space in mind.
>>  From my point, even indirect buffer should use it's own private space and
>> leave contents of direct mbuf it attached to unmodified.
>> After attach() operation, only contents of the buffer are shared between mbufs,
>> but not the mbuf's metadata.
>
> Sorry if it was not clear in my previous messages, but I agree
> with your description. When attaching a mbuf, only data, not
> metadata should be shared.
>
> In the solution you are suggesting (quoted above), you say we need
> to set mi->priv_size to md->priv_size in rte_pktmbuf_attach(). I felt
> this was not possible, but it depends on the meaning we give to
> priv_size:
>
> 1. If the meaning is "the size of the private data embedded in this
>     mbuf", which is the most logical meaning, we cannot do this
>     affectation
>
> 2. If the meaning is "the size of the private data embedded in the
>     mbuf the buf_addr is pointing to" (which is harder to get), the
>     affectation makes sense.
>
>  From what I understand, you feel we should use 2/ as priv_size
> definition. Is it correct?
>
> In my previous message, the definition of m->priv_size was 1/,
> so that's why I felt assigning mi->priv_size to md->priv_size was
> not possible.
>
> I agree 2/ is probably a good choice, as it would allow to attach
> to a mbuf with a different priv_size. It may require some additional
> comments above the field in the structure to explain that.
I think we need to document it in the comments very well that you can 
attach mbuf's to each other with different private area sizes, and 
applications should care about this difference. And we should give a 
macro to get the private area size, which will get rte_mbuf.mp->priv_size.
Actually we should give some better name to rte_mbuf.priv_size, it's a 
bit misleading now. Maybe direct_priv_size?
>
>
>> Otherwise on detach(), you'll have to copy contents of private space back, from direct to indirect mbuf?
>> Again how to deal with the case, when 2 or more mbufs will attach to the same direct one?
>>
>> So let say, if we'll have a macro:
>>
>> #define RTE_MBUF_PRIV_PTR(mb)	((void *)((struct rte_mbuf *)(mb)) + 1))
>>
>> No matter is mb  a direct or indirect mbuf.
>> Do you have something else in mind here?
>
> I completely agree with this macro. We should consider the private data
> as an extension of the mbuf structure.
>
>
>>>> Introducing rte_mbuf_pool_create() seems a good idea to me, it
>>>> would hide 'rte_pktmbuf_pool_private' from the user and force
>>>> to initialize all the required fields (mbuf_data_room_size only
>>>> today, and maybe mbuf_priv_size).
>>>>
>>>> The API would be:
>>>>
>>>> struct rte_mempool *
>>>> rte_mbuf_pool_create(const char *name, unsigned n, unsigned elt_size,
>>>> 	unsigned cache_size, size_t mbuf_priv_size,
>>>> 	rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg,
>>>> 	int socket_id, unsigned flags)
>>>>
>>>> I can give it a try and send a patch for this.
>>>
>>> About this, it is not required anymore for this patch series if we
>>> agree with my comment above.
>>
>> I still think we need some way to setup priv_size on a per-mempool basis.
>> Doing that in rte_mbuf_pool_create() seems like a good thing to me.
>> Not sure, why you decided to drop it?
>
> I think we can already do it without changing the API by providing
> our own rte_pktmbuf_init and rte_pktmbuf_pool_init.
>
> rte_pktmbuf_init() has to set:
>    m->buf_len = mp->elt_size - sizeof(struct mbuf);
>    m->priv_size = sizeof(struct mbuf) - sizeof(struct rte_mbuf);
What's struct mbuf? If we take my assumption above, direct_priv_size 
could go uninitalized, and we can set it when attaching.
>
> rte_pktmbuf_pool_init() has to set:
>    /* we can use the default function */
>    mbp_priv->mbuf_data_room_size = MBUF_RXDATA_SIZE +
>    	RTE_PKTMBUF_HEADROOM;
>
> In this case, it is possible to calculate the mbuf_priv_size only
> from the pool object:
>
>    mbuf_priv_size = pool->elt_size - RTE_PKTMBUF_HEADROOM -
> 	pool_private->mbuf_data_room_size -
> 	sizeof(rte_mbuf)
My understanding is that the pool private date is something completely 
different than the private data of the mbufs. I think 
rte_mempool.priv_size should be initialized in *mp_init.

>
>
> I agree it's not ideal, but I think the mbuf pool initialization
> is another problem. That's why I suggested to change this in a
> separate series that will add rte_mbuf_pool_create() with the
> API described above. Thoughts?


>
>
> Thanks,
> Olivier
>
>
>>
>> Konstantin
>>
>>>
>>> I'll send a separate patch for that. It's probably a good occasion
>>> to get rid of the pointer casted into an integer for
>>> mbuf_data_room_size.
>>>
>>> Regards,
>>> Olivier

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-27 18:11               ` Zoltan Kiss
@ 2015-03-28 21:19                 ` Olivier MATZ
  0 siblings, 0 replies; 101+ messages in thread
From: Olivier MATZ @ 2015-03-28 21:19 UTC (permalink / raw)
  To: Zoltan Kiss, Ananyev, Konstantin, dev

Hi Zoltan,

On 03/27/2015 07:11 PM, Zoltan Kiss wrote:
>> Sorry if it was not clear in my previous messages, but I agree
>> with your description. When attaching a mbuf, only data, not
>> metadata should be shared.
>>
>> In the solution you are suggesting (quoted above), you say we need
>> to set mi->priv_size to md->priv_size in rte_pktmbuf_attach(). I felt
>> this was not possible, but it depends on the meaning we give to
>> priv_size:
>>
>> 1. If the meaning is "the size of the private data embedded in this
>>     mbuf", which is the most logical meaning, we cannot do this
>>     affectation
>>
>> 2. If the meaning is "the size of the private data embedded in the
>>     mbuf the buf_addr is pointing to" (which is harder to get), the
>>     affectation makes sense.
>>
>>  From what I understand, you feel we should use 2/ as priv_size
>> definition. Is it correct?
>>
>> In my previous message, the definition of m->priv_size was 1/,
>> so that's why I felt assigning mi->priv_size to md->priv_size was
>> not possible.
>>
>> I agree 2/ is probably a good choice, as it would allow to attach
>> to a mbuf with a different priv_size. It may require some additional
>> comments above the field in the structure to explain that.
> I think we need to document it in the comments very well that you can
> attach mbuf's to each other with different private area sizes, and
> applications should care about this difference. And we should give a
> macro to get the private area size, which will get rte_mbuf.mp->priv_size.
> Actually we should give some better name to rte_mbuf.priv_size, it's a
> bit misleading now. Maybe direct_priv_size?

I agree it should be well documented in the API comments, but I'm
not sure it's worth changing the name of the field. After all,
m->buf_addr and m->buf_len are also related to the buffer of the
direct mbuf without beeing named "direct_*".


>>>>> Introducing rte_mbuf_pool_create() seems a good idea to me, it
>>>>> would hide 'rte_pktmbuf_pool_private' from the user and force
>>>>> to initialize all the required fields (mbuf_data_room_size only
>>>>> today, and maybe mbuf_priv_size).
>>>>>
>>>>> The API would be:
>>>>>
>>>>> struct rte_mempool *
>>>>> rte_mbuf_pool_create(const char *name, unsigned n, unsigned elt_size,
>>>>>     unsigned cache_size, size_t mbuf_priv_size,
>>>>>     rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg,
>>>>>     int socket_id, unsigned flags)
>>>>>
>>>>> I can give it a try and send a patch for this.
>>>>
>>>> About this, it is not required anymore for this patch series if we
>>>> agree with my comment above.
>>>
>>> I still think we need some way to setup priv_size on a per-mempool
>>> basis.
>>> Doing that in rte_mbuf_pool_create() seems like a good thing to me.
>>> Not sure, why you decided to drop it?
>>
>> I think we can already do it without changing the API by providing
>> our own rte_pktmbuf_init and rte_pktmbuf_pool_init.
>>
>> rte_pktmbuf_init() has to set:
>>    m->buf_len = mp->elt_size - sizeof(struct mbuf);
>>    m->priv_size = sizeof(struct mbuf) - sizeof(struct rte_mbuf);
> What's struct mbuf? If we take my assumption above, direct_priv_size
> could go uninitalized, and we can set it when attaching.

In this example, "struct mbuf" is the mbuf used by the application:

struct mbuf {
	struct rte_mbuf rte_mb;
	struct app_private priv;
};

Therefore, we have:

sizeof(struct mbuf) = sizeof(struct rte_mbuf) +
	sizeof(struct app_private);


About keeping the m->priv_size field not initialized, I'm not really
convinced because we would always have to use the pool->mbuf_priv_size
when we want to get the address of data buffer embedded in a mbuf. This
implies several indirections, and we have only one if the info is
already in the mbuf.


>> rte_pktmbuf_pool_init() has to set:
>>    /* we can use the default function */
>>    mbp_priv->mbuf_data_room_size = MBUF_RXDATA_SIZE +
>>        RTE_PKTMBUF_HEADROOM;
>>
>> In this case, it is possible to calculate the mbuf_priv_size only
>> from the pool object:
>>
>>    mbuf_priv_size = pool->elt_size - RTE_PKTMBUF_HEADROOM -
>>     pool_private->mbuf_data_room_size -
>>     sizeof(rte_mbuf)
> My understanding is that the pool private date is something completely
> different than the private data of the mbufs. I think
> rte_mempool.priv_size should be initialized in *mp_init.

As I said in my previous mail, I think we don't need to have
pool_private->mbuf_priv_size for this series, as it can be
calculated from what we already have in pool_private. I'll send
a v3 patch that implement this solution, and it can be a base for
discussions.

However, I think the way mbuf pools are initialized may need some
rework, maybe using rte_mbuf_pool_create() as Konstantin suggested.
I'll try to do some reworks in this area in another series.

Regards,
Olivier



> 
>>
>>
>> I agree it's not ideal, but I think the mbuf pool initialization
>> is another problem. That's why I suggested to change this in a
>> separate series that will add rte_mbuf_pool_create() with the
>> API described above. Thoughts?
> 
> 
>>
>>
>> Thanks,
>> Olivier
>>
>>
>>>
>>> Konstantin
>>>
>>>>
>>>> I'll send a separate patch for that. It's probably a good occasion
>>>> to get rid of the pointer casted into an integer for
>>>> mbuf_data_room_size.
>>>>
>>>> Regards,
>>>> Olivier

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-27 15:17             ` Olivier MATZ
  2015-03-27 18:11               ` Zoltan Kiss
@ 2015-03-30 12:34               ` Ananyev, Konstantin
  2015-03-30 19:55                 ` Olivier MATZ
  1 sibling, 1 reply; 101+ messages in thread
From: Ananyev, Konstantin @ 2015-03-30 12:34 UTC (permalink / raw)
  To: Olivier MATZ; +Cc: dev

Hi Olivier,

> -----Original Message-----
> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> Sent: Friday, March 27, 2015 3:17 PM
> To: Ananyev, Konstantin; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
> 
> Hi Konstantin,
> 
> On 03/27/2015 03:25 PM, Ananyev, Konstantin wrote:
> > Hi Olivier,
> >
> >> -----Original Message-----
> >> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> >> Sent: Friday, March 27, 2015 1:56 PM
> >> To: Ananyev, Konstantin; dev@dpdk.org
> >> Subject: Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
> >>
> >> Hi Konstantin,
> >>
> >> On 03/27/2015 10:07 AM, Olivier MATZ wrote:
> >>>> I think that to support ability to setup priv_size on a mempool basis,
> >>>> and reserve private space between struct rte_mbuf and rte_mbuf. buf_addr,
> >>>> we need to:
> >>>>
> >>>> 1. Store priv_size both inside the mempool and inside the mbuf.
> >>>>
> >>>> 2. rte_pktmbuf_attach() should change the value of priv_size to the priv_size of the direct mbuf we are going to attach to:
> >>>> rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) {... mi->priv_size = md->priv_size; ...}
> >>>>
> >>>> 3. rte_pktmbuf_detach() should restore original value of mbuf's priv_size:
> >>>> rte_pktmbuf_detach(struct rte_mbuf *m)
> >>>> {
> >>>>   ...
> >>>>    m->priv_size = rte_mempool_get_privsize(m->pool);
> >>>>    m->buf _addr= rte_mbuf_to_baddr(m);
> >>>>    ...
> >>>> }
> >>>>
> >>>> Also I think we need to provide a way to specify priv_size for all mbufs of the mepool at init time:
> >>>> - either force people to specify it at rte_mempool_create() time (probably use init_arg for that),
> >>>> - or provide separate function that could be called straight after rte_mempool_create() , that
> >>>> would setup priv_size for the  pool and for all its mbufs.
> >>>> - or some sort of combination of these 2 approaches - introduce a wrapper function
> >>>> (rte_mbuf_pool_create() or something) that would take priv_size as parameter,
> >>>> create a new mempool and then setup priv_size.
> >>
> >> I though a bit more about this solution, and I realized that doing
> >> mi->priv_size = md->priv_size in rte_pktmbuf_attach() is probably not
> >> a good idea, as there is no garantee that the size of mi is large enough
> >> to store the priv of md.
> >>
> >> Having the same priv_size for mi and md is maybe a good constraint.
> >> I can add this in the API comments and assertions in the code to
> >> check this condition, what do you think?
> >
> > Probably we have a different concepts of what is mbuf's  private space in mind.
> > From my point, even indirect buffer should use it's own private space and
> > leave contents of direct mbuf it attached to unmodified.
> > After attach() operation, only contents of the buffer are shared between mbufs,
> > but not the mbuf's metadata.
> 
> Sorry if it was not clear in my previous messages, but I agree
> with your description. When attaching a mbuf, only data, not
> metadata should be shared.
> 
> In the solution you are suggesting (quoted above), you say we need
> to set mi->priv_size to md->priv_size in rte_pktmbuf_attach(). I felt
> this was not possible, but it depends on the meaning we give to
> priv_size:
> 
> 1. If the meaning is "the size of the private data embedded in this
>    mbuf", which is the most logical meaning, we cannot do this
>    affectation
> 
> 2. If the meaning is "the size of the private data embedded in the
>    mbuf the buf_addr is pointing to" (which is harder to get), the
>    affectation makes sense.
> 
> From what I understand, you feel we should use 2/ as priv_size
> definition. Is it correct?

Yes, I meant 2.
>From my point priv_size inside mbuf is more like 'buf_ofs'.
It's main purpose is for internal use - to help our mbuf manipulation routinies
(attach/detach/free) to work correctly.
If the user wants to query size of private space for the mbuf, he probably should
use the value from mempool.

> 
> In my previous message, the definition of m->priv_size was 1/,
> so that's why I felt assigning mi->priv_size to md->priv_size was
> not possible.
> 
> I agree 2/ is probably a good choice, as it would allow to attach
> to a mbuf with a different priv_size. It may require some additional
> comments above the field in the structure to explain that.
> 
> 
> > Otherwise on detach(), you'll have to copy contents of private space back, from direct to indirect mbuf?
> > Again how to deal with the case, when 2 or more mbufs will attach to the same direct one?
> >
> > So let say, if we'll have a macro:
> >
> > #define RTE_MBUF_PRIV_PTR(mb)	((void *)((struct rte_mbuf *)(mb)) + 1))
> >
> > No matter is mb  a direct or indirect mbuf.
> > Do you have something else in mind here?
> 
> I completely agree with this macro. We should consider the private data
> as an extension of the mbuf structure.
> 
> 
> >>> Introducing rte_mbuf_pool_create() seems a good idea to me, it
> >>> would hide 'rte_pktmbuf_pool_private' from the user and force
> >>> to initialize all the required fields (mbuf_data_room_size only
> >>> today, and maybe mbuf_priv_size).
> >>>
> >>> The API would be:
> >>>
> >>> struct rte_mempool *
> >>> rte_mbuf_pool_create(const char *name, unsigned n, unsigned elt_size,
> >>> 	unsigned cache_size, size_t mbuf_priv_size,
> >>> 	rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg,
> >>> 	int socket_id, unsigned flags)
> >>>
> >>> I can give it a try and send a patch for this.
> >>
> >> About this, it is not required anymore for this patch series if we
> >> agree with my comment above.
> >
> > I still think we need some way to setup priv_size on a per-mempool basis.
> > Doing that in rte_mbuf_pool_create() seems like a good thing to me.
> > Not sure, why you decided to drop it?
> 
> I think we can already do it without changing the API by providing
> our own rte_pktmbuf_init and rte_pktmbuf_pool_init.
> 
> rte_pktmbuf_init() has to set:
>   m->buf_len = mp->elt_size - sizeof(struct mbuf);
>   m->priv_size = sizeof(struct mbuf) - sizeof(struct rte_mbuf);
> 
> rte_pktmbuf_pool_init() has to set:
>   /* we can use the default function */
>   mbp_priv->mbuf_data_room_size = MBUF_RXDATA_SIZE +
>   	RTE_PKTMBUF_HEADROOM;

Yeh, when  arg==NULL for rte_pktmbuf_pool_init() we always set up
mbuf_data_room_size to the hardcoded value.
Which always looked strange to me.
I think it should be set to:
mp->elt_size - sizeof(struct rte_mbuf) - RTE_PKTMBUF_HEADROOM;
for that case.

> 
> In this case, it is possible to calculate the mbuf_priv_size only
> from the pool object:
> 
>   mbuf_priv_size = pool->elt_size - RTE_PKTMBUF_HEADROOM -
> 	pool_private->mbuf_data_room_size -
> 	sizeof(rte_mbuf)
> 

So if I understand your idea correctly:
If  second parameter for rte_pktmbuf_pool_init() is NULL, then 
we setup

mbp_priv->mbuf_data_room_size = mp->elt_size - sizeof(struct rte_mbuf) - RTE_PKTMBUF_HEADROOM;

Which means that  priv_size ==0  for all  mbufs in the pool 
Otherwise we setup:

 mbp_priv->mbuf_data_room_size = opaque_arg;

As we are doing now, and priv_size for all mbufs in the pool will be:
pool->elt_size - pool_private->mbuf_data_room_size - sizeof(rte_mbuf);

And in that case, all users have to do to specify priv_size for mempool is to pass a proper argument
for rte_pktmbuf_pool_init() at  mempool_create().
Correct? 

> 
> I agree it's not ideal, but I think the mbuf pool initialization
> is another problem. That's why I suggested to change this in a
> separate series that will add rte_mbuf_pool_create() with the
> API described above. Thoughts?
> 

I also put answers to another mail below.
Just to keep all discussion in one place.

> > Though, I still think that the better approach is to reserve private space before struct rte_mbuf, not after.
> > In that case, user got his private space, and we keep buf_addr straight after  rte_mbuf, without any whole.
> > So we don't need steps 2 and 3, above,
> > plus we don't need rte_mbuf_to_baddr() and rte_mbuf_from_indirect() -
> > RTE_MBUF_TO_BADDR/ RTE_MBUF_FROM_BADDR would keep working correctly.
> > In fact, with this scheme - we don't even need priv_size for mbuf management (attach/detach/free).
> >
> > Wonder did you try that approach?
> 
> Yes, I though about this approach too. But I think it would require
> more changes. When an application or a driver allocate a mbuf with
> mempool_get(), it expects that the returned pointer is the rte_mbuf *.

Yep, sure it will still get the pointer to the rte_mbuf *.
Though later, if upper layer would like to convert from  rte_mbuf* to app_specific_mbuf *,
it would have to use a macro:

#define RTE_MBUF_TO_PRIV(m)	((void *)((uintptr_t)(m) - (m)->priv_size)) 

> 
> With this solution, there are 2 options:
> - no mempool modification, so each application/driver has to add
>   priv_size bytes to the object to get the mbuf pointer. This does not
>   look feasible.
> - change the mempool to support private area before each object. I
>   think mempool API is already quite complex, and I think it's not
>   the role of the mempool library to provide such features.


In fact, I think the changes would be minimal.
All we have to do, is to make changes in rte_pktmbuf_init():

void
rte_pktmbuf_init(struct rte_mempool *mp,
                 __attribute__((unused)) void *opaque_arg,
                 void *_m,
                 __attribute__((unused)) unsigned i)
{

     //extract priv_size from mempool   (discussed above).
      uint16_t priv_size = rte_mbufpool_get_priv_size(mp); 

      struct rte_mbuf *m = _m + priv_size;
      uint32_t buf_len = mp->elt_size - sizeof(struct rte_mbuf) - priv_size;

....


With that way priv_size inside mbuf would always be the size its own private space,
for both direct and indirect mbus., so we don't require to set priv_size at attach/detach.
Again RTE_MBUF_TO_BADDR() and RTE_MBUF_FROM_BADDR() would just work without any modifications.

Konstantin
 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-30 12:34               ` Ananyev, Konstantin
@ 2015-03-30 19:55                 ` Olivier MATZ
  2015-03-30 23:17                   ` Ananyev, Konstantin
  0 siblings, 1 reply; 101+ messages in thread
From: Olivier MATZ @ 2015-03-30 19:55 UTC (permalink / raw)
  To: Ananyev, Konstantin; +Cc: dev

Hi Konstantin,

On 03/30/2015 02:34 PM, Ananyev, Konstantin wrote:
> Hi Olivier,
> 
>> -----Original Message-----
>> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
>> Sent: Friday, March 27, 2015 3:17 PM
>> To: Ananyev, Konstantin; dev@dpdk.org
>> Subject: Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
>>
>> Hi Konstantin,
>>
>> On 03/27/2015 03:25 PM, Ananyev, Konstantin wrote:
>>> Hi Olivier,
>>>
>>>> -----Original Message-----
>>>> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
>>>> Sent: Friday, March 27, 2015 1:56 PM
>>>> To: Ananyev, Konstantin; dev@dpdk.org
>>>> Subject: Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
>>>>
>>>> Hi Konstantin,
>>>>
>>>> On 03/27/2015 10:07 AM, Olivier MATZ wrote:
>>>>>> I think that to support ability to setup priv_size on a mempool basis,
>>>>>> and reserve private space between struct rte_mbuf and rte_mbuf. buf_addr,
>>>>>> we need to:
>>>>>>
>>>>>> 1. Store priv_size both inside the mempool and inside the mbuf.
>>>>>>
>>>>>> 2. rte_pktmbuf_attach() should change the value of priv_size to the priv_size of the direct mbuf we are going to attach to:
>>>>>> rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) {... mi->priv_size = md->priv_size; ...}
>>>>>>
>>>>>> 3. rte_pktmbuf_detach() should restore original value of mbuf's priv_size:
>>>>>> rte_pktmbuf_detach(struct rte_mbuf *m)
>>>>>> {
>>>>>>   ...
>>>>>>    m->priv_size = rte_mempool_get_privsize(m->pool);
>>>>>>    m->buf _addr= rte_mbuf_to_baddr(m);
>>>>>>    ...
>>>>>> }
>>>>>>
>>>>>> Also I think we need to provide a way to specify priv_size for all mbufs of the mepool at init time:
>>>>>> - either force people to specify it at rte_mempool_create() time (probably use init_arg for that),
>>>>>> - or provide separate function that could be called straight after rte_mempool_create() , that
>>>>>> would setup priv_size for the  pool and for all its mbufs.
>>>>>> - or some sort of combination of these 2 approaches - introduce a wrapper function
>>>>>> (rte_mbuf_pool_create() or something) that would take priv_size as parameter,
>>>>>> create a new mempool and then setup priv_size.
>>>>
>>>> I though a bit more about this solution, and I realized that doing
>>>> mi->priv_size = md->priv_size in rte_pktmbuf_attach() is probably not
>>>> a good idea, as there is no garantee that the size of mi is large enough
>>>> to store the priv of md.
>>>>
>>>> Having the same priv_size for mi and md is maybe a good constraint.
>>>> I can add this in the API comments and assertions in the code to
>>>> check this condition, what do you think?
>>>
>>> Probably we have a different concepts of what is mbuf's  private space in mind.
>>> From my point, even indirect buffer should use it's own private space and
>>> leave contents of direct mbuf it attached to unmodified.
>>> After attach() operation, only contents of the buffer are shared between mbufs,
>>> but not the mbuf's metadata.
>>
>> Sorry if it was not clear in my previous messages, but I agree
>> with your description. When attaching a mbuf, only data, not
>> metadata should be shared.
>>
>> In the solution you are suggesting (quoted above), you say we need
>> to set mi->priv_size to md->priv_size in rte_pktmbuf_attach(). I felt
>> this was not possible, but it depends on the meaning we give to
>> priv_size:
>>
>> 1. If the meaning is "the size of the private data embedded in this
>>    mbuf", which is the most logical meaning, we cannot do this
>>    affectation
>>
>> 2. If the meaning is "the size of the private data embedded in the
>>    mbuf the buf_addr is pointing to" (which is harder to get), the
>>    affectation makes sense.
>>
>> From what I understand, you feel we should use 2/ as priv_size
>> definition. Is it correct?
> 
> Yes, I meant 2.
> From my point priv_size inside mbuf is more like 'buf_ofs'.
> It's main purpose is for internal use - to help our mbuf manipulation routinies
> (attach/detach/free) to work correctly.
> If the user wants to query size of private space for the mbuf, he probably should
> use the value from mempool.

Agree.


>> In my previous message, the definition of m->priv_size was 1/,
>> so that's why I felt assigning mi->priv_size to md->priv_size was
>> not possible.
>>
>> I agree 2/ is probably a good choice, as it would allow to attach
>> to a mbuf with a different priv_size. It may require some additional
>> comments above the field in the structure to explain that.
>>
>>
>>> Otherwise on detach(), you'll have to copy contents of private space back, from direct to indirect mbuf?
>>> Again how to deal with the case, when 2 or more mbufs will attach to the same direct one?
>>>
>>> So let say, if we'll have a macro:
>>>
>>> #define RTE_MBUF_PRIV_PTR(mb)	((void *)((struct rte_mbuf *)(mb)) + 1))
>>>
>>> No matter is mb  a direct or indirect mbuf.
>>> Do you have something else in mind here?
>>
>> I completely agree with this macro. We should consider the private data
>> as an extension of the mbuf structure.
>>
>>
>>>>> Introducing rte_mbuf_pool_create() seems a good idea to me, it
>>>>> would hide 'rte_pktmbuf_pool_private' from the user and force
>>>>> to initialize all the required fields (mbuf_data_room_size only
>>>>> today, and maybe mbuf_priv_size).
>>>>>
>>>>> The API would be:
>>>>>
>>>>> struct rte_mempool *
>>>>> rte_mbuf_pool_create(const char *name, unsigned n, unsigned elt_size,
>>>>> 	unsigned cache_size, size_t mbuf_priv_size,
>>>>> 	rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg,
>>>>> 	int socket_id, unsigned flags)
>>>>>
>>>>> I can give it a try and send a patch for this.
>>>>
>>>> About this, it is not required anymore for this patch series if we
>>>> agree with my comment above.
>>>
>>> I still think we need some way to setup priv_size on a per-mempool basis.
>>> Doing that in rte_mbuf_pool_create() seems like a good thing to me.
>>> Not sure, why you decided to drop it?
>>
>> I think we can already do it without changing the API by providing
>> our own rte_pktmbuf_init and rte_pktmbuf_pool_init.
>>
>> rte_pktmbuf_init() has to set:
>>   m->buf_len = mp->elt_size - sizeof(struct mbuf);
>>   m->priv_size = sizeof(struct mbuf) - sizeof(struct rte_mbuf);
>>
>> rte_pktmbuf_pool_init() has to set:
>>   /* we can use the default function */
>>   mbp_priv->mbuf_data_room_size = MBUF_RXDATA_SIZE +
>>   	RTE_PKTMBUF_HEADROOM;
> 
> Yeh, when  arg==NULL for rte_pktmbuf_pool_init() we always set up
> mbuf_data_room_size to the hardcoded value.
> Which always looked strange to me.
> I think it should be set to:
> mp->elt_size - sizeof(struct rte_mbuf) - RTE_PKTMBUF_HEADROOM;
> for that case.

Yes, that would make more sense instead of the hardcoded value.
But I'm not sure it should be part of this series as the clone
patches won't change this behavior. I would prefer to have it in
another series that reworks mbuf pool initialization. I can also
work on it.

On the other hand if you really feel this patch is needed in
this series, it's not a problem as it's a one-liner.

> 
>>
>> In this case, it is possible to calculate the mbuf_priv_size only
>> from the pool object:
>>
>>   mbuf_priv_size = pool->elt_size - RTE_PKTMBUF_HEADROOM -
>> 	pool_private->mbuf_data_room_size -
>> 	sizeof(rte_mbuf)
>>
> 
> So if I understand your idea correctly:
> If  second parameter for rte_pktmbuf_pool_init() is NULL, then 
> we setup
> 
> mbp_priv->mbuf_data_room_size = mp->elt_size - sizeof(struct rte_mbuf) - RTE_PKTMBUF_HEADROOM;
> 
> Which means that  priv_size ==0  for all  mbufs in the pool 
> Otherwise we setup:
> 
>  mbp_priv->mbuf_data_room_size = opaque_arg;
> 
> As we are doing now, and priv_size for all mbufs in the pool will be:
> pool->elt_size - pool_private->mbuf_data_room_size - sizeof(rte_mbuf);
> 
> And in that case, all users have to do to specify priv_size for mempool is to pass a proper argument
> for rte_pktmbuf_pool_init() at  mempool_create().
> Correct? 

Correct.



> 
>>
>> I agree it's not ideal, but I think the mbuf pool initialization
>> is another problem. That's why I suggested to change this in a
>> separate series that will add rte_mbuf_pool_create() with the
>> API described above. Thoughts?
>>
> 
> I also put answers to another mail below.
> Just to keep all discussion in one place.
> 
>>> Though, I still think that the better approach is to reserve private space before struct rte_mbuf, not after.
>>> In that case, user got his private space, and we keep buf_addr straight after  rte_mbuf, without any whole.
>>> So we don't need steps 2 and 3, above,
>>> plus we don't need rte_mbuf_to_baddr() and rte_mbuf_from_indirect() -
>>> RTE_MBUF_TO_BADDR/ RTE_MBUF_FROM_BADDR would keep working correctly.
>>> In fact, with this scheme - we don't even need priv_size for mbuf management (attach/detach/free).
>>>
>>> Wonder did you try that approach?
>>
>> Yes, I though about this approach too. But I think it would require
>> more changes. When an application or a driver allocate a mbuf with
>> mempool_get(), it expects that the returned pointer is the rte_mbuf *.
> 
> Yep, sure it will still get the pointer to the rte_mbuf *.
> Though later, if upper layer would like to convert from  rte_mbuf* to app_specific_mbuf *,
> it would have to use a macro:
> 
> #define RTE_MBUF_TO_PRIV(m)	((void *)((uintptr_t)(m) - (m)->priv_size)) 
> 
>>
>> With this solution, there are 2 options:
>> - no mempool modification, so each application/driver has to add
>>   priv_size bytes to the object to get the mbuf pointer. This does not
>>   look feasible.
>> - change the mempool to support private area before each object. I
>>   think mempool API is already quite complex, and I think it's not
>>   the role of the mempool library to provide such features.
> 
> 
> In fact, I think the changes would be minimal.
> All we have to do, is to make changes in rte_pktmbuf_init():
> 
> void
> rte_pktmbuf_init(struct rte_mempool *mp,
>                  __attribute__((unused)) void *opaque_arg,
>                  void *_m,
>                  __attribute__((unused)) unsigned i)
> {
> 
>      //extract priv_size from mempool   (discussed above).
>       uint16_t priv_size = rte_mbufpool_get_priv_size(mp); 
> 
>       struct rte_mbuf *m = _m + priv_size;
>       uint32_t buf_len = mp->elt_size - sizeof(struct rte_mbuf) - priv_size;
> 
> ....
> 
> 
> With that way priv_size inside mbuf would always be the size its own private space,
> for both direct and indirect mbus., so we don't require to set priv_size at attach/detach.
> Again RTE_MBUF_TO_BADDR() and RTE_MBUF_FROM_BADDR() would just work without any modifications.

I'm not sure I'm getting it. The argument '_m' of your
rte_pktmbuf_init() is the pointer to the priv data, right?
So it means that the mbuf is located priv_size bytes after.

The rte_pktmbuf_init() function is called by mempool_create(),
and the _m parameter is a pointer to a mempool object. So
in my understanding, mempool_get() would not return a rte_mbuf
but a pointer to the application private data.


Regards,
Olivier



> 
> Konstantin
>  
> 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-30 19:55                 ` Olivier MATZ
@ 2015-03-30 23:17                   ` Ananyev, Konstantin
  2015-03-31 19:01                     ` Olivier MATZ
  0 siblings, 1 reply; 101+ messages in thread
From: Ananyev, Konstantin @ 2015-03-30 23:17 UTC (permalink / raw)
  To: Olivier MATZ; +Cc: dev

Hi Olivier,

> -----Original Message-----
> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> Sent: Monday, March 30, 2015 8:56 PM
> To: Ananyev, Konstantin
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
> 
> Hi Konstantin,
> 
> On 03/30/2015 02:34 PM, Ananyev, Konstantin wrote:
> > Hi Olivier,
> >
> >> -----Original Message-----
> >> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> >> Sent: Friday, March 27, 2015 3:17 PM
> >> To: Ananyev, Konstantin; dev@dpdk.org
> >> Subject: Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
> >>
> >> Hi Konstantin,
> >>
> >> On 03/27/2015 03:25 PM, Ananyev, Konstantin wrote:
> >>> Hi Olivier,
> >>>
> >>>> -----Original Message-----
> >>>> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> >>>> Sent: Friday, March 27, 2015 1:56 PM
> >>>> To: Ananyev, Konstantin; dev@dpdk.org
> >>>> Subject: Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
> >>>>
> >>>> Hi Konstantin,
> >>>>
> >>>> On 03/27/2015 10:07 AM, Olivier MATZ wrote:
> >>>>>> I think that to support ability to setup priv_size on a mempool basis,
> >>>>>> and reserve private space between struct rte_mbuf and rte_mbuf. buf_addr,
> >>>>>> we need to:
> >>>>>>
> >>>>>> 1. Store priv_size both inside the mempool and inside the mbuf.
> >>>>>>
> >>>>>> 2. rte_pktmbuf_attach() should change the value of priv_size to the priv_size of the direct mbuf we are going to attach to:
> >>>>>> rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) {... mi->priv_size = md->priv_size; ...}
> >>>>>>
> >>>>>> 3. rte_pktmbuf_detach() should restore original value of mbuf's priv_size:
> >>>>>> rte_pktmbuf_detach(struct rte_mbuf *m)
> >>>>>> {
> >>>>>>   ...
> >>>>>>    m->priv_size = rte_mempool_get_privsize(m->pool);
> >>>>>>    m->buf _addr= rte_mbuf_to_baddr(m);
> >>>>>>    ...
> >>>>>> }
> >>>>>>
> >>>>>> Also I think we need to provide a way to specify priv_size for all mbufs of the mepool at init time:
> >>>>>> - either force people to specify it at rte_mempool_create() time (probably use init_arg for that),
> >>>>>> - or provide separate function that could be called straight after rte_mempool_create() , that
> >>>>>> would setup priv_size for the  pool and for all its mbufs.
> >>>>>> - or some sort of combination of these 2 approaches - introduce a wrapper function
> >>>>>> (rte_mbuf_pool_create() or something) that would take priv_size as parameter,
> >>>>>> create a new mempool and then setup priv_size.
> >>>>
> >>>> I though a bit more about this solution, and I realized that doing
> >>>> mi->priv_size = md->priv_size in rte_pktmbuf_attach() is probably not
> >>>> a good idea, as there is no garantee that the size of mi is large enough
> >>>> to store the priv of md.
> >>>>
> >>>> Having the same priv_size for mi and md is maybe a good constraint.
> >>>> I can add this in the API comments and assertions in the code to
> >>>> check this condition, what do you think?
> >>>
> >>> Probably we have a different concepts of what is mbuf's  private space in mind.
> >>> From my point, even indirect buffer should use it's own private space and
> >>> leave contents of direct mbuf it attached to unmodified.
> >>> After attach() operation, only contents of the buffer are shared between mbufs,
> >>> but not the mbuf's metadata.
> >>
> >> Sorry if it was not clear in my previous messages, but I agree
> >> with your description. When attaching a mbuf, only data, not
> >> metadata should be shared.
> >>
> >> In the solution you are suggesting (quoted above), you say we need
> >> to set mi->priv_size to md->priv_size in rte_pktmbuf_attach(). I felt
> >> this was not possible, but it depends on the meaning we give to
> >> priv_size:
> >>
> >> 1. If the meaning is "the size of the private data embedded in this
> >>    mbuf", which is the most logical meaning, we cannot do this
> >>    affectation
> >>
> >> 2. If the meaning is "the size of the private data embedded in the
> >>    mbuf the buf_addr is pointing to" (which is harder to get), the
> >>    affectation makes sense.
> >>
> >> From what I understand, you feel we should use 2/ as priv_size
> >> definition. Is it correct?
> >
> > Yes, I meant 2.
> > From my point priv_size inside mbuf is more like 'buf_ofs'.
> > It's main purpose is for internal use - to help our mbuf manipulation routinies
> > (attach/detach/free) to work correctly.
> > If the user wants to query size of private space for the mbuf, he probably should
> > use the value from mempool.
> 
> Agree.
> 
> 
> >> In my previous message, the definition of m->priv_size was 1/,
> >> so that's why I felt assigning mi->priv_size to md->priv_size was
> >> not possible.
> >>
> >> I agree 2/ is probably a good choice, as it would allow to attach
> >> to a mbuf with a different priv_size. It may require some additional
> >> comments above the field in the structure to explain that.
> >>
> >>
> >>> Otherwise on detach(), you'll have to copy contents of private space back, from direct to indirect mbuf?
> >>> Again how to deal with the case, when 2 or more mbufs will attach to the same direct one?
> >>>
> >>> So let say, if we'll have a macro:
> >>>
> >>> #define RTE_MBUF_PRIV_PTR(mb)	((void *)((struct rte_mbuf *)(mb)) + 1))
> >>>
> >>> No matter is mb  a direct or indirect mbuf.
> >>> Do you have something else in mind here?
> >>
> >> I completely agree with this macro. We should consider the private data
> >> as an extension of the mbuf structure.
> >>
> >>
> >>>>> Introducing rte_mbuf_pool_create() seems a good idea to me, it
> >>>>> would hide 'rte_pktmbuf_pool_private' from the user and force
> >>>>> to initialize all the required fields (mbuf_data_room_size only
> >>>>> today, and maybe mbuf_priv_size).
> >>>>>
> >>>>> The API would be:
> >>>>>
> >>>>> struct rte_mempool *
> >>>>> rte_mbuf_pool_create(const char *name, unsigned n, unsigned elt_size,
> >>>>> 	unsigned cache_size, size_t mbuf_priv_size,
> >>>>> 	rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg,
> >>>>> 	int socket_id, unsigned flags)
> >>>>>
> >>>>> I can give it a try and send a patch for this.
> >>>>
> >>>> About this, it is not required anymore for this patch series if we
> >>>> agree with my comment above.
> >>>
> >>> I still think we need some way to setup priv_size on a per-mempool basis.
> >>> Doing that in rte_mbuf_pool_create() seems like a good thing to me.
> >>> Not sure, why you decided to drop it?
> >>
> >> I think we can already do it without changing the API by providing
> >> our own rte_pktmbuf_init and rte_pktmbuf_pool_init.
> >>
> >> rte_pktmbuf_init() has to set:
> >>   m->buf_len = mp->elt_size - sizeof(struct mbuf);
> >>   m->priv_size = sizeof(struct mbuf) - sizeof(struct rte_mbuf);
> >>
> >> rte_pktmbuf_pool_init() has to set:
> >>   /* we can use the default function */
> >>   mbp_priv->mbuf_data_room_size = MBUF_RXDATA_SIZE +
> >>   	RTE_PKTMBUF_HEADROOM;
> >
> > Yeh, when  arg==NULL for rte_pktmbuf_pool_init() we always set up
> > mbuf_data_room_size to the hardcoded value.
> > Which always looked strange to me.
> > I think it should be set to:
> > mp->elt_size - sizeof(struct rte_mbuf) - RTE_PKTMBUF_HEADROOM;
> > for that case.
> 
> Yes, that would make more sense instead of the hardcoded value.
> But I'm not sure it should be part of this series as the clone
> patches won't change this behavior. I would prefer to have it in
> another series that reworks mbuf pool initialization. I can also
> work on it.
> 
> On the other hand if you really feel this patch is needed in
> this series, it's not a problem as it's a one-liner.
> 
> >
> >>
> >> In this case, it is possible to calculate the mbuf_priv_size only
> >> from the pool object:
> >>
> >>   mbuf_priv_size = pool->elt_size - RTE_PKTMBUF_HEADROOM -
> >> 	pool_private->mbuf_data_room_size -
> >> 	sizeof(rte_mbuf)
> >>
> >
> > So if I understand your idea correctly:
> > If  second parameter for rte_pktmbuf_pool_init() is NULL, then
> > we setup
> >
> > mbp_priv->mbuf_data_room_size = mp->elt_size - sizeof(struct rte_mbuf) - RTE_PKTMBUF_HEADROOM;
> >
> > Which means that  priv_size ==0  for all  mbufs in the pool
> > Otherwise we setup:
> >
> >  mbp_priv->mbuf_data_room_size = opaque_arg;
> >
> > As we are doing now, and priv_size for all mbufs in the pool will be:
> > pool->elt_size - pool_private->mbuf_data_room_size - sizeof(rte_mbuf);
> >
> > And in that case, all users have to do to specify priv_size for mempool is to pass a proper argument
> > for rte_pktmbuf_pool_init() at  mempool_create().
> > Correct?
> 
> Correct.
> 
> 
> 
> >
> >>
> >> I agree it's not ideal, but I think the mbuf pool initialization
> >> is another problem. That's why I suggested to change this in a
> >> separate series that will add rte_mbuf_pool_create() with the
> >> API described above. Thoughts?
> >>
> >
> > I also put answers to another mail below.
> > Just to keep all discussion in one place.
> >
> >>> Though, I still think that the better approach is to reserve private space before struct rte_mbuf, not after.
> >>> In that case, user got his private space, and we keep buf_addr straight after  rte_mbuf, without any whole.
> >>> So we don't need steps 2 and 3, above,
> >>> plus we don't need rte_mbuf_to_baddr() and rte_mbuf_from_indirect() -
> >>> RTE_MBUF_TO_BADDR/ RTE_MBUF_FROM_BADDR would keep working correctly.
> >>> In fact, with this scheme - we don't even need priv_size for mbuf management (attach/detach/free).
> >>>
> >>> Wonder did you try that approach?
> >>
> >> Yes, I though about this approach too. But I think it would require
> >> more changes. When an application or a driver allocate a mbuf with
> >> mempool_get(), it expects that the returned pointer is the rte_mbuf *.
> >
> > Yep, sure it will still get the pointer to the rte_mbuf *.
> > Though later, if upper layer would like to convert from  rte_mbuf* to app_specific_mbuf *,
> > it would have to use a macro:
> >
> > #define RTE_MBUF_TO_PRIV(m)	((void *)((uintptr_t)(m) - (m)->priv_size))
> >
> >>
> >> With this solution, there are 2 options:
> >> - no mempool modification, so each application/driver has to add
> >>   priv_size bytes to the object to get the mbuf pointer. This does not
> >>   look feasible.
> >> - change the mempool to support private area before each object. I
> >>   think mempool API is already quite complex, and I think it's not
> >>   the role of the mempool library to provide such features.
> >
> >
> > In fact, I think the changes would be minimal.
> > All we have to do, is to make changes in rte_pktmbuf_init():
> >
> > void
> > rte_pktmbuf_init(struct rte_mempool *mp,
> >                  __attribute__((unused)) void *opaque_arg,
> >                  void *_m,
> >                  __attribute__((unused)) unsigned i)
> > {
> >
> >      //extract priv_size from mempool   (discussed above).
> >       uint16_t priv_size = rte_mbufpool_get_priv_size(mp);
> >
> >       struct rte_mbuf *m = _m + priv_size;
> >       uint32_t buf_len = mp->elt_size - sizeof(struct rte_mbuf) - priv_size;
> >
> > ....
> >
> >
> > With that way priv_size inside mbuf would always be the size its own private space,
> > for both direct and indirect mbus., so we don't require to set priv_size at attach/detach.
> > Again RTE_MBUF_TO_BADDR() and RTE_MBUF_FROM_BADDR() would just work without any modifications.
> 
> I'm not sure I'm getting it. The argument '_m' of your
> rte_pktmbuf_init() is the pointer to the priv data, right?
> So it means that the mbuf is located priv_size bytes after.
> 
> The rte_pktmbuf_init() function is called by mempool_create(),
> and the _m parameter is a pointer to a mempool object. So
> in my understanding, mempool_get() would not return a rte_mbuf
> but a pointer to the application private data.

Ah my bad, forgot that mempool's obj_init() returns void now :(
To make this approach work also need to change it, so it return a pointer to the new object. 
So, rte_pktmbuf_init() would return m and then in mempool_add_elem():

if (obj_init)
                obj = obj_init(mp, obj_init_arg, obj, obj_idx);

rte_ring_sp_enqueue(mp->ring, obj); 

Konstantin

> 
> 
> Regards,
> Olivier
> 
> 
> 
> >
> > Konstantin
> >
> >

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-30 23:17                   ` Ananyev, Konstantin
@ 2015-03-31 19:01                     ` Olivier MATZ
  2015-04-01 13:48                       ` Ananyev, Konstantin
  0 siblings, 1 reply; 101+ messages in thread
From: Olivier MATZ @ 2015-03-31 19:01 UTC (permalink / raw)
  To: Ananyev, Konstantin; +Cc: dev

Hi Konstantin,

On 03/31/2015 01:17 AM, Ananyev, Konstantin wrote:
>>>> With this solution, there are 2 options:
>>>> - no mempool modification, so each application/driver has to add
>>>>   priv_size bytes to the object to get the mbuf pointer. This does not
>>>>   look feasible.
>>>> - change the mempool to support private area before each object. I
>>>>   think mempool API is already quite complex, and I think it's not
>>>>   the role of the mempool library to provide such features.
>>>
>>>
>>> In fact, I think the changes would be minimal.
>>> All we have to do, is to make changes in rte_pktmbuf_init():
>>>
>>> void
>>> rte_pktmbuf_init(struct rte_mempool *mp,
>>>                  __attribute__((unused)) void *opaque_arg,
>>>                  void *_m,
>>>                  __attribute__((unused)) unsigned i)
>>> {
>>>
>>>      //extract priv_size from mempool   (discussed above).
>>>       uint16_t priv_size = rte_mbufpool_get_priv_size(mp);
>>>
>>>       struct rte_mbuf *m = _m + priv_size;
>>>       uint32_t buf_len = mp->elt_size - sizeof(struct rte_mbuf) - priv_size;
>>>
>>> ....
>>>
>>>
>>> With that way priv_size inside mbuf would always be the size its own private space,
>>> for both direct and indirect mbus., so we don't require to set priv_size at attach/detach.
>>> Again RTE_MBUF_TO_BADDR() and RTE_MBUF_FROM_BADDR() would just work without any modifications.
>>
>> I'm not sure I'm getting it. The argument '_m' of your
>> rte_pktmbuf_init() is the pointer to the priv data, right?
>> So it means that the mbuf is located priv_size bytes after.
>>
>> The rte_pktmbuf_init() function is called by mempool_create(),
>> and the _m parameter is a pointer to a mempool object. So
>> in my understanding, mempool_get() would not return a rte_mbuf
>> but a pointer to the application private data.
> 
> Ah my bad, forgot that mempool's obj_init() returns void now :(
> To make this approach work also need to change it, so it return a pointer to the new object. 
> So, rte_pktmbuf_init() would return m and then in mempool_add_elem():
> 
> if (obj_init)
>                 obj = obj_init(mp, obj_init_arg, obj, obj_idx);
> 
> rte_ring_sp_enqueue(mp->ring, obj); 

Yes, but modififying mempool is what I wanted to avoid for several
reasons. First, I think that changing the mempool_create() API here
(actually the obj_init prototype) would impact existing applications.

Also, I'm afraid that storing a different address than the start
address of the object would have additional impacts. For instance,
some data is supposed to be stored before the object, see
__mempool_from_obj() or mempool_obj_audit().

Finally, I believe that mempool is not the proper place to do
modifications that are only needed for mbufs. If we really want
to implement mbuf private data in that way, maybe it would be
better to add a new layer above mempool (a mbuf pool layer).


Regards
Olivier

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v3 0/5] mbuf: enhancements of mbuf clones
  2015-03-26 15:59 ` [dpdk-dev] [PATCH v2 0/5] mbuf: enhancements of mbuf clones Olivier Matz
                     ` (4 preceding siblings ...)
  2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 5/5] test/mbuf: verify that cloning a clone works properly Olivier Matz
@ 2015-03-31 19:22   ` Olivier Matz
  2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
                       ` (4 more replies)
  5 siblings, 5 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-31 19:22 UTC (permalink / raw)
  To: dev

This series fixes the support of indirect mbufs when the application
reserves a private area in mbufs. This is done adding a new field
in each mbuf storing the size of this private area. Another option
would have been to store that in the mbuf pool private info, but
as we have enough room in mbuf, it's faster to have it in the mbuf.

The series also removes the limitation that rte_pktmbuf_clone() is
only allowed on direct (non-cloned) mbufs.

Changes in v3:
- a mbuf can now attach to another one that have a different private
  size. In this case, the m->priv_size corresponds to the size of the
  private area of the direct mbuf.
- add comments to reflect these changes
- minor style modifications

Changes in v2:
- do not change the use of MBUF_EXT_MEM() in vhost
- change rte_mbuf_from_baddr() to rte_mbuf_from_indirect(), removing
  one parameter
- fix and rework rte_pktmbuf_detach()
- move m->priv_size in second mbuf cache line
- fix mbuf free in test error case

Olivier Matz (5):
  mbuf: fix clone support when application uses private mbuf data
  mbuf: allow to clone an indirect mbuf
  test/mbuf: rename mc variable in m
  test/mbuf: enhance mbuf refcnt test
  test/mbuf: verify that cloning a clone works properly

 app/test-pmd/testpmd.c     |   1 +
 app/test/test_mbuf.c       |  88 +++++++++++++++++++++++++++-----
 examples/vhost/main.c      |   4 +-
 lib/librte_mbuf/rte_mbuf.c |   1 +
 lib/librte_mbuf/rte_mbuf.h | 123 +++++++++++++++++++++++++++++++--------------
 5 files changed, 164 insertions(+), 53 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-31 19:22   ` [dpdk-dev] [PATCH v3 0/5] mbuf: enhancements of mbuf clones Olivier Matz
@ 2015-03-31 19:23     ` Olivier Matz
  2015-04-02 14:32       ` Zoltan Kiss
                         ` (2 more replies)
  2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 2/5] mbuf: allow to clone an indirect mbuf Olivier Matz
                       ` (3 subsequent siblings)
  4 siblings, 3 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-31 19:23 UTC (permalink / raw)
  To: dev

From: Olivier Matz <olivier.matz@6wind.com>

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 <olivier.matz@6wind.com>
---
 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);
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v3 2/5] mbuf: allow to clone an indirect mbuf
  2015-03-31 19:22   ` [dpdk-dev] [PATCH v3 0/5] mbuf: enhancements of mbuf clones Olivier Matz
  2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
@ 2015-03-31 19:23     ` Olivier Matz
  2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 3/5] test/mbuf: rename mc variable in m Olivier Matz
                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-31 19:23 UTC (permalink / raw)
  To: dev

From: Olivier Matz <olivier.matz@6wind.com>

Remove one limitation of rte_pktmbuf_attach(): "mbuf we're attaching to
must be direct".

Now, when we attach to an indirect mbuf:
- copy the all relevant fields (addr, len, offload, ...) as before
- get the pointer to the mbuf that embeds the data buffer (direct mbuf),
  and increase the reference counter of this one.

When detaching the mbuf, we can retrieve this direct mbuf as the pointer
is determined from the buffer address.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_mbuf/rte_mbuf.h | 48 ++++++++++++++++++++++++++--------------------
 1 file changed, 27 insertions(+), 21 deletions(-)

diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 932fe58..ca6be88 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -725,44 +725,50 @@ static inline struct rte_mbuf *rte_pktmbuf_alloc(struct rte_mempool *mp)
  * After attachment we refer the mbuf we attached as 'indirect',
  * while mbuf we attached to as 'direct'.
  * Right now, not supported:
- *  - attachment to indirect mbuf (e.g. - md  has to be direct).
  *  - attachment for already indirect mbuf (e.g. - mi has to be direct).
  *  - mbuf we trying to attach (mi) is used by someone else
  *    e.g. it's reference counter is greater then 1.
  *
  * @param mi
  *   The indirect packet mbuf.
- * @param md
- *   The direct packet mbuf.
+ * @param m
+ *   The packet mbuf we're attaching to.
  */
-static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md)
+static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
 {
-	RTE_MBUF_ASSERT(RTE_MBUF_DIRECT(md) &&
-	    RTE_MBUF_DIRECT(mi) &&
+	struct rte_mbuf *md;
+
+	RTE_MBUF_ASSERT(RTE_MBUF_DIRECT(mi) &&
 	    rte_mbuf_refcnt_read(mi) == 1);
 
+	/* if m is not direct, get the mbuf that embeds the data */
+	if (RTE_MBUF_DIRECT(m))
+		md = m;
+	else
+		md = rte_mbuf_from_indirect(m);
+
 	rte_mbuf_refcnt_update(md, 1);
-	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;
-	mi->data_len = md->data_len;
-	mi->port = md->port;
-	mi->vlan_tci = md->vlan_tci;
-	mi->tx_offload = md->tx_offload;
-	mi->hash = md->hash;
+	mi->buf_physaddr = m->buf_physaddr;
+	mi->buf_addr = m->buf_addr;
+	mi->buf_len = m->buf_len;
+	mi->priv_size = m->priv_size;
+
+	mi->next = m->next;
+	mi->data_off = m->data_off;
+	mi->data_len = m->data_len;
+	mi->port = m->port;
+	mi->vlan_tci = m->vlan_tci;
+	mi->tx_offload = m->tx_offload;
+	mi->hash = m->hash;
 
 	mi->next = NULL;
 	mi->pkt_len = mi->data_len;
 	mi->nb_segs = 1;
-	mi->ol_flags = md->ol_flags | IND_ATTACHED_MBUF;
-	mi->packet_type = md->packet_type;
+	mi->ol_flags = m->ol_flags | IND_ATTACHED_MBUF;
+	mi->packet_type = m->packet_type;
 
 	__rte_mbuf_sanity_check(mi, 1);
-	__rte_mbuf_sanity_check(md, 0);
+	__rte_mbuf_sanity_check(m, 0);
 }
 
 /**
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v3 3/5] test/mbuf: rename mc variable in m
  2015-03-31 19:22   ` [dpdk-dev] [PATCH v3 0/5] mbuf: enhancements of mbuf clones Olivier Matz
  2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
  2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 2/5] mbuf: allow to clone an indirect mbuf Olivier Matz
@ 2015-03-31 19:23     ` Olivier Matz
  2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 4/5] test/mbuf: enhance mbuf refcnt test Olivier Matz
  2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 5/5] test/mbuf: verify that cloning a clone works properly Olivier Matz
  4 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-31 19:23 UTC (permalink / raw)
  To: dev

From: Olivier Matz <olivier.matz@6wind.com>

It's better to name the mbuf 'm' instead of 'mc' as it's not a clone.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 1ff66cb..9a3cf8f 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -321,43 +321,42 @@ fail:
 static int
 testclone_testupdate_testdetach(void)
 {
-	struct rte_mbuf *mc = NULL;
+	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
 
 	/* alloc a mbuf */
-
-	mc = rte_pktmbuf_alloc(pktmbuf_pool);
-	if (mc == NULL)
+	m = rte_pktmbuf_alloc(pktmbuf_pool);
+	if (m == NULL)
 		GOTO_FAIL("ooops not allocating mbuf");
 
-	if (rte_pktmbuf_pkt_len(mc) != 0)
+	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("Bad length");
 
 
 	/* clone the allocated mbuf */
-	clone = rte_pktmbuf_clone(mc, pktmbuf_pool);
+	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 	rte_pktmbuf_free(clone);
 
-	mc->next = rte_pktmbuf_alloc(pktmbuf_pool);
-	if(mc->next == NULL)
+	m->next = rte_pktmbuf_alloc(pktmbuf_pool);
+	if (m->next == NULL)
 		GOTO_FAIL("Next Pkt Null\n");
 
-	clone = rte_pktmbuf_clone(mc, pktmbuf_pool);
+	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 
 	/* free mbuf */
-	rte_pktmbuf_free(mc);
+	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
-	mc = NULL;
+	m = NULL;
 	clone = NULL;
 	return 0;
 
 fail:
-	if (mc)
-		rte_pktmbuf_free(mc);
+	if (m)
+		rte_pktmbuf_free(m);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v3 4/5] test/mbuf: enhance mbuf refcnt test
  2015-03-31 19:22   ` [dpdk-dev] [PATCH v3 0/5] mbuf: enhancements of mbuf clones Olivier Matz
                       ` (2 preceding siblings ...)
  2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 3/5] test/mbuf: rename mc variable in m Olivier Matz
@ 2015-03-31 19:23     ` Olivier Matz
  2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 5/5] test/mbuf: verify that cloning a clone works properly Olivier Matz
  4 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-31 19:23 UTC (permalink / raw)
  To: dev

From: Olivier Matz <olivier.matz@6wind.com>

Check that the data in the cloned mbuf is the same than in the
reference mbuf.
Check that the reference counter is incremented for each segment.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 9a3cf8f..9d8ee4e 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -76,6 +76,8 @@
 #define REFCNT_MBUF_SIZE        (sizeof (struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
 #define REFCNT_RING_SIZE        (REFCNT_MBUF_NUM * REFCNT_MAX_REF)
 
+#define MAGIC_DATA              0x42424242
+
 #define MAKE_STRING(x)          # x
 
 static struct rte_mempool *pktmbuf_pool = NULL;
@@ -323,6 +325,7 @@ testclone_testupdate_testdetach(void)
 {
 	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
+	uint32_t *data;
 
 	/* alloc a mbuf */
 	m = rte_pktmbuf_alloc(pktmbuf_pool);
@@ -332,21 +335,53 @@ testclone_testupdate_testdetach(void)
 	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("Bad length");
 
+	rte_pktmbuf_append(m, sizeof(uint32_t));
+	data = rte_pktmbuf_mtod(m, uint32_t *);
+	*data = MAGIC_DATA;
 
 	/* clone the allocated mbuf */
 	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
+
+	data = rte_pktmbuf_mtod(clone, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone\n");
+
+	if (rte_mbuf_refcnt_read(m) != 2)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	/* free the clone */
 	rte_pktmbuf_free(clone);
+	clone = NULL;
 
+	/* same test with a chained mbuf */
 	m->next = rte_pktmbuf_alloc(pktmbuf_pool);
 	if (m->next == NULL)
 		GOTO_FAIL("Next Pkt Null\n");
 
+	rte_pktmbuf_append(m->next, sizeof(uint32_t));
+	data = rte_pktmbuf_mtod(m->next, uint32_t *);
+	*data = MAGIC_DATA;
+
 	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 
+	data = rte_pktmbuf_mtod(clone, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone\n");
+
+	data = rte_pktmbuf_mtod(clone->next, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone->next\n");
+
+	if (rte_mbuf_refcnt_read(m) != 2)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	if (rte_mbuf_refcnt_read(m->next) != 2)
+		GOTO_FAIL("invalid refcnt in m->next\n");
+
 	/* free mbuf */
 	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
@@ -357,6 +392,8 @@ testclone_testupdate_testdetach(void)
 fail:
 	if (m)
 		rte_pktmbuf_free(m);
+	if (clone)
+		rte_pktmbuf_free(clone);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v3 5/5] test/mbuf: verify that cloning a clone works properly
  2015-03-31 19:22   ` [dpdk-dev] [PATCH v3 0/5] mbuf: enhancements of mbuf clones Olivier Matz
                       ` (3 preceding siblings ...)
  2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 4/5] test/mbuf: enhance mbuf refcnt test Olivier Matz
@ 2015-03-31 19:23     ` Olivier Matz
  4 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-03-31 19:23 UTC (permalink / raw)
  To: dev

From: Olivier Matz <olivier.matz@6wind.com>

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 9d8ee4e..e59aedc 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -325,6 +325,7 @@ testclone_testupdate_testdetach(void)
 {
 	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
+	struct rte_mbuf *clone2 = NULL;
 	uint32_t *data;
 
 	/* alloc a mbuf */
@@ -382,11 +383,34 @@ testclone_testupdate_testdetach(void)
 	if (rte_mbuf_refcnt_read(m->next) != 2)
 		GOTO_FAIL("invalid refcnt in m->next\n");
 
+	/* try to clone the clone */
+
+	clone2 = rte_pktmbuf_clone(clone, pktmbuf_pool);
+	if (clone2 == NULL)
+		GOTO_FAIL("cannot clone the clone\n");
+
+	data = rte_pktmbuf_mtod(clone2, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone2\n");
+
+	data = rte_pktmbuf_mtod(clone2->next, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone2->next\n");
+
+	if (rte_mbuf_refcnt_read(m) != 3)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	if (rte_mbuf_refcnt_read(m->next) != 3)
+		GOTO_FAIL("invalid refcnt in m->next\n");
+
 	/* free mbuf */
 	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
+	rte_pktmbuf_free(clone2);
+
 	m = NULL;
 	clone = NULL;
+	clone2 = NULL;
 	return 0;
 
 fail:
@@ -394,6 +418,8 @@ fail:
 		rte_pktmbuf_free(m);
 	if (clone)
 		rte_pktmbuf_free(clone);
+	if (clone2)
+		rte_pktmbuf_free(clone2);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-31 19:01                     ` Olivier MATZ
@ 2015-04-01 13:48                       ` Ananyev, Konstantin
  2015-04-01 15:18                         ` Olivier MATZ
  0 siblings, 1 reply; 101+ messages in thread
From: Ananyev, Konstantin @ 2015-04-01 13:48 UTC (permalink / raw)
  To: Olivier MATZ; +Cc: dev



> -----Original Message-----
> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> Sent: Tuesday, March 31, 2015 8:01 PM
> To: Ananyev, Konstantin
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
> 
> Hi Konstantin,
> 
> On 03/31/2015 01:17 AM, Ananyev, Konstantin wrote:
> >>>> With this solution, there are 2 options:
> >>>> - no mempool modification, so each application/driver has to add
> >>>>   priv_size bytes to the object to get the mbuf pointer. This does not
> >>>>   look feasible.
> >>>> - change the mempool to support private area before each object. I
> >>>>   think mempool API is already quite complex, and I think it's not
> >>>>   the role of the mempool library to provide such features.
> >>>
> >>>
> >>> In fact, I think the changes would be minimal.
> >>> All we have to do, is to make changes in rte_pktmbuf_init():
> >>>
> >>> void
> >>> rte_pktmbuf_init(struct rte_mempool *mp,
> >>>                  __attribute__((unused)) void *opaque_arg,
> >>>                  void *_m,
> >>>                  __attribute__((unused)) unsigned i)
> >>> {
> >>>
> >>>      //extract priv_size from mempool   (discussed above).
> >>>       uint16_t priv_size = rte_mbufpool_get_priv_size(mp);
> >>>
> >>>       struct rte_mbuf *m = _m + priv_size;
> >>>       uint32_t buf_len = mp->elt_size - sizeof(struct rte_mbuf) - priv_size;
> >>>
> >>> ....
> >>>
> >>>
> >>> With that way priv_size inside mbuf would always be the size its own private space,
> >>> for both direct and indirect mbus., so we don't require to set priv_size at attach/detach.
> >>> Again RTE_MBUF_TO_BADDR() and RTE_MBUF_FROM_BADDR() would just work without any modifications.
> >>
> >> I'm not sure I'm getting it. The argument '_m' of your
> >> rte_pktmbuf_init() is the pointer to the priv data, right?
> >> So it means that the mbuf is located priv_size bytes after.
> >>
> >> The rte_pktmbuf_init() function is called by mempool_create(),
> >> and the _m parameter is a pointer to a mempool object. So
> >> in my understanding, mempool_get() would not return a rte_mbuf
> >> but a pointer to the application private data.
> >
> > Ah my bad, forgot that mempool's obj_init() returns void now :(
> > To make this approach work also need to change it, so it return a pointer to the new object.
> > So, rte_pktmbuf_init() would return m and then in mempool_add_elem():
> >
> > if (obj_init)
> >                 obj = obj_init(mp, obj_init_arg, obj, obj_idx);
> >
> > rte_ring_sp_enqueue(mp->ring, obj);
> 
> Yes, but modififying mempool is what I wanted to avoid for several
> reasons. First, I think that changing the mempool_create() API here
> (actually the obj_init prototype) would impact existing applications.
> 
> Also, I'm afraid that storing a different address than the start
> address of the object would have additional impacts. For instance,
> some data is supposed to be stored before the object, see
> __mempool_from_obj() or mempool_obj_audit().

mempool_obj_audit() should be ok, I think, but yes -
rte_mempool_from_obj() would change the behaviour and
can't be used by mempool_obj_audit() anymore.

Ok, I am convinced - let's stick with private space between rte_mbuf and buf_adddr, as you suggested.  

> 
> Finally, I believe that mempool is not the proper place to do
> modifications that are only needed for mbufs. If we really want
> to implement mbuf private data in that way, maybe it would be
> better to add a new layer above mempool (a mbuf pool layer).

Not that I am against it, but seems like even more massive change -
every application would need to be changed to use rte_mbufpool_create(), no?

Konstantin

> 
> 
> Regards
> Olivier

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-04-01 13:48                       ` Ananyev, Konstantin
@ 2015-04-01 15:18                         ` Olivier MATZ
  0 siblings, 0 replies; 101+ messages in thread
From: Olivier MATZ @ 2015-04-01 15:18 UTC (permalink / raw)
  To: Ananyev, Konstantin; +Cc: dev

Hi,

On 04/01/2015 03:48 PM, Ananyev, Konstantin wrote:
>>>>>> With this solution, there are 2 options:
>>>>>> - no mempool modification, so each application/driver has to add
>>>>>>   priv_size bytes to the object to get the mbuf pointer. This does not
>>>>>>   look feasible.
>>>>>> - change the mempool to support private area before each object. I
>>>>>>   think mempool API is already quite complex, and I think it's not
>>>>>>   the role of the mempool library to provide such features.
>>>>>
>>>>>
>>>>> In fact, I think the changes would be minimal.
>>>>> All we have to do, is to make changes in rte_pktmbuf_init():
>>>>>
>>>>> void
>>>>> rte_pktmbuf_init(struct rte_mempool *mp,
>>>>>                  __attribute__((unused)) void *opaque_arg,
>>>>>                  void *_m,
>>>>>                  __attribute__((unused)) unsigned i)
>>>>> {
>>>>>
>>>>>      //extract priv_size from mempool   (discussed above).
>>>>>       uint16_t priv_size = rte_mbufpool_get_priv_size(mp);
>>>>>
>>>>>       struct rte_mbuf *m = _m + priv_size;
>>>>>       uint32_t buf_len = mp->elt_size - sizeof(struct rte_mbuf) - priv_size;
>>>>>
>>>>> ....
>>>>>
>>>>>
>>>>> With that way priv_size inside mbuf would always be the size its own private space,
>>>>> for both direct and indirect mbus., so we don't require to set priv_size at attach/detach.
>>>>> Again RTE_MBUF_TO_BADDR() and RTE_MBUF_FROM_BADDR() would just work without any modifications.
>>>>
>>>> I'm not sure I'm getting it. The argument '_m' of your
>>>> rte_pktmbuf_init() is the pointer to the priv data, right?
>>>> So it means that the mbuf is located priv_size bytes after.
>>>>
>>>> The rte_pktmbuf_init() function is called by mempool_create(),
>>>> and the _m parameter is a pointer to a mempool object. So
>>>> in my understanding, mempool_get() would not return a rte_mbuf
>>>> but a pointer to the application private data.
>>>
>>> Ah my bad, forgot that mempool's obj_init() returns void now :(
>>> To make this approach work also need to change it, so it return a pointer to the new object.
>>> So, rte_pktmbuf_init() would return m and then in mempool_add_elem():
>>>
>>> if (obj_init)
>>>                 obj = obj_init(mp, obj_init_arg, obj, obj_idx);
>>>
>>> rte_ring_sp_enqueue(mp->ring, obj);
>>
>> Yes, but modififying mempool is what I wanted to avoid for several
>> reasons. First, I think that changing the mempool_create() API here
>> (actually the obj_init prototype) would impact existing applications.
>>
>> Also, I'm afraid that storing a different address than the start
>> address of the object would have additional impacts. For instance,
>> some data is supposed to be stored before the object, see
>> __mempool_from_obj() or mempool_obj_audit().
> 
> mempool_obj_audit() should be ok, I think, but yes -
> rte_mempool_from_obj() would change the behaviour and
> can't be used by mempool_obj_audit() anymore.
> 
> Ok, I am convinced - let's stick with private space between rte_mbuf and buf_adddr, as you suggested.  
> 
>>
>> Finally, I believe that mempool is not the proper place to do
>> modifications that are only needed for mbufs. If we really want
>> to implement mbuf private data in that way, maybe it would be
>> better to add a new layer above mempool (a mbuf pool layer).
> 
> Not that I am against it, but seems like even more massive change -
> every application would need to be changed to use rte_mbufpool_create(), no?

Yes, indeed that would be a significant change for the applications,
which is probably not what we want, except if we can keep backward
compatibility. Maybe it's possible. That's something to keep in mind
if I send a patch series that introduce a new rte_mbuf_pool_create()
function.

Regards,
Olivier

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
@ 2015-04-02 14:32       ` Zoltan Kiss
  2015-04-02 17:21       ` Ananyev, Konstantin
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
  2 siblings, 0 replies; 101+ messages in thread
From: Zoltan Kiss @ 2015-04-02 14:32 UTC (permalink / raw)
  To: Olivier Matz, dev



On 31/03/15 20:23, Olivier Matz wrote:
> From: Olivier Matz <olivier.matz@6wind.com>
>
> 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 <olivier.matz@6wind.com>
Reviewed-by: Zoltan Kiss <zoltan.kiss@linaro.org>

I assume the rest of the series haven't changed apart from occasional 
rebasing, I've reviewed them earlier.

> ---
>   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);
>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
  2015-04-02 14:32       ` Zoltan Kiss
@ 2015-04-02 17:21       ` Ananyev, Konstantin
  2015-04-06 21:49         ` Olivier MATZ
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
  2 siblings, 1 reply; 101+ messages in thread
From: Ananyev, Konstantin @ 2015-04-02 17:21 UTC (permalink / raw)
  To: Olivier Matz, dev

Hi Olivier,

> -----Original Message-----
> From: Olivier Matz [mailto:olivier.matz@6wind.com]
> Sent: Tuesday, March 31, 2015 8:23 PM
> To: dev@dpdk.org
> Cc: Ananyev, Konstantin; zoltan.kiss@linaro.org; Richardson, Bruce; Olivier Matz
> Subject: [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
> 
> From: Olivier Matz <olivier.matz@6wind.com>
> 
> 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 <olivier.matz@6wind.com>
> ---
>  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;

Why it is 0?
Shouldn't it be the same calulations as in detach() below:
m->priv_size = /*get private size from mempool private*/;
m->buf_addr = (char *)m + sizeof(struct rte_mbuf) + m->priv_size;
m->buf_len = mp->elt_size - sizeof(struct rte_mbuf) - m->priv_size;
?

BTW, don't see changes in rte_pktmbuf_pool_init() to setup
mbp_priv->mbuf_data_room_size properly.
Without that changes, how can people start using that feature?
It seems that the only way now - setup priv_size and buf_len for each mbuf manually.

>  }
> 
>  /* 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);

(uintptr_t)mi->buf_addr?

> +       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 *

Might be better to return 'void *' here.

> +rte_mbuf_to_baddr(struct rte_mbuf *md)
> +{
> +       char *buffer_addr;

uintptr_t 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);

I think it is better to put this priv_size calculation above into the separate function -
rte_mbuf_get_priv_size(m) or something.
We need it in few places, and users would probably need it anyway. 

> +
> +	buf = rte_mbuf_to_baddr(m);
> +	mhdr_size = (char *)buf - (char *)m;

Why do you need to recalculate mhdr_size here?
As I understand it is a m->priv_size, and you just retrieved it, 2 lines above.

> +	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mhdr_size;

Actually I think could just be:
m->buf_physaddr = rte_mempool_virt2phy(mp, buf);

>  	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);
> --
> 2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-04-02 17:21       ` Ananyev, Konstantin
@ 2015-04-06 21:49         ` Olivier MATZ
  2015-04-07 12:40           ` Ananyev, Konstantin
  0 siblings, 1 reply; 101+ messages in thread
From: Olivier MATZ @ 2015-04-06 21:49 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

Thanks for your comments.

On 04/02/2015 07:21 PM, Ananyev, Konstantin wrote:
> Hi Olivier,
> 
>> -----Original Message-----
>> From: Olivier Matz [mailto:olivier.matz@6wind.com]
>> Sent: Tuesday, March 31, 2015 8:23 PM
>> To: dev@dpdk.org
>> Cc: Ananyev, Konstantin; zoltan.kiss@linaro.org; Richardson, Bruce; Olivier Matz
>> Subject: [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
>>
>> From: Olivier Matz <olivier.matz@6wind.com>
>>
>> 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 <olivier.matz@6wind.com>
>> ---
>>  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;
> 
> Why it is 0?
> Shouldn't it be the same calulations as in detach() below:
> m->priv_size = /*get private size from mempool private*/;
> m->buf_addr = (char *)m + sizeof(struct rte_mbuf) + m->priv_size;
> m->buf_len = mp->elt_size - sizeof(struct rte_mbuf) - m->priv_size;
> ?

It's 0 because we also have in the function (not visible in the
patch):

  m->buf_addr = (char *)m + sizeof(struct rte_mbuf);

It means that an application that wants to use a private area has
to provide another init function derived from this default function.
This was already the case before the patch series.

As we discussed in previous mail, I plan to propose a rework of
mbuf pool initialization in another series, and my initial idea was to
change this at the same time. But on the other hand it does not hurt
to do this change now. I'll include it in next version.


> BTW, don't see changes in rte_pktmbuf_pool_init() to setup
> mbp_priv->mbuf_data_room_size properly.
> Without that changes, how can people start using that feature?
> It seems that the only way now - setup priv_size and buf_len for each mbuf manually.

It's the same reason than above. To use a private are, the user has
to provide its own function that sets up data_room_size, derived from
this pool_init default function. This was also the case before the
patch series.


> 
>>  }
>>
>>  /* 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);
> 
> (uintptr_t)mi->buf_addr?

Any clue why (uintptr_t) would be better than (char *) ?
By the way, I added this cast because it would not compile with
g++ (and probably with icc too).

> 
>> +       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 *
> 
> Might be better to return 'void *' here.

Ok, as m->buf_addr is a (void *).

> 
>> +rte_mbuf_to_baddr(struct rte_mbuf *md)
>> +{
>> +       char *buffer_addr;
> 
> uintptr_t buffer_addr? 

Same question than above, I don't really see why it's better than
(char *).

> 
>> +       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);
> 
> I think it is better to put this priv_size calculation above into the separate function -
> rte_mbuf_get_priv_size(m) or something.
> We need it in few places, and users would probably need it anyway.

yep, good idea

> 
>> +
>> +	buf = rte_mbuf_to_baddr(m);
>> +	mhdr_size = (char *)buf - (char *)m;
> 
> Why do you need to recalculate mhdr_size here?
> As I understand it is a m->priv_size, and you just retrieved it, 2 lines above.
> 

It's not m->priv_size but (sizeof(rte_mbuf) + m->priv_size).
In both case, it requires an operation, but maybe
  mhdr_size = (sizeof(rte_mbuf) + m->priv_size)
is clearer than
  mhdr_size = (char *)buf - (char *)m


>> +	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mhdr_size;
> 
> Actually I think could just be:
> m->buf_physaddr = rte_mempool_virt2phy(mp, buf);

Even if it would work, the API of rte_mempool_virt2phy()
says that the second argument should be "A pointer (virtual address)
to the element of the pool."
I think we should keep the initial code.

Regards,
Olivier

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-04-06 21:49         ` Olivier MATZ
@ 2015-04-07 12:40           ` Ananyev, Konstantin
  2015-04-07 15:45             ` Olivier MATZ
  0 siblings, 1 reply; 101+ messages in thread
From: Ananyev, Konstantin @ 2015-04-07 12:40 UTC (permalink / raw)
  To: Olivier MATZ, dev

Hi Olivier,

> -----Original Message-----
> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> Sent: Monday, April 06, 2015 10:50 PM
> To: Ananyev, Konstantin; dev@dpdk.org
> Cc: zoltan.kiss@linaro.org; Richardson, Bruce
> Subject: Re: [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
> 
> Hi Konstantin,
> 
> Thanks for your comments.
> 
> On 04/02/2015 07:21 PM, Ananyev, Konstantin wrote:
> > Hi Olivier,
> >
> >> -----Original Message-----
> >> From: Olivier Matz [mailto:olivier.matz@6wind.com]
> >> Sent: Tuesday, March 31, 2015 8:23 PM
> >> To: dev@dpdk.org
> >> Cc: Ananyev, Konstantin; zoltan.kiss@linaro.org; Richardson, Bruce; Olivier Matz
> >> Subject: [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
> >>
> >> From: Olivier Matz <olivier.matz@6wind.com>
> >>
> >> 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 <olivier.matz@6wind.com>
> >> ---
> >>  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;
> >
> > Why it is 0?
> > Shouldn't it be the same calulations as in detach() below:
> > m->priv_size = /*get private size from mempool private*/;
> > m->buf_addr = (char *)m + sizeof(struct rte_mbuf) + m->priv_size;
> > m->buf_len = mp->elt_size - sizeof(struct rte_mbuf) - m->priv_size;
> > ?
> 
> It's 0 because we also have in the function (not visible in the
> patch):
> 
>   m->buf_addr = (char *)m + sizeof(struct rte_mbuf);

Yep, that's why as I wrote above, I think we need to setup here all 3 fields:
priv_size, buf_addr, buf_len exactly in the same way as in detach().  

> 
> It means that an application that wants to use a private area has
> to provide another init function derived from this default function.

After your changes, attach/free and other functions from public mbuf API
rely on priv_size being set properly.
So I suppose 'official' pktmbuf_init() should also set it in a proper manner. 

> This was already the case before the patch series.

Before this patch series, we don't have priv_size, so we have nothing to setup.

> 
> As we discussed in previous mail, I plan to propose a rework of
> mbuf pool initialization in another series, and my initial idea was to
> change this at the same time. But on the other hand it does not hurt
> to do this change now. I'll include it in next version.

Ok.

> 
> 
> > BTW, don't see changes in rte_pktmbuf_pool_init() to setup
> > mbp_priv->mbuf_data_room_size properly.
> > Without that changes, how can people start using that feature?
> > It seems that the only way now - setup priv_size and buf_len for each mbuf manually.
> 
> It's the same reason than above. To use a private are, the user has
> to provide its own function that sets up data_room_size, derived from
> this pool_init default function. This was also the case before the
> patch series.
> 
> 
> >
> >>  }
> >>
> >>  /* 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);
> >
> > (uintptr_t)mi->buf_addr?
> 
> Any clue why (uintptr_t) would be better than (char *) ?

No big difference really, just looks a bit better to me :)

> By the way, I added this cast because it would not compile with
> g++ (and probably with icc too).
> 
> >
> >> +       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 *
> >
> > Might be better to return 'void *' here.
> 
> Ok, as m->buf_addr is a (void *).
> 
> >
> >> +rte_mbuf_to_baddr(struct rte_mbuf *md)
> >> +{
> >> +       char *buffer_addr;
> >
> > uintptr_t buffer_addr?
> 
> Same question than above, I don't really see why it's better than
> (char *).
> 
> >
> >> +       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);
> >
> > I think it is better to put this priv_size calculation above into the separate function -
> > rte_mbuf_get_priv_size(m) or something.
> > We need it in few places, and users would probably need it anyway.
> 
> yep, good idea
> 
> >
> >> +
> >> +	buf = rte_mbuf_to_baddr(m);
> >> +	mhdr_size = (char *)buf - (char *)m;
> >
> > Why do you need to recalculate mhdr_size here?
> > As I understand it is a m->priv_size, and you just retrieved it, 2 lines above.
> >
> 
> It's not m->priv_size but (sizeof(rte_mbuf) + m->priv_size).

Ah yes, sorry for confusion.

> In both case, it requires an operation, but maybe
>   mhdr_size = (sizeof(rte_mbuf) + m->priv_size)
> is clearer than
>   mhdr_size = (char *)buf - (char *)m
> 
> 
> >> +	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mhdr_size;
> >
> > Actually I think could just be:
> > m->buf_physaddr = rte_mempool_virt2phy(mp, buf);
> 
> Even if it would work, the API of rte_mempool_virt2phy()
> says that the second argument should be "A pointer (virtual address)
> to the element of the pool."
> I think we should keep the initial code.

Ok.
Konstantin

> 
> Regards,
> Olivier
> 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-04-07 12:40           ` Ananyev, Konstantin
@ 2015-04-07 15:45             ` Olivier MATZ
  2015-04-07 17:17               ` Ananyev, Konstantin
  0 siblings, 1 reply; 101+ messages in thread
From: Olivier MATZ @ 2015-04-07 15:45 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

On 04/07/2015 02:40 PM, Ananyev, Konstantin wrote:
> Hi Olivier,
>
>> -----Original Message-----
>> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
>> Sent: Monday, April 06, 2015 10:50 PM
>> To: Ananyev, Konstantin; dev@dpdk.org
>> Cc: zoltan.kiss@linaro.org; Richardson, Bruce
>> Subject: Re: [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
>>
>> Hi Konstantin,
>>
>> Thanks for your comments.
>>
>> On 04/02/2015 07:21 PM, Ananyev, Konstantin wrote:
>>> Hi Olivier,
>>>
>>>> -----Original Message-----
>>>> From: Olivier Matz [mailto:olivier.matz@6wind.com]
>>>> Sent: Tuesday, March 31, 2015 8:23 PM
>>>> To: dev@dpdk.org
>>>> Cc: Ananyev, Konstantin; zoltan.kiss@linaro.org; Richardson, Bruce; Olivier Matz
>>>> Subject: [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
>>>>
>>>> From: Olivier Matz <olivier.matz@6wind.com>
>>>>
>>>> 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 <olivier.matz@6wind.com>
>>>> ---
>>>>   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;
>>>
>>> Why it is 0?
>>> Shouldn't it be the same calulations as in detach() below:
>>> m->priv_size = /*get private size from mempool private*/;
>>> m->buf_addr = (char *)m + sizeof(struct rte_mbuf) + m->priv_size;
>>> m->buf_len = mp->elt_size - sizeof(struct rte_mbuf) - m->priv_size;
>>> ?
>>
>> It's 0 because we also have in the function (not visible in the
>> patch):
>>
>>    m->buf_addr = (char *)m + sizeof(struct rte_mbuf);
>
> Yep, that's why as I wrote above, I think we need to setup here all 3 fields:
> priv_size, buf_addr, buf_len exactly in the same way as in detach().
>
>>
>> It means that an application that wants to use a private area has
>> to provide another init function derived from this default function.
>
> After your changes, attach/free and other functions from public mbuf API
> rely on priv_size being set properly.
> So I suppose 'official' pktmbuf_init() should also set it in a proper manner.
>
>> This was already the case before the patch series.
>
> Before this patch series, we don't have priv_size, so we have nothing to setup.
>
>>
>> As we discussed in previous mail, I plan to propose a rework of
>> mbuf pool initialization in another series, and my initial idea was to
>> change this at the same time. But on the other hand it does not hurt
>> to do this change now. I'll include it in next version.
>
> Ok.

Just to be sure we're on the same line:

- before the patch series

   - private area was working before that patch series if clones were not
     used. To use a private are, the user had to provide another
     function derived from pktmbuf_init() to change m->buf_addr and
     m->buf_len.
   - using both private area + clones was broken

- after the patch series

   - private area is working with or without clone. But yo use it,
     the user still has to provide another function to change
     m->buf_addr, m->buf_len *and m->priv_size*.

The series just fixes the fact that "clones + priv" was not working.
It does not address the problem that providing a new pktmbuf_init()
function is required to use privata area. To fix this, I think it
could require a API evolution that should be part of another series.

I'll send a v4 addressing the comments soon, thanks.

Regards,
Olivier



>
>>
>>
>>> BTW, don't see changes in rte_pktmbuf_pool_init() to setup
>>> mbp_priv->mbuf_data_room_size properly.
>>> Without that changes, how can people start using that feature?
>>> It seems that the only way now - setup priv_size and buf_len for each mbuf manually.
>>
>> It's the same reason than above. To use a private are, the user has
>> to provide its own function that sets up data_room_size, derived from
>> this pool_init default function. This was also the case before the
>> patch series.
>>
>>
>>>
>>>>   }
>>>>
>>>>   /* 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);
>>>
>>> (uintptr_t)mi->buf_addr?
>>
>> Any clue why (uintptr_t) would be better than (char *) ?
>
> No big difference really, just looks a bit better to me :)
>
>> By the way, I added this cast because it would not compile with
>> g++ (and probably with icc too).
>>
>>>
>>>> +       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 *
>>>
>>> Might be better to return 'void *' here.
>>
>> Ok, as m->buf_addr is a (void *).
>>
>>>
>>>> +rte_mbuf_to_baddr(struct rte_mbuf *md)
>>>> +{
>>>> +       char *buffer_addr;
>>>
>>> uintptr_t buffer_addr?
>>
>> Same question than above, I don't really see why it's better than
>> (char *).
>>
>>>
>>>> +       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);
>>>
>>> I think it is better to put this priv_size calculation above into the separate function -
>>> rte_mbuf_get_priv_size(m) or something.
>>> We need it in few places, and users would probably need it anyway.
>>
>> yep, good idea
>>
>>>
>>>> +
>>>> +	buf = rte_mbuf_to_baddr(m);
>>>> +	mhdr_size = (char *)buf - (char *)m;
>>>
>>> Why do you need to recalculate mhdr_size here?
>>> As I understand it is a m->priv_size, and you just retrieved it, 2 lines above.
>>>
>>
>> It's not m->priv_size but (sizeof(rte_mbuf) + m->priv_size).
>
> Ah yes, sorry for confusion.
>
>> In both case, it requires an operation, but maybe
>>    mhdr_size = (sizeof(rte_mbuf) + m->priv_size)
>> is clearer than
>>    mhdr_size = (char *)buf - (char *)m
>>
>>
>>>> +	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mhdr_size;
>>>
>>> Actually I think could just be:
>>> m->buf_physaddr = rte_mempool_virt2phy(mp, buf);
>>
>> Even if it would work, the API of rte_mempool_virt2phy()
>> says that the second argument should be "A pointer (virtual address)
>> to the element of the pool."
>> I think we should keep the initial code.
>
> Ok.
> Konstantin
>
>>
>> Regards,
>> Olivier
>>
>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-04-07 15:45             ` Olivier MATZ
@ 2015-04-07 17:17               ` Ananyev, Konstantin
  2015-04-08  9:44                 ` Olivier MATZ
  0 siblings, 1 reply; 101+ messages in thread
From: Ananyev, Konstantin @ 2015-04-07 17:17 UTC (permalink / raw)
  To: Olivier MATZ, dev

Hi Olivier,

> -----Original Message-----
> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> Sent: Tuesday, April 07, 2015 4:46 PM
> To: Ananyev, Konstantin; dev@dpdk.org
> Cc: zoltan.kiss@linaro.org; Richardson, Bruce
> Subject: Re: [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
> 
> Hi Konstantin,
> 
> On 04/07/2015 02:40 PM, Ananyev, Konstantin wrote:
> > Hi Olivier,
> >
> >> -----Original Message-----
> >> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> >> Sent: Monday, April 06, 2015 10:50 PM
> >> To: Ananyev, Konstantin; dev@dpdk.org
> >> Cc: zoltan.kiss@linaro.org; Richardson, Bruce
> >> Subject: Re: [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
> >>
> >> Hi Konstantin,
> >>
> >> Thanks for your comments.
> >>
> >> On 04/02/2015 07:21 PM, Ananyev, Konstantin wrote:
> >>> Hi Olivier,
> >>>
> >>>> -----Original Message-----
> >>>> From: Olivier Matz [mailto:olivier.matz@6wind.com]
> >>>> Sent: Tuesday, March 31, 2015 8:23 PM
> >>>> To: dev@dpdk.org
> >>>> Cc: Ananyev, Konstantin; zoltan.kiss@linaro.org; Richardson, Bruce; Olivier Matz
> >>>> Subject: [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
> >>>>
> >>>> From: Olivier Matz <olivier.matz@6wind.com>
> >>>>
> >>>> 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 <olivier.matz@6wind.com>
> >>>> ---
> >>>>   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;
> >>>
> >>> Why it is 0?
> >>> Shouldn't it be the same calulations as in detach() below:
> >>> m->priv_size = /*get private size from mempool private*/;
> >>> m->buf_addr = (char *)m + sizeof(struct rte_mbuf) + m->priv_size;
> >>> m->buf_len = mp->elt_size - sizeof(struct rte_mbuf) - m->priv_size;
> >>> ?
> >>
> >> It's 0 because we also have in the function (not visible in the
> >> patch):
> >>
> >>    m->buf_addr = (char *)m + sizeof(struct rte_mbuf);
> >
> > Yep, that's why as I wrote above, I think we need to setup here all 3 fields:
> > priv_size, buf_addr, buf_len exactly in the same way as in detach().
> >
> >>
> >> It means that an application that wants to use a private area has
> >> to provide another init function derived from this default function.
> >
> > After your changes, attach/free and other functions from public mbuf API
> > rely on priv_size being set properly.
> > So I suppose 'official' pktmbuf_init() should also set it in a proper manner.
> >
> >> This was already the case before the patch series.
> >
> > Before this patch series, we don't have priv_size, so we have nothing to setup.
> >
> >>
> >> As we discussed in previous mail, I plan to propose a rework of
> >> mbuf pool initialization in another series, and my initial idea was to
> >> change this at the same time. But on the other hand it does not hurt
> >> to do this change now. I'll include it in next version.
> >
> > Ok.
> 
> Just to be sure we're on the same line:
> 
> - before the patch series
> 
>    - private area was working before that patch series if clones were not
>      used. To use a private are, the user had to provide another
>      function derived from pktmbuf_init() to change m->buf_addr and
>      m->buf_len.
>    - using both private area + clones was broken
> 
> - after the patch series
> 
>    - private area is working with or without clone. But yo use it,
>      the user still has to provide another function to change
>      m->buf_addr, m->buf_len *and m->priv_size*.
> 
> The series just fixes the fact that "clones + priv" was not working.
> It does not address the problem that providing a new pktmbuf_init()
> function is required to use privata area. To fix this, I think it
> could require a API evolution that should be part of another series.

I don't think we need new pktmbuf_init().
We just need to update it, so both pktmbuf_init() and detach() setup
buf_addr, buf_len (and priv_size) to exactly the same values.
If they don't do that, it means that you can't use attach/detach with
mempools created with pktmbuf_init() any more.

BTW, another thing that I just realised:
examples/ipv4_multicast and examples/ip_fragmentation/ -
both create a pool of mbufs with elem_size < 2K and don't populate mempool's private area -
so mbp_priv->mbuf_data_room_size == 0, for them. 

So that code in detach():

 +	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);


Would break both these samples.
I suppose we need to handle situation when mp->elt_size < RTE_PKTMBUF_HEADROOM + sizeof(struct rte_mbuf),
(and probably also when mbuf_data_room_size == 0) correctly. 

Konstantin


> 
> I'll send a v4 addressing the comments soon, thanks.
> 
> Regards,
> Olivier
> 
> 
> 
> >
> >>
> >>
> >>> BTW, don't see changes in rte_pktmbuf_pool_init() to setup
> >>> mbp_priv->mbuf_data_room_size properly.
> >>> Without that changes, how can people start using that feature?
> >>> It seems that the only way now - setup priv_size and buf_len for each mbuf manually.
> >>
> >> It's the same reason than above. To use a private are, the user has
> >> to provide its own function that sets up data_room_size, derived from
> >> this pool_init default function. This was also the case before the
> >> patch series.
> >>
> >>
> >>>
> >>>>   }
> >>>>
> >>>>   /* 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);
> >>>
> >>> (uintptr_t)mi->buf_addr?
> >>
> >> Any clue why (uintptr_t) would be better than (char *) ?
> >
> > No big difference really, just looks a bit better to me :)
> >
> >> By the way, I added this cast because it would not compile with
> >> g++ (and probably with icc too).
> >>
> >>>
> >>>> +       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 *
> >>>
> >>> Might be better to return 'void *' here.
> >>
> >> Ok, as m->buf_addr is a (void *).
> >>
> >>>
> >>>> +rte_mbuf_to_baddr(struct rte_mbuf *md)
> >>>> +{
> >>>> +       char *buffer_addr;
> >>>
> >>> uintptr_t buffer_addr?
> >>
> >> Same question than above, I don't really see why it's better than
> >> (char *).
> >>
> >>>
> >>>> +       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);
> >>>
> >>> I think it is better to put this priv_size calculation above into the separate function -
> >>> rte_mbuf_get_priv_size(m) or something.
> >>> We need it in few places, and users would probably need it anyway.
> >>
> >> yep, good idea
> >>
> >>>
> >>>> +
> >>>> +	buf = rte_mbuf_to_baddr(m);
> >>>> +	mhdr_size = (char *)buf - (char *)m;
> >>>
> >>> Why do you need to recalculate mhdr_size here?
> >>> As I understand it is a m->priv_size, and you just retrieved it, 2 lines above.
> >>>
> >>
> >> It's not m->priv_size but (sizeof(rte_mbuf) + m->priv_size).
> >
> > Ah yes, sorry for confusion.
> >
> >> In both case, it requires an operation, but maybe
> >>    mhdr_size = (sizeof(rte_mbuf) + m->priv_size)
> >> is clearer than
> >>    mhdr_size = (char *)buf - (char *)m
> >>
> >>
> >>>> +	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mhdr_size;
> >>>
> >>> Actually I think could just be:
> >>> m->buf_physaddr = rte_mempool_virt2phy(mp, buf);
> >>
> >> Even if it would work, the API of rte_mempool_virt2phy()
> >> says that the second argument should be "A pointer (virtual address)
> >> to the element of the pool."
> >> I think we should keep the initial code.
> >
> > Ok.
> > Konstantin
> >
> >>
> >> Regards,
> >> Olivier
> >>
> >

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-04-07 17:17               ` Ananyev, Konstantin
@ 2015-04-08  9:44                 ` Olivier MATZ
  2015-04-08 13:45                   ` Ananyev, Konstantin
  0 siblings, 1 reply; 101+ messages in thread
From: Olivier MATZ @ 2015-04-08  9:44 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

On 04/07/2015 07:17 PM, Ananyev, Konstantin wrote:
>> Just to be sure we're on the same line:
>>
>> - before the patch series
>>
>>     - private area was working before that patch series if clones were not
>>       used. To use a private are, the user had to provide another
>>       function derived from pktmbuf_init() to change m->buf_addr and
>>       m->buf_len.
>>     - using both private area + clones was broken
>>
>> - after the patch series
>>
>>     - private area is working with or without clone. But yo use it,
>>       the user still has to provide another function to change
>>       m->buf_addr, m->buf_len *and m->priv_size*.
>>
>> The series just fixes the fact that "clones + priv" was not working.
>> It does not address the problem that providing a new pktmbuf_init()
>> function is required to use privata area. To fix this, I think it
>> could require a API evolution that should be part of another series.
>
> I don't think we need new pktmbuf_init().
> We just need to update it, so both pktmbuf_init() and detach() setup
> buf_addr, buf_len (and priv_size) to exactly the same values.
> If they don't do that, it means that you can't use attach/detach with
> mempools created with pktmbuf_init() any more.
>
> BTW, another thing that I just realised:
> examples/ipv4_multicast and examples/ip_fragmentation/ -
> both create a pool of mbufs with elem_size < 2K and don't populate mempool's private area -
> so mbp_priv->mbuf_data_room_size == 0, for them.
>
> So that code in detach():
>
>   +	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);
>
>
> Would break both these samples.
> I suppose we need to handle situation when mp->elt_size < RTE_PKTMBUF_HEADROOM + sizeof(struct rte_mbuf),
> (and probably also when mbuf_data_room_size == 0) correctly.

Indeed. I think a mbuf pool (even with buf_len == 0 like in
ip_fragmentation example) should have a pool with a private area and
should call rte_pktmbuf_pool_init() to populate it. So
rte_pktmbuf_pool_init() has to be fixed first to use elt_size
and support the buf_len < RTE_PKTMBUF_HEADROOM, then we can
update frag/multicast examples.

Unfortunately, we don't know the size of the mbuf private area
in rte_pktmbuf_pool_init() if the opaque arg (data_room_size)
is 0, which is the default. I think it should be replaced by a structure
containing data_room_size and mbuf_priv_size, but it would break
applications that are setting data_room_size. I don't see any good
solution to do that while keeping a backward compatibility for
rte_pktmbuf_pool_init(), but as the current API is not ideal,
I think it's worth changing it and add something in the release
note.

We may also want to introduce a new helper as discussed previously:

struct rte_mempool *
rte_pktmbuf_pool_create(const char *name, unsigned n, unsigned elt_size,
	unsigned cache_size, size_t mbuf_priv_size,
	rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg,
	int socket_id, unsigned flags)

Any comment?


>
> Konstantin

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-04-08  9:44                 ` Olivier MATZ
@ 2015-04-08 13:45                   ` Ananyev, Konstantin
  2015-04-09 13:06                     ` Olivier MATZ
  0 siblings, 1 reply; 101+ messages in thread
From: Ananyev, Konstantin @ 2015-04-08 13:45 UTC (permalink / raw)
  To: Olivier MATZ, dev

Hi Olivier,

> -----Original Message-----
> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> Sent: Wednesday, April 08, 2015 10:44 AM
> To: Ananyev, Konstantin; dev@dpdk.org
> Cc: zoltan.kiss@linaro.org; Richardson, Bruce
> Subject: Re: [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
> 
> Hi Konstantin,
> 
> On 04/07/2015 07:17 PM, Ananyev, Konstantin wrote:
> >> Just to be sure we're on the same line:
> >>
> >> - before the patch series
> >>
> >>     - private area was working before that patch series if clones were not
> >>       used. To use a private are, the user had to provide another
> >>       function derived from pktmbuf_init() to change m->buf_addr and
> >>       m->buf_len.
> >>     - using both private area + clones was broken
> >>
> >> - after the patch series
> >>
> >>     - private area is working with or without clone. But yo use it,
> >>       the user still has to provide another function to change
> >>       m->buf_addr, m->buf_len *and m->priv_size*.
> >>
> >> The series just fixes the fact that "clones + priv" was not working.
> >> It does not address the problem that providing a new pktmbuf_init()
> >> function is required to use privata area. To fix this, I think it
> >> could require a API evolution that should be part of another series.
> >
> > I don't think we need new pktmbuf_init().
> > We just need to update it, so both pktmbuf_init() and detach() setup
> > buf_addr, buf_len (and priv_size) to exactly the same values.
> > If they don't do that, it means that you can't use attach/detach with
> > mempools created with pktmbuf_init() any more.
> >
> > BTW, another thing that I just realised:
> > examples/ipv4_multicast and examples/ip_fragmentation/ -
> > both create a pool of mbufs with elem_size < 2K and don't populate mempool's private area -
> > so mbp_priv->mbuf_data_room_size == 0, for them.
> >
> > So that code in detach():
> >
> >   +	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);
> >
> >
> > Would break both these samples.
> > I suppose we need to handle situation when mp->elt_size < RTE_PKTMBUF_HEADROOM + sizeof(struct rte_mbuf),
> > (and probably also when mbuf_data_room_size == 0) correctly.
> 
> Indeed. I think a mbuf pool (even with buf_len == 0 like in
> ip_fragmentation example) should have a pool with a private area and
> should call rte_pktmbuf_pool_init() to populate it. So
> rte_pktmbuf_pool_init() has to be fixed first to use elt_size
> and support the buf_len < RTE_PKTMBUF_HEADROOM, then we can
> update frag/multicast examples.
> 
> Unfortunately, we don't know the size of the mbuf private area
> in rte_pktmbuf_pool_init() if the opaque arg (data_room_size)
> is 0, which is the default. I think it should be replaced by a structure
> containing data_room_size and mbuf_priv_size, but it would break
> applications that are setting data_room_size.

Yes, same thoughts here.

> I don't see any good
> solution to do that while keeping a backward compatibility for
> rte_pktmbuf_pool_init(), but as the current API is not ideal,
> I think it's worth changing it and add something in the release
> note.

If no one else has a better alternative than that, then I suppose it is good enough. 

> 
> We may also want to introduce a new helper as discussed previously:
> 
> struct rte_mempool *
> rte_pktmbuf_pool_create(const char *name, unsigned n, unsigned elt_size,
> 	unsigned cache_size, size_t mbuf_priv_size,
> 	rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg,
> 	int socket_id, unsigned flags)
> 
> Any comment?

Looks good to me.
Should we also introduce rte_pktmbuf_pool_xmem_create()? 
Konstantin

> 
> 
> >
> > Konstantin

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
  2015-04-08 13:45                   ` Ananyev, Konstantin
@ 2015-04-09 13:06                     ` Olivier MATZ
  0 siblings, 0 replies; 101+ messages in thread
From: Olivier MATZ @ 2015-04-09 13:06 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

On 04/08/2015 03:45 PM, Ananyev, Konstantin wrote:
> Hi Olivier,
>
>> -----Original Message-----
>> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
>> Sent: Wednesday, April 08, 2015 10:44 AM
>> To: Ananyev, Konstantin; dev@dpdk.org
>> Cc: zoltan.kiss@linaro.org; Richardson, Bruce
>> Subject: Re: [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data
>>
>> Hi Konstantin,
>>
>> On 04/07/2015 07:17 PM, Ananyev, Konstantin wrote:
>>>> Just to be sure we're on the same line:
>>>>
>>>> - before the patch series
>>>>
>>>>      - private area was working before that patch series if clones were not
>>>>        used. To use a private are, the user had to provide another
>>>>        function derived from pktmbuf_init() to change m->buf_addr and
>>>>        m->buf_len.
>>>>      - using both private area + clones was broken
>>>>
>>>> - after the patch series
>>>>
>>>>      - private area is working with or without clone. But yo use it,
>>>>        the user still has to provide another function to change
>>>>        m->buf_addr, m->buf_len *and m->priv_size*.
>>>>
>>>> The series just fixes the fact that "clones + priv" was not working.
>>>> It does not address the problem that providing a new pktmbuf_init()
>>>> function is required to use privata area. To fix this, I think it
>>>> could require a API evolution that should be part of another series.
>>>
>>> I don't think we need new pktmbuf_init().
>>> We just need to update it, so both pktmbuf_init() and detach() setup
>>> buf_addr, buf_len (and priv_size) to exactly the same values.
>>> If they don't do that, it means that you can't use attach/detach with
>>> mempools created with pktmbuf_init() any more.
>>>
>>> BTW, another thing that I just realised:
>>> examples/ipv4_multicast and examples/ip_fragmentation/ -
>>> both create a pool of mbufs with elem_size < 2K and don't populate mempool's private area -
>>> so mbp_priv->mbuf_data_room_size == 0, for them.
>>>
>>> So that code in detach():
>>>
>>>    +	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);
>>>
>>>
>>> Would break both these samples.
>>> I suppose we need to handle situation when mp->elt_size < RTE_PKTMBUF_HEADROOM + sizeof(struct rte_mbuf),
>>> (and probably also when mbuf_data_room_size == 0) correctly.
>>
>> Indeed. I think a mbuf pool (even with buf_len == 0 like in
>> ip_fragmentation example) should have a pool with a private area and
>> should call rte_pktmbuf_pool_init() to populate it. So
>> rte_pktmbuf_pool_init() has to be fixed first to use elt_size
>> and support the buf_len < RTE_PKTMBUF_HEADROOM, then we can
>> update frag/multicast examples.
>>
>> Unfortunately, we don't know the size of the mbuf private area
>> in rte_pktmbuf_pool_init() if the opaque arg (data_room_size)
>> is 0, which is the default. I think it should be replaced by a structure
>> containing data_room_size and mbuf_priv_size, but it would break
>> applications that are setting data_room_size.
>
> Yes, same thoughts here.
>
>> I don't see any good
>> solution to do that while keeping a backward compatibility for
>> rte_pktmbuf_pool_init(), but as the current API is not ideal,
>> I think it's worth changing it and add something in the release
>> note.
>
> If no one else has a better alternative than that, then I suppose it is good enough.
>
>>
>> We may also want to introduce a new helper as discussed previously:
>>
>> struct rte_mempool *
>> rte_pktmbuf_pool_create(const char *name, unsigned n, unsigned elt_size,
>> 	unsigned cache_size, size_t mbuf_priv_size,
>> 	rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg,
>> 	int socket_id, unsigned flags)
>>
>> Any comment?
>
> Looks good to me.
> Should we also introduce rte_pktmbuf_pool_xmem_create()?

Hmmm as it's only used in one place, I'm not sure it's really
required. As the previous way to create mbuf pool using
rte_mempool_create() will still work, I think we could consider
it's a special case. If it becomes necessary, there's no problem
to add it later.

Olivier



> Konstantin
>
>>
>>
>>>
>>> Konstantin
>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones
  2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
  2015-04-02 14:32       ` Zoltan Kiss
  2015-04-02 17:21       ` Ananyev, Konstantin
@ 2015-04-20 15:41       ` Olivier Matz
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 01/12] mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init Olivier Matz
                           ` (13 more replies)
  2 siblings, 14 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-20 15:41 UTC (permalink / raw)
  To: dev

The first objective of this series is to fix the support of indirect
mbufs when the application reserves a private area in mbufs. It also
removes the limitation that rte_pktmbuf_clone() is only allowed on
direct (non-cloned) mbufs. The series also contains some enhancements
and fixes in the mbuf area that makes the implementation of the
last patches easier.

Changes in v4:
- do not add a priv_size in mbuf structure, having a proper accessor
  to read it from the pool private area is clearer
- prepend some reworks in the mbuf area to simplify the implementation
  (fix mbuf initialization by not using a hardcoded mbuf size, add
  accessors for mbuf pool private area, add a helper to create a
  mbuf pool)

Changes in v3:
- a mbuf can now attach to another one that have a different private
  size. In this case, the m->priv_size corresponds to the size of the
  private area of the direct mbuf.
- add comments to reflect these changes
- minor style modifications

Changes in v2:
- do not change the use of MBUF_EXT_MEM() in vhost
- change rte_mbuf_from_baddr() to rte_mbuf_from_indirect(), removing
  one parameter
- fix and rework rte_pktmbuf_detach()
- move m->priv_size in second mbuf cache line
- fix mbuf free in test error case


Olivier Matz (12):
  mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
  examples: always initialize mbuf_pool private area
  mbuf: add accessors to get data room size and private size
  mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
  testpmd: use standard functions to initialize mbufs and mbuf pool
  mbuf: introduce a new helper to create a mbuf pool
  apps: use rte_pktmbuf_pool_create to create mbuf pools
  mbuf: fix clone support when application uses private mbuf data
  mbuf: allow to clone an indirect mbuf
  test/mbuf: rename mc variable in m
  test/mbuf: enhance mbuf refcnt test
  test/mbuf: verify that cloning a clone works properly

 app/test-pipeline/init.c                           |  15 +-
 app/test-pmd/testpmd.c                             |  78 +--------
 app/test/test_distributor.c                        |  10 +-
 app/test/test_distributor_perf.c                   |  10 +-
 app/test/test_kni.c                                |  16 +-
 app/test/test_link_bonding.c                       |  10 +-
 app/test/test_link_bonding_mode4.c                 |  12 +-
 app/test/test_mbuf.c                               | 110 +++++++++---
 app/test/test_pmd_perf.c                           |  11 +-
 app/test/test_pmd_ring.c                           |  10 +-
 app/test/test_reorder.c                            |  10 +-
 app/test/test_sched.c                              |  16 +-
 app/test/test_table.c                              |   9 +-
 app/test/test_table.h                              |   3 +-
 doc/guides/rel_notes/updating_apps.rst             |  16 ++
 examples/bond/main.c                               |  10 +-
 examples/distributor/main.c                        |  11 +-
 examples/dpdk_qat/main.c                           |  10 +-
 examples/exception_path/main.c                     |  14 +-
 examples/ip_fragmentation/main.c                   |  18 +-
 examples/ip_pipeline/init.c                        |  28 +--
 examples/ipv4_multicast/main.c                     |  21 +--
 examples/kni/main.c                                |  12 +-
 examples/l2fwd-ivshmem/host/host.c                 |  10 +-
 examples/l2fwd-jobstats/main.c                     |  10 +-
 examples/l2fwd/main.c                              |  11 +-
 examples/l3fwd-acl/main.c                          |  11 +-
 examples/l3fwd-power/main.c                        |  11 +-
 examples/l3fwd-vf/main.c                           |  12 +-
 examples/l3fwd/main.c                              |  10 +-
 examples/link_status_interrupt/main.c              |  10 +-
 examples/load_balancer/init.c                      |  12 +-
 examples/load_balancer/main.h                      |   4 +-
 .../client_server_mp/mp_server/init.c              |  10 +-
 examples/multi_process/symmetric_mp/main.c         |  10 +-
 examples/netmap_compat/bridge/bridge.c             |  12 +-
 examples/packet_ordering/main.c                    |  11 +-
 examples/qos_meter/main.c                          |   7 +-
 examples/qos_sched/init.c                          |  10 +-
 examples/qos_sched/main.h                          |   2 +-
 examples/quota_watermark/include/conf.h            |   2 +-
 examples/quota_watermark/qw/main.c                 |   7 +-
 examples/rxtx_callbacks/main.c                     |  11 +-
 examples/skeleton/basicfwd.c                       |  13 +-
 examples/vhost/main.c                              |  31 ++--
 examples/vhost_xen/main.c                          |  11 +-
 examples/vmdq/main.c                               |  11 +-
 examples/vmdq_dcb/main.c                           |  10 +-
 lib/librte_ether/rte_ethdev.c                      |   4 +-
 lib/librte_mbuf/rte_mbuf.c                         |  63 +++++--
 lib/librte_mbuf/rte_mbuf.h                         | 189 ++++++++++++++++-----
 lib/librte_pmd_af_packet/rte_eth_af_packet.c       |   6 +-
 lib/librte_pmd_bond/rte_eth_bond_alb.c             |  16 +-
 lib/librte_pmd_e1000/em_rxtx.c                     |   5 +-
 lib/librte_pmd_e1000/igb_rxtx.c                    |  12 +-
 lib/librte_pmd_fm10k/fm10k_ethdev.c                |   6 +-
 lib/librte_pmd_i40e/i40e_ethdev_vf.c               |   6 +-
 lib/librte_pmd_i40e/i40e_rxtx.c                    |  15 +-
 lib/librte_pmd_ixgbe/ixgbe_rxtx.c                  |  12 +-
 lib/librte_pmd_pcap/rte_eth_pcap.c                 |   5 +-
 lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c              |   7 +-
 61 files changed, 499 insertions(+), 566 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v4 01/12] mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
@ 2015-04-20 15:41         ` Olivier Matz
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 02/12] examples: always initialize mbuf_pool private area Olivier Matz
                           ` (12 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-20 15:41 UTC (permalink / raw)
  To: dev

Deduct the mbuf data room size from mempool->elt_size and priv_size,
instead of using an hardcoded value that is not related to the real
buffer size.

To use rte_pktmbuf_pool_init(), the user can either:
- give a NULL parameter to rte_pktmbuf_pool_init(): in this case, the
  private size is assumed to be 0, and the room size is
  mp->elt_size - sizeof(struct rte_mbuf).
- give the rte_pktmbuf_pool_private filled with appropriate
  data_room_size and priv_size values.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test-pmd/testpmd.c                 |  1 +
 doc/guides/rel_notes/updating_apps.rst | 12 ++++++++++++
 examples/vhost/main.c                  |  5 ++---
 lib/librte_mbuf/rte_mbuf.c             | 27 ++++++++++++++++++++-------
 lib/librte_mbuf/rte_mbuf.h             |  3 ++-
 5 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 3057791..10e4347 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -443,6 +443,7 @@ testpmd_mbuf_pool_ctor(struct rte_mempool *mp,
 	mbp_ctor_arg = (struct mbuf_pool_ctor_arg *) opaque_arg;
 	mbp_priv = rte_mempool_get_priv(mp);
 	mbp_priv->mbuf_data_room_size = mbp_ctor_arg->seg_buf_size;
+	mbp_priv->mbuf_priv_size = 0;
 }
 
 static void
diff --git a/doc/guides/rel_notes/updating_apps.rst b/doc/guides/rel_notes/updating_apps.rst
index 4dbf268..f513615 100644
--- a/doc/guides/rel_notes/updating_apps.rst
+++ b/doc/guides/rel_notes/updating_apps.rst
@@ -4,6 +4,18 @@ Updating Applications from Previous Versions
 Although backward compatibility is being maintained across DPDK releases, code written for previous versions of the DPDK
 may require some code updates to benefit from performance and user experience enhancements provided in later DPDK releases.
 
+DPDK 2.0 to DPDK 2.1
+--------------------
+
+*   The second argument of rte_pktmbuf_pool_init(mempool, opaque) is now a
+    pointer to a struct rte_pktmbuf_pool_private instead of a uint16_t
+    casted into a pointer. Backward compatibility is preserved when the
+    argument was NULL which is the majority of use cases, but not if the
+    opaque pointer was not NULL, as it is not technically feasible. In
+    this case, the application has to be modified to properly fill a
+    rte_pktmbuf_pool_private structure and pass it to
+    rte_pktmbuf_pool_init().
+
 DPDK 1.7 to DPDK 1.8
 --------------------
 
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index ad10f82..fc73d1e 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -2844,11 +2844,10 @@ static void
 setup_mempool_tbl(int socket, uint32_t index, char *pool_name,
 	char *ring_name, uint32_t nb_mbuf)
 {
-	uint16_t roomsize = VIRTIO_DESCRIPTOR_LEN_ZCP + RTE_PKTMBUF_HEADROOM;
 	vpool_array[index].pool
 		= rte_mempool_create(pool_name, nb_mbuf, MBUF_SIZE_ZCP,
 		MBUF_CACHE_SIZE_ZCP, sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, (void *)(uintptr_t)roomsize,
+		rte_pktmbuf_pool_init, NULL,
 		rte_pktmbuf_init, NULL, socket, 0);
 	if (vpool_array[index].pool != NULL) {
 		vpool_array[index].ring
@@ -2870,7 +2869,7 @@ setup_mempool_tbl(int socket, uint32_t index, char *pool_name,
 		}
 
 		/* Need consider head room. */
-		vpool_array[index].buf_size = roomsize - RTE_PKTMBUF_HEADROOM;
+		vpool_array[index].buf_size = VIRTIO_DESCRIPTOR_LEN_ZCP;
 	} else {
 		rte_exit(EXIT_FAILURE, "mempool_create(%s) failed", pool_name);
 	}
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index 526b18d..231cfb8 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -81,17 +81,30 @@ rte_ctrlmbuf_init(struct rte_mempool *mp,
 void
 rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg)
 {
-	struct rte_pktmbuf_pool_private *mbp_priv;
+	struct rte_pktmbuf_pool_private *user_mbp_priv, *mbp_priv;
+	struct rte_pktmbuf_pool_private default_mbp_priv;
 	uint16_t roomsz;
 
-	mbp_priv = rte_mempool_get_priv(mp);
-	roomsz = (uint16_t)(uintptr_t)opaque_arg;
+	RTE_MBUF_ASSERT(mp->elt_size >= sizeof(struct rte_mbuf));
 
-	/* Use default data room size. */
-	if (0 == roomsz)
-		roomsz = 2048 + RTE_PKTMBUF_HEADROOM;
+	/* if no structure is provided, assume no mbuf private area */
+	user_mbp_priv = opaque_arg;
+	if (user_mbp_priv == NULL) {
+		default_mbp_priv.mbuf_priv_size = 0;
+		if (mp->elt_size > sizeof(struct rte_mbuf))
+			roomsz = mp->elt_size - sizeof(struct rte_mbuf);
+		else
+			roomsz = 0;
+		default_mbp_priv.mbuf_data_room_size = roomsz;
+		user_mbp_priv = &default_mbp_priv;
+	}
 
-	mbp_priv->mbuf_data_room_size = roomsz;
+	RTE_MBUF_ASSERT(mp->elt_size >= sizeof(struct rte_mbuf) +
+		user_mbp_priv->mbuf_data_room_size +
+		user_mbp_priv->mbuf_priv_size);
+
+	mbp_priv = rte_mempool_get_priv(mp);
+	memcpy(mbp_priv, user_mbp_priv, sizeof(*mbp_priv));
 }
 
 /*
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 45f73c2..13fd626 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -348,7 +348,8 @@ struct rte_mbuf {
  * appended after the mempool structure (in private data).
  */
 struct rte_pktmbuf_pool_private {
-	uint16_t mbuf_data_room_size; /**< Size of data space in each mbuf.*/
+	uint16_t mbuf_data_room_size; /**< Size of data space in each mbuf. */
+	uint16_t mbuf_priv_size;      /**< Size of private area in each mbuf. */
 };
 
 #ifdef RTE_LIBRTE_MBUF_DEBUG
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v4 02/12] examples: always initialize mbuf_pool private area
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 01/12] mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init Olivier Matz
@ 2015-04-20 15:41         ` Olivier Matz
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 03/12] mbuf: add accessors to get data room size and private size Olivier Matz
                           ` (11 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-20 15:41 UTC (permalink / raw)
  To: dev

The mbuf pool private area must always be populated in a mbuf pool.
The applications or drivers may expect that for a mbuf pool, the mbuf
pool private area (mbuf_data_room_size and mbuf_priv_size) are
properly filled.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 examples/ip_fragmentation/main.c | 4 ++--
 examples/ip_pipeline/init.c      | 8 ++++++--
 examples/ipv4_multicast/main.c   | 6 ++++--
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 93ea2a1..cf63718 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -764,8 +764,8 @@ init_mem(void)
 
 			mp = rte_mempool_create(buf, NB_MBUF,
 							   sizeof(struct rte_mbuf), 32,
-							   0,
-							   NULL, NULL,
+							   sizeof(struct rte_pktmbuf_pool_private),
+							   rte_pktmbuf_pool_init, NULL,
 							   rte_pktmbuf_init, NULL,
 							   socket, 0);
 			if (mp == NULL) {
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index 96aee2b..61d71c3 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -363,6 +363,8 @@ app_get_ring_resp(uint32_t core_id)
 static void
 app_init_mbuf_pools(void)
 {
+	struct rte_pktmbuf_pool_private indirect_mbp_priv;
+
 	/* Init the buffer pool */
 	RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n");
 	app.pool = rte_mempool_create(
@@ -380,13 +382,15 @@ app_init_mbuf_pools(void)
 
 	/* Init the indirect buffer pool */
 	RTE_LOG(INFO, USER1, "Creating the indirect mbuf pool ...\n");
+	indirect_mbp_priv.mbuf_data_room_size = 0;
+	indirect_mbp_priv.mbuf_priv_size = sizeof(struct app_pkt_metadata);
 	app.indirect_pool = rte_mempool_create(
 		"indirect mempool",
 		app.pool_size,
 		sizeof(struct rte_mbuf) + sizeof(struct app_pkt_metadata),
 		app.pool_cache_size,
-		0,
-		NULL, NULL,
+		sizeof(struct rte_pktmbuf_pool_private),
+		rte_pktmbuf_pool_init, &indirect_mbp_priv,
 		rte_pktmbuf_init, NULL,
 		rte_socket_id(),
 		0);
diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index eed5611..19832d8 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -699,14 +699,16 @@ main(int argc, char **argv)
 		rte_exit(EXIT_FAILURE, "Cannot init packet mbuf pool\n");
 
 	header_pool = rte_mempool_create("header_pool", NB_HDR_MBUF,
-	    HDR_MBUF_SIZE, 32, 0, NULL, NULL, rte_pktmbuf_init, NULL,
+	    HDR_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
+	    rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
 	    rte_socket_id(), 0);
 
 	if (header_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init header mbuf pool\n");
 
 	clone_pool = rte_mempool_create("clone_pool", NB_CLONE_MBUF,
-	    CLONE_MBUF_SIZE, 32, 0, NULL, NULL, rte_pktmbuf_init, NULL,
+	    CLONE_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
+	    rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
 	    rte_socket_id(), 0);
 
 	if (clone_pool == NULL)
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v4 03/12] mbuf: add accessors to get data room size and private size
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 01/12] mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init Olivier Matz
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 02/12] examples: always initialize mbuf_pool private area Olivier Matz
@ 2015-04-20 15:41         ` Olivier Matz
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 04/12] mbuf: fix rte_pktmbuf_init when mbuf private size is not zero Olivier Matz
                           ` (10 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-20 15:41 UTC (permalink / raw)
  To: dev

This code retrieving the pool private area is duplicated in many
places, we can use of function for it.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_ether/rte_ethdev.c                |  4 +--
 lib/librte_mbuf/rte_mbuf.h                   | 41 ++++++++++++++++++++++++++++
 lib/librte_pmd_af_packet/rte_eth_af_packet.c |  6 ++--
 lib/librte_pmd_e1000/em_rxtx.c               |  5 ++--
 lib/librte_pmd_e1000/igb_rxtx.c              | 12 +++-----
 lib/librte_pmd_fm10k/fm10k_ethdev.c          |  6 ++--
 lib/librte_pmd_i40e/i40e_ethdev_vf.c         |  6 ++--
 lib/librte_pmd_i40e/i40e_rxtx.c              | 15 ++++------
 lib/librte_pmd_ixgbe/ixgbe_rxtx.c            | 12 +++-----
 lib/librte_pmd_pcap/rte_eth_pcap.c           |  5 +---
 lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c        |  7 ++---
 11 files changed, 67 insertions(+), 52 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index e20cca5..ff06256 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1439,7 +1439,6 @@ rte_eth_rx_queue_setup(uint8_t port_id, uint16_t rx_queue_id,
 	int ret;
 	uint32_t mbp_buf_size;
 	struct rte_eth_dev *dev;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	struct rte_eth_dev_info dev_info;
 
 	/* This function is only safe when called from the primary process
@@ -1478,8 +1477,7 @@ rte_eth_rx_queue_setup(uint8_t port_id, uint16_t rx_queue_id,
 				(int) sizeof(struct rte_pktmbuf_pool_private));
 		return (-ENOSPC);
 	}
-	mbp_priv = rte_mempool_get_priv(mp);
-	mbp_buf_size = mbp_priv->mbuf_data_room_size;
+	mbp_buf_size = rte_pktmbuf_data_room_size(mp);
 
 	if ((mbp_buf_size - RTE_PKTMBUF_HEADROOM) < dev_info.min_rx_bufsize) {
 		PMD_DEBUG_TRACE("%s mbuf_data_room_size %d < %d "
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 13fd626..a4146fa 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -642,6 +642,47 @@ void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg,
 void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
 
 /**
+ * Get the data room size of mbufs stored in a pktmbuf_pool
+ *
+ * The data room size is the amount of data that can be stored in a
+ * mbuf including the headroom (RTE_PKTMBUF_HEADROOM).
+ *
+ * @param mp
+ *   The packet mbuf pool.
+ * @return
+ *   The data room size of mbufs stored in this mempool.
+ */
+static inline uint16_t
+rte_pktmbuf_data_room_size(struct rte_mempool *mp)
+{
+	struct rte_pktmbuf_pool_private *mbp_priv;
+
+	mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
+	return mbp_priv->mbuf_data_room_size;
+}
+
+/**
+ * Get the application private size of mbufs stored in a pktmbuf_pool
+ *
+ * The private size of mbuf is a zone located between the rte_mbuf
+ * structure and the data buffer where an application can store data
+ * associated to a packet.
+ *
+ * @param mp
+ *   The packet mbuf pool.
+ * @return
+ *   The private size of mbufs stored in this mempool.
+ */
+static inline uint16_t
+rte_pktmbuf_priv_size(struct rte_mempool *mp)
+{
+	struct rte_pktmbuf_pool_private *mbp_priv;
+
+	mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
+	return mbp_priv->mbuf_priv_size;
+}
+
+/**
  * Reset the fields of a packet mbuf to their default values.
  *
  * The given mbuf must have only one segment.
diff --git a/lib/librte_pmd_af_packet/rte_eth_af_packet.c b/lib/librte_pmd_af_packet/rte_eth_af_packet.c
index f7e9ec9..bdd9628 100644
--- a/lib/librte_pmd_af_packet/rte_eth_af_packet.c
+++ b/lib/librte_pmd_af_packet/rte_eth_af_packet.c
@@ -348,15 +348,13 @@ eth_rx_queue_setup(struct rte_eth_dev *dev,
 {
 	struct pmd_internals *internals = dev->data->dev_private;
 	struct pkt_rx_queue *pkt_q = &internals->rx_queue[rx_queue_id];
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint16_t buf_size;
 
 	pkt_q->mb_pool = mb_pool;
 
 	/* Now get the space available for data in the mbuf */
-	mbp_priv = rte_mempool_get_priv(pkt_q->mb_pool);
-	buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-	                       RTE_PKTMBUF_HEADROOM);
+	buf_size = (uint16_t)(rte_pktmbuf_data_room_size(pkt_q->mb_pool) -
+		RTE_PKTMBUF_HEADROOM);
 
 	if (ETH_FRAME_LEN > buf_size) {
 		RTE_LOG(ERR, PMD,
diff --git a/lib/librte_pmd_e1000/em_rxtx.c b/lib/librte_pmd_e1000/em_rxtx.c
index 8e20920..64d067c 100644
--- a/lib/librte_pmd_e1000/em_rxtx.c
+++ b/lib/librte_pmd_e1000/em_rxtx.c
@@ -1668,12 +1668,11 @@ eth_em_rx_init(struct rte_eth_dev *dev)
 	/* Determine RX bufsize. */
 	rctl_bsize = EM_MAX_BUF_SIZE;
 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
-		struct rte_pktmbuf_pool_private *mbp_priv;
 		uint32_t buf_size;
 
 		rxq = dev->data->rx_queues[i];
-		mbp_priv = rte_mempool_get_priv(rxq->mb_pool);
-		buf_size = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM;
+		buf_size = rte_pktmbuf_data_room_size(rxq->mb_pool) -
+			RTE_PKTMBUF_HEADROOM;
 		rctl_bsize = RTE_MIN(rctl_bsize, buf_size);
 	}
 
diff --git a/lib/librte_pmd_e1000/igb_rxtx.c b/lib/librte_pmd_e1000/igb_rxtx.c
index 084e45a..80d05c0 100644
--- a/lib/librte_pmd_e1000/igb_rxtx.c
+++ b/lib/librte_pmd_e1000/igb_rxtx.c
@@ -1921,7 +1921,6 @@ eth_igb_rx_init(struct rte_eth_dev *dev)
 {
 	struct e1000_hw     *hw;
 	struct igb_rx_queue *rxq;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint32_t rctl;
 	uint32_t rxcsum;
 	uint32_t srrctl;
@@ -1991,9 +1990,8 @@ eth_igb_rx_init(struct rte_eth_dev *dev)
 		/*
 		 * Configure RX buffer size.
 		 */
-		mbp_priv = rte_mempool_get_priv(rxq->mb_pool);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-				       RTE_PKTMBUF_HEADROOM);
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) -
+			RTE_PKTMBUF_HEADROOM);
 		if (buf_size >= 1024) {
 			/*
 			 * Configure the BSIZEPACKET field of the SRRCTL
@@ -2221,7 +2219,6 @@ eth_igbvf_rx_init(struct rte_eth_dev *dev)
 {
 	struct e1000_hw     *hw;
 	struct igb_rx_queue *rxq;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint32_t srrctl;
 	uint16_t buf_size;
 	uint16_t rctl_bsize;
@@ -2262,9 +2259,8 @@ eth_igbvf_rx_init(struct rte_eth_dev *dev)
 		/*
 		 * Configure RX buffer size.
 		 */
-		mbp_priv = rte_mempool_get_priv(rxq->mb_pool);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-				       RTE_PKTMBUF_HEADROOM);
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) -
+			RTE_PKTMBUF_HEADROOM);
 		if (buf_size >= 1024) {
 			/*
 			 * Configure the BSIZEPACKET field of the SRRCTL
diff --git a/lib/librte_pmd_fm10k/fm10k_ethdev.c b/lib/librte_pmd_fm10k/fm10k_ethdev.c
index 1a96cf2..dd4454c 100644
--- a/lib/librte_pmd_fm10k/fm10k_ethdev.c
+++ b/lib/librte_pmd_fm10k/fm10k_ethdev.c
@@ -397,7 +397,6 @@ fm10k_dev_rx_init(struct rte_eth_dev *dev)
 	uint32_t size;
 	uint32_t rxdctl = FM10K_RXDCTL_WRITE_BACK_MIN_DELAY;
 	uint16_t buf_size;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 
 	/* Disable RXINT to avoid possible interrupt */
 	for (i = 0; i < hw->mac.max_queues; i++)
@@ -425,9 +424,8 @@ fm10k_dev_rx_init(struct rte_eth_dev *dev)
 		FM10K_WRITE_REG(hw, FM10K_RDLEN(i), size);
 
 		/* Configure the Rx buffer size for one buff without split */
-		mbp_priv = rte_mempool_get_priv(rxq->mp);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-					RTE_PKTMBUF_HEADROOM);
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mp) -
+			RTE_PKTMBUF_HEADROOM);
 		FM10K_WRITE_REG(hw, FM10K_SRRCTL(i),
 				buf_size >> FM10K_SRRCTL_BSIZEPKT_SHIFT);
 
diff --git a/lib/librte_pmd_i40e/i40e_ethdev_vf.c b/lib/librte_pmd_i40e/i40e_ethdev_vf.c
index 4581c5b..473d441 100644
--- a/lib/librte_pmd_i40e/i40e_ethdev_vf.c
+++ b/lib/librte_pmd_i40e/i40e_ethdev_vf.c
@@ -571,13 +571,11 @@ i40evf_fill_virtchnl_vsi_rxq_info(struct i40e_virtchnl_rxq_info *rxq_info,
 	rxq_info->queue_id = queue_id;
 	rxq_info->max_pkt_size = max_pkt_size;
 	if (queue_id < nb_rxq) {
-		struct rte_pktmbuf_pool_private *mbp_priv;
-
 		rxq_info->ring_len = rxq->nb_rx_desc;
 		rxq_info->dma_ring_addr = rxq->rx_ring_phys_addr;
-		mbp_priv = rte_mempool_get_priv(rxq->mp);
 		rxq_info->databuffer_size =
-			mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM;
+			(rte_pktmbuf_data_room_size(rxq->mp) -
+				RTE_PKTMBUF_HEADROOM);
 	}
 }
 
diff --git a/lib/librte_pmd_i40e/i40e_rxtx.c b/lib/librte_pmd_i40e/i40e_rxtx.c
index abe68f4..493cfa3 100644
--- a/lib/librte_pmd_i40e/i40e_rxtx.c
+++ b/lib/librte_pmd_i40e/i40e_rxtx.c
@@ -2444,11 +2444,10 @@ i40e_rx_queue_config(struct i40e_rx_queue *rxq)
 	struct i40e_pf *pf = I40E_VSI_TO_PF(rxq->vsi);
 	struct i40e_hw *hw = I40E_VSI_TO_HW(rxq->vsi);
 	struct rte_eth_dev_data *data = pf->dev_data;
-	struct rte_pktmbuf_pool_private *mbp_priv =
-			rte_mempool_get_priv(rxq->mp);
-	uint16_t buf_size = (uint16_t)(mbp_priv->mbuf_data_room_size -
-						RTE_PKTMBUF_HEADROOM);
-	uint16_t len;
+	uint16_t buf_size, len;
+
+	buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mp) -
+		RTE_PKTMBUF_HEADROOM);
 
 	switch (pf->flags & (I40E_FLAG_HEADER_SPLIT_DISABLED |
 			I40E_FLAG_HEADER_SPLIT_ENABLED)) {
@@ -2506,7 +2505,6 @@ i40e_rx_queue_init(struct i40e_rx_queue *rxq)
 	uint16_t pf_q = rxq->reg_idx;
 	uint16_t buf_size;
 	struct i40e_hmc_obj_rxq rx_ctx;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 
 	err = i40e_rx_queue_config(rxq);
 	if (err < 0) {
@@ -2553,9 +2551,8 @@ i40e_rx_queue_init(struct i40e_rx_queue *rxq)
 
 	rxq->qrx_tail = hw->hw_addr + I40E_QRX_TAIL(pf_q);
 
-	mbp_priv = rte_mempool_get_priv(rxq->mp);
-	buf_size = (uint16_t)(mbp_priv->mbuf_data_room_size -
-					RTE_PKTMBUF_HEADROOM);
+	buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mp) -
+		RTE_PKTMBUF_HEADROOM);
 
 	/* Check if scattered RX needs to be used. */
 	if ((rxq->max_pkt_len + 2 * I40E_VLAN_TAG_SIZE) > buf_size) {
diff --git a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c
index 3c61d1c..7f15f15 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c
+++ b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c
@@ -4203,7 +4203,6 @@ ixgbe_dev_rx_init(struct rte_eth_dev *dev)
 {
 	struct ixgbe_hw     *hw;
 	struct ixgbe_rx_queue *rxq;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint64_t bus_addr;
 	uint32_t rxctrl;
 	uint32_t fctrl;
@@ -4320,9 +4319,8 @@ ixgbe_dev_rx_init(struct rte_eth_dev *dev)
 		 * The value is in 1 KB resolution. Valid values can be from
 		 * 1 KB to 16 KB.
 		 */
-		mbp_priv = rte_mempool_get_priv(rxq->mb_pool);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-				       RTE_PKTMBUF_HEADROOM);
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) -
+			RTE_PKTMBUF_HEADROOM);
 		srrctl |= ((buf_size >> IXGBE_SRRCTL_BSIZEPKT_SHIFT) &
 			   IXGBE_SRRCTL_BSIZEPKT_MASK);
 
@@ -4738,7 +4736,6 @@ ixgbevf_dev_rx_init(struct rte_eth_dev *dev)
 {
 	struct ixgbe_hw     *hw;
 	struct ixgbe_rx_queue *rxq;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint64_t bus_addr;
 	uint32_t srrctl, psrtype = 0;
 	uint16_t buf_size;
@@ -4825,9 +4822,8 @@ ixgbevf_dev_rx_init(struct rte_eth_dev *dev)
 		 * The value is in 1 KB resolution. Valid values can be from
 		 * 1 KB to 16 KB.
 		 */
-		mbp_priv = rte_mempool_get_priv(rxq->mb_pool);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-				       RTE_PKTMBUF_HEADROOM);
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) -
+			RTE_PKTMBUF_HEADROOM);
 		srrctl |= ((buf_size >> IXGBE_SRRCTL_BSIZEPKT_SHIFT) &
 			   IXGBE_SRRCTL_BSIZEPKT_MASK);
 
diff --git a/lib/librte_pmd_pcap/rte_eth_pcap.c b/lib/librte_pmd_pcap/rte_eth_pcap.c
index e5d2279..e1aea34 100644
--- a/lib/librte_pmd_pcap/rte_eth_pcap.c
+++ b/lib/librte_pmd_pcap/rte_eth_pcap.c
@@ -136,9 +136,7 @@ eth_pcap_rx(void *queue,
 	const u_char *packet;
 	struct rte_mbuf *mbuf;
 	struct pcap_rx_queue *pcap_q = queue;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint16_t num_rx = 0;
-	uint16_t buf_size;
 
 	if (unlikely(pcap_q->pcap == NULL || nb_pkts == 0))
 		return 0;
@@ -157,8 +155,7 @@ eth_pcap_rx(void *queue,
 			break;
 
 		/* Now get the space available for data in the mbuf */
-		mbp_priv =  rte_mempool_get_priv(pcap_q->mb_pool);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(pcap_q->mb_pool) -
 				RTE_PKTMBUF_HEADROOM);
 
 		if (header.len <= buf_size) {
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
index a530c80..d8019f5 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
@@ -838,14 +838,11 @@ vmxnet3_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint8_t i;
 	char mem_name[32];
 	uint16_t buf_size;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 
 	PMD_INIT_FUNC_TRACE();
 
-	mbp_priv = (struct rte_pktmbuf_pool_private *)
-		rte_mempool_get_priv(mp);
-	buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-			       RTE_PKTMBUF_HEADROOM);
+	buf_size = rte_pktmbuf_data_room_size(mp) -
+		RTE_PKTMBUF_HEADROOM;
 
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len > buf_size) {
 		PMD_INIT_LOG(ERR, "buf_size = %u, max_pkt_len = %u, "
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v4 04/12] mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
                           ` (2 preceding siblings ...)
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 03/12] mbuf: add accessors to get data room size and private size Olivier Matz
@ 2015-04-20 15:41         ` Olivier Matz
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 05/12] testpmd: use standard functions to initialize mbufs and mbuf pool Olivier Matz
                           ` (9 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-20 15:41 UTC (permalink / raw)
  To: dev

Allow the user to use the default rte_pktmbuf_init() function even
if the mbuf private size is not 0.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_mbuf/rte_mbuf.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index 231cfb8..d7f0380 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -119,16 +119,19 @@ rte_pktmbuf_init(struct rte_mempool *mp,
 		 __attribute__((unused)) unsigned i)
 {
 	struct rte_mbuf *m = _m;
-	uint32_t buf_len = mp->elt_size - sizeof(struct rte_mbuf);
+	uint32_t mbuf_size, buf_len;
 
-	RTE_MBUF_ASSERT(mp->elt_size >= sizeof(struct rte_mbuf));
+	mbuf_size = sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(mp);
+	buf_len = rte_pktmbuf_data_room_size(mp);
+
+	RTE_MBUF_ASSERT(mp->elt_size >= mbuf_size);
+	RTE_MBUF_ASSERT(buf_len <= 0xffff);
 
 	memset(m, 0, mp->elt_size);
 
 	/* start of buffer is just after mbuf structure */
-	m->buf_addr = (char *)m + sizeof(struct rte_mbuf);
-	m->buf_physaddr = rte_mempool_virt2phy(mp, m) +
-			sizeof(struct rte_mbuf);
+	m->buf_addr = (char *)m + mbuf_size;
+	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mbuf_size;
 	m->buf_len = (uint16_t)buf_len;
 
 	/* keep some headroom between start of buffer and data */
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v4 05/12] testpmd: use standard functions to initialize mbufs and mbuf pool
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
                           ` (3 preceding siblings ...)
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 04/12] mbuf: fix rte_pktmbuf_init when mbuf private size is not zero Olivier Matz
@ 2015-04-20 15:41         ` Olivier Matz
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 06/12] mbuf: introduce a new helper to create a " Olivier Matz
                           ` (8 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-20 15:41 UTC (permalink / raw)
  To: dev

The rte_pktmbuf_pool_init() and rte_pktmbuf_init() functions now
support to have a non-hardcoded buffer length. We can remove the
specific functions used in testpmd and replace them by the standard
ones.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test-pmd/testpmd.c | 74 +++++---------------------------------------------
 1 file changed, 7 insertions(+), 67 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 10e4347..1f2445e 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -393,83 +393,23 @@ set_def_fwd_config(void)
 /*
  * Configuration initialisation done once at init time.
  */
-struct mbuf_ctor_arg {
-	uint16_t seg_buf_offset; /**< offset of data in data segment of mbuf. */
-	uint16_t seg_buf_size;   /**< size of data segment in mbuf. */
-};
-
-struct mbuf_pool_ctor_arg {
-	uint16_t seg_buf_size; /**< size of data segment in mbuf. */
-};
-
-static void
-testpmd_mbuf_ctor(struct rte_mempool *mp,
-		  void *opaque_arg,
-		  void *raw_mbuf,
-		  __attribute__((unused)) unsigned i)
-{
-	struct mbuf_ctor_arg *mb_ctor_arg;
-	struct rte_mbuf    *mb;
-
-	mb_ctor_arg = (struct mbuf_ctor_arg *) opaque_arg;
-	mb = (struct rte_mbuf *) raw_mbuf;
-
-	mb->pool         = mp;
-	mb->buf_addr     = (void *) ((char *)mb + mb_ctor_arg->seg_buf_offset);
-	mb->buf_physaddr = (uint64_t) (rte_mempool_virt2phy(mp, mb) +
-			mb_ctor_arg->seg_buf_offset);
-	mb->buf_len      = mb_ctor_arg->seg_buf_size;
-	mb->ol_flags     = 0;
-	mb->data_off     = RTE_PKTMBUF_HEADROOM;
-	mb->nb_segs      = 1;
-	mb->tx_offload   = 0;
-	mb->vlan_tci     = 0;
-	mb->hash.rss     = 0;
-}
-
-static void
-testpmd_mbuf_pool_ctor(struct rte_mempool *mp,
-		       void *opaque_arg)
-{
-	struct mbuf_pool_ctor_arg      *mbp_ctor_arg;
-	struct rte_pktmbuf_pool_private *mbp_priv;
-
-	if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) {
-		printf("%s(%s) private_data_size %d < %d\n",
-		       __func__, mp->name, (int) mp->private_data_size,
-		       (int) sizeof(struct rte_pktmbuf_pool_private));
-		return;
-	}
-	mbp_ctor_arg = (struct mbuf_pool_ctor_arg *) opaque_arg;
-	mbp_priv = rte_mempool_get_priv(mp);
-	mbp_priv->mbuf_data_room_size = mbp_ctor_arg->seg_buf_size;
-	mbp_priv->mbuf_priv_size = 0;
-}
-
 static void
 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 		 unsigned int socket_id)
 {
 	char pool_name[RTE_MEMPOOL_NAMESIZE];
 	struct rte_mempool *rte_mp;
-	struct mbuf_pool_ctor_arg mbp_ctor_arg;
-	struct mbuf_ctor_arg mb_ctor_arg;
 	uint32_t mb_size;
 
-	mbp_ctor_arg.seg_buf_size = (uint16_t) (RTE_PKTMBUF_HEADROOM +
-						mbuf_seg_size);
-	mb_ctor_arg.seg_buf_offset =
-		(uint16_t) RTE_CACHE_LINE_ROUNDUP(sizeof(struct rte_mbuf));
-	mb_ctor_arg.seg_buf_size = mbp_ctor_arg.seg_buf_size;
-	mb_size = mb_ctor_arg.seg_buf_offset + mb_ctor_arg.seg_buf_size;
+	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
 
 #ifdef RTE_LIBRTE_PMD_XENVIRT
 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
                                    (unsigned) mb_mempool_cache,
                                    sizeof(struct rte_pktmbuf_pool_private),
-                                   testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
-                                   testpmd_mbuf_ctor, &mb_ctor_arg,
+                                   rte_pktmbuf_pool_init, NULL,
+                                   rte_pktmbuf_init, NULL,
                                    socket_id, 0);
 
 
@@ -479,15 +419,15 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 		rte_mp = mempool_anon_create(pool_name, nb_mbuf, mb_size,
 				    (unsigned) mb_mempool_cache,
 				    sizeof(struct rte_pktmbuf_pool_private),
-				    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
-				    testpmd_mbuf_ctor, &mb_ctor_arg,
+				    rte_pktmbuf_pool_init, NULL,
+				    rte_pktmbuf_init, NULL,
 				    socket_id, 0);
 	else
 		rte_mp = rte_mempool_create(pool_name, nb_mbuf, mb_size,
 				    (unsigned) mb_mempool_cache,
 				    sizeof(struct rte_pktmbuf_pool_private),
-				    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
-				    testpmd_mbuf_ctor, &mb_ctor_arg,
+				    rte_pktmbuf_pool_init, NULL,
+				    rte_pktmbuf_init, NULL,
 				    socket_id, 0);
 
 #endif
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v4 06/12] mbuf: introduce a new helper to create a mbuf pool
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
                           ` (4 preceding siblings ...)
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 05/12] testpmd: use standard functions to initialize mbufs and mbuf pool Olivier Matz
@ 2015-04-20 15:41         ` Olivier Matz
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 07/12] apps: use rte_pktmbuf_pool_create to create mbuf pools Olivier Matz
                           ` (7 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-20 15:41 UTC (permalink / raw)
  To: dev

Add a new wrapper to rte_mempool_create() to simplify the creation
of a packet mbuf pool.

This wrapper can be used if there is no specific mempool flags, and
no specific mbuf or pool constructor function, which is most of the
use cases.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 doc/guides/rel_notes/updating_apps.rst |  4 ++++
 lib/librte_mbuf/rte_mbuf.c             | 21 ++++++++++++++++++
 lib/librte_mbuf/rte_mbuf.h             | 40 ++++++++++++++++++++++++++++++++++
 3 files changed, 65 insertions(+)

diff --git a/doc/guides/rel_notes/updating_apps.rst b/doc/guides/rel_notes/updating_apps.rst
index f513615..f4dd196 100644
--- a/doc/guides/rel_notes/updating_apps.rst
+++ b/doc/guides/rel_notes/updating_apps.rst
@@ -16,6 +16,10 @@ DPDK 2.0 to DPDK 2.1
     rte_pktmbuf_pool_private structure and pass it to
     rte_pktmbuf_pool_init().
 
+*   A simpler helper rte_pktmbuf_pool_create() can be used to create a
+    packet mbuf pool. The old way using rte_mempool_create() is still
+    supported though and is still used for more specific cases.
+
 DPDK 1.7 to DPDK 1.8
 --------------------
 
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index d7f0380..b013607 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -143,6 +143,27 @@ rte_pktmbuf_init(struct rte_mempool *mp,
 	m->port = 0xff;
 }
 
+/* helper to create a mbuf pool */
+struct rte_mempool *
+rte_pktmbuf_pool_create(const char *name, unsigned n,
+	unsigned cache_size, uint16_t priv_size, uint16_t data_room_size,
+	int socket_id)
+{
+	struct rte_pktmbuf_pool_private mbp_priv;
+	unsigned elt_size;
+
+
+	elt_size = sizeof(struct rte_mbuf) + (unsigned)priv_size +
+		(unsigned)data_room_size;
+	mbp_priv.mbuf_data_room_size = data_room_size;
+	mbp_priv.mbuf_priv_size = priv_size;
+
+	return rte_mempool_create(name, n, elt_size,
+		cache_size, sizeof(struct rte_pktmbuf_pool_private),
+		rte_pktmbuf_pool_init, &mbp_priv, rte_pktmbuf_init, NULL,
+		socket_id, 0);
+}
+
 /* do some sanity checks on a mbuf: panic if it fails */
 void
 rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header)
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index a4146fa..42db8e3 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -642,6 +642,46 @@ void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg,
 void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
 
 /**
+ * Create a mbuf pool.
+ *
+ * This function creates and initializes a packet mbuf pool. It is
+ * a wrapper to rte_mempool_create() with the proper packet constructor
+ * and mempool constructor.
+ *
+ * @param name
+ *   The name of the mbuf pool.
+ * @param n
+ *   The number of elements in the mbuf pool. The optimum size (in terms
+ *   of memory usage) for a mempool is when n is a power of two minus one:
+ *   n = (2^q - 1).
+ * @param cache_size
+ *   Size of the per-core object cache. See rte_mempool_create() for
+ *   details.
+ * @param priv_size
+ *   Size of application private are between the rte_mbuf structure
+ *   and the data buffer.
+ * @param data_room_size
+ *   Size of data buffer in each mbuf, including RTE_PKTMBUF_HEADROOM.
+ * @param socket_id
+ *   The socket identifier where the memory should be allocated. The
+ *   value can be *SOCKET_ID_ANY* if there is no NUMA constraint for the
+ *   reserved zone.
+ * @return
+ *   The pointer to the new allocated mempool, on success. NULL on error
+ *   with rte_errno set appropriately. Possible rte_errno values include:
+ *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
+ *    - E_RTE_SECONDARY - function was called from a secondary process instance
+ *    - EINVAL - cache size provided is too large
+ *    - ENOSPC - the maximum number of memzones has already been allocated
+ *    - EEXIST - a memzone with the same name already exists
+ *    - ENOMEM - no appropriate memory area found in which to create memzone
+ */
+struct rte_mempool *
+rte_pktmbuf_pool_create(const char *name, unsigned n,
+	unsigned cache_size, uint16_t priv_size, uint16_t data_room_size,
+	int socket_id);
+
+/**
  * Get the data room size of mbufs stored in a pktmbuf_pool
  *
  * The data room size is the amount of data that can be stored in a
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v4 07/12] apps: use rte_pktmbuf_pool_create to create mbuf pools
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
                           ` (5 preceding siblings ...)
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 06/12] mbuf: introduce a new helper to create a " Olivier Matz
@ 2015-04-20 15:41         ` Olivier Matz
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 08/12] mbuf: fix clone support when application uses private mbuf data Olivier Matz
                           ` (6 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-20 15:41 UTC (permalink / raw)
  To: dev

When it's possible, use the new helper to create the mbuf pools.
Most of the patch is trivial, except for the following files that
have some specifics (indirect mbufs):
- ip_fragmentation
- ip_pipeline
- ipv4_multicast
- vhost

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test-pipeline/init.c                           | 15 ++--------
 app/test-pmd/testpmd.c                             |  9 ++----
 app/test/test_distributor.c                        | 10 ++-----
 app/test/test_distributor_perf.c                   | 10 ++-----
 app/test/test_kni.c                                | 16 +++--------
 app/test/test_link_bonding.c                       | 10 +++----
 app/test/test_link_bonding_mode4.c                 | 12 +++-----
 app/test/test_mbuf.c                               | 22 +++++----------
 app/test/test_pmd_perf.c                           | 11 +++-----
 app/test/test_pmd_ring.c                           | 10 ++-----
 app/test/test_reorder.c                            | 10 ++-----
 app/test/test_sched.c                              | 16 ++---------
 app/test/test_table.c                              |  9 ++----
 app/test/test_table.h                              |  3 +-
 examples/bond/main.c                               | 10 ++-----
 examples/distributor/main.c                        | 11 +++-----
 examples/dpdk_qat/main.c                           | 10 ++-----
 examples/exception_path/main.c                     | 14 ++++------
 examples/ip_fragmentation/main.c                   | 18 ++++--------
 examples/ip_pipeline/init.c                        | 32 ++++------------------
 examples/ipv4_multicast/main.c                     | 23 ++++++----------
 examples/kni/main.c                                | 12 +++-----
 examples/l2fwd-ivshmem/host/host.c                 | 10 ++-----
 examples/l2fwd-jobstats/main.c                     | 10 ++-----
 examples/l2fwd/main.c                              | 11 ++------
 examples/l3fwd-acl/main.c                          | 11 +++-----
 examples/l3fwd-power/main.c                        | 11 +++-----
 examples/l3fwd-vf/main.c                           | 12 +++-----
 examples/l3fwd/main.c                              | 10 +++----
 examples/link_status_interrupt/main.c              | 10 ++-----
 examples/load_balancer/init.c                      | 12 ++------
 examples/load_balancer/main.h                      |  4 +--
 .../client_server_mp/mp_server/init.c              | 10 ++-----
 examples/multi_process/symmetric_mp/main.c         | 10 +++----
 examples/netmap_compat/bridge/bridge.c             | 12 +++-----
 examples/packet_ordering/main.c                    | 11 +++-----
 examples/qos_meter/main.c                          |  7 ++---
 examples/qos_sched/init.c                          | 10 ++-----
 examples/qos_sched/main.h                          |  2 +-
 examples/quota_watermark/include/conf.h            |  2 +-
 examples/quota_watermark/qw/main.c                 |  7 ++---
 examples/rxtx_callbacks/main.c                     | 11 +++-----
 examples/skeleton/basicfwd.c                       | 13 ++-------
 examples/vhost/main.c                              | 24 +++++-----------
 examples/vhost_xen/main.c                          | 11 +++-----
 examples/vmdq/main.c                               | 11 +++-----
 examples/vmdq_dcb/main.c                           | 10 ++-----
 lib/librte_pmd_bond/rte_eth_bond_alb.c             | 16 +++++------
 48 files changed, 175 insertions(+), 386 deletions(-)

diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index 05f4503..db2196b 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -85,8 +85,7 @@ struct app_params app = {
 	.ring_tx_size = 128,
 
 	/* Buffer pool */
-	.pool_buffer_size = 2048 + sizeof(struct rte_mbuf) +
-		RTE_PKTMBUF_HEADROOM,
+	.pool_buffer_size = 2048 + RTE_PKTMBUF_HEADROOM,
 	.pool_size = 32 * 1024,
 	.pool_cache_size = 256,
 
@@ -144,16 +143,8 @@ app_init_mbuf_pools(void)
 {
 	/* Init the buffer pool */
 	RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n");
-	app.pool = rte_mempool_create(
-		"mempool",
-		app.pool_size,
-		app.pool_buffer_size,
-		app.pool_cache_size,
-		sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, NULL,
-		rte_pktmbuf_init, NULL,
-		rte_socket_id(),
-		0);
+	app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size,
+		app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id());
 	if (app.pool == NULL)
 		rte_panic("Cannot create mbuf pool\n");
 }
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 1f2445e..8418db3 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -423,12 +423,9 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 				    rte_pktmbuf_init, NULL,
 				    socket_id, 0);
 	else
-		rte_mp = rte_mempool_create(pool_name, nb_mbuf, mb_size,
-				    (unsigned) mb_mempool_cache,
-				    sizeof(struct rte_pktmbuf_pool_private),
-				    rte_pktmbuf_pool_init, NULL,
-				    rte_pktmbuf_init, NULL,
-				    socket_id, 0);
+		/* wrapper to rte_mempool_create() */
+		rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
+			mb_mempool_cache, 0, mbuf_seg_size, socket_id);
 
 #endif
 
diff --git a/app/test/test_distributor.c b/app/test/test_distributor.c
index 9e8c06d..ad46987 100644
--- a/app/test/test_distributor.c
+++ b/app/test/test_distributor.c
@@ -500,7 +500,7 @@ quit_workers(struct rte_distributor *d, struct rte_mempool *p)
 	worker_idx = 0;
 }
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 static int
 test_distributor(void)
@@ -528,12 +528,8 @@ test_distributor(void)
 	const unsigned nb_bufs = (511 * rte_lcore_count()) < BIG_BATCH ?
 			(BIG_BATCH * 2) - 1 : (511 * rte_lcore_count());
 	if (p == NULL) {
-		p = rte_mempool_create("DT_MBUF_POOL", nb_bufs,
-				MBUF_SIZE, BURST,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL,
-				rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+		p = rte_pktmbuf_pool_create("DT_MBUF_POOL", nb_bufs, BURST,
+			0, MBUF_DATA_SIZE, rte_socket_id());
 		if (p == NULL) {
 			printf("Error creating mempool\n");
 			return -1;
diff --git a/app/test/test_distributor_perf.c b/app/test/test_distributor_perf.c
index 31431bb..f04cb15 100644
--- a/app/test/test_distributor_perf.c
+++ b/app/test/test_distributor_perf.c
@@ -209,7 +209,7 @@ quit_workers(struct rte_distributor *d, struct rte_mempool *p)
 	worker_idx = 0;
 }
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 static int
 test_distributor_perf(void)
@@ -240,12 +240,8 @@ test_distributor_perf(void)
 	const unsigned nb_bufs = (511 * rte_lcore_count()) < BIG_BATCH ?
 			(BIG_BATCH * 2) - 1 : (511 * rte_lcore_count());
 	if (p == NULL) {
-		p = rte_mempool_create("DPT_MBUF_POOL", nb_bufs,
-				MBUF_SIZE, BURST,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL,
-				rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+		p = rte_pktmbuf_pool_create("DPT_MBUF_POOL", nb_bufs, BURST,
+			0, MBUF_DATA_SIZE, rte_socket_id());
 		if (p == NULL) {
 			printf("Error creating mempool\n");
 			return -1;
diff --git a/app/test/test_kni.c b/app/test/test_kni.c
index 608901d..506b543 100644
--- a/app/test/test_kni.c
+++ b/app/test/test_kni.c
@@ -47,8 +47,7 @@
 
 #define NB_MBUF          8192
 #define MAX_PACKET_SZ    2048
-#define MBUF_SZ \
-	(MAX_PACKET_SZ + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SZ     (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM)
 #define PKT_BURST_SZ     32
 #define MEMPOOL_CACHE_SZ PKT_BURST_SZ
 #define SOCKET           0
@@ -118,17 +117,10 @@ test_kni_create_mempool(void)
 
 	mp = rte_mempool_lookup("kni_mempool");
 	if (!mp)
-		mp = rte_mempool_create("kni_mempool",
+		mp = rte_pktmbuf_pool_create("kni_mempool",
 				NB_MBUF,
-				MBUF_SZ,
-				MEMPOOL_CACHE_SZ,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init,
-				NULL,
-				rte_pktmbuf_init,
-				NULL,
-				SOCKET,
-				0);
+				MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ,
+				SOCKET);
 
 	return mp;
 }
diff --git a/app/test/test_link_bonding.c b/app/test/test_link_bonding.c
index 8c24314..674d8dd 100644
--- a/app/test/test_link_bonding.c
+++ b/app/test/test_link_bonding.c
@@ -75,8 +75,7 @@
 	ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \
 	ETH_TXQ_FLAGS_NOXSUMTCP)
 
-#define MBUF_PAYLOAD_SIZE	(2048)
-#define MBUF_SIZE (MBUF_PAYLOAD_SIZE + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE (250)
 #define BURST_SIZE (32)
 
@@ -280,10 +279,9 @@ test_setup(void)
 	nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
 			RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
 	if (test_params->mbuf_pool == NULL) {
-		test_params->mbuf_pool = rte_mempool_create("MBUF_POOL", nb_mbuf_per_pool,
-				MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+		test_params->mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+			nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+			rte_socket_id());
 		TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
 				"rte_mempool_create failed");
 	}
diff --git a/app/test/test_link_bonding_mode4.c b/app/test/test_link_bonding_mode4.c
index 02380f9..590daad 100644
--- a/app/test/test_link_bonding_mode4.c
+++ b/app/test/test_link_bonding_mode4.c
@@ -65,9 +65,7 @@
 #define RX_RING_SIZE 128
 #define TX_RING_SIZE 512
 
-#define MBUF_PAYLOAD_SIZE	    (2048)
-#define MBUF_SIZE (MBUF_PAYLOAD_SIZE + sizeof(struct rte_mbuf) + \
-	RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE          (2048 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE         (250)
 #define BURST_SIZE              (32)
 
@@ -390,11 +388,9 @@ test_setup(void)
 	if (test_params.mbuf_pool == NULL) {
 		nb_mbuf_per_pool = TEST_RX_DESC_MAX + DEF_PKT_BURST +
 					TEST_TX_DESC_MAX + MAX_PKT_BURST;
-		test_params.mbuf_pool = rte_mempool_create("TEST_MODE4",
-				nb_mbuf_per_pool, MBUF_SIZE, MBUF_CACHE_SIZE,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-				socket_id, 0);
+		test_params.mbuf_pool = rte_pktmbuf_pool_create("TEST_MODE4",
+			nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+			socket_id);
 
 		TEST_ASSERT(test_params.mbuf_pool != NULL,
 			"rte_mempool_create failed\n");
diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 1ff66cb..4774263 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -61,7 +61,7 @@
 
 #include "test.h"
 
-#define MBUF_SIZE               2048
+#define MBUF_DATA_SIZE          2048
 #define NB_MBUF                 128
 #define MBUF_TEST_DATA_LEN      1464
 #define MBUF_TEST_DATA_LEN2     50
@@ -73,7 +73,6 @@
 #define REFCNT_MAX_TIMEOUT      10
 #define REFCNT_MAX_REF          (RTE_MAX_LCORE)
 #define REFCNT_MBUF_NUM         64
-#define REFCNT_MBUF_SIZE        (sizeof (struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
 #define REFCNT_RING_SIZE        (REFCNT_MBUF_NUM * REFCNT_MAX_REF)
 
 #define MAKE_STRING(x)          # x
@@ -622,12 +621,10 @@ test_refcnt_mbuf(void)
 	/* create refcnt pool & ring if they don't exist */
 
 	if (refcnt_pool == NULL &&
-			(refcnt_pool = rte_mempool_create(
-			MAKE_STRING(refcnt_pool),
-			REFCNT_MBUF_NUM, REFCNT_MBUF_SIZE, 0,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-			SOCKET_ID_ANY, 0)) == NULL) {
+			(refcnt_pool = rte_pktmbuf_pool_create(
+				MAKE_STRING(refcnt_pool),
+				REFCNT_MBUF_NUM, 0, 0, 0,
+				SOCKET_ID_ANY)) == NULL) {
 		printf("%s: cannot allocate " MAKE_STRING(refcnt_pool) "\n",
 		    __func__);
 		return (-1);
@@ -764,13 +761,8 @@ test_mbuf(void)
 
 	/* create pktmbuf pool if it does not exist */
 	if (pktmbuf_pool == NULL) {
-		pktmbuf_pool =
-			rte_mempool_create("test_pktmbuf_pool", NB_MBUF,
-					   MBUF_SIZE, 32,
-					   sizeof(struct rte_pktmbuf_pool_private),
-					   rte_pktmbuf_pool_init, NULL,
-					   rte_pktmbuf_init, NULL,
-					   SOCKET_ID_ANY, 0);
+		pktmbuf_pool = rte_pktmbuf_pool_create("test_pktmbuf_pool",
+			NB_MBUF, 32, 0, MBUF_DATA_SIZE, SOCKET_ID_ANY);
 	}
 
 	if (pktmbuf_pool == NULL) {
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index d6a4a45..49a494d 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -47,7 +47,7 @@
 #define NB_ETHPORTS_USED                (1)
 #define NB_SOCKETS                      (2)
 #define MEMPOOL_CACHE_SIZE 250
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define MAX_PKT_BURST                   (32)
 #define RTE_TEST_RX_DESC_DEFAULT        (128)
 #define RTE_TEST_TX_DESC_DEFAULT        (512)
@@ -289,12 +289,9 @@ init_mbufpool(unsigned nb_mbuf)
 		if (mbufpool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
 			mbufpool[socketid] =
-				rte_mempool_create(s, nb_mbuf, MBUF_SIZE,
-					MEMPOOL_CACHE_SIZE,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, 0);
+				rte_pktmbuf_pool_create(s, nb_mbuf,
+					MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+					socketid);
 			if (mbufpool[socketid] == NULL)
 				rte_exit(EXIT_FAILURE,
 					"Cannot init mbuf pool on socket %d\n",
diff --git a/app/test/test_pmd_ring.c b/app/test/test_pmd_ring.c
index 7490112..53897f7 100644
--- a/app/test/test_pmd_ring.c
+++ b/app/test/test_pmd_ring.c
@@ -48,7 +48,7 @@ static struct rte_mempool *mp;
 
 #define RING_SIZE 256
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   512
 
 static int
@@ -406,12 +406,8 @@ test_pmd_ring_pair_create_attach(void)
 static int
 test_pmd_ring(void)
 {
-	mp = rte_mempool_create("mbuf_pool", NB_MBUF,
-			MBUF_SIZE, 32,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL,
-			rte_pktmbuf_init, NULL,
-			rte_socket_id(), 0);
+	mp = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32,
+		0, MBUF_DATA_SIZE, rte_socket_id());
 	if (mp == NULL)
 		return -1;
 
diff --git a/app/test/test_reorder.c b/app/test/test_reorder.c
index 61cf8d3..91fbe9a 100644
--- a/app/test/test_reorder.c
+++ b/app/test/test_reorder.c
@@ -50,7 +50,7 @@
 #define REORDER_BUFFER_SIZE 16384
 #define NUM_MBUFS (2*REORDER_BUFFER_SIZE)
 #define REORDER_BUFFER_SIZE_INVALID 2049
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 struct reorder_unittest_params {
 	struct rte_mempool *p;
@@ -351,12 +351,8 @@ test_setup(void)
 
 	/* mempool creation */
 	if (test_params->p == NULL) {
-		test_params->p = rte_mempool_create("RO_MBUF_POOL", NUM_MBUFS,
-				MBUF_SIZE, BURST,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL,
-				rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+		test_params->p = rte_pktmbuf_pool_create("RO_MBUF_POOL",
+			NUM_MBUFS, BURST, 0, MBUF_DATA_SIZE, rte_socket_id());
 		if (test_params->p == NULL) {
 			printf("%s: Error creating mempool\n", __func__);
 			return -1;
diff --git a/app/test/test_sched.c b/app/test/test_sched.c
index 60c62de..c7239f8 100644
--- a/app/test/test_sched.c
+++ b/app/test/test_sched.c
@@ -86,8 +86,7 @@ static struct rte_sched_port_params port_param = {
 };
 
 #define NB_MBUF          32
-#define MAX_PACKET_SZ    2048
-#define MBUF_SZ (MAX_PACKET_SZ + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SZ     (2048 + RTE_PKTMBUF_HEADROOM)
 #define PKT_BURST_SZ     32
 #define MEMPOOL_CACHE_SZ PKT_BURST_SZ
 #define SOCKET           0
@@ -100,17 +99,8 @@ create_mempool(void)
 
 	mp = rte_mempool_lookup("test_sched");
 	if (!mp)
-		mp = rte_mempool_create("test_sched",
-				NB_MBUF,
-				MBUF_SZ,
-				MEMPOOL_CACHE_SZ,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init,
-				NULL,
-				rte_pktmbuf_init,
-				NULL,
-				SOCKET,
-				0);
+		mp = rte_pktmbuf_pool_create("test_sched", NB_MBUF,
+			MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, SOCKET);
 
 	return mp;
 }
diff --git a/app/test/test_table.c b/app/test/test_table.c
index c3093cc..de6c27d 100644
--- a/app/test/test_table.c
+++ b/app/test/test_table.c
@@ -89,15 +89,10 @@ app_init_mbuf_pools(void)
 	printf("Getting/Creating the mempool ...\n");
 	pool = rte_mempool_lookup("mempool");
 	if (!pool) {
-		pool = rte_mempool_create(
+		pool = rte_pktmbuf_pool_create(
 			"mempool",
 			POOL_SIZE,
-			POOL_BUFFER_SIZE,
-			POOL_CACHE_SIZE,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL,
-			rte_pktmbuf_init, NULL,
-			0,
+			POOL_CACHE_SIZE, 0, POOL_BUFFER_SIZE,
 			0);
 		if (pool == NULL)
 			rte_panic("Cannot create mbuf pool\n");
diff --git a/app/test/test_table.h b/app/test/test_table.h
index 64e9427..be331c0 100644
--- a/app/test/test_table.h
+++ b/app/test/test_table.h
@@ -65,7 +65,7 @@
 #define PORT_TX_RING_SIZE   512
 #define RING_RX_SIZE        128
 #define RING_TX_SIZE        128
-#define POOL_BUFFER_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define POOL_BUFFER_SIZE    (2048 + RTE_PKTMBUF_HEADROOM)
 #define POOL_SIZE           (32 * 1024)
 #define POOL_CACHE_SIZE     256
 #define BURST_SIZE          8
@@ -73,7 +73,6 @@
 #define MAX_DUMMY_PORTS     2
 #define MP_NAME             "dummy_port_mempool"
 #define MBUF_COUNT          (8000 * MAX_DUMMY_PORTS)
-#define MBUF_SIZE        (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
 #define MP_CACHE_SZ         256
 #define MP_SOCKET           0
 #define MP_FLAGS            0
diff --git a/examples/bond/main.c b/examples/bond/main.c
index 67c283d..fcb4c4e 100644
--- a/examples/bond/main.c
+++ b/examples/bond/main.c
@@ -96,7 +96,7 @@
 
 #define RTE_LOGTYPE_DCB RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   (1024*8)
 
 #define MAX_PKT_BURST 32
@@ -738,12 +738,8 @@ main(int argc, char *argv[])
 	else if (nb_ports > MAX_PORTS)
 		rte_exit(EXIT_FAILURE, "You can have max 4 ports\n");
 
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NB_MBUF,
-				       MBUF_SIZE, 32,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init, NULL,
-				       rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NB_MBUF, 32,
+		0, MBUF_DATA_SIZE, rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/examples/distributor/main.c b/examples/distributor/main.c
index 13fb04d..78fe3e9 100644
--- a/examples/distributor/main.c
+++ b/examples/distributor/main.c
@@ -47,7 +47,7 @@
 #define RX_RING_SIZE 256
 #define TX_RING_SIZE 512
 #define NUM_MBUFS ((64*1024)-1)
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE 250
 #define BURST_SIZE 32
 #define RTE_RING_SZ 1024
@@ -528,12 +528,9 @@ main(int argc, char *argv[])
 		rte_exit(EXIT_FAILURE, "Error: number of ports must be even, except "
 				"when using a single port\n");
 
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
-			MBUF_SIZE, MBUF_CACHE_SIZE,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL,
-			rte_pktmbuf_init, NULL,
-			rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+		NUM_MBUFS * nb_ports, MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+		rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 	nb_ports_available = nb_ports;
diff --git a/examples/dpdk_qat/main.c b/examples/dpdk_qat/main.c
index 20e78bc..053be91 100644
--- a/examples/dpdk_qat/main.c
+++ b/examples/dpdk_qat/main.c
@@ -70,7 +70,7 @@
 
 #include "crypto.h"
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   (32 * 1024)
 
 #define MAX_PKT_BURST 32
@@ -598,7 +598,6 @@ print_ethaddr(const char *name, const struct ether_addr *eth_addr)
 static int
 init_mem(void)
 {
-	const unsigned flags = 0;
 	int socketid;
 	unsigned lcoreid;
 	char s[64];
@@ -613,11 +612,8 @@ init_mem(void)
 		if (pktmbuf_pool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
 			pktmbuf_pool[socketid] =
-				rte_mempool_create(s, NB_MBUF, MBUF_SIZE, 32,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, flags);
+				rte_pktmbuf_pool_create(s, NB_MBUF, 32, 0,
+					MBUF_DATA_SIZE, socketid);
 			if (pktmbuf_pool[socketid] == NULL) {
 				printf("Cannot init mbuf pool on socket %d\n", socketid);
 				return -1;
diff --git a/examples/exception_path/main.c b/examples/exception_path/main.c
index 14582de..b3fe170 100644
--- a/examples/exception_path/main.c
+++ b/examples/exception_path/main.c
@@ -81,11 +81,10 @@
 #define MAX_PORTS               (RTE_MAX_LCORE / 2)
 
 /* Max size of a single packet */
-#define MAX_PACKET_SZ           2048
+#define MAX_PACKET_SZ (2048)
 
-/* Number of bytes needed for each mbuf */
-#define MBUF_SZ \
-	(MAX_PACKET_SZ + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+/* Size of the data buffer in each mbuf */
+#define MBUF_DATA_SZ (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM)
 
 /* Number of mbufs in mempool that is created */
 #define NB_MBUF                 8192
@@ -532,11 +531,8 @@ main(int argc, char** argv)
 	parse_args(argc, argv);
 
 	/* Create the mbuf pool */
-	pktmbuf_pool = rte_mempool_create("mbuf_pool", NB_MBUF, MBUF_SZ,
-			MEMPOOL_CACHE_SZ,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-			rte_socket_id(), 0);
+	pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
+			MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, rte_socket_id());
 	if (pktmbuf_pool == NULL) {
 		FATAL_ERROR("Could not initialise mbuf pool");
 		return -1;
diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index cf63718..c702fdd 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -76,7 +76,7 @@
 
 #define RTE_LOGTYPE_IP_FRAG RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /* allow max jumbo frame 9.5 KB */
 #define JUMBO_FRAME_MAX_SIZE	0x2600
@@ -744,12 +744,8 @@ init_mem(void)
 					socket);
 			snprintf(buf, sizeof(buf), "pool_direct_%i", socket);
 
-			mp = rte_mempool_create(buf, NB_MBUF,
-						   MBUF_SIZE, 32,
-						   sizeof(struct rte_pktmbuf_pool_private),
-						   rte_pktmbuf_pool_init, NULL,
-						   rte_pktmbuf_init, NULL,
-						   socket, 0);
+			mp = rte_pktmbuf_pool_create(buf, NB_MBUF, 32,
+				0, MBUF_DATA_SIZE, socket);
 			if (mp == NULL) {
 				RTE_LOG(ERR, IP_FRAG, "Cannot create direct mempool\n");
 				return -1;
@@ -762,12 +758,8 @@ init_mem(void)
 					socket);
 			snprintf(buf, sizeof(buf), "pool_indirect_%i", socket);
 
-			mp = rte_mempool_create(buf, NB_MBUF,
-							   sizeof(struct rte_mbuf), 32,
-							   sizeof(struct rte_pktmbuf_pool_private),
-							   rte_pktmbuf_pool_init, NULL,
-							   rte_pktmbuf_init, NULL,
-							   socket, 0);
+			mp = rte_pktmbuf_pool_create(buf, NB_MBUF, 32, 0, 0,
+				socket);
 			if (mp == NULL) {
 				RTE_LOG(ERR, IP_FRAG, "Cannot create indirect mempool\n");
 				return -1;
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index 61d71c3..275fb35 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -146,8 +146,7 @@ struct app_params app = {
 	.bsz_swq_wr = 64,
 
 	/* Buffer pool */
-	.pool_buffer_size = 2048 + sizeof(struct rte_mbuf) +
-		RTE_PKTMBUF_HEADROOM,
+	.pool_buffer_size = 2048 + RTE_PKTMBUF_HEADROOM,
 	.pool_size = 32 * 1024,
 	.pool_cache_size = 256,
 
@@ -363,37 +362,18 @@ app_get_ring_resp(uint32_t core_id)
 static void
 app_init_mbuf_pools(void)
 {
-	struct rte_pktmbuf_pool_private indirect_mbp_priv;
-
 	/* Init the buffer pool */
 	RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n");
-	app.pool = rte_mempool_create(
-		"mempool",
-		app.pool_size,
-		app.pool_buffer_size,
-		app.pool_cache_size,
-		sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, NULL,
-		rte_pktmbuf_init, NULL,
-		rte_socket_id(),
-		0);
+	app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size,
+		app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id());
 	if (app.pool == NULL)
 		rte_panic("Cannot create mbuf pool\n");
 
 	/* Init the indirect buffer pool */
 	RTE_LOG(INFO, USER1, "Creating the indirect mbuf pool ...\n");
-	indirect_mbp_priv.mbuf_data_room_size = 0;
-	indirect_mbp_priv.mbuf_priv_size = sizeof(struct app_pkt_metadata);
-	app.indirect_pool = rte_mempool_create(
-		"indirect mempool",
-		app.pool_size,
-		sizeof(struct rte_mbuf) + sizeof(struct app_pkt_metadata),
-		app.pool_cache_size,
-		sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, &indirect_mbp_priv,
-		rte_pktmbuf_init, NULL,
-		rte_socket_id(),
-		0);
+	app.indirect_pool = rte_pktmbuf_pool_create("indirect mempool",
+		app.pool_size, app.pool_cache_size,
+		sizeof(struct app_pkt_metadata), 0, rte_socket_id());
 	if (app.indirect_pool == NULL)
 		rte_panic("Cannot create mbuf pool\n");
 
diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index 19832d8..575e989 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -77,13 +77,12 @@
 #define	MCAST_CLONE_PORTS	2
 #define	MCAST_CLONE_SEGS	2
 
-#define	PKT_MBUF_SIZE	(2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define	PKT_MBUF_DATA_SIZE	(2048 + RTE_PKTMBUF_HEADROOM)
 #define	NB_PKT_MBUF	8192
 
-#define	HDR_MBUF_SIZE	(sizeof(struct rte_mbuf) + 2 * RTE_PKTMBUF_HEADROOM)
+#define	HDR_MBUF_DATA_SIZE	(2 * RTE_PKTMBUF_HEADROOM)
 #define	NB_HDR_MBUF	(NB_PKT_MBUF * MAX_PORTS)
 
-#define	CLONE_MBUF_SIZE	(sizeof(struct rte_mbuf))
 #define	NB_CLONE_MBUF	(NB_PKT_MBUF * MCAST_CLONE_PORTS * MCAST_CLONE_SEGS * 2)
 
 /* allow max jumbo frame 9.5 KB */
@@ -690,26 +689,20 @@ main(int argc, char **argv)
 		rte_exit(EXIT_FAILURE, "Invalid IPV4_MULTICAST parameters\n");
 
 	/* create the mbuf pools */
-	packet_pool = rte_mempool_create("packet_pool", NB_PKT_MBUF,
-	    PKT_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
-	    rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-	    rte_socket_id(), 0);
+	packet_pool = rte_pktmbuf_pool_create("packet_pool", NB_PKT_MBUF, 32,
+		0, PKT_MBUF_DATA_SIZE, rte_socket_id());
 
 	if (packet_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init packet mbuf pool\n");
 
-	header_pool = rte_mempool_create("header_pool", NB_HDR_MBUF,
-	    HDR_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
-	    rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-	    rte_socket_id(), 0);
+	header_pool = rte_pktmbuf_pool_create("header_pool", NB_HDR_MBUF, 32,
+		0, HDR_MBUF_DATA_SIZE, rte_socket_id());
 
 	if (header_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init header mbuf pool\n");
 
-	clone_pool = rte_mempool_create("clone_pool", NB_CLONE_MBUF,
-	    CLONE_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
-	    rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-	    rte_socket_id(), 0);
+	clone_pool = rte_pktmbuf_pool_create("clone_pool", NB_CLONE_MBUF, 32,
+		0, 0, rte_socket_id());
 
 	if (clone_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init clone mbuf pool\n");
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 19d25d4..96ca473 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -80,9 +80,8 @@
 /* Max size of a single packet */
 #define MAX_PACKET_SZ           2048
 
-/* Number of bytes needed for each mbuf */
-#define MBUF_SZ \
-	(MAX_PACKET_SZ + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+/* Size of the data buffer in each mbuf */
+#define MBUF_DATA_SZ (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM)
 
 /* Number of mbufs in mempool that is created */
 #define NB_MBUF                 (8192 * 16)
@@ -867,11 +866,8 @@ main(int argc, char** argv)
 		rte_exit(EXIT_FAILURE, "Could not parse input parameters\n");
 
 	/* Create the mbuf pool */
-	pktmbuf_pool = rte_mempool_create("mbuf_pool", NB_MBUF, MBUF_SZ,
-			MEMPOOL_CACHE_SZ,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-			rte_socket_id(), 0);
+	pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
+		MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, rte_socket_id());
 	if (pktmbuf_pool == NULL) {
 		rte_exit(EXIT_FAILURE, "Could not initialise mbuf pool\n");
 		return -1;
diff --git a/examples/l2fwd-ivshmem/host/host.c b/examples/l2fwd-ivshmem/host/host.c
index 4f8d23e..197f22b 100644
--- a/examples/l2fwd-ivshmem/host/host.c
+++ b/examples/l2fwd-ivshmem/host/host.c
@@ -71,7 +71,7 @@ static uint32_t l2fwd_ivshmem_enabled_port_mask = 0;
 static struct ether_addr l2fwd_ivshmem_ports_eth_addr[RTE_MAX_ETHPORTS];
 
 #define NB_MBUF   8192
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 #define MAX_RX_QUEUE_PER_LCORE 16
 #define MAX_TX_QUEUE_PER_PORT 16
@@ -670,12 +670,8 @@ int main(int argc, char **argv)
 
 	/* create a shared mbuf pool */
 	l2fwd_ivshmem_pktmbuf_pool =
-		rte_mempool_create(MBUF_MP_NAME, NB_MBUF,
-				   MBUF_SIZE, 32,
-				   sizeof(struct rte_pktmbuf_pool_private),
-				   rte_pktmbuf_pool_init, NULL,
-				   rte_pktmbuf_init, NULL,
-				   rte_socket_id(), 0);
+		rte_pktmbuf_pool_create(MBUF_MP_NAME, NB_MBUF, 32,
+			0, MBUF_DATA_SIZE, rte_socket_id());
 	if (l2fwd_ivshmem_pktmbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
 
diff --git a/examples/l2fwd-jobstats/main.c b/examples/l2fwd-jobstats/main.c
index f990045..fcebbda 100644
--- a/examples/l2fwd-jobstats/main.c
+++ b/examples/l2fwd-jobstats/main.c
@@ -70,7 +70,7 @@
 
 #define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   8192
 
 #define MAX_PKT_BURST 32
@@ -833,12 +833,8 @@ main(int argc, char **argv)
 
 	/* create the mbuf pool */
 	l2fwd_pktmbuf_pool =
-		rte_mempool_create("mbuf_pool", NB_MBUF,
-				   MBUF_SIZE, 32,
-				   sizeof(struct rte_pktmbuf_pool_private),
-				   rte_pktmbuf_pool_init, NULL,
-				   rte_pktmbuf_init, NULL,
-				   rte_socket_id(), 0);
+		rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32,
+			0, MBUF_DATA_SIZE, rte_socket_id());
 	if (l2fwd_pktmbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
 
diff --git a/examples/l2fwd/main.c b/examples/l2fwd/main.c
index 17621ee..d0a1ec8 100644
--- a/examples/l2fwd/main.c
+++ b/examples/l2fwd/main.c
@@ -71,7 +71,7 @@
 
 #define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   8192
 
 #define MAX_PKT_BURST 32
@@ -560,13 +560,8 @@ main(int argc, char **argv)
 		rte_exit(EXIT_FAILURE, "Invalid L2FWD arguments\n");
 
 	/* create the mbuf pool */
-	l2fwd_pktmbuf_pool =
-		rte_mempool_create("mbuf_pool", NB_MBUF,
-				   MBUF_SIZE, 32,
-				   sizeof(struct rte_pktmbuf_pool_private),
-				   rte_pktmbuf_pool_init, NULL,
-				   rte_pktmbuf_init, NULL,
-				   rte_socket_id(), 0);
+	l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32,
+		0, MBUF_DATA_SIZE, rte_socket_id());
 	if (l2fwd_pktmbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
 
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index fce55f3..1a04004 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -80,7 +80,7 @@
 
 #define MEMPOOL_CACHE_SIZE 256
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * This expression is used to calculate the number of mbufs needed
@@ -1848,12 +1848,9 @@ init_mem(unsigned nb_mbuf)
 		if (pktmbuf_pool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
 			pktmbuf_pool[socketid] =
-				rte_mempool_create(s, nb_mbuf, MBUF_SIZE,
-					MEMPOOL_CACHE_SIZE,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, 0);
+				rte_pktmbuf_pool_create(s, nb_mbuf,
+					MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+					socketid);
 			if (pktmbuf_pool[socketid] == NULL)
 				rte_exit(EXIT_FAILURE,
 					"Cannot init mbuf pool on socket %d\n",
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 4221239..bb0b66f 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -121,7 +121,7 @@
 
 #define MEMPOOL_CACHE_SIZE 256
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * This expression is used to calculate the number of mbufs needed depending on
@@ -1379,12 +1379,9 @@ init_mem(unsigned nb_mbuf)
 		if (pktmbuf_pool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
 			pktmbuf_pool[socketid] =
-				rte_mempool_create(s, nb_mbuf,
-					MBUF_SIZE, MEMPOOL_CACHE_SIZE,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, 0);
+				rte_pktmbuf_pool_create(s, nb_mbuf,
+					MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+					socketid);
 			if (pktmbuf_pool[socketid] == NULL)
 				rte_exit(EXIT_FAILURE,
 					"Cannot init mbuf pool on socket %d\n",
diff --git a/examples/l3fwd-vf/main.c b/examples/l3fwd-vf/main.c
index 20ba03a..f007bc1 100644
--- a/examples/l3fwd-vf/main.c
+++ b/examples/l3fwd-vf/main.c
@@ -94,7 +94,7 @@
 
 #define MEMPOOL_CACHE_SIZE 256
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * This expression is used to calculate the number of mbufs needed depending on user input, taking
@@ -924,13 +924,9 @@ init_mem(unsigned nb_mbuf)
 		}
 		if (pktmbuf_pool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
-			pktmbuf_pool[socketid] =
-				rte_mempool_create(s, nb_mbuf, MBUF_SIZE,
-						   MEMPOOL_CACHE_SIZE,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, 0);
+			pktmbuf_pool[socketid] = rte_pktmbuf_pool_create(s,
+				nb_mbuf, MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+				socketid);
 			if (pktmbuf_pool[socketid] == NULL)
 				rte_exit(EXIT_FAILURE, "Cannot init mbuf pool on socket %d\n", socketid);
 			else
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 90e177f..7871038 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -119,7 +119,7 @@
 
 #define MEMPOOL_CACHE_SIZE 256
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * This expression is used to calculate the number of mbufs needed depending on user input, taking
@@ -2315,11 +2315,9 @@ init_mem(unsigned nb_mbuf)
 		if (pktmbuf_pool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
 			pktmbuf_pool[socketid] =
-				rte_mempool_create(s, nb_mbuf, MBUF_SIZE, MEMPOOL_CACHE_SIZE,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, 0);
+				rte_pktmbuf_pool_create(s, nb_mbuf,
+					MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+					socketid);
 			if (pktmbuf_pool[socketid] == NULL)
 				rte_exit(EXIT_FAILURE,
 						"Cannot init mbuf pool on socket %d\n", socketid);
diff --git a/examples/link_status_interrupt/main.c b/examples/link_status_interrupt/main.c
index e6fb218..6adbd79 100644
--- a/examples/link_status_interrupt/main.c
+++ b/examples/link_status_interrupt/main.c
@@ -72,7 +72,7 @@
 
 #define RTE_LOGTYPE_LSI RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   8192
 
 #define MAX_PKT_BURST 32
@@ -614,12 +614,8 @@ main(int argc, char **argv)
 
 	/* create the mbuf pool */
 	lsi_pktmbuf_pool =
-		rte_mempool_create("mbuf_pool", NB_MBUF,
-				   MBUF_SIZE, 32,
-				   sizeof(struct rte_pktmbuf_pool_private),
-				   rte_pktmbuf_pool_init, NULL,
-				   rte_pktmbuf_init, NULL,
-				   rte_socket_id(), 0);
+		rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32, 0,
+			MBUF_DATA_SIZE, rte_socket_id());
 	if (lsi_pktmbuf_pool == NULL)
 		rte_panic("Cannot init mbuf pool\n");
 
diff --git a/examples/load_balancer/init.c b/examples/load_balancer/init.c
index b35f797..5a56078 100644
--- a/examples/load_balancer/init.c
+++ b/examples/load_balancer/init.c
@@ -127,16 +127,10 @@ app_init_mbuf_pools(void)
 
 		snprintf(name, sizeof(name), "mbuf_pool_%u", socket);
 		printf("Creating the mbuf pool for socket %u ...\n", socket);
-		app.pools[socket] = rte_mempool_create(
-			name,
-			APP_DEFAULT_MEMPOOL_BUFFERS,
-			APP_DEFAULT_MBUF_SIZE,
+		app.pools[socket] = rte_pktmbuf_pool_create(
+			name, APP_DEFAULT_MEMPOOL_BUFFERS,
 			APP_DEFAULT_MEMPOOL_CACHE_SIZE,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL,
-			rte_pktmbuf_init, NULL,
-			socket,
-			0);
+			0, APP_DEFAULT_MBUF_DATA_SIZE, socket);
 		if (app.pools[socket] == NULL) {
 			rte_panic("Cannot create mbuf pool on socket %u\n", socket);
 		}
diff --git a/examples/load_balancer/main.h b/examples/load_balancer/main.h
index d9f878b..17c0f77 100644
--- a/examples/load_balancer/main.h
+++ b/examples/load_balancer/main.h
@@ -82,8 +82,8 @@
 
 
 /* Mempools */
-#ifndef APP_DEFAULT_MBUF_SIZE
-#define APP_DEFAULT_MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#ifndef APP_DEFAULT_MBUF_DATA_SIZE
+#define APP_DEFAULT_MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #endif
 
 #ifndef APP_DEFAULT_MEMPOOL_BUFFERS
diff --git a/examples/multi_process/client_server_mp/mp_server/init.c b/examples/multi_process/client_server_mp/mp_server/init.c
index aadee76..dc3647d 100644
--- a/examples/multi_process/client_server_mp/mp_server/init.c
+++ b/examples/multi_process/client_server_mp/mp_server/init.c
@@ -71,9 +71,7 @@
 #define MBUFS_PER_CLIENT 1536
 #define MBUFS_PER_PORT 1536
 #define MBUF_CACHE_SIZE 512
-#define MBUF_OVERHEAD (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
-#define RX_MBUF_DATA_SIZE 2048
-#define MBUF_SIZE (RX_MBUF_DATA_SIZE + MBUF_OVERHEAD)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 #define RTE_MP_RX_DESC_DEFAULT 512
 #define RTE_MP_TX_DESC_DEFAULT 512
@@ -104,10 +102,8 @@ init_mbuf_pools(void)
 	 * seems faster to use a cache instead */
 	printf("Creating mbuf pool '%s' [%u mbufs] ...\n",
 			PKTMBUF_POOL_NAME, num_mbufs);
-	pktmbuf_pool = rte_mempool_create(PKTMBUF_POOL_NAME, num_mbufs,
-			MBUF_SIZE, MBUF_CACHE_SIZE,
-			sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init,
-			NULL, rte_pktmbuf_init, NULL, rte_socket_id(), NO_FLAGS );
+	pktmbuf_pool = rte_pktmbuf_pool_create(PKTMBUF_POOL_NAME, num_mbufs,
+		MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE, rte_socket_id());
 
 	return (pktmbuf_pool == NULL); /* 0  on success */
 }
diff --git a/examples/multi_process/symmetric_mp/main.c b/examples/multi_process/symmetric_mp/main.c
index 48448b4..7829c86 100644
--- a/examples/multi_process/symmetric_mp/main.c
+++ b/examples/multi_process/symmetric_mp/main.c
@@ -78,7 +78,7 @@
 
 #define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUFS 64*1024 /* use 64k mbufs */
 #define MBUF_CACHE_SIZE 256
 #define PKT_BURST 32
@@ -446,11 +446,9 @@ main(int argc, char **argv)
 	proc_type = rte_eal_process_type();
 	mp = (proc_type == RTE_PROC_SECONDARY) ?
 			rte_mempool_lookup(_SMP_MBUF_POOL) :
-			rte_mempool_create(_SMP_MBUF_POOL, NB_MBUFS, MBUF_SIZE,
-					MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					rte_socket_id(), 0);
+			rte_pktmbuf_pool_create(_SMP_MBUF_POOL, NB_MBUFS,
+				MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+				rte_socket_id());
 	if (mp == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot get memory pool for buffers\n");
 
diff --git a/examples/netmap_compat/bridge/bridge.c b/examples/netmap_compat/bridge/bridge.c
index 0a8efbe..2d935cb 100644
--- a/examples/netmap_compat/bridge/bridge.c
+++ b/examples/netmap_compat/bridge/bridge.c
@@ -47,9 +47,8 @@
 #include "compat_netmap.h"
 
 
-#define	BUF_SIZE	2048
-#define MBUF_SIZE	(BUF_SIZE + sizeof(struct rte_mbuf) + \
-	RTE_PKTMBUF_HEADROOM)
+#define BUF_SIZE	(2048)
+#define MBUF_DATA_SIZE	(BUF_SIZE + RTE_PKTMBUF_HEADROOM)
 
 #define MBUF_PER_POOL	8192
 
@@ -272,11 +271,8 @@ int main(int argc, char *argv[])
 	if (rte_eth_dev_count() < 1)
 		rte_exit(EXIT_FAILURE, "Not enough ethernet ports available\n");
 
-	pool = rte_mempool_create("mbuf_pool", MBUF_PER_POOL, MBUF_SIZE, 32,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL,
-				rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+	pool = rte_pktmbuf_pool_create("mbuf_pool", MBUF_PER_POOL, 32, 0,
+		MBUF_DATA_SIZE, rte_socket_id());
 	if (pool == NULL)
 		rte_exit(EXIT_FAILURE, "Couldn't create mempool\n");
 
diff --git a/examples/packet_ordering/main.c b/examples/packet_ordering/main.c
index f0a1b5a..5403c33 100644
--- a/examples/packet_ordering/main.c
+++ b/examples/packet_ordering/main.c
@@ -50,7 +50,7 @@
 #define MAX_PKTS_BURST 32
 #define REORDER_BUFFER_SIZE 8192
 #define MBUF_PER_POOL 65535
-#define MBUF_SIZE (1600 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (1600 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_POOL_CACHE_SIZE 250
 
 #define RING_SIZE 16384
@@ -622,12 +622,9 @@ main(int argc, char **argv)
 		rte_exit(EXIT_FAILURE, "Error: number of ports must be even, except "
 				"when using a single port\n");
 
-	mbuf_pool = rte_mempool_create("mbuf_pool", MBUF_PER_POOL, MBUF_SIZE,
-			MBUF_POOL_CACHE_SIZE,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL,
-			rte_pktmbuf_init, NULL,
-			rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", MBUF_PER_POOL,
+			MBUF_POOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+			rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno));
 
diff --git a/examples/qos_meter/main.c b/examples/qos_meter/main.c
index 4a981c6..a5e2510 100644
--- a/examples/qos_meter/main.c
+++ b/examples/qos_meter/main.c
@@ -70,7 +70,7 @@
  * Buffer pool configuration
  *
  ***/
-#define MBUF_SIZE           (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE      (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF             8192
 #define MEMPOOL_CACHE_SIZE  256
 
@@ -360,9 +360,8 @@ main(int argc, char **argv)
 		rte_exit(EXIT_FAILURE, "Invalid input arguments\n");
 
 	/* Buffer pool init */
-	pool = rte_mempool_create("pool", NB_MBUF, MBUF_SIZE, MEMPOOL_CACHE_SIZE,
-		sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL,
-		rte_pktmbuf_init, NULL, rte_socket_id(), 0);
+	pool = rte_pktmbuf_pool_create("pool", NB_MBUF, MEMPOOL_CACHE_SIZE,
+		0, MBUF_DATA_SIZE, rte_socket_id());
 	if (pool == NULL)
 		rte_exit(EXIT_FAILURE, "Buffer pool creation error\n");
 
diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c
index f38802e..aaf3466 100644
--- a/examples/qos_sched/init.c
+++ b/examples/qos_sched/init.c
@@ -335,13 +335,9 @@ int app_init(void)
 
 		/* create the mbuf pools for each RX Port */
 		snprintf(pool_name, MAX_NAME_LEN, "mbuf_pool%u", i);
-		qos_conf[i].mbuf_pool = rte_mempool_create(pool_name, mp_size, MBUF_SIZE,
-						burst_conf.rx_burst * 4,
-						sizeof(struct rte_pktmbuf_pool_private),
-						rte_pktmbuf_pool_init, NULL,
-						rte_pktmbuf_init, NULL,
-						rte_eth_dev_socket_id(qos_conf[i].rx_port),
-						0);
+		qos_conf[i].mbuf_pool = rte_pktmbuf_pool_create(pool_name,
+			mp_size, burst_conf.rx_burst * 4, 0, MBUF_DATA_SIZE,
+			rte_eth_dev_socket_id(qos_conf[i].rx_port));
 		if (qos_conf[i].mbuf_pool == NULL)
 			rte_exit(EXIT_FAILURE, "Cannot init mbuf pool for socket %u\n", i);
 
diff --git a/examples/qos_sched/main.h b/examples/qos_sched/main.h
index 971ec27..0e6f264 100644
--- a/examples/qos_sched/main.h
+++ b/examples/qos_sched/main.h
@@ -50,7 +50,7 @@ extern "C" {
 #define APP_RX_DESC_DEFAULT 128
 #define APP_TX_DESC_DEFAULT 256
 
-#define MBUF_SIZE (1528 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (1528 + RTE_PKTMBUF_HEADROOM)
 #define APP_RING_SIZE (8*1024)
 #define NB_MBUF   (2*1024*1024)
 
diff --git a/examples/quota_watermark/include/conf.h b/examples/quota_watermark/include/conf.h
index 8d95aaa..e80aca5 100644
--- a/examples/quota_watermark/include/conf.h
+++ b/examples/quota_watermark/include/conf.h
@@ -40,7 +40,7 @@
 #define RX_DESC_PER_QUEUE   128
 #define TX_DESC_PER_QUEUE   512
 
-#define MBUF_SIZE     (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE     (2048 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_PER_POOL 8192
 
 #define QUOTA_WATERMARK_MEMZONE_NAME "qw_global_vars"
diff --git a/examples/quota_watermark/qw/main.c b/examples/quota_watermark/qw/main.c
index f269546..8ed0214 100644
--- a/examples/quota_watermark/qw/main.c
+++ b/examples/quota_watermark/qw/main.c
@@ -335,11 +335,8 @@ main(int argc, char **argv)
         rte_exit(EXIT_FAILURE, "Invalid quota/watermark argument(s)\n");
 
     /* Create a pool of mbuf to store packets */
-    mbuf_pool = rte_mempool_create("mbuf_pool", MBUF_PER_POOL, MBUF_SIZE, 32,
-                                   sizeof(struct rte_pktmbuf_pool_private),
-                                   rte_pktmbuf_pool_init, NULL,
-                                   rte_pktmbuf_init, NULL,
-                                   rte_socket_id(), 0);
+    mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", MBUF_PER_POOL, 32, 0,
+	    MBUF_DATA_SIZE, rte_socket_id());
     if (mbuf_pool == NULL)
         rte_panic("%s\n", rte_strerror(rte_errno));
 
diff --git a/examples/rxtx_callbacks/main.c b/examples/rxtx_callbacks/main.c
index 21117ce..fb8da51 100644
--- a/examples/rxtx_callbacks/main.c
+++ b/examples/rxtx_callbacks/main.c
@@ -43,7 +43,7 @@
 #define TX_RING_SIZE 512
 
 #define NUM_MBUFS 8191
-#define MBUF_SIZE (1600 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (1600 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE 250
 #define BURST_SIZE 32
 
@@ -204,12 +204,9 @@ main(int argc, char *argv[])
 	if (nb_ports < 2 || (nb_ports & 1))
 		rte_exit(EXIT_FAILURE, "Error: number of ports must be even\n");
 
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
-				       MBUF_SIZE, MBUF_CACHE_SIZE,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init, NULL,
-				       rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+		NUM_MBUFS * nb_ports, MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+		rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/examples/skeleton/basicfwd.c b/examples/skeleton/basicfwd.c
index 1bce6e7..ae606bf 100644
--- a/examples/skeleton/basicfwd.c
+++ b/examples/skeleton/basicfwd.c
@@ -43,7 +43,7 @@
 #define TX_RING_SIZE 512
 
 #define NUM_MBUFS 8191
-#define MBUF_SIZE (1600 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (1600 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE 250
 #define BURST_SIZE 32
 
@@ -190,15 +190,8 @@ main(int argc, char *argv[])
 		rte_exit(EXIT_FAILURE, "Error: number of ports must be even\n");
 
 	/* Creates a new mempool in memory to hold the mbufs. */
-	mbuf_pool = rte_mempool_create("MBUF_POOL",
-				       NUM_MBUFS * nb_ports,
-				       MBUF_SIZE,
-				       MBUF_CACHE_SIZE,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init,      NULL,
-				       rte_socket_id(),
-				       0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
+		MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE, rte_socket_id());
 
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index fc73d1e..22d6a4b 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -67,7 +67,7 @@
 							(num_switching_cores*MBUF_CACHE_SIZE))
 
 #define MBUF_CACHE_SIZE 128
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * No frame data buffer allocated from host are required for zero copy
@@ -75,8 +75,7 @@
  * directly use it.
  */
 #define VIRTIO_DESCRIPTOR_LEN_ZCP 1518
-#define MBUF_SIZE_ZCP (VIRTIO_DESCRIPTOR_LEN_ZCP + sizeof(struct rte_mbuf) \
-	+ RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE_ZCP (VIRTIO_DESCRIPTOR_LEN_ZCP + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE_ZCP 0
 
 #define MAX_PKT_BURST 32 		/* Max burst size for RX/TX */
@@ -2844,11 +2843,8 @@ static void
 setup_mempool_tbl(int socket, uint32_t index, char *pool_name,
 	char *ring_name, uint32_t nb_mbuf)
 {
-	vpool_array[index].pool
-		= rte_mempool_create(pool_name, nb_mbuf, MBUF_SIZE_ZCP,
-		MBUF_CACHE_SIZE_ZCP, sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, NULL,
-		rte_pktmbuf_init, NULL, socket, 0);
+	vpool_array[index].pool	= rte_pktmbuf_pool_create(pool_name, nb_mbuf,
+		MBUF_CACHE_SIZE_ZCP, 0, MBUF_DATA_SIZE_ZCP, socket);
 	if (vpool_array[index].pool != NULL) {
 		vpool_array[index].ring
 			= rte_ring_create(ring_name,
@@ -2932,15 +2928,9 @@ main(int argc, char *argv[])
 
 	if (zero_copy == 0) {
 		/* Create the mbuf pool. */
-		mbuf_pool = rte_mempool_create(
-				"MBUF_POOL",
-				NUM_MBUFS_PER_PORT
-				* valid_num_ports,
-				MBUF_SIZE, MBUF_CACHE_SIZE,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL,
-				rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+		mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+			NUM_MBUFS_PER_PORT * valid_num_ports, MBUF_CACHE_SIZE,
+			0, MBUF_DATA_SIZE, rte_socket_id());
 		if (mbuf_pool == NULL)
 			rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/examples/vhost_xen/main.c b/examples/vhost_xen/main.c
index b4a86e3..b672bf3 100644
--- a/examples/vhost_xen/main.c
+++ b/examples/vhost_xen/main.c
@@ -67,7 +67,7 @@
 							(num_switching_cores*MBUF_CACHE_SIZE))
 
 #define MBUF_CACHE_SIZE 64
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * RX and TX Prefetch, Host, and Write-back threshold values should be
@@ -1474,12 +1474,9 @@ main(int argc, char *argv[])
 	}
 
 	/* Create the mbuf pool. */
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS_PER_PORT * valid_num_ports,
-				       MBUF_SIZE, MBUF_CACHE_SIZE,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init, NULL,
-				       rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+		NUM_MBUFS_PER_PORT * valid_num_ports, MBUF_CACHE_SIZE, 0,
+		MBUF_DATA_SIZE, rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/examples/vmdq/main.c b/examples/vmdq/main.c
index 7001860..7596bac 100644
--- a/examples/vmdq/main.c
+++ b/examples/vmdq/main.c
@@ -76,7 +76,7 @@
  */
 #define NUM_MBUFS_PER_PORT (128*512)
 #define MBUF_CACHE_SIZE 64
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 #define MAX_PKT_BURST 32
 
@@ -613,12 +613,9 @@ main(int argc, char *argv[])
 		rte_exit(EXIT_FAILURE, "Error with valid ports number is not even or less than 2\n");
 	}
 
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS_PER_PORT * nb_ports,
-				       MBUF_SIZE, MBUF_CACHE_SIZE,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init, NULL,
-				       rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+		NUM_MBUFS_PER_PORT * nb_ports, MBUF_CACHE_SIZE,
+		0, MBUF_DATA_SIZE, rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/examples/vmdq_dcb/main.c b/examples/vmdq_dcb/main.c
index 048c167..3c7f2b3 100644
--- a/examples/vmdq_dcb/main.c
+++ b/examples/vmdq_dcb/main.c
@@ -74,7 +74,7 @@
 
 #define NUM_MBUFS 64*1024
 #define MBUF_CACHE_SIZE 64
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 #define INVALID_PORT_ID 0xFF
 
@@ -441,12 +441,8 @@ main(int argc, char *argv[])
 		rte_exit(EXIT_FAILURE, "Error with valid ports number is not even or less than 2\n");
 	}
 
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
-				       MBUF_SIZE, MBUF_CACHE_SIZE,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init, NULL,
-				       rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
+		MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE, rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/lib/librte_pmd_bond/rte_eth_bond_alb.c b/lib/librte_pmd_bond/rte_eth_bond_alb.c
index 5778b25..6df318e 100644
--- a/lib/librte_pmd_bond/rte_eth_bond_alb.c
+++ b/lib/librte_pmd_bond/rte_eth_bond_alb.c
@@ -63,7 +63,7 @@ bond_mode_alb_enable(struct rte_eth_dev *bond_dev)
 	struct bond_dev_private *internals = bond_dev->data->dev_private;
 	struct client_data *hash_table = internals->mode6.client_table;
 
-	uint16_t element_size;
+	uint16_t data_size;
 	char mem_name[RTE_ETH_NAME_MAX_LEN];
 	int socket_id = bond_dev->pci_dev->numa_node;
 
@@ -79,15 +79,13 @@ bond_mode_alb_enable(struct rte_eth_dev *bond_dev)
 		 * 256 is size of ETH header, ARP header and nested VLAN headers.
 		 * The value is chosen to be cache aligned.
 		 */
-		element_size = 256 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM;
+		data_size = 256 + RTE_PKTMBUF_HEADROOM;
 		snprintf(mem_name, sizeof(mem_name), "%s_MODE6", bond_dev->data->name);
-		internals->mode6.mempool = rte_mempool_create(mem_name,
-				512 * RTE_MAX_ETHPORTS,
-				element_size,
-				RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
-						32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
-				sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init,
-				NULL, rte_pktmbuf_init, NULL, socket_id, 0);
+		internals->mode6.mempool = rte_pktmbuf_pool_create(mem_name,
+			512 * RTE_MAX_ETHPORTS,
+			RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
+				32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
+			0, data_size, socket_id);
 
 		if (internals->mode6.mempool == NULL) {
 			RTE_LOG(ERR, PMD, "%s: Failed to initialize ALB mempool.\n",
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v4 08/12] mbuf: fix clone support when application uses private mbuf data
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
                           ` (6 preceding siblings ...)
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 07/12] apps: use rte_pktmbuf_pool_create to create mbuf pools Olivier Matz
@ 2015-04-20 15:41         ` Olivier Matz
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 09/12] mbuf: allow to clone an indirect mbuf Olivier Matz
                           ` (5 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-20 15:41 UTC (permalink / raw)
  To: dev

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 <olivier.matz@6wind.com>
Reviewed-by: Zoltan Kiss <zoltan.kiss@linaro.org>
---
 examples/vhost/main.c      |  4 ++--
 lib/librte_mbuf/rte_mbuf.c |  2 +-
 lib/librte_mbuf/rte_mbuf.h | 59 +++++++++++++++++++++++++++++++---------------
 3 files changed, 43 insertions(+), 22 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 22d6a4b..195d82f 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -138,7 +138,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;
@@ -1549,7 +1549,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 b013607..784ae8b 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -129,7 +129,7 @@ rte_pktmbuf_init(struct rte_mempool *mp,
 
 	memset(m, 0, mp->elt_size);
 
-	/* start of buffer is just after mbuf structure */
+	/* start of buffer is after mbuf structure and priv data */
 	m->buf_addr = (char *)m + mbuf_size;
 	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mbuf_size;
 	m->buf_len = (uint16_t)buf_len;
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 42db8e3..5c01c5b 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -320,16 +320,40 @@ struct rte_mbuf {
 	};
 } __rte_cache_aligned;
 
+static inline uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp);
+
 /**
- * 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;
+       md = (struct rte_mbuf *)((char *)mi->buf_addr -
+	       sizeof(*mi) - rte_pktmbuf_priv_size(mi->pool));
+       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.
+ *
+ * @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) + rte_pktmbuf_priv_size(md->pool);
+       return buffer_addr;
+}
 
 /**
  * Returns TRUE if given mbuf is indirect, or FALSE otherwise.
@@ -771,6 +795,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:
@@ -784,7 +809,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) &&
@@ -815,7 +839,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.
@@ -823,22 +848,18 @@ 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_mempool *mp = m->pool;
+	uint32_t mbuf_size, buf_len;
 
-	m->buf_addr = buf;
+	mbuf_size = sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(mp);
+	buf_len = rte_pktmbuf_data_room_size(mp);
+	m->buf_addr = rte_mbuf_to_baddr(m);
+	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mbuf_size;
 	m->buf_len = (uint16_t)buf_len;
-
-	m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
-			RTE_PKTMBUF_HEADROOM : m->buf_len;
-
+	m->data_off = RTE_MIN(RTE_PKTMBUF_HEADROOM, (uint16_t)m->buf_len);
 	m->data_len = 0;
-
 	m->ol_flags = 0;
 }
 
@@ -867,7 +888,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);
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v4 09/12] mbuf: allow to clone an indirect mbuf
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
                           ` (7 preceding siblings ...)
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 08/12] mbuf: fix clone support when application uses private mbuf data Olivier Matz
@ 2015-04-20 15:41         ` Olivier Matz
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 10/12] test/mbuf: rename mc variable in m Olivier Matz
                           ` (4 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-20 15:41 UTC (permalink / raw)
  To: dev

Remove one limitation of rte_pktmbuf_attach(): "mbuf we're attaching to
must be direct".

Now, when we attach to an indirect mbuf:
- copy the all relevant fields (addr, len, offload, ...) as before
- get the pointer to the mbuf that embeds the data buffer (direct mbuf),
  and increase the reference counter of this one.

When detaching the mbuf, we can retrieve this direct mbuf as the pointer
is determined from the buffer address.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_mbuf/rte_mbuf.h | 46 ++++++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 20 deletions(-)

diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 5c01c5b..df54a46 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -799,43 +799,49 @@ static inline struct rte_mbuf *rte_pktmbuf_alloc(struct rte_mempool *mp)
  * After attachment we refer the mbuf we attached as 'indirect',
  * while mbuf we attached to as 'direct'.
  * Right now, not supported:
- *  - attachment to indirect mbuf (e.g. - md  has to be direct).
  *  - attachment for already indirect mbuf (e.g. - mi has to be direct).
  *  - mbuf we trying to attach (mi) is used by someone else
  *    e.g. it's reference counter is greater then 1.
  *
  * @param mi
  *   The indirect packet mbuf.
- * @param md
- *   The direct packet mbuf.
+ * @param m
+ *   The packet mbuf we're attaching to.
  */
-static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md)
+static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
 {
-	RTE_MBUF_ASSERT(RTE_MBUF_DIRECT(md) &&
-	    RTE_MBUF_DIRECT(mi) &&
+	struct rte_mbuf *md;
+
+	RTE_MBUF_ASSERT(RTE_MBUF_DIRECT(mi) &&
 	    rte_mbuf_refcnt_read(mi) == 1);
 
+	/* if m is not direct, get the mbuf that embeds the data */
+	if (RTE_MBUF_DIRECT(m))
+		md = m;
+	else
+		md = rte_mbuf_from_indirect(m);
+
 	rte_mbuf_refcnt_update(md, 1);
-	mi->buf_physaddr = md->buf_physaddr;
-	mi->buf_addr = md->buf_addr;
-	mi->buf_len = md->buf_len;
-
-	mi->next = md->next;
-	mi->data_off = md->data_off;
-	mi->data_len = md->data_len;
-	mi->port = md->port;
-	mi->vlan_tci = md->vlan_tci;
-	mi->tx_offload = md->tx_offload;
-	mi->hash = md->hash;
+	mi->buf_physaddr = m->buf_physaddr;
+	mi->buf_addr = m->buf_addr;
+	mi->buf_len = m->buf_len;
+
+	mi->next = m->next;
+	mi->data_off = m->data_off;
+	mi->data_len = m->data_len;
+	mi->port = m->port;
+	mi->vlan_tci = m->vlan_tci;
+	mi->tx_offload = m->tx_offload;
+	mi->hash = m->hash;
 
 	mi->next = NULL;
 	mi->pkt_len = mi->data_len;
 	mi->nb_segs = 1;
-	mi->ol_flags = md->ol_flags | IND_ATTACHED_MBUF;
-	mi->packet_type = md->packet_type;
+	mi->ol_flags = m->ol_flags | IND_ATTACHED_MBUF;
+	mi->packet_type = m->packet_type;
 
 	__rte_mbuf_sanity_check(mi, 1);
-	__rte_mbuf_sanity_check(md, 0);
+	__rte_mbuf_sanity_check(m, 0);
 }
 
 /**
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v4 10/12] test/mbuf: rename mc variable in m
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
                           ` (8 preceding siblings ...)
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 09/12] mbuf: allow to clone an indirect mbuf Olivier Matz
@ 2015-04-20 15:41         ` Olivier Matz
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 11/12] test/mbuf: enhance mbuf refcnt test Olivier Matz
                           ` (3 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-20 15:41 UTC (permalink / raw)
  To: dev

It's better to name the mbuf 'm' instead of 'mc' as it's not a clone.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 4774263..2614598 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -320,43 +320,42 @@ fail:
 static int
 testclone_testupdate_testdetach(void)
 {
-	struct rte_mbuf *mc = NULL;
+	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
 
 	/* alloc a mbuf */
-
-	mc = rte_pktmbuf_alloc(pktmbuf_pool);
-	if (mc == NULL)
+	m = rte_pktmbuf_alloc(pktmbuf_pool);
+	if (m == NULL)
 		GOTO_FAIL("ooops not allocating mbuf");
 
-	if (rte_pktmbuf_pkt_len(mc) != 0)
+	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("Bad length");
 
 
 	/* clone the allocated mbuf */
-	clone = rte_pktmbuf_clone(mc, pktmbuf_pool);
+	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 	rte_pktmbuf_free(clone);
 
-	mc->next = rte_pktmbuf_alloc(pktmbuf_pool);
-	if(mc->next == NULL)
+	m->next = rte_pktmbuf_alloc(pktmbuf_pool);
+	if (m->next == NULL)
 		GOTO_FAIL("Next Pkt Null\n");
 
-	clone = rte_pktmbuf_clone(mc, pktmbuf_pool);
+	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 
 	/* free mbuf */
-	rte_pktmbuf_free(mc);
+	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
-	mc = NULL;
+	m = NULL;
 	clone = NULL;
 	return 0;
 
 fail:
-	if (mc)
-		rte_pktmbuf_free(mc);
+	if (m)
+		rte_pktmbuf_free(m);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v4 11/12] test/mbuf: enhance mbuf refcnt test
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
                           ` (9 preceding siblings ...)
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 10/12] test/mbuf: rename mc variable in m Olivier Matz
@ 2015-04-20 15:41         ` Olivier Matz
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 12/12] test/mbuf: verify that cloning a clone works properly Olivier Matz
                           ` (2 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-20 15:41 UTC (permalink / raw)
  To: dev

Check that the data in the cloned mbuf is the same than in the
reference mbuf.
Check that the reference counter is incremented for each segment.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 2614598..01838c6 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -75,6 +75,8 @@
 #define REFCNT_MBUF_NUM         64
 #define REFCNT_RING_SIZE        (REFCNT_MBUF_NUM * REFCNT_MAX_REF)
 
+#define MAGIC_DATA              0x42424242
+
 #define MAKE_STRING(x)          # x
 
 static struct rte_mempool *pktmbuf_pool = NULL;
@@ -322,6 +324,7 @@ testclone_testupdate_testdetach(void)
 {
 	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
+	uint32_t *data;
 
 	/* alloc a mbuf */
 	m = rte_pktmbuf_alloc(pktmbuf_pool);
@@ -331,21 +334,53 @@ testclone_testupdate_testdetach(void)
 	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("Bad length");
 
+	rte_pktmbuf_append(m, sizeof(uint32_t));
+	data = rte_pktmbuf_mtod(m, uint32_t *);
+	*data = MAGIC_DATA;
 
 	/* clone the allocated mbuf */
 	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
+
+	data = rte_pktmbuf_mtod(clone, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone\n");
+
+	if (rte_mbuf_refcnt_read(m) != 2)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	/* free the clone */
 	rte_pktmbuf_free(clone);
+	clone = NULL;
 
+	/* same test with a chained mbuf */
 	m->next = rte_pktmbuf_alloc(pktmbuf_pool);
 	if (m->next == NULL)
 		GOTO_FAIL("Next Pkt Null\n");
 
+	rte_pktmbuf_append(m->next, sizeof(uint32_t));
+	data = rte_pktmbuf_mtod(m->next, uint32_t *);
+	*data = MAGIC_DATA;
+
 	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 
+	data = rte_pktmbuf_mtod(clone, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone\n");
+
+	data = rte_pktmbuf_mtod(clone->next, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone->next\n");
+
+	if (rte_mbuf_refcnt_read(m) != 2)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	if (rte_mbuf_refcnt_read(m->next) != 2)
+		GOTO_FAIL("invalid refcnt in m->next\n");
+
 	/* free mbuf */
 	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
@@ -356,6 +391,8 @@ testclone_testupdate_testdetach(void)
 fail:
 	if (m)
 		rte_pktmbuf_free(m);
+	if (clone)
+		rte_pktmbuf_free(clone);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v4 12/12] test/mbuf: verify that cloning a clone works properly
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
                           ` (10 preceding siblings ...)
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 11/12] test/mbuf: enhance mbuf refcnt test Olivier Matz
@ 2015-04-20 15:41         ` Olivier Matz
  2015-04-20 16:53         ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Neil Horman
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-20 15:41 UTC (permalink / raw)
  To: dev

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 01838c6..b5ae5b7 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -324,6 +324,7 @@ testclone_testupdate_testdetach(void)
 {
 	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
+	struct rte_mbuf *clone2 = NULL;
 	uint32_t *data;
 
 	/* alloc a mbuf */
@@ -381,11 +382,34 @@ testclone_testupdate_testdetach(void)
 	if (rte_mbuf_refcnt_read(m->next) != 2)
 		GOTO_FAIL("invalid refcnt in m->next\n");
 
+	/* try to clone the clone */
+
+	clone2 = rte_pktmbuf_clone(clone, pktmbuf_pool);
+	if (clone2 == NULL)
+		GOTO_FAIL("cannot clone the clone\n");
+
+	data = rte_pktmbuf_mtod(clone2, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone2\n");
+
+	data = rte_pktmbuf_mtod(clone2->next, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone2->next\n");
+
+	if (rte_mbuf_refcnt_read(m) != 3)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	if (rte_mbuf_refcnt_read(m->next) != 3)
+		GOTO_FAIL("invalid refcnt in m->next\n");
+
 	/* free mbuf */
 	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
+	rte_pktmbuf_free(clone2);
+
 	m = NULL;
 	clone = NULL;
+	clone2 = NULL;
 	return 0;
 
 fail:
@@ -393,6 +417,8 @@ fail:
 		rte_pktmbuf_free(m);
 	if (clone)
 		rte_pktmbuf_free(clone);
+	if (clone2)
+		rte_pktmbuf_free(clone2);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
                           ` (11 preceding siblings ...)
  2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 12/12] test/mbuf: verify that cloning a clone works properly Olivier Matz
@ 2015-04-20 16:53         ` Neil Horman
  2015-04-20 17:07           ` Olivier MATZ
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
  13 siblings, 1 reply; 101+ messages in thread
From: Neil Horman @ 2015-04-20 16:53 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

On Mon, Apr 20, 2015 at 05:41:24PM +0200, Olivier Matz wrote:
> The first objective of this series is to fix the support of indirect
> mbufs when the application reserves a private area in mbufs. It also
> removes the limitation that rte_pktmbuf_clone() is only allowed on
> direct (non-cloned) mbufs. The series also contains some enhancements
> and fixes in the mbuf area that makes the implementation of the
> last patches easier.
> 
> Changes in v4:
> - do not add a priv_size in mbuf structure, having a proper accessor
>   to read it from the pool private area is clearer
> - prepend some reworks in the mbuf area to simplify the implementation
>   (fix mbuf initialization by not using a hardcoded mbuf size, add
>   accessors for mbuf pool private area, add a helper to create a
>   mbuf pool)
> 
> Changes in v3:
> - a mbuf can now attach to another one that have a different private
>   size. In this case, the m->priv_size corresponds to the size of the
>   private area of the direct mbuf.
> - add comments to reflect these changes
> - minor style modifications
> 
> Changes in v2:
> - do not change the use of MBUF_EXT_MEM() in vhost
> - change rte_mbuf_from_baddr() to rte_mbuf_from_indirect(), removing
>   one parameter
> - fix and rework rte_pktmbuf_detach()
> - move m->priv_size in second mbuf cache line
> - fix mbuf free in test error case
> 
> 
> Olivier Matz (12):
>   mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
>   examples: always initialize mbuf_pool private area
>   mbuf: add accessors to get data room size and private size
>   mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
>   testpmd: use standard functions to initialize mbufs and mbuf pool
>   mbuf: introduce a new helper to create a mbuf pool
>   apps: use rte_pktmbuf_pool_create to create mbuf pools
>   mbuf: fix clone support when application uses private mbuf data
>   mbuf: allow to clone an indirect mbuf
>   test/mbuf: rename mc variable in m
>   test/mbuf: enhance mbuf refcnt test
>   test/mbuf: verify that cloning a clone works properly
> 
>  app/test-pipeline/init.c                           |  15 +-
>  app/test-pmd/testpmd.c                             |  78 +--------
>  app/test/test_distributor.c                        |  10 +-
>  app/test/test_distributor_perf.c                   |  10 +-
>  app/test/test_kni.c                                |  16 +-
>  app/test/test_link_bonding.c                       |  10 +-
>  app/test/test_link_bonding_mode4.c                 |  12 +-
>  app/test/test_mbuf.c                               | 110 +++++++++---
>  app/test/test_pmd_perf.c                           |  11 +-
>  app/test/test_pmd_ring.c                           |  10 +-
>  app/test/test_reorder.c                            |  10 +-
>  app/test/test_sched.c                              |  16 +-
>  app/test/test_table.c                              |   9 +-
>  app/test/test_table.h                              |   3 +-
>  doc/guides/rel_notes/updating_apps.rst             |  16 ++
>  examples/bond/main.c                               |  10 +-
>  examples/distributor/main.c                        |  11 +-
>  examples/dpdk_qat/main.c                           |  10 +-
>  examples/exception_path/main.c                     |  14 +-
>  examples/ip_fragmentation/main.c                   |  18 +-
>  examples/ip_pipeline/init.c                        |  28 +--
>  examples/ipv4_multicast/main.c                     |  21 +--
>  examples/kni/main.c                                |  12 +-
>  examples/l2fwd-ivshmem/host/host.c                 |  10 +-
>  examples/l2fwd-jobstats/main.c                     |  10 +-
>  examples/l2fwd/main.c                              |  11 +-
>  examples/l3fwd-acl/main.c                          |  11 +-
>  examples/l3fwd-power/main.c                        |  11 +-
>  examples/l3fwd-vf/main.c                           |  12 +-
>  examples/l3fwd/main.c                              |  10 +-
>  examples/link_status_interrupt/main.c              |  10 +-
>  examples/load_balancer/init.c                      |  12 +-
>  examples/load_balancer/main.h                      |   4 +-
>  .../client_server_mp/mp_server/init.c              |  10 +-
>  examples/multi_process/symmetric_mp/main.c         |  10 +-
>  examples/netmap_compat/bridge/bridge.c             |  12 +-
>  examples/packet_ordering/main.c                    |  11 +-
>  examples/qos_meter/main.c                          |   7 +-
>  examples/qos_sched/init.c                          |  10 +-
>  examples/qos_sched/main.h                          |   2 +-
>  examples/quota_watermark/include/conf.h            |   2 +-
>  examples/quota_watermark/qw/main.c                 |   7 +-
>  examples/rxtx_callbacks/main.c                     |  11 +-
>  examples/skeleton/basicfwd.c                       |  13 +-
>  examples/vhost/main.c                              |  31 ++--
>  examples/vhost_xen/main.c                          |  11 +-
>  examples/vmdq/main.c                               |  11 +-
>  examples/vmdq_dcb/main.c                           |  10 +-
>  lib/librte_ether/rte_ethdev.c                      |   4 +-
>  lib/librte_mbuf/rte_mbuf.c                         |  63 +++++--
>  lib/librte_mbuf/rte_mbuf.h                         | 189 ++++++++++++++++-----
>  lib/librte_pmd_af_packet/rte_eth_af_packet.c       |   6 +-
>  lib/librte_pmd_bond/rte_eth_bond_alb.c             |  16 +-
>  lib/librte_pmd_e1000/em_rxtx.c                     |   5 +-
>  lib/librte_pmd_e1000/igb_rxtx.c                    |  12 +-
>  lib/librte_pmd_fm10k/fm10k_ethdev.c                |   6 +-
>  lib/librte_pmd_i40e/i40e_ethdev_vf.c               |   6 +-
>  lib/librte_pmd_i40e/i40e_rxtx.c                    |  15 +-
>  lib/librte_pmd_ixgbe/ixgbe_rxtx.c                  |  12 +-
>  lib/librte_pmd_pcap/rte_eth_pcap.c                 |   5 +-
>  lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c              |   7 +-
>  61 files changed, 499 insertions(+), 566 deletions(-)
> 
> -- 
> 2.1.4
> 
> 


[nhorman@hmsreliant dpdk]$ make config T=x86_64-native-linuxapp-gcc
Configuration done
[nhorman@hmsreliant dpdk]$ make
...
 CC test_kvargs.o
  LD test
test_pmd_perf.o: In function `test_pmd_perf':
test_pmd_perf.c:(.text+0xd1b): undefined reference to `rte_pktmbuf_pool_create'
test_table.o: In function `test_table':
test_table.c:(.text+0x2da): undefined reference to `rte_pktmbuf_pool_create'
test_mbuf.o: In function `test_mbuf':
test_mbuf.c:(.text+0x3d5c): undefined reference to `rte_pktmbuf_pool_create'
test_mbuf.c:(.text+0x542a): undefined reference to `rte_pktmbuf_pool_create'
test_sched.o: In function `test_sched':
test_sched.c:(.text+0x5b1): undefined reference to `rte_pktmbuf_pool_create'
test_distributor.o:test_distributor.c:(.text+0x40a9): more undefined references
to `rte_pktmbuf_pool_create' follow

Neil

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones
  2015-04-20 16:53         ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Neil Horman
@ 2015-04-20 17:07           ` Olivier MATZ
  2015-04-20 17:21             ` Neil Horman
  0 siblings, 1 reply; 101+ messages in thread
From: Olivier MATZ @ 2015-04-20 17:07 UTC (permalink / raw)
  To: Neil Horman; +Cc: dev

Hi Neil,

On 04/20/2015 06:53 PM, Neil Horman wrote:
> On Mon, Apr 20, 2015 at 05:41:24PM +0200, Olivier Matz wrote:
>> The first objective of this series is to fix the support of indirect
>> mbufs when the application reserves a private area in mbufs. It also
>> removes the limitation that rte_pktmbuf_clone() is only allowed on
>> direct (non-cloned) mbufs. The series also contains some enhancements
>> and fixes in the mbuf area that makes the implementation of the
>> last patches easier.
>>
>> Changes in v4:
>> - do not add a priv_size in mbuf structure, having a proper accessor
>>   to read it from the pool private area is clearer
>> - prepend some reworks in the mbuf area to simplify the implementation
>>   (fix mbuf initialization by not using a hardcoded mbuf size, add
>>   accessors for mbuf pool private area, add a helper to create a
>>   mbuf pool)
>>
>> Changes in v3:
>> - a mbuf can now attach to another one that have a different private
>>   size. In this case, the m->priv_size corresponds to the size of the
>>   private area of the direct mbuf.
>> - add comments to reflect these changes
>> - minor style modifications
>>
>> Changes in v2:
>> - do not change the use of MBUF_EXT_MEM() in vhost
>> - change rte_mbuf_from_baddr() to rte_mbuf_from_indirect(), removing
>>   one parameter
>> - fix and rework rte_pktmbuf_detach()
>> - move m->priv_size in second mbuf cache line
>> - fix mbuf free in test error case
>>
>>
>> Olivier Matz (12):
>>   mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
>>   examples: always initialize mbuf_pool private area
>>   mbuf: add accessors to get data room size and private size
>>   mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
>>   testpmd: use standard functions to initialize mbufs and mbuf pool
>>   mbuf: introduce a new helper to create a mbuf pool
>>   apps: use rte_pktmbuf_pool_create to create mbuf pools
>>   mbuf: fix clone support when application uses private mbuf data
>>   mbuf: allow to clone an indirect mbuf
>>   test/mbuf: rename mc variable in m
>>   test/mbuf: enhance mbuf refcnt test
>>   test/mbuf: verify that cloning a clone works properly
>>
>>  app/test-pipeline/init.c                           |  15 +-
>>  app/test-pmd/testpmd.c                             |  78 +--------
>>  app/test/test_distributor.c                        |  10 +-
>>  app/test/test_distributor_perf.c                   |  10 +-
>>  app/test/test_kni.c                                |  16 +-
>>  app/test/test_link_bonding.c                       |  10 +-
>>  app/test/test_link_bonding_mode4.c                 |  12 +-
>>  app/test/test_mbuf.c                               | 110 +++++++++---
>>  app/test/test_pmd_perf.c                           |  11 +-
>>  app/test/test_pmd_ring.c                           |  10 +-
>>  app/test/test_reorder.c                            |  10 +-
>>  app/test/test_sched.c                              |  16 +-
>>  app/test/test_table.c                              |   9 +-
>>  app/test/test_table.h                              |   3 +-
>>  doc/guides/rel_notes/updating_apps.rst             |  16 ++
>>  examples/bond/main.c                               |  10 +-
>>  examples/distributor/main.c                        |  11 +-
>>  examples/dpdk_qat/main.c                           |  10 +-
>>  examples/exception_path/main.c                     |  14 +-
>>  examples/ip_fragmentation/main.c                   |  18 +-
>>  examples/ip_pipeline/init.c                        |  28 +--
>>  examples/ipv4_multicast/main.c                     |  21 +--
>>  examples/kni/main.c                                |  12 +-
>>  examples/l2fwd-ivshmem/host/host.c                 |  10 +-
>>  examples/l2fwd-jobstats/main.c                     |  10 +-
>>  examples/l2fwd/main.c                              |  11 +-
>>  examples/l3fwd-acl/main.c                          |  11 +-
>>  examples/l3fwd-power/main.c                        |  11 +-
>>  examples/l3fwd-vf/main.c                           |  12 +-
>>  examples/l3fwd/main.c                              |  10 +-
>>  examples/link_status_interrupt/main.c              |  10 +-
>>  examples/load_balancer/init.c                      |  12 +-
>>  examples/load_balancer/main.h                      |   4 +-
>>  .../client_server_mp/mp_server/init.c              |  10 +-
>>  examples/multi_process/symmetric_mp/main.c         |  10 +-
>>  examples/netmap_compat/bridge/bridge.c             |  12 +-
>>  examples/packet_ordering/main.c                    |  11 +-
>>  examples/qos_meter/main.c                          |   7 +-
>>  examples/qos_sched/init.c                          |  10 +-
>>  examples/qos_sched/main.h                          |   2 +-
>>  examples/quota_watermark/include/conf.h            |   2 +-
>>  examples/quota_watermark/qw/main.c                 |   7 +-
>>  examples/rxtx_callbacks/main.c                     |  11 +-
>>  examples/skeleton/basicfwd.c                       |  13 +-
>>  examples/vhost/main.c                              |  31 ++--
>>  examples/vhost_xen/main.c                          |  11 +-
>>  examples/vmdq/main.c                               |  11 +-
>>  examples/vmdq_dcb/main.c                           |  10 +-
>>  lib/librte_ether/rte_ethdev.c                      |   4 +-
>>  lib/librte_mbuf/rte_mbuf.c                         |  63 +++++--
>>  lib/librte_mbuf/rte_mbuf.h                         | 189 ++++++++++++++++-----
>>  lib/librte_pmd_af_packet/rte_eth_af_packet.c       |   6 +-
>>  lib/librte_pmd_bond/rte_eth_bond_alb.c             |  16 +-
>>  lib/librte_pmd_e1000/em_rxtx.c                     |   5 +-
>>  lib/librte_pmd_e1000/igb_rxtx.c                    |  12 +-
>>  lib/librte_pmd_fm10k/fm10k_ethdev.c                |   6 +-
>>  lib/librte_pmd_i40e/i40e_ethdev_vf.c               |   6 +-
>>  lib/librte_pmd_i40e/i40e_rxtx.c                    |  15 +-
>>  lib/librte_pmd_ixgbe/ixgbe_rxtx.c                  |  12 +-
>>  lib/librte_pmd_pcap/rte_eth_pcap.c                 |   5 +-
>>  lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c              |   7 +-
>>  61 files changed, 499 insertions(+), 566 deletions(-)
>>
>> -- 
>> 2.1.4
>>
>>
> 
> 
> [nhorman@hmsreliant dpdk]$ make config T=x86_64-native-linuxapp-gcc
> Configuration done
> [nhorman@hmsreliant dpdk]$ make
> ...
>  CC test_kvargs.o
>   LD test
> test_pmd_perf.o: In function `test_pmd_perf':
> test_pmd_perf.c:(.text+0xd1b): undefined reference to `rte_pktmbuf_pool_create'
> test_table.o: In function `test_table':
> test_table.c:(.text+0x2da): undefined reference to `rte_pktmbuf_pool_create'
> test_mbuf.o: In function `test_mbuf':
> test_mbuf.c:(.text+0x3d5c): undefined reference to `rte_pktmbuf_pool_create'
> test_mbuf.c:(.text+0x542a): undefined reference to `rte_pktmbuf_pool_create'
> test_sched.o: In function `test_sched':
> test_sched.c:(.text+0x5b1): undefined reference to `rte_pktmbuf_pool_create'
> test_distributor.o:test_distributor.c:(.text+0x40a9): more undefined references
> to `rte_pktmbuf_pool_create' follow

I cannot reproduce the issue. Maybe you forgot to clean something?


matz@glumotte:~/DEV/toto$ git clone http://dpdk.org/git/dpdk
Cloning into 'dpdk'...
remote: Counting objects: 24195, done.
remote: Compressing objects: 100% (5000/5000), done.
remote: Total 24195 (delta 19183), reused 23953 (delta 19014)
Receiving objects: 100% (24195/24195), 20.39 MiB | 199.00 KiB/s, done.
Resolving deltas: 100% (19183/19183), done.
Checking connectivity... done.
matz@glumotte:~/DEV/toto$ cd dpdk/
matz@glumotte:~/DEV/toto/dpdk$ git am /tmp/mbuf_clone_v4/*
Applying: mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
Applying: examples: always initialize mbuf_pool private area
Applying: mbuf: add accessors to get data room size and private size
Applying: mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
Applying: testpmd: use standard functions to initialize mbufs and mbuf pool
Applying: mbuf: introduce a new helper to create a mbuf pool
Applying: apps: use rte_pktmbuf_pool_create to create mbuf pools
Applying: mbuf: fix clone support when application uses private mbuf data
Applying: mbuf: allow to clone an indirect mbuf
Applying: test/mbuf: rename mc variable in m
Applying: test/mbuf: enhance mbuf refcnt test
Applying: test/mbuf: verify that cloning a clone works properly
matz@glumotte:~/DEV/toto/dpdk$ make config T=x86_64-native-linuxapp-gcc
Configuration done
matz@glumotte:~/DEV/toto/dpdk$ make
== Build lib
[...]
  CC main.o
  LD dump_cfg
  INSTALL-APP dump_cfg
  INSTALL-MAP dump_cfg.map
Build complete


Regards,
Olivier

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones
  2015-04-20 17:07           ` Olivier MATZ
@ 2015-04-20 17:21             ` Neil Horman
  2015-04-20 18:24               ` Olivier MATZ
  0 siblings, 1 reply; 101+ messages in thread
From: Neil Horman @ 2015-04-20 17:21 UTC (permalink / raw)
  To: Olivier MATZ; +Cc: dev

On Mon, Apr 20, 2015 at 07:07:31PM +0200, Olivier MATZ wrote:
> Hi Neil,
> 
> On 04/20/2015 06:53 PM, Neil Horman wrote:
> > On Mon, Apr 20, 2015 at 05:41:24PM +0200, Olivier Matz wrote:
> >> The first objective of this series is to fix the support of indirect
> >> mbufs when the application reserves a private area in mbufs. It also
> >> removes the limitation that rte_pktmbuf_clone() is only allowed on
> >> direct (non-cloned) mbufs. The series also contains some enhancements
> >> and fixes in the mbuf area that makes the implementation of the
> >> last patches easier.
> >>
> >> Changes in v4:
> >> - do not add a priv_size in mbuf structure, having a proper accessor
> >>   to read it from the pool private area is clearer
> >> - prepend some reworks in the mbuf area to simplify the implementation
> >>   (fix mbuf initialization by not using a hardcoded mbuf size, add
> >>   accessors for mbuf pool private area, add a helper to create a
> >>   mbuf pool)
> >>
> >> Changes in v3:
> >> - a mbuf can now attach to another one that have a different private
> >>   size. In this case, the m->priv_size corresponds to the size of the
> >>   private area of the direct mbuf.
> >> - add comments to reflect these changes
> >> - minor style modifications
> >>
> >> Changes in v2:
> >> - do not change the use of MBUF_EXT_MEM() in vhost
> >> - change rte_mbuf_from_baddr() to rte_mbuf_from_indirect(), removing
> >>   one parameter
> >> - fix and rework rte_pktmbuf_detach()
> >> - move m->priv_size in second mbuf cache line
> >> - fix mbuf free in test error case
> >>
> >>
> >> Olivier Matz (12):
> >>   mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
> >>   examples: always initialize mbuf_pool private area
> >>   mbuf: add accessors to get data room size and private size
> >>   mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
> >>   testpmd: use standard functions to initialize mbufs and mbuf pool
> >>   mbuf: introduce a new helper to create a mbuf pool
> >>   apps: use rte_pktmbuf_pool_create to create mbuf pools
> >>   mbuf: fix clone support when application uses private mbuf data
> >>   mbuf: allow to clone an indirect mbuf
> >>   test/mbuf: rename mc variable in m
> >>   test/mbuf: enhance mbuf refcnt test
> >>   test/mbuf: verify that cloning a clone works properly
> >>
> >>  app/test-pipeline/init.c                           |  15 +-
> >>  app/test-pmd/testpmd.c                             |  78 +--------
> >>  app/test/test_distributor.c                        |  10 +-
> >>  app/test/test_distributor_perf.c                   |  10 +-
> >>  app/test/test_kni.c                                |  16 +-
> >>  app/test/test_link_bonding.c                       |  10 +-
> >>  app/test/test_link_bonding_mode4.c                 |  12 +-
> >>  app/test/test_mbuf.c                               | 110 +++++++++---
> >>  app/test/test_pmd_perf.c                           |  11 +-
> >>  app/test/test_pmd_ring.c                           |  10 +-
> >>  app/test/test_reorder.c                            |  10 +-
> >>  app/test/test_sched.c                              |  16 +-
> >>  app/test/test_table.c                              |   9 +-
> >>  app/test/test_table.h                              |   3 +-
> >>  doc/guides/rel_notes/updating_apps.rst             |  16 ++
> >>  examples/bond/main.c                               |  10 +-
> >>  examples/distributor/main.c                        |  11 +-
> >>  examples/dpdk_qat/main.c                           |  10 +-
> >>  examples/exception_path/main.c                     |  14 +-
> >>  examples/ip_fragmentation/main.c                   |  18 +-
> >>  examples/ip_pipeline/init.c                        |  28 +--
> >>  examples/ipv4_multicast/main.c                     |  21 +--
> >>  examples/kni/main.c                                |  12 +-
> >>  examples/l2fwd-ivshmem/host/host.c                 |  10 +-
> >>  examples/l2fwd-jobstats/main.c                     |  10 +-
> >>  examples/l2fwd/main.c                              |  11 +-
> >>  examples/l3fwd-acl/main.c                          |  11 +-
> >>  examples/l3fwd-power/main.c                        |  11 +-
> >>  examples/l3fwd-vf/main.c                           |  12 +-
> >>  examples/l3fwd/main.c                              |  10 +-
> >>  examples/link_status_interrupt/main.c              |  10 +-
> >>  examples/load_balancer/init.c                      |  12 +-
> >>  examples/load_balancer/main.h                      |   4 +-
> >>  .../client_server_mp/mp_server/init.c              |  10 +-
> >>  examples/multi_process/symmetric_mp/main.c         |  10 +-
> >>  examples/netmap_compat/bridge/bridge.c             |  12 +-
> >>  examples/packet_ordering/main.c                    |  11 +-
> >>  examples/qos_meter/main.c                          |   7 +-
> >>  examples/qos_sched/init.c                          |  10 +-
> >>  examples/qos_sched/main.h                          |   2 +-
> >>  examples/quota_watermark/include/conf.h            |   2 +-
> >>  examples/quota_watermark/qw/main.c                 |   7 +-
> >>  examples/rxtx_callbacks/main.c                     |  11 +-
> >>  examples/skeleton/basicfwd.c                       |  13 +-
> >>  examples/vhost/main.c                              |  31 ++--
> >>  examples/vhost_xen/main.c                          |  11 +-
> >>  examples/vmdq/main.c                               |  11 +-
> >>  examples/vmdq_dcb/main.c                           |  10 +-
> >>  lib/librte_ether/rte_ethdev.c                      |   4 +-
> >>  lib/librte_mbuf/rte_mbuf.c                         |  63 +++++--
> >>  lib/librte_mbuf/rte_mbuf.h                         | 189 ++++++++++++++++-----
> >>  lib/librte_pmd_af_packet/rte_eth_af_packet.c       |   6 +-
> >>  lib/librte_pmd_bond/rte_eth_bond_alb.c             |  16 +-
> >>  lib/librte_pmd_e1000/em_rxtx.c                     |   5 +-
> >>  lib/librte_pmd_e1000/igb_rxtx.c                    |  12 +-
> >>  lib/librte_pmd_fm10k/fm10k_ethdev.c                |   6 +-
> >>  lib/librte_pmd_i40e/i40e_ethdev_vf.c               |   6 +-
> >>  lib/librte_pmd_i40e/i40e_rxtx.c                    |  15 +-
> >>  lib/librte_pmd_ixgbe/ixgbe_rxtx.c                  |  12 +-
> >>  lib/librte_pmd_pcap/rte_eth_pcap.c                 |   5 +-
> >>  lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c              |   7 +-
> >>  61 files changed, 499 insertions(+), 566 deletions(-)
> >>
> >> -- 
> >> 2.1.4
> >>
> >>
> > 
> > 
> > [nhorman@hmsreliant dpdk]$ make config T=x86_64-native-linuxapp-gcc
> > Configuration done
> > [nhorman@hmsreliant dpdk]$ make
> > ...
> >  CC test_kvargs.o
> >   LD test
> > test_pmd_perf.o: In function `test_pmd_perf':
> > test_pmd_perf.c:(.text+0xd1b): undefined reference to `rte_pktmbuf_pool_create'
> > test_table.o: In function `test_table':
> > test_table.c:(.text+0x2da): undefined reference to `rte_pktmbuf_pool_create'
> > test_mbuf.o: In function `test_mbuf':
> > test_mbuf.c:(.text+0x3d5c): undefined reference to `rte_pktmbuf_pool_create'
> > test_mbuf.c:(.text+0x542a): undefined reference to `rte_pktmbuf_pool_create'
> > test_sched.o: In function `test_sched':
> > test_sched.c:(.text+0x5b1): undefined reference to `rte_pktmbuf_pool_create'
> > test_distributor.o:test_distributor.c:(.text+0x40a9): more undefined references
> > to `rte_pktmbuf_pool_create' follow
> 
> I cannot reproduce the issue. Maybe you forgot to clean something?
> 
Nope, fresh clone.  You didn't try building with shared libraries configured :)
Neil

> 
> matz@glumotte:~/DEV/toto$ git clone http://dpdk.org/git/dpdk
> Cloning into 'dpdk'...
> remote: Counting objects: 24195, done.
> remote: Compressing objects: 100% (5000/5000), done.
> remote: Total 24195 (delta 19183), reused 23953 (delta 19014)
> Receiving objects: 100% (24195/24195), 20.39 MiB | 199.00 KiB/s, done.
> Resolving deltas: 100% (19183/19183), done.
> Checking connectivity... done.
> matz@glumotte:~/DEV/toto$ cd dpdk/
> matz@glumotte:~/DEV/toto/dpdk$ git am /tmp/mbuf_clone_v4/*
> Applying: mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
> Applying: examples: always initialize mbuf_pool private area
> Applying: mbuf: add accessors to get data room size and private size
> Applying: mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
> Applying: testpmd: use standard functions to initialize mbufs and mbuf pool
> Applying: mbuf: introduce a new helper to create a mbuf pool
> Applying: apps: use rte_pktmbuf_pool_create to create mbuf pools
> Applying: mbuf: fix clone support when application uses private mbuf data
> Applying: mbuf: allow to clone an indirect mbuf
> Applying: test/mbuf: rename mc variable in m
> Applying: test/mbuf: enhance mbuf refcnt test
> Applying: test/mbuf: verify that cloning a clone works properly
> matz@glumotte:~/DEV/toto/dpdk$ make config T=x86_64-native-linuxapp-gcc
> Configuration done
> matz@glumotte:~/DEV/toto/dpdk$ make
> == Build lib
> [...]
>   CC main.o
>   LD dump_cfg
>   INSTALL-APP dump_cfg
>   INSTALL-MAP dump_cfg.map
> Build complete
> 
> 
> Regards,
> Olivier
> 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones
  2015-04-20 17:21             ` Neil Horman
@ 2015-04-20 18:24               ` Olivier MATZ
  0 siblings, 0 replies; 101+ messages in thread
From: Olivier MATZ @ 2015-04-20 18:24 UTC (permalink / raw)
  To: Neil Horman; +Cc: dev

Hi Neil,

On 04/20/2015 07:21 PM, Neil Horman wrote:
> On Mon, Apr 20, 2015 at 07:07:31PM +0200, Olivier MATZ wrote:
>> Hi Neil,
>>
>> On 04/20/2015 06:53 PM, Neil Horman wrote:
>>> On Mon, Apr 20, 2015 at 05:41:24PM +0200, Olivier Matz wrote:
>>>> The first objective of this series is to fix the support of indirect
>>>> mbufs when the application reserves a private area in mbufs. It also
>>>> removes the limitation that rte_pktmbuf_clone() is only allowed on
>>>> direct (non-cloned) mbufs. The series also contains some enhancements
>>>> and fixes in the mbuf area that makes the implementation of the
>>>> last patches easier.
>>>>
>>>> Changes in v4:
>>>> - do not add a priv_size in mbuf structure, having a proper accessor
>>>>   to read it from the pool private area is clearer
>>>> - prepend some reworks in the mbuf area to simplify the implementation
>>>>   (fix mbuf initialization by not using a hardcoded mbuf size, add
>>>>   accessors for mbuf pool private area, add a helper to create a
>>>>   mbuf pool)
>>>>
>>>> Changes in v3:
>>>> - a mbuf can now attach to another one that have a different private
>>>>   size. In this case, the m->priv_size corresponds to the size of the
>>>>   private area of the direct mbuf.
>>>> - add comments to reflect these changes
>>>> - minor style modifications
>>>>
>>>> Changes in v2:
>>>> - do not change the use of MBUF_EXT_MEM() in vhost
>>>> - change rte_mbuf_from_baddr() to rte_mbuf_from_indirect(), removing
>>>>   one parameter
>>>> - fix and rework rte_pktmbuf_detach()
>>>> - move m->priv_size in second mbuf cache line
>>>> - fix mbuf free in test error case
>>>>
>>>>
>>>> Olivier Matz (12):
>>>>   mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
>>>>   examples: always initialize mbuf_pool private area
>>>>   mbuf: add accessors to get data room size and private size
>>>>   mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
>>>>   testpmd: use standard functions to initialize mbufs and mbuf pool
>>>>   mbuf: introduce a new helper to create a mbuf pool
>>>>   apps: use rte_pktmbuf_pool_create to create mbuf pools
>>>>   mbuf: fix clone support when application uses private mbuf data
>>>>   mbuf: allow to clone an indirect mbuf
>>>>   test/mbuf: rename mc variable in m
>>>>   test/mbuf: enhance mbuf refcnt test
>>>>   test/mbuf: verify that cloning a clone works properly
>>>>
>>>>  app/test-pipeline/init.c                           |  15 +-
>>>>  app/test-pmd/testpmd.c                             |  78 +--------
>>>>  app/test/test_distributor.c                        |  10 +-
>>>>  app/test/test_distributor_perf.c                   |  10 +-
>>>>  app/test/test_kni.c                                |  16 +-
>>>>  app/test/test_link_bonding.c                       |  10 +-
>>>>  app/test/test_link_bonding_mode4.c                 |  12 +-
>>>>  app/test/test_mbuf.c                               | 110 +++++++++---
>>>>  app/test/test_pmd_perf.c                           |  11 +-
>>>>  app/test/test_pmd_ring.c                           |  10 +-
>>>>  app/test/test_reorder.c                            |  10 +-
>>>>  app/test/test_sched.c                              |  16 +-
>>>>  app/test/test_table.c                              |   9 +-
>>>>  app/test/test_table.h                              |   3 +-
>>>>  doc/guides/rel_notes/updating_apps.rst             |  16 ++
>>>>  examples/bond/main.c                               |  10 +-
>>>>  examples/distributor/main.c                        |  11 +-
>>>>  examples/dpdk_qat/main.c                           |  10 +-
>>>>  examples/exception_path/main.c                     |  14 +-
>>>>  examples/ip_fragmentation/main.c                   |  18 +-
>>>>  examples/ip_pipeline/init.c                        |  28 +--
>>>>  examples/ipv4_multicast/main.c                     |  21 +--
>>>>  examples/kni/main.c                                |  12 +-
>>>>  examples/l2fwd-ivshmem/host/host.c                 |  10 +-
>>>>  examples/l2fwd-jobstats/main.c                     |  10 +-
>>>>  examples/l2fwd/main.c                              |  11 +-
>>>>  examples/l3fwd-acl/main.c                          |  11 +-
>>>>  examples/l3fwd-power/main.c                        |  11 +-
>>>>  examples/l3fwd-vf/main.c                           |  12 +-
>>>>  examples/l3fwd/main.c                              |  10 +-
>>>>  examples/link_status_interrupt/main.c              |  10 +-
>>>>  examples/load_balancer/init.c                      |  12 +-
>>>>  examples/load_balancer/main.h                      |   4 +-
>>>>  .../client_server_mp/mp_server/init.c              |  10 +-
>>>>  examples/multi_process/symmetric_mp/main.c         |  10 +-
>>>>  examples/netmap_compat/bridge/bridge.c             |  12 +-
>>>>  examples/packet_ordering/main.c                    |  11 +-
>>>>  examples/qos_meter/main.c                          |   7 +-
>>>>  examples/qos_sched/init.c                          |  10 +-
>>>>  examples/qos_sched/main.h                          |   2 +-
>>>>  examples/quota_watermark/include/conf.h            |   2 +-
>>>>  examples/quota_watermark/qw/main.c                 |   7 +-
>>>>  examples/rxtx_callbacks/main.c                     |  11 +-
>>>>  examples/skeleton/basicfwd.c                       |  13 +-
>>>>  examples/vhost/main.c                              |  31 ++--
>>>>  examples/vhost_xen/main.c                          |  11 +-
>>>>  examples/vmdq/main.c                               |  11 +-
>>>>  examples/vmdq_dcb/main.c                           |  10 +-
>>>>  lib/librte_ether/rte_ethdev.c                      |   4 +-
>>>>  lib/librte_mbuf/rte_mbuf.c                         |  63 +++++--
>>>>  lib/librte_mbuf/rte_mbuf.h                         | 189 ++++++++++++++++-----
>>>>  lib/librte_pmd_af_packet/rte_eth_af_packet.c       |   6 +-
>>>>  lib/librte_pmd_bond/rte_eth_bond_alb.c             |  16 +-
>>>>  lib/librte_pmd_e1000/em_rxtx.c                     |   5 +-
>>>>  lib/librte_pmd_e1000/igb_rxtx.c                    |  12 +-
>>>>  lib/librte_pmd_fm10k/fm10k_ethdev.c                |   6 +-
>>>>  lib/librte_pmd_i40e/i40e_ethdev_vf.c               |   6 +-
>>>>  lib/librte_pmd_i40e/i40e_rxtx.c                    |  15 +-
>>>>  lib/librte_pmd_ixgbe/ixgbe_rxtx.c                  |  12 +-
>>>>  lib/librte_pmd_pcap/rte_eth_pcap.c                 |   5 +-
>>>>  lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c              |   7 +-
>>>>  61 files changed, 499 insertions(+), 566 deletions(-)
>>>>
>>>> -- 
>>>> 2.1.4
>>>>
>>>>
>>>
>>>
>>> [nhorman@hmsreliant dpdk]$ make config T=x86_64-native-linuxapp-gcc
>>> Configuration done
>>> [nhorman@hmsreliant dpdk]$ make
>>> ...
>>>  CC test_kvargs.o
>>>   LD test
>>> test_pmd_perf.o: In function `test_pmd_perf':
>>> test_pmd_perf.c:(.text+0xd1b): undefined reference to `rte_pktmbuf_pool_create'
>>> test_table.o: In function `test_table':
>>> test_table.c:(.text+0x2da): undefined reference to `rte_pktmbuf_pool_create'
>>> test_mbuf.o: In function `test_mbuf':
>>> test_mbuf.c:(.text+0x3d5c): undefined reference to `rte_pktmbuf_pool_create'
>>> test_mbuf.c:(.text+0x542a): undefined reference to `rte_pktmbuf_pool_create'
>>> test_sched.o: In function `test_sched':
>>> test_sched.c:(.text+0x5b1): undefined reference to `rte_pktmbuf_pool_create'
>>> test_distributor.o:test_distributor.c:(.text+0x40a9): more undefined references
>>> to `rte_pktmbuf_pool_create' follow
>>
>> I cannot reproduce the issue. Maybe you forgot to clean something?
>>
> Nope, fresh clone.  You didn't try building with shared libraries configured :)
> Neil

OK, thanks for reporting. I'll fix that and add it to my checklist
for next times.

Regards,
Olivier


> 
>>
>> matz@glumotte:~/DEV/toto$ git clone http://dpdk.org/git/dpdk
>> Cloning into 'dpdk'...
>> remote: Counting objects: 24195, done.
>> remote: Compressing objects: 100% (5000/5000), done.
>> remote: Total 24195 (delta 19183), reused 23953 (delta 19014)
>> Receiving objects: 100% (24195/24195), 20.39 MiB | 199.00 KiB/s, done.
>> Resolving deltas: 100% (19183/19183), done.
>> Checking connectivity... done.
>> matz@glumotte:~/DEV/toto$ cd dpdk/
>> matz@glumotte:~/DEV/toto/dpdk$ git am /tmp/mbuf_clone_v4/*
>> Applying: mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
>> Applying: examples: always initialize mbuf_pool private area
>> Applying: mbuf: add accessors to get data room size and private size
>> Applying: mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
>> Applying: testpmd: use standard functions to initialize mbufs and mbuf pool
>> Applying: mbuf: introduce a new helper to create a mbuf pool
>> Applying: apps: use rte_pktmbuf_pool_create to create mbuf pools
>> Applying: mbuf: fix clone support when application uses private mbuf data
>> Applying: mbuf: allow to clone an indirect mbuf
>> Applying: test/mbuf: rename mc variable in m
>> Applying: test/mbuf: enhance mbuf refcnt test
>> Applying: test/mbuf: verify that cloning a clone works properly
>> matz@glumotte:~/DEV/toto/dpdk$ make config T=x86_64-native-linuxapp-gcc
>> Configuration done
>> matz@glumotte:~/DEV/toto/dpdk$ make
>> == Build lib
>> [...]
>>   CC main.o
>>   LD dump_cfg
>>   INSTALL-APP dump_cfg
>>   INSTALL-MAP dump_cfg.map
>> Build complete
>>
>>
>> Regards,
>> Olivier
>>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v5 00/12] mbuf: enhancements of mbuf clones
  2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
                           ` (12 preceding siblings ...)
  2015-04-20 16:53         ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Neil Horman
@ 2015-04-21  9:55         ` Olivier Matz
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 01/12] mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init Olivier Matz
                             ` (13 more replies)
  13 siblings, 14 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-21  9:55 UTC (permalink / raw)
  To: dev

The first objective of this series is to fix the support of indirect
mbufs when the application reserves a private area in mbufs. It also
removes the limitation that rte_pktmbuf_clone() is only allowed on
direct (non-cloned) mbufs. The series also contains some enhancements
and fixes in the mbuf area that makes the implementation of the
last patches easier.

Changes in v5:
- update rte_mbuf_version.map to fix compilation with shared libraries

Changes in v4:
- do not add a priv_size in mbuf structure, having a proper accessor
  to read it from the pool private area is clearer
- prepend some reworks in the mbuf area to simplify the implementation
  (fix mbuf initialization by not using a hardcoded mbuf size, add
  accessors for mbuf pool private area, add a helper to create a
  mbuf pool)

Changes in v3:
- a mbuf can now attach to another one that have a different private
  size. In this case, the m->priv_size corresponds to the size of the
  private area of the direct mbuf.
- add comments to reflect these changes
- minor style modifications

Changes in v2:
- do not change the use of MBUF_EXT_MEM() in vhost
- change rte_mbuf_from_baddr() to rte_mbuf_from_indirect(), removing
  one parameter
- fix and rework rte_pktmbuf_detach()
- move m->priv_size in second mbuf cache line
- fix mbuf free in test error case

Olivier Matz (12):
  mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
  examples: always initialize mbuf_pool private area
  mbuf: add accessors to get data room size and private size
  mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
  testpmd: use standard functions to initialize mbufs and mbuf pool
  mbuf: introduce a new helper to create a mbuf pool
  apps: use rte_pktmbuf_pool_create to create mbuf pools
  mbuf: fix clone support when application uses private mbuf data
  mbuf: allow to clone an indirect mbuf
  test/mbuf: rename mc variable in m
  test/mbuf: enhance mbuf refcnt test
  test/mbuf: verify that cloning a clone works properly

 app/test-pipeline/init.c                           |  15 +-
 app/test-pmd/testpmd.c                             |  78 +--------
 app/test/test_distributor.c                        |  10 +-
 app/test/test_distributor_perf.c                   |  10 +-
 app/test/test_kni.c                                |  16 +-
 app/test/test_link_bonding.c                       |  10 +-
 app/test/test_link_bonding_mode4.c                 |  12 +-
 app/test/test_mbuf.c                               | 110 +++++++++---
 app/test/test_pmd_perf.c                           |  11 +-
 app/test/test_pmd_ring.c                           |  10 +-
 app/test/test_reorder.c                            |  10 +-
 app/test/test_sched.c                              |  16 +-
 app/test/test_table.c                              |   9 +-
 app/test/test_table.h                              |   3 +-
 doc/guides/rel_notes/updating_apps.rst             |  16 ++
 examples/bond/main.c                               |  10 +-
 examples/distributor/main.c                        |  11 +-
 examples/dpdk_qat/main.c                           |  10 +-
 examples/exception_path/main.c                     |  14 +-
 examples/ip_fragmentation/main.c                   |  18 +-
 examples/ip_pipeline/init.c                        |  28 +--
 examples/ipv4_multicast/main.c                     |  21 +--
 examples/kni/main.c                                |  12 +-
 examples/l2fwd-ivshmem/host/host.c                 |  10 +-
 examples/l2fwd-jobstats/main.c                     |  10 +-
 examples/l2fwd/main.c                              |  11 +-
 examples/l3fwd-acl/main.c                          |  11 +-
 examples/l3fwd-power/main.c                        |  11 +-
 examples/l3fwd-vf/main.c                           |  12 +-
 examples/l3fwd/main.c                              |  10 +-
 examples/link_status_interrupt/main.c              |  10 +-
 examples/load_balancer/init.c                      |  12 +-
 examples/load_balancer/main.h                      |   4 +-
 .../client_server_mp/mp_server/init.c              |  10 +-
 examples/multi_process/symmetric_mp/main.c         |  10 +-
 examples/netmap_compat/bridge/bridge.c             |  12 +-
 examples/packet_ordering/main.c                    |  11 +-
 examples/qos_meter/main.c                          |   7 +-
 examples/qos_sched/init.c                          |  10 +-
 examples/qos_sched/main.h                          |   2 +-
 examples/quota_watermark/include/conf.h            |   2 +-
 examples/quota_watermark/qw/main.c                 |   7 +-
 examples/rxtx_callbacks/main.c                     |  11 +-
 examples/skeleton/basicfwd.c                       |  13 +-
 examples/vhost/main.c                              |  31 ++--
 examples/vhost_xen/main.c                          |  11 +-
 examples/vmdq/main.c                               |  11 +-
 examples/vmdq_dcb/main.c                           |  10 +-
 lib/librte_ether/rte_ethdev.c                      |   4 +-
 lib/librte_mbuf/rte_mbuf.c                         |  63 +++++--
 lib/librte_mbuf/rte_mbuf.h                         | 189 ++++++++++++++++-----
 lib/librte_mbuf/rte_mbuf_version.map               |   8 +
 lib/librte_pmd_af_packet/rte_eth_af_packet.c       |   6 +-
 lib/librte_pmd_bond/rte_eth_bond_alb.c             |  16 +-
 lib/librte_pmd_e1000/em_rxtx.c                     |   5 +-
 lib/librte_pmd_e1000/igb_rxtx.c                    |  12 +-
 lib/librte_pmd_fm10k/fm10k_ethdev.c                |   6 +-
 lib/librte_pmd_i40e/i40e_ethdev_vf.c               |   6 +-
 lib/librte_pmd_i40e/i40e_rxtx.c                    |  15 +-
 lib/librte_pmd_ixgbe/ixgbe_rxtx.c                  |  12 +-
 lib/librte_pmd_pcap/rte_eth_pcap.c                 |   5 +-
 lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c              |   7 +-
 62 files changed, 507 insertions(+), 566 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v5 01/12] mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
@ 2015-04-21  9:55           ` Olivier Matz
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 02/12] examples: always initialize mbuf_pool private area Olivier Matz
                             ` (12 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-21  9:55 UTC (permalink / raw)
  To: dev

Deduct the mbuf data room size from mempool->elt_size and priv_size,
instead of using an hardcoded value that is not related to the real
buffer size.

To use rte_pktmbuf_pool_init(), the user can either:
- give a NULL parameter to rte_pktmbuf_pool_init(): in this case, the
  private size is assumed to be 0, and the room size is
  mp->elt_size - sizeof(struct rte_mbuf).
- give the rte_pktmbuf_pool_private filled with appropriate
  data_room_size and priv_size values.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test-pmd/testpmd.c                 |  1 +
 doc/guides/rel_notes/updating_apps.rst | 12 ++++++++++++
 examples/vhost/main.c                  |  5 ++---
 lib/librte_mbuf/rte_mbuf.c             | 27 ++++++++++++++++++++-------
 lib/librte_mbuf/rte_mbuf.h             |  3 ++-
 5 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 3057791..10e4347 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -443,6 +443,7 @@ testpmd_mbuf_pool_ctor(struct rte_mempool *mp,
 	mbp_ctor_arg = (struct mbuf_pool_ctor_arg *) opaque_arg;
 	mbp_priv = rte_mempool_get_priv(mp);
 	mbp_priv->mbuf_data_room_size = mbp_ctor_arg->seg_buf_size;
+	mbp_priv->mbuf_priv_size = 0;
 }
 
 static void
diff --git a/doc/guides/rel_notes/updating_apps.rst b/doc/guides/rel_notes/updating_apps.rst
index 4dbf268..f513615 100644
--- a/doc/guides/rel_notes/updating_apps.rst
+++ b/doc/guides/rel_notes/updating_apps.rst
@@ -4,6 +4,18 @@ Updating Applications from Previous Versions
 Although backward compatibility is being maintained across DPDK releases, code written for previous versions of the DPDK
 may require some code updates to benefit from performance and user experience enhancements provided in later DPDK releases.
 
+DPDK 2.0 to DPDK 2.1
+--------------------
+
+*   The second argument of rte_pktmbuf_pool_init(mempool, opaque) is now a
+    pointer to a struct rte_pktmbuf_pool_private instead of a uint16_t
+    casted into a pointer. Backward compatibility is preserved when the
+    argument was NULL which is the majority of use cases, but not if the
+    opaque pointer was not NULL, as it is not technically feasible. In
+    this case, the application has to be modified to properly fill a
+    rte_pktmbuf_pool_private structure and pass it to
+    rte_pktmbuf_pool_init().
+
 DPDK 1.7 to DPDK 1.8
 --------------------
 
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index ad10f82..fc73d1e 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -2844,11 +2844,10 @@ static void
 setup_mempool_tbl(int socket, uint32_t index, char *pool_name,
 	char *ring_name, uint32_t nb_mbuf)
 {
-	uint16_t roomsize = VIRTIO_DESCRIPTOR_LEN_ZCP + RTE_PKTMBUF_HEADROOM;
 	vpool_array[index].pool
 		= rte_mempool_create(pool_name, nb_mbuf, MBUF_SIZE_ZCP,
 		MBUF_CACHE_SIZE_ZCP, sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, (void *)(uintptr_t)roomsize,
+		rte_pktmbuf_pool_init, NULL,
 		rte_pktmbuf_init, NULL, socket, 0);
 	if (vpool_array[index].pool != NULL) {
 		vpool_array[index].ring
@@ -2870,7 +2869,7 @@ setup_mempool_tbl(int socket, uint32_t index, char *pool_name,
 		}
 
 		/* Need consider head room. */
-		vpool_array[index].buf_size = roomsize - RTE_PKTMBUF_HEADROOM;
+		vpool_array[index].buf_size = VIRTIO_DESCRIPTOR_LEN_ZCP;
 	} else {
 		rte_exit(EXIT_FAILURE, "mempool_create(%s) failed", pool_name);
 	}
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index 526b18d..231cfb8 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -81,17 +81,30 @@ rte_ctrlmbuf_init(struct rte_mempool *mp,
 void
 rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg)
 {
-	struct rte_pktmbuf_pool_private *mbp_priv;
+	struct rte_pktmbuf_pool_private *user_mbp_priv, *mbp_priv;
+	struct rte_pktmbuf_pool_private default_mbp_priv;
 	uint16_t roomsz;
 
-	mbp_priv = rte_mempool_get_priv(mp);
-	roomsz = (uint16_t)(uintptr_t)opaque_arg;
+	RTE_MBUF_ASSERT(mp->elt_size >= sizeof(struct rte_mbuf));
 
-	/* Use default data room size. */
-	if (0 == roomsz)
-		roomsz = 2048 + RTE_PKTMBUF_HEADROOM;
+	/* if no structure is provided, assume no mbuf private area */
+	user_mbp_priv = opaque_arg;
+	if (user_mbp_priv == NULL) {
+		default_mbp_priv.mbuf_priv_size = 0;
+		if (mp->elt_size > sizeof(struct rte_mbuf))
+			roomsz = mp->elt_size - sizeof(struct rte_mbuf);
+		else
+			roomsz = 0;
+		default_mbp_priv.mbuf_data_room_size = roomsz;
+		user_mbp_priv = &default_mbp_priv;
+	}
 
-	mbp_priv->mbuf_data_room_size = roomsz;
+	RTE_MBUF_ASSERT(mp->elt_size >= sizeof(struct rte_mbuf) +
+		user_mbp_priv->mbuf_data_room_size +
+		user_mbp_priv->mbuf_priv_size);
+
+	mbp_priv = rte_mempool_get_priv(mp);
+	memcpy(mbp_priv, user_mbp_priv, sizeof(*mbp_priv));
 }
 
 /*
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 45f73c2..13fd626 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -348,7 +348,8 @@ struct rte_mbuf {
  * appended after the mempool structure (in private data).
  */
 struct rte_pktmbuf_pool_private {
-	uint16_t mbuf_data_room_size; /**< Size of data space in each mbuf.*/
+	uint16_t mbuf_data_room_size; /**< Size of data space in each mbuf. */
+	uint16_t mbuf_priv_size;      /**< Size of private area in each mbuf. */
 };
 
 #ifdef RTE_LIBRTE_MBUF_DEBUG
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v5 02/12] examples: always initialize mbuf_pool private area
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 01/12] mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init Olivier Matz
@ 2015-04-21  9:55           ` Olivier Matz
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 03/12] mbuf: add accessors to get data room size and private size Olivier Matz
                             ` (11 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-21  9:55 UTC (permalink / raw)
  To: dev

The mbuf pool private area must always be populated in a mbuf pool.
The applications or drivers may expect that for a mbuf pool, the mbuf
pool private area (mbuf_data_room_size and mbuf_priv_size) are
properly filled.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 examples/ip_fragmentation/main.c | 4 ++--
 examples/ip_pipeline/init.c      | 8 ++++++--
 examples/ipv4_multicast/main.c   | 6 ++++--
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 93ea2a1..cf63718 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -764,8 +764,8 @@ init_mem(void)
 
 			mp = rte_mempool_create(buf, NB_MBUF,
 							   sizeof(struct rte_mbuf), 32,
-							   0,
-							   NULL, NULL,
+							   sizeof(struct rte_pktmbuf_pool_private),
+							   rte_pktmbuf_pool_init, NULL,
 							   rte_pktmbuf_init, NULL,
 							   socket, 0);
 			if (mp == NULL) {
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index 96aee2b..61d71c3 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -363,6 +363,8 @@ app_get_ring_resp(uint32_t core_id)
 static void
 app_init_mbuf_pools(void)
 {
+	struct rte_pktmbuf_pool_private indirect_mbp_priv;
+
 	/* Init the buffer pool */
 	RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n");
 	app.pool = rte_mempool_create(
@@ -380,13 +382,15 @@ app_init_mbuf_pools(void)
 
 	/* Init the indirect buffer pool */
 	RTE_LOG(INFO, USER1, "Creating the indirect mbuf pool ...\n");
+	indirect_mbp_priv.mbuf_data_room_size = 0;
+	indirect_mbp_priv.mbuf_priv_size = sizeof(struct app_pkt_metadata);
 	app.indirect_pool = rte_mempool_create(
 		"indirect mempool",
 		app.pool_size,
 		sizeof(struct rte_mbuf) + sizeof(struct app_pkt_metadata),
 		app.pool_cache_size,
-		0,
-		NULL, NULL,
+		sizeof(struct rte_pktmbuf_pool_private),
+		rte_pktmbuf_pool_init, &indirect_mbp_priv,
 		rte_pktmbuf_init, NULL,
 		rte_socket_id(),
 		0);
diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index eed5611..19832d8 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -699,14 +699,16 @@ main(int argc, char **argv)
 		rte_exit(EXIT_FAILURE, "Cannot init packet mbuf pool\n");
 
 	header_pool = rte_mempool_create("header_pool", NB_HDR_MBUF,
-	    HDR_MBUF_SIZE, 32, 0, NULL, NULL, rte_pktmbuf_init, NULL,
+	    HDR_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
+	    rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
 	    rte_socket_id(), 0);
 
 	if (header_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init header mbuf pool\n");
 
 	clone_pool = rte_mempool_create("clone_pool", NB_CLONE_MBUF,
-	    CLONE_MBUF_SIZE, 32, 0, NULL, NULL, rte_pktmbuf_init, NULL,
+	    CLONE_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
+	    rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
 	    rte_socket_id(), 0);
 
 	if (clone_pool == NULL)
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v5 03/12] mbuf: add accessors to get data room size and private size
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 01/12] mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init Olivier Matz
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 02/12] examples: always initialize mbuf_pool private area Olivier Matz
@ 2015-04-21  9:55           ` Olivier Matz
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 04/12] mbuf: fix rte_pktmbuf_init when mbuf private size is not zero Olivier Matz
                             ` (10 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-21  9:55 UTC (permalink / raw)
  To: dev

This code retrieving the pool private area is duplicated in many
places, we can use of function for it.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_ether/rte_ethdev.c                |  4 +--
 lib/librte_mbuf/rte_mbuf.h                   | 41 ++++++++++++++++++++++++++++
 lib/librte_pmd_af_packet/rte_eth_af_packet.c |  6 ++--
 lib/librte_pmd_e1000/em_rxtx.c               |  5 ++--
 lib/librte_pmd_e1000/igb_rxtx.c              | 12 +++-----
 lib/librte_pmd_fm10k/fm10k_ethdev.c          |  6 ++--
 lib/librte_pmd_i40e/i40e_ethdev_vf.c         |  6 ++--
 lib/librte_pmd_i40e/i40e_rxtx.c              | 15 ++++------
 lib/librte_pmd_ixgbe/ixgbe_rxtx.c            | 12 +++-----
 lib/librte_pmd_pcap/rte_eth_pcap.c           |  5 +---
 lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c        |  7 ++---
 11 files changed, 67 insertions(+), 52 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index e20cca5..ff06256 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1439,7 +1439,6 @@ rte_eth_rx_queue_setup(uint8_t port_id, uint16_t rx_queue_id,
 	int ret;
 	uint32_t mbp_buf_size;
 	struct rte_eth_dev *dev;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	struct rte_eth_dev_info dev_info;
 
 	/* This function is only safe when called from the primary process
@@ -1478,8 +1477,7 @@ rte_eth_rx_queue_setup(uint8_t port_id, uint16_t rx_queue_id,
 				(int) sizeof(struct rte_pktmbuf_pool_private));
 		return (-ENOSPC);
 	}
-	mbp_priv = rte_mempool_get_priv(mp);
-	mbp_buf_size = mbp_priv->mbuf_data_room_size;
+	mbp_buf_size = rte_pktmbuf_data_room_size(mp);
 
 	if ((mbp_buf_size - RTE_PKTMBUF_HEADROOM) < dev_info.min_rx_bufsize) {
 		PMD_DEBUG_TRACE("%s mbuf_data_room_size %d < %d "
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 13fd626..a4146fa 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -642,6 +642,47 @@ void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg,
 void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
 
 /**
+ * Get the data room size of mbufs stored in a pktmbuf_pool
+ *
+ * The data room size is the amount of data that can be stored in a
+ * mbuf including the headroom (RTE_PKTMBUF_HEADROOM).
+ *
+ * @param mp
+ *   The packet mbuf pool.
+ * @return
+ *   The data room size of mbufs stored in this mempool.
+ */
+static inline uint16_t
+rte_pktmbuf_data_room_size(struct rte_mempool *mp)
+{
+	struct rte_pktmbuf_pool_private *mbp_priv;
+
+	mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
+	return mbp_priv->mbuf_data_room_size;
+}
+
+/**
+ * Get the application private size of mbufs stored in a pktmbuf_pool
+ *
+ * The private size of mbuf is a zone located between the rte_mbuf
+ * structure and the data buffer where an application can store data
+ * associated to a packet.
+ *
+ * @param mp
+ *   The packet mbuf pool.
+ * @return
+ *   The private size of mbufs stored in this mempool.
+ */
+static inline uint16_t
+rte_pktmbuf_priv_size(struct rte_mempool *mp)
+{
+	struct rte_pktmbuf_pool_private *mbp_priv;
+
+	mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
+	return mbp_priv->mbuf_priv_size;
+}
+
+/**
  * Reset the fields of a packet mbuf to their default values.
  *
  * The given mbuf must have only one segment.
diff --git a/lib/librte_pmd_af_packet/rte_eth_af_packet.c b/lib/librte_pmd_af_packet/rte_eth_af_packet.c
index f7e9ec9..bdd9628 100644
--- a/lib/librte_pmd_af_packet/rte_eth_af_packet.c
+++ b/lib/librte_pmd_af_packet/rte_eth_af_packet.c
@@ -348,15 +348,13 @@ eth_rx_queue_setup(struct rte_eth_dev *dev,
 {
 	struct pmd_internals *internals = dev->data->dev_private;
 	struct pkt_rx_queue *pkt_q = &internals->rx_queue[rx_queue_id];
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint16_t buf_size;
 
 	pkt_q->mb_pool = mb_pool;
 
 	/* Now get the space available for data in the mbuf */
-	mbp_priv = rte_mempool_get_priv(pkt_q->mb_pool);
-	buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-	                       RTE_PKTMBUF_HEADROOM);
+	buf_size = (uint16_t)(rte_pktmbuf_data_room_size(pkt_q->mb_pool) -
+		RTE_PKTMBUF_HEADROOM);
 
 	if (ETH_FRAME_LEN > buf_size) {
 		RTE_LOG(ERR, PMD,
diff --git a/lib/librte_pmd_e1000/em_rxtx.c b/lib/librte_pmd_e1000/em_rxtx.c
index 8e20920..64d067c 100644
--- a/lib/librte_pmd_e1000/em_rxtx.c
+++ b/lib/librte_pmd_e1000/em_rxtx.c
@@ -1668,12 +1668,11 @@ eth_em_rx_init(struct rte_eth_dev *dev)
 	/* Determine RX bufsize. */
 	rctl_bsize = EM_MAX_BUF_SIZE;
 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
-		struct rte_pktmbuf_pool_private *mbp_priv;
 		uint32_t buf_size;
 
 		rxq = dev->data->rx_queues[i];
-		mbp_priv = rte_mempool_get_priv(rxq->mb_pool);
-		buf_size = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM;
+		buf_size = rte_pktmbuf_data_room_size(rxq->mb_pool) -
+			RTE_PKTMBUF_HEADROOM;
 		rctl_bsize = RTE_MIN(rctl_bsize, buf_size);
 	}
 
diff --git a/lib/librte_pmd_e1000/igb_rxtx.c b/lib/librte_pmd_e1000/igb_rxtx.c
index 084e45a..80d05c0 100644
--- a/lib/librte_pmd_e1000/igb_rxtx.c
+++ b/lib/librte_pmd_e1000/igb_rxtx.c
@@ -1921,7 +1921,6 @@ eth_igb_rx_init(struct rte_eth_dev *dev)
 {
 	struct e1000_hw     *hw;
 	struct igb_rx_queue *rxq;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint32_t rctl;
 	uint32_t rxcsum;
 	uint32_t srrctl;
@@ -1991,9 +1990,8 @@ eth_igb_rx_init(struct rte_eth_dev *dev)
 		/*
 		 * Configure RX buffer size.
 		 */
-		mbp_priv = rte_mempool_get_priv(rxq->mb_pool);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-				       RTE_PKTMBUF_HEADROOM);
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) -
+			RTE_PKTMBUF_HEADROOM);
 		if (buf_size >= 1024) {
 			/*
 			 * Configure the BSIZEPACKET field of the SRRCTL
@@ -2221,7 +2219,6 @@ eth_igbvf_rx_init(struct rte_eth_dev *dev)
 {
 	struct e1000_hw     *hw;
 	struct igb_rx_queue *rxq;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint32_t srrctl;
 	uint16_t buf_size;
 	uint16_t rctl_bsize;
@@ -2262,9 +2259,8 @@ eth_igbvf_rx_init(struct rte_eth_dev *dev)
 		/*
 		 * Configure RX buffer size.
 		 */
-		mbp_priv = rte_mempool_get_priv(rxq->mb_pool);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-				       RTE_PKTMBUF_HEADROOM);
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) -
+			RTE_PKTMBUF_HEADROOM);
 		if (buf_size >= 1024) {
 			/*
 			 * Configure the BSIZEPACKET field of the SRRCTL
diff --git a/lib/librte_pmd_fm10k/fm10k_ethdev.c b/lib/librte_pmd_fm10k/fm10k_ethdev.c
index 1a96cf2..dd4454c 100644
--- a/lib/librte_pmd_fm10k/fm10k_ethdev.c
+++ b/lib/librte_pmd_fm10k/fm10k_ethdev.c
@@ -397,7 +397,6 @@ fm10k_dev_rx_init(struct rte_eth_dev *dev)
 	uint32_t size;
 	uint32_t rxdctl = FM10K_RXDCTL_WRITE_BACK_MIN_DELAY;
 	uint16_t buf_size;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 
 	/* Disable RXINT to avoid possible interrupt */
 	for (i = 0; i < hw->mac.max_queues; i++)
@@ -425,9 +424,8 @@ fm10k_dev_rx_init(struct rte_eth_dev *dev)
 		FM10K_WRITE_REG(hw, FM10K_RDLEN(i), size);
 
 		/* Configure the Rx buffer size for one buff without split */
-		mbp_priv = rte_mempool_get_priv(rxq->mp);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-					RTE_PKTMBUF_HEADROOM);
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mp) -
+			RTE_PKTMBUF_HEADROOM);
 		FM10K_WRITE_REG(hw, FM10K_SRRCTL(i),
 				buf_size >> FM10K_SRRCTL_BSIZEPKT_SHIFT);
 
diff --git a/lib/librte_pmd_i40e/i40e_ethdev_vf.c b/lib/librte_pmd_i40e/i40e_ethdev_vf.c
index 4581c5b..473d441 100644
--- a/lib/librte_pmd_i40e/i40e_ethdev_vf.c
+++ b/lib/librte_pmd_i40e/i40e_ethdev_vf.c
@@ -571,13 +571,11 @@ i40evf_fill_virtchnl_vsi_rxq_info(struct i40e_virtchnl_rxq_info *rxq_info,
 	rxq_info->queue_id = queue_id;
 	rxq_info->max_pkt_size = max_pkt_size;
 	if (queue_id < nb_rxq) {
-		struct rte_pktmbuf_pool_private *mbp_priv;
-
 		rxq_info->ring_len = rxq->nb_rx_desc;
 		rxq_info->dma_ring_addr = rxq->rx_ring_phys_addr;
-		mbp_priv = rte_mempool_get_priv(rxq->mp);
 		rxq_info->databuffer_size =
-			mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM;
+			(rte_pktmbuf_data_room_size(rxq->mp) -
+				RTE_PKTMBUF_HEADROOM);
 	}
 }
 
diff --git a/lib/librte_pmd_i40e/i40e_rxtx.c b/lib/librte_pmd_i40e/i40e_rxtx.c
index abe68f4..493cfa3 100644
--- a/lib/librte_pmd_i40e/i40e_rxtx.c
+++ b/lib/librte_pmd_i40e/i40e_rxtx.c
@@ -2444,11 +2444,10 @@ i40e_rx_queue_config(struct i40e_rx_queue *rxq)
 	struct i40e_pf *pf = I40E_VSI_TO_PF(rxq->vsi);
 	struct i40e_hw *hw = I40E_VSI_TO_HW(rxq->vsi);
 	struct rte_eth_dev_data *data = pf->dev_data;
-	struct rte_pktmbuf_pool_private *mbp_priv =
-			rte_mempool_get_priv(rxq->mp);
-	uint16_t buf_size = (uint16_t)(mbp_priv->mbuf_data_room_size -
-						RTE_PKTMBUF_HEADROOM);
-	uint16_t len;
+	uint16_t buf_size, len;
+
+	buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mp) -
+		RTE_PKTMBUF_HEADROOM);
 
 	switch (pf->flags & (I40E_FLAG_HEADER_SPLIT_DISABLED |
 			I40E_FLAG_HEADER_SPLIT_ENABLED)) {
@@ -2506,7 +2505,6 @@ i40e_rx_queue_init(struct i40e_rx_queue *rxq)
 	uint16_t pf_q = rxq->reg_idx;
 	uint16_t buf_size;
 	struct i40e_hmc_obj_rxq rx_ctx;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 
 	err = i40e_rx_queue_config(rxq);
 	if (err < 0) {
@@ -2553,9 +2551,8 @@ i40e_rx_queue_init(struct i40e_rx_queue *rxq)
 
 	rxq->qrx_tail = hw->hw_addr + I40E_QRX_TAIL(pf_q);
 
-	mbp_priv = rte_mempool_get_priv(rxq->mp);
-	buf_size = (uint16_t)(mbp_priv->mbuf_data_room_size -
-					RTE_PKTMBUF_HEADROOM);
+	buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mp) -
+		RTE_PKTMBUF_HEADROOM);
 
 	/* Check if scattered RX needs to be used. */
 	if ((rxq->max_pkt_len + 2 * I40E_VLAN_TAG_SIZE) > buf_size) {
diff --git a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c
index 3c61d1c..7f15f15 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c
+++ b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c
@@ -4203,7 +4203,6 @@ ixgbe_dev_rx_init(struct rte_eth_dev *dev)
 {
 	struct ixgbe_hw     *hw;
 	struct ixgbe_rx_queue *rxq;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint64_t bus_addr;
 	uint32_t rxctrl;
 	uint32_t fctrl;
@@ -4320,9 +4319,8 @@ ixgbe_dev_rx_init(struct rte_eth_dev *dev)
 		 * The value is in 1 KB resolution. Valid values can be from
 		 * 1 KB to 16 KB.
 		 */
-		mbp_priv = rte_mempool_get_priv(rxq->mb_pool);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-				       RTE_PKTMBUF_HEADROOM);
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) -
+			RTE_PKTMBUF_HEADROOM);
 		srrctl |= ((buf_size >> IXGBE_SRRCTL_BSIZEPKT_SHIFT) &
 			   IXGBE_SRRCTL_BSIZEPKT_MASK);
 
@@ -4738,7 +4736,6 @@ ixgbevf_dev_rx_init(struct rte_eth_dev *dev)
 {
 	struct ixgbe_hw     *hw;
 	struct ixgbe_rx_queue *rxq;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint64_t bus_addr;
 	uint32_t srrctl, psrtype = 0;
 	uint16_t buf_size;
@@ -4825,9 +4822,8 @@ ixgbevf_dev_rx_init(struct rte_eth_dev *dev)
 		 * The value is in 1 KB resolution. Valid values can be from
 		 * 1 KB to 16 KB.
 		 */
-		mbp_priv = rte_mempool_get_priv(rxq->mb_pool);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-				       RTE_PKTMBUF_HEADROOM);
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) -
+			RTE_PKTMBUF_HEADROOM);
 		srrctl |= ((buf_size >> IXGBE_SRRCTL_BSIZEPKT_SHIFT) &
 			   IXGBE_SRRCTL_BSIZEPKT_MASK);
 
diff --git a/lib/librte_pmd_pcap/rte_eth_pcap.c b/lib/librte_pmd_pcap/rte_eth_pcap.c
index e5d2279..e1aea34 100644
--- a/lib/librte_pmd_pcap/rte_eth_pcap.c
+++ b/lib/librte_pmd_pcap/rte_eth_pcap.c
@@ -136,9 +136,7 @@ eth_pcap_rx(void *queue,
 	const u_char *packet;
 	struct rte_mbuf *mbuf;
 	struct pcap_rx_queue *pcap_q = queue;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint16_t num_rx = 0;
-	uint16_t buf_size;
 
 	if (unlikely(pcap_q->pcap == NULL || nb_pkts == 0))
 		return 0;
@@ -157,8 +155,7 @@ eth_pcap_rx(void *queue,
 			break;
 
 		/* Now get the space available for data in the mbuf */
-		mbp_priv =  rte_mempool_get_priv(pcap_q->mb_pool);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(pcap_q->mb_pool) -
 				RTE_PKTMBUF_HEADROOM);
 
 		if (header.len <= buf_size) {
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
index a530c80..d8019f5 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
@@ -838,14 +838,11 @@ vmxnet3_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint8_t i;
 	char mem_name[32];
 	uint16_t buf_size;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 
 	PMD_INIT_FUNC_TRACE();
 
-	mbp_priv = (struct rte_pktmbuf_pool_private *)
-		rte_mempool_get_priv(mp);
-	buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-			       RTE_PKTMBUF_HEADROOM);
+	buf_size = rte_pktmbuf_data_room_size(mp) -
+		RTE_PKTMBUF_HEADROOM;
 
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len > buf_size) {
 		PMD_INIT_LOG(ERR, "buf_size = %u, max_pkt_len = %u, "
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v5 04/12] mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
                             ` (2 preceding siblings ...)
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 03/12] mbuf: add accessors to get data room size and private size Olivier Matz
@ 2015-04-21  9:55           ` Olivier Matz
  2015-04-21 15:07             ` Ananyev, Konstantin
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 05/12] testpmd: use standard functions to initialize mbufs and mbuf pool Olivier Matz
                             ` (9 subsequent siblings)
  13 siblings, 1 reply; 101+ messages in thread
From: Olivier Matz @ 2015-04-21  9:55 UTC (permalink / raw)
  To: dev

Allow the user to use the default rte_pktmbuf_init() function even
if the mbuf private size is not 0.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_mbuf/rte_mbuf.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index 231cfb8..d7f0380 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -119,16 +119,19 @@ rte_pktmbuf_init(struct rte_mempool *mp,
 		 __attribute__((unused)) unsigned i)
 {
 	struct rte_mbuf *m = _m;
-	uint32_t buf_len = mp->elt_size - sizeof(struct rte_mbuf);
+	uint32_t mbuf_size, buf_len;
 
-	RTE_MBUF_ASSERT(mp->elt_size >= sizeof(struct rte_mbuf));
+	mbuf_size = sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(mp);
+	buf_len = rte_pktmbuf_data_room_size(mp);
+
+	RTE_MBUF_ASSERT(mp->elt_size >= mbuf_size);
+	RTE_MBUF_ASSERT(buf_len <= 0xffff);
 
 	memset(m, 0, mp->elt_size);
 
 	/* start of buffer is just after mbuf structure */
-	m->buf_addr = (char *)m + sizeof(struct rte_mbuf);
-	m->buf_physaddr = rte_mempool_virt2phy(mp, m) +
-			sizeof(struct rte_mbuf);
+	m->buf_addr = (char *)m + mbuf_size;
+	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mbuf_size;
 	m->buf_len = (uint16_t)buf_len;
 
 	/* keep some headroom between start of buffer and data */
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v5 05/12] testpmd: use standard functions to initialize mbufs and mbuf pool
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
                             ` (3 preceding siblings ...)
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 04/12] mbuf: fix rte_pktmbuf_init when mbuf private size is not zero Olivier Matz
@ 2015-04-21  9:55           ` Olivier Matz
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 06/12] mbuf: introduce a new helper to create a " Olivier Matz
                             ` (8 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-21  9:55 UTC (permalink / raw)
  To: dev

The rte_pktmbuf_pool_init() and rte_pktmbuf_init() functions now
support to have a non-hardcoded buffer length. We can remove the
specific functions used in testpmd and replace them by the standard
ones.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test-pmd/testpmd.c | 74 +++++---------------------------------------------
 1 file changed, 7 insertions(+), 67 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 10e4347..1f2445e 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -393,83 +393,23 @@ set_def_fwd_config(void)
 /*
  * Configuration initialisation done once at init time.
  */
-struct mbuf_ctor_arg {
-	uint16_t seg_buf_offset; /**< offset of data in data segment of mbuf. */
-	uint16_t seg_buf_size;   /**< size of data segment in mbuf. */
-};
-
-struct mbuf_pool_ctor_arg {
-	uint16_t seg_buf_size; /**< size of data segment in mbuf. */
-};
-
-static void
-testpmd_mbuf_ctor(struct rte_mempool *mp,
-		  void *opaque_arg,
-		  void *raw_mbuf,
-		  __attribute__((unused)) unsigned i)
-{
-	struct mbuf_ctor_arg *mb_ctor_arg;
-	struct rte_mbuf    *mb;
-
-	mb_ctor_arg = (struct mbuf_ctor_arg *) opaque_arg;
-	mb = (struct rte_mbuf *) raw_mbuf;
-
-	mb->pool         = mp;
-	mb->buf_addr     = (void *) ((char *)mb + mb_ctor_arg->seg_buf_offset);
-	mb->buf_physaddr = (uint64_t) (rte_mempool_virt2phy(mp, mb) +
-			mb_ctor_arg->seg_buf_offset);
-	mb->buf_len      = mb_ctor_arg->seg_buf_size;
-	mb->ol_flags     = 0;
-	mb->data_off     = RTE_PKTMBUF_HEADROOM;
-	mb->nb_segs      = 1;
-	mb->tx_offload   = 0;
-	mb->vlan_tci     = 0;
-	mb->hash.rss     = 0;
-}
-
-static void
-testpmd_mbuf_pool_ctor(struct rte_mempool *mp,
-		       void *opaque_arg)
-{
-	struct mbuf_pool_ctor_arg      *mbp_ctor_arg;
-	struct rte_pktmbuf_pool_private *mbp_priv;
-
-	if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) {
-		printf("%s(%s) private_data_size %d < %d\n",
-		       __func__, mp->name, (int) mp->private_data_size,
-		       (int) sizeof(struct rte_pktmbuf_pool_private));
-		return;
-	}
-	mbp_ctor_arg = (struct mbuf_pool_ctor_arg *) opaque_arg;
-	mbp_priv = rte_mempool_get_priv(mp);
-	mbp_priv->mbuf_data_room_size = mbp_ctor_arg->seg_buf_size;
-	mbp_priv->mbuf_priv_size = 0;
-}
-
 static void
 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 		 unsigned int socket_id)
 {
 	char pool_name[RTE_MEMPOOL_NAMESIZE];
 	struct rte_mempool *rte_mp;
-	struct mbuf_pool_ctor_arg mbp_ctor_arg;
-	struct mbuf_ctor_arg mb_ctor_arg;
 	uint32_t mb_size;
 
-	mbp_ctor_arg.seg_buf_size = (uint16_t) (RTE_PKTMBUF_HEADROOM +
-						mbuf_seg_size);
-	mb_ctor_arg.seg_buf_offset =
-		(uint16_t) RTE_CACHE_LINE_ROUNDUP(sizeof(struct rte_mbuf));
-	mb_ctor_arg.seg_buf_size = mbp_ctor_arg.seg_buf_size;
-	mb_size = mb_ctor_arg.seg_buf_offset + mb_ctor_arg.seg_buf_size;
+	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
 
 #ifdef RTE_LIBRTE_PMD_XENVIRT
 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
                                    (unsigned) mb_mempool_cache,
                                    sizeof(struct rte_pktmbuf_pool_private),
-                                   testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
-                                   testpmd_mbuf_ctor, &mb_ctor_arg,
+                                   rte_pktmbuf_pool_init, NULL,
+                                   rte_pktmbuf_init, NULL,
                                    socket_id, 0);
 
 
@@ -479,15 +419,15 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 		rte_mp = mempool_anon_create(pool_name, nb_mbuf, mb_size,
 				    (unsigned) mb_mempool_cache,
 				    sizeof(struct rte_pktmbuf_pool_private),
-				    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
-				    testpmd_mbuf_ctor, &mb_ctor_arg,
+				    rte_pktmbuf_pool_init, NULL,
+				    rte_pktmbuf_init, NULL,
 				    socket_id, 0);
 	else
 		rte_mp = rte_mempool_create(pool_name, nb_mbuf, mb_size,
 				    (unsigned) mb_mempool_cache,
 				    sizeof(struct rte_pktmbuf_pool_private),
-				    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
-				    testpmd_mbuf_ctor, &mb_ctor_arg,
+				    rte_pktmbuf_pool_init, NULL,
+				    rte_pktmbuf_init, NULL,
 				    socket_id, 0);
 
 #endif
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v5 06/12] mbuf: introduce a new helper to create a mbuf pool
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
                             ` (4 preceding siblings ...)
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 05/12] testpmd: use standard functions to initialize mbufs and mbuf pool Olivier Matz
@ 2015-04-21  9:55           ` Olivier Matz
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 07/12] apps: use rte_pktmbuf_pool_create to create mbuf pools Olivier Matz
                             ` (7 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-21  9:55 UTC (permalink / raw)
  To: dev

Add a new wrapper to rte_mempool_create() to simplify the creation
of a packet mbuf pool.

This wrapper can be used if there is no specific mempool flags, and
no specific mbuf or pool constructor function, which is most of the
use cases.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 doc/guides/rel_notes/updating_apps.rst |  4 ++++
 lib/librte_mbuf/rte_mbuf.c             | 21 ++++++++++++++++++
 lib/librte_mbuf/rte_mbuf.h             | 40 ++++++++++++++++++++++++++++++++++
 lib/librte_mbuf/rte_mbuf_version.map   |  8 +++++++
 4 files changed, 73 insertions(+)

diff --git a/doc/guides/rel_notes/updating_apps.rst b/doc/guides/rel_notes/updating_apps.rst
index f513615..f4dd196 100644
--- a/doc/guides/rel_notes/updating_apps.rst
+++ b/doc/guides/rel_notes/updating_apps.rst
@@ -16,6 +16,10 @@ DPDK 2.0 to DPDK 2.1
     rte_pktmbuf_pool_private structure and pass it to
     rte_pktmbuf_pool_init().
 
+*   A simpler helper rte_pktmbuf_pool_create() can be used to create a
+    packet mbuf pool. The old way using rte_mempool_create() is still
+    supported though and is still used for more specific cases.
+
 DPDK 1.7 to DPDK 1.8
 --------------------
 
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index d7f0380..b013607 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -143,6 +143,27 @@ rte_pktmbuf_init(struct rte_mempool *mp,
 	m->port = 0xff;
 }
 
+/* helper to create a mbuf pool */
+struct rte_mempool *
+rte_pktmbuf_pool_create(const char *name, unsigned n,
+	unsigned cache_size, uint16_t priv_size, uint16_t data_room_size,
+	int socket_id)
+{
+	struct rte_pktmbuf_pool_private mbp_priv;
+	unsigned elt_size;
+
+
+	elt_size = sizeof(struct rte_mbuf) + (unsigned)priv_size +
+		(unsigned)data_room_size;
+	mbp_priv.mbuf_data_room_size = data_room_size;
+	mbp_priv.mbuf_priv_size = priv_size;
+
+	return rte_mempool_create(name, n, elt_size,
+		cache_size, sizeof(struct rte_pktmbuf_pool_private),
+		rte_pktmbuf_pool_init, &mbp_priv, rte_pktmbuf_init, NULL,
+		socket_id, 0);
+}
+
 /* do some sanity checks on a mbuf: panic if it fails */
 void
 rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header)
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index a4146fa..42db8e3 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -642,6 +642,46 @@ void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg,
 void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
 
 /**
+ * Create a mbuf pool.
+ *
+ * This function creates and initializes a packet mbuf pool. It is
+ * a wrapper to rte_mempool_create() with the proper packet constructor
+ * and mempool constructor.
+ *
+ * @param name
+ *   The name of the mbuf pool.
+ * @param n
+ *   The number of elements in the mbuf pool. The optimum size (in terms
+ *   of memory usage) for a mempool is when n is a power of two minus one:
+ *   n = (2^q - 1).
+ * @param cache_size
+ *   Size of the per-core object cache. See rte_mempool_create() for
+ *   details.
+ * @param priv_size
+ *   Size of application private are between the rte_mbuf structure
+ *   and the data buffer.
+ * @param data_room_size
+ *   Size of data buffer in each mbuf, including RTE_PKTMBUF_HEADROOM.
+ * @param socket_id
+ *   The socket identifier where the memory should be allocated. The
+ *   value can be *SOCKET_ID_ANY* if there is no NUMA constraint for the
+ *   reserved zone.
+ * @return
+ *   The pointer to the new allocated mempool, on success. NULL on error
+ *   with rte_errno set appropriately. Possible rte_errno values include:
+ *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
+ *    - E_RTE_SECONDARY - function was called from a secondary process instance
+ *    - EINVAL - cache size provided is too large
+ *    - ENOSPC - the maximum number of memzones has already been allocated
+ *    - EEXIST - a memzone with the same name already exists
+ *    - ENOMEM - no appropriate memory area found in which to create memzone
+ */
+struct rte_mempool *
+rte_pktmbuf_pool_create(const char *name, unsigned n,
+	unsigned cache_size, uint16_t priv_size, uint16_t data_room_size,
+	int socket_id);
+
+/**
  * Get the data room size of mbufs stored in a pktmbuf_pool
  *
  * The data room size is the amount of data that can be stored in a
diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map
index c4be3df..7ae2244 100644
--- a/lib/librte_mbuf/rte_mbuf_version.map
+++ b/lib/librte_mbuf/rte_mbuf_version.map
@@ -11,3 +11,11 @@ DPDK_2.0 {
 
 	local: *;
 };
+
+DPDK_2.1 {
+       global:
+
+       rte_pktmbuf_pool_create;
+
+       local: *;
+} DPDK_2.0;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v5 07/12] apps: use rte_pktmbuf_pool_create to create mbuf pools
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
                             ` (5 preceding siblings ...)
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 06/12] mbuf: introduce a new helper to create a " Olivier Matz
@ 2015-04-21  9:55           ` Olivier Matz
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 08/12] mbuf: fix clone support when application uses private mbuf data Olivier Matz
                             ` (6 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-21  9:55 UTC (permalink / raw)
  To: dev

When it's possible, use the new helper to create the mbuf pools.
Most of the patch is trivial, except for the following files that
have some specifics (indirect mbufs):
- ip_fragmentation
- ip_pipeline
- ipv4_multicast
- vhost

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test-pipeline/init.c                           | 15 ++--------
 app/test-pmd/testpmd.c                             |  9 ++----
 app/test/test_distributor.c                        | 10 ++-----
 app/test/test_distributor_perf.c                   | 10 ++-----
 app/test/test_kni.c                                | 16 +++--------
 app/test/test_link_bonding.c                       | 10 +++----
 app/test/test_link_bonding_mode4.c                 | 12 +++-----
 app/test/test_mbuf.c                               | 22 +++++----------
 app/test/test_pmd_perf.c                           | 11 +++-----
 app/test/test_pmd_ring.c                           | 10 ++-----
 app/test/test_reorder.c                            | 10 ++-----
 app/test/test_sched.c                              | 16 ++---------
 app/test/test_table.c                              |  9 ++----
 app/test/test_table.h                              |  3 +-
 examples/bond/main.c                               | 10 ++-----
 examples/distributor/main.c                        | 11 +++-----
 examples/dpdk_qat/main.c                           | 10 ++-----
 examples/exception_path/main.c                     | 14 ++++------
 examples/ip_fragmentation/main.c                   | 18 ++++--------
 examples/ip_pipeline/init.c                        | 32 ++++------------------
 examples/ipv4_multicast/main.c                     | 23 ++++++----------
 examples/kni/main.c                                | 12 +++-----
 examples/l2fwd-ivshmem/host/host.c                 | 10 ++-----
 examples/l2fwd-jobstats/main.c                     | 10 ++-----
 examples/l2fwd/main.c                              | 11 ++------
 examples/l3fwd-acl/main.c                          | 11 +++-----
 examples/l3fwd-power/main.c                        | 11 +++-----
 examples/l3fwd-vf/main.c                           | 12 +++-----
 examples/l3fwd/main.c                              | 10 +++----
 examples/link_status_interrupt/main.c              | 10 ++-----
 examples/load_balancer/init.c                      | 12 ++------
 examples/load_balancer/main.h                      |  4 +--
 .../client_server_mp/mp_server/init.c              | 10 ++-----
 examples/multi_process/symmetric_mp/main.c         | 10 +++----
 examples/netmap_compat/bridge/bridge.c             | 12 +++-----
 examples/packet_ordering/main.c                    | 11 +++-----
 examples/qos_meter/main.c                          |  7 ++---
 examples/qos_sched/init.c                          | 10 ++-----
 examples/qos_sched/main.h                          |  2 +-
 examples/quota_watermark/include/conf.h            |  2 +-
 examples/quota_watermark/qw/main.c                 |  7 ++---
 examples/rxtx_callbacks/main.c                     | 11 +++-----
 examples/skeleton/basicfwd.c                       | 13 ++-------
 examples/vhost/main.c                              | 24 +++++-----------
 examples/vhost_xen/main.c                          | 11 +++-----
 examples/vmdq/main.c                               | 11 +++-----
 examples/vmdq_dcb/main.c                           | 10 ++-----
 lib/librte_pmd_bond/rte_eth_bond_alb.c             | 16 +++++------
 48 files changed, 175 insertions(+), 386 deletions(-)

diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index 05f4503..db2196b 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -85,8 +85,7 @@ struct app_params app = {
 	.ring_tx_size = 128,
 
 	/* Buffer pool */
-	.pool_buffer_size = 2048 + sizeof(struct rte_mbuf) +
-		RTE_PKTMBUF_HEADROOM,
+	.pool_buffer_size = 2048 + RTE_PKTMBUF_HEADROOM,
 	.pool_size = 32 * 1024,
 	.pool_cache_size = 256,
 
@@ -144,16 +143,8 @@ app_init_mbuf_pools(void)
 {
 	/* Init the buffer pool */
 	RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n");
-	app.pool = rte_mempool_create(
-		"mempool",
-		app.pool_size,
-		app.pool_buffer_size,
-		app.pool_cache_size,
-		sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, NULL,
-		rte_pktmbuf_init, NULL,
-		rte_socket_id(),
-		0);
+	app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size,
+		app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id());
 	if (app.pool == NULL)
 		rte_panic("Cannot create mbuf pool\n");
 }
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 1f2445e..8418db3 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -423,12 +423,9 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 				    rte_pktmbuf_init, NULL,
 				    socket_id, 0);
 	else
-		rte_mp = rte_mempool_create(pool_name, nb_mbuf, mb_size,
-				    (unsigned) mb_mempool_cache,
-				    sizeof(struct rte_pktmbuf_pool_private),
-				    rte_pktmbuf_pool_init, NULL,
-				    rte_pktmbuf_init, NULL,
-				    socket_id, 0);
+		/* wrapper to rte_mempool_create() */
+		rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
+			mb_mempool_cache, 0, mbuf_seg_size, socket_id);
 
 #endif
 
diff --git a/app/test/test_distributor.c b/app/test/test_distributor.c
index 9e8c06d..ad46987 100644
--- a/app/test/test_distributor.c
+++ b/app/test/test_distributor.c
@@ -500,7 +500,7 @@ quit_workers(struct rte_distributor *d, struct rte_mempool *p)
 	worker_idx = 0;
 }
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 static int
 test_distributor(void)
@@ -528,12 +528,8 @@ test_distributor(void)
 	const unsigned nb_bufs = (511 * rte_lcore_count()) < BIG_BATCH ?
 			(BIG_BATCH * 2) - 1 : (511 * rte_lcore_count());
 	if (p == NULL) {
-		p = rte_mempool_create("DT_MBUF_POOL", nb_bufs,
-				MBUF_SIZE, BURST,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL,
-				rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+		p = rte_pktmbuf_pool_create("DT_MBUF_POOL", nb_bufs, BURST,
+			0, MBUF_DATA_SIZE, rte_socket_id());
 		if (p == NULL) {
 			printf("Error creating mempool\n");
 			return -1;
diff --git a/app/test/test_distributor_perf.c b/app/test/test_distributor_perf.c
index 31431bb..f04cb15 100644
--- a/app/test/test_distributor_perf.c
+++ b/app/test/test_distributor_perf.c
@@ -209,7 +209,7 @@ quit_workers(struct rte_distributor *d, struct rte_mempool *p)
 	worker_idx = 0;
 }
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 static int
 test_distributor_perf(void)
@@ -240,12 +240,8 @@ test_distributor_perf(void)
 	const unsigned nb_bufs = (511 * rte_lcore_count()) < BIG_BATCH ?
 			(BIG_BATCH * 2) - 1 : (511 * rte_lcore_count());
 	if (p == NULL) {
-		p = rte_mempool_create("DPT_MBUF_POOL", nb_bufs,
-				MBUF_SIZE, BURST,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL,
-				rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+		p = rte_pktmbuf_pool_create("DPT_MBUF_POOL", nb_bufs, BURST,
+			0, MBUF_DATA_SIZE, rte_socket_id());
 		if (p == NULL) {
 			printf("Error creating mempool\n");
 			return -1;
diff --git a/app/test/test_kni.c b/app/test/test_kni.c
index 608901d..506b543 100644
--- a/app/test/test_kni.c
+++ b/app/test/test_kni.c
@@ -47,8 +47,7 @@
 
 #define NB_MBUF          8192
 #define MAX_PACKET_SZ    2048
-#define MBUF_SZ \
-	(MAX_PACKET_SZ + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SZ     (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM)
 #define PKT_BURST_SZ     32
 #define MEMPOOL_CACHE_SZ PKT_BURST_SZ
 #define SOCKET           0
@@ -118,17 +117,10 @@ test_kni_create_mempool(void)
 
 	mp = rte_mempool_lookup("kni_mempool");
 	if (!mp)
-		mp = rte_mempool_create("kni_mempool",
+		mp = rte_pktmbuf_pool_create("kni_mempool",
 				NB_MBUF,
-				MBUF_SZ,
-				MEMPOOL_CACHE_SZ,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init,
-				NULL,
-				rte_pktmbuf_init,
-				NULL,
-				SOCKET,
-				0);
+				MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ,
+				SOCKET);
 
 	return mp;
 }
diff --git a/app/test/test_link_bonding.c b/app/test/test_link_bonding.c
index 8c24314..674d8dd 100644
--- a/app/test/test_link_bonding.c
+++ b/app/test/test_link_bonding.c
@@ -75,8 +75,7 @@
 	ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \
 	ETH_TXQ_FLAGS_NOXSUMTCP)
 
-#define MBUF_PAYLOAD_SIZE	(2048)
-#define MBUF_SIZE (MBUF_PAYLOAD_SIZE + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE (250)
 #define BURST_SIZE (32)
 
@@ -280,10 +279,9 @@ test_setup(void)
 	nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
 			RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
 	if (test_params->mbuf_pool == NULL) {
-		test_params->mbuf_pool = rte_mempool_create("MBUF_POOL", nb_mbuf_per_pool,
-				MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+		test_params->mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+			nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+			rte_socket_id());
 		TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
 				"rte_mempool_create failed");
 	}
diff --git a/app/test/test_link_bonding_mode4.c b/app/test/test_link_bonding_mode4.c
index 02380f9..590daad 100644
--- a/app/test/test_link_bonding_mode4.c
+++ b/app/test/test_link_bonding_mode4.c
@@ -65,9 +65,7 @@
 #define RX_RING_SIZE 128
 #define TX_RING_SIZE 512
 
-#define MBUF_PAYLOAD_SIZE	    (2048)
-#define MBUF_SIZE (MBUF_PAYLOAD_SIZE + sizeof(struct rte_mbuf) + \
-	RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE          (2048 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE         (250)
 #define BURST_SIZE              (32)
 
@@ -390,11 +388,9 @@ test_setup(void)
 	if (test_params.mbuf_pool == NULL) {
 		nb_mbuf_per_pool = TEST_RX_DESC_MAX + DEF_PKT_BURST +
 					TEST_TX_DESC_MAX + MAX_PKT_BURST;
-		test_params.mbuf_pool = rte_mempool_create("TEST_MODE4",
-				nb_mbuf_per_pool, MBUF_SIZE, MBUF_CACHE_SIZE,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-				socket_id, 0);
+		test_params.mbuf_pool = rte_pktmbuf_pool_create("TEST_MODE4",
+			nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+			socket_id);
 
 		TEST_ASSERT(test_params.mbuf_pool != NULL,
 			"rte_mempool_create failed\n");
diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 1ff66cb..4774263 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -61,7 +61,7 @@
 
 #include "test.h"
 
-#define MBUF_SIZE               2048
+#define MBUF_DATA_SIZE          2048
 #define NB_MBUF                 128
 #define MBUF_TEST_DATA_LEN      1464
 #define MBUF_TEST_DATA_LEN2     50
@@ -73,7 +73,6 @@
 #define REFCNT_MAX_TIMEOUT      10
 #define REFCNT_MAX_REF          (RTE_MAX_LCORE)
 #define REFCNT_MBUF_NUM         64
-#define REFCNT_MBUF_SIZE        (sizeof (struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
 #define REFCNT_RING_SIZE        (REFCNT_MBUF_NUM * REFCNT_MAX_REF)
 
 #define MAKE_STRING(x)          # x
@@ -622,12 +621,10 @@ test_refcnt_mbuf(void)
 	/* create refcnt pool & ring if they don't exist */
 
 	if (refcnt_pool == NULL &&
-			(refcnt_pool = rte_mempool_create(
-			MAKE_STRING(refcnt_pool),
-			REFCNT_MBUF_NUM, REFCNT_MBUF_SIZE, 0,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-			SOCKET_ID_ANY, 0)) == NULL) {
+			(refcnt_pool = rte_pktmbuf_pool_create(
+				MAKE_STRING(refcnt_pool),
+				REFCNT_MBUF_NUM, 0, 0, 0,
+				SOCKET_ID_ANY)) == NULL) {
 		printf("%s: cannot allocate " MAKE_STRING(refcnt_pool) "\n",
 		    __func__);
 		return (-1);
@@ -764,13 +761,8 @@ test_mbuf(void)
 
 	/* create pktmbuf pool if it does not exist */
 	if (pktmbuf_pool == NULL) {
-		pktmbuf_pool =
-			rte_mempool_create("test_pktmbuf_pool", NB_MBUF,
-					   MBUF_SIZE, 32,
-					   sizeof(struct rte_pktmbuf_pool_private),
-					   rte_pktmbuf_pool_init, NULL,
-					   rte_pktmbuf_init, NULL,
-					   SOCKET_ID_ANY, 0);
+		pktmbuf_pool = rte_pktmbuf_pool_create("test_pktmbuf_pool",
+			NB_MBUF, 32, 0, MBUF_DATA_SIZE, SOCKET_ID_ANY);
 	}
 
 	if (pktmbuf_pool == NULL) {
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index d6a4a45..49a494d 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -47,7 +47,7 @@
 #define NB_ETHPORTS_USED                (1)
 #define NB_SOCKETS                      (2)
 #define MEMPOOL_CACHE_SIZE 250
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define MAX_PKT_BURST                   (32)
 #define RTE_TEST_RX_DESC_DEFAULT        (128)
 #define RTE_TEST_TX_DESC_DEFAULT        (512)
@@ -289,12 +289,9 @@ init_mbufpool(unsigned nb_mbuf)
 		if (mbufpool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
 			mbufpool[socketid] =
-				rte_mempool_create(s, nb_mbuf, MBUF_SIZE,
-					MEMPOOL_CACHE_SIZE,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, 0);
+				rte_pktmbuf_pool_create(s, nb_mbuf,
+					MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+					socketid);
 			if (mbufpool[socketid] == NULL)
 				rte_exit(EXIT_FAILURE,
 					"Cannot init mbuf pool on socket %d\n",
diff --git a/app/test/test_pmd_ring.c b/app/test/test_pmd_ring.c
index 7490112..53897f7 100644
--- a/app/test/test_pmd_ring.c
+++ b/app/test/test_pmd_ring.c
@@ -48,7 +48,7 @@ static struct rte_mempool *mp;
 
 #define RING_SIZE 256
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   512
 
 static int
@@ -406,12 +406,8 @@ test_pmd_ring_pair_create_attach(void)
 static int
 test_pmd_ring(void)
 {
-	mp = rte_mempool_create("mbuf_pool", NB_MBUF,
-			MBUF_SIZE, 32,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL,
-			rte_pktmbuf_init, NULL,
-			rte_socket_id(), 0);
+	mp = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32,
+		0, MBUF_DATA_SIZE, rte_socket_id());
 	if (mp == NULL)
 		return -1;
 
diff --git a/app/test/test_reorder.c b/app/test/test_reorder.c
index 61cf8d3..91fbe9a 100644
--- a/app/test/test_reorder.c
+++ b/app/test/test_reorder.c
@@ -50,7 +50,7 @@
 #define REORDER_BUFFER_SIZE 16384
 #define NUM_MBUFS (2*REORDER_BUFFER_SIZE)
 #define REORDER_BUFFER_SIZE_INVALID 2049
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 struct reorder_unittest_params {
 	struct rte_mempool *p;
@@ -351,12 +351,8 @@ test_setup(void)
 
 	/* mempool creation */
 	if (test_params->p == NULL) {
-		test_params->p = rte_mempool_create("RO_MBUF_POOL", NUM_MBUFS,
-				MBUF_SIZE, BURST,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL,
-				rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+		test_params->p = rte_pktmbuf_pool_create("RO_MBUF_POOL",
+			NUM_MBUFS, BURST, 0, MBUF_DATA_SIZE, rte_socket_id());
 		if (test_params->p == NULL) {
 			printf("%s: Error creating mempool\n", __func__);
 			return -1;
diff --git a/app/test/test_sched.c b/app/test/test_sched.c
index 60c62de..c7239f8 100644
--- a/app/test/test_sched.c
+++ b/app/test/test_sched.c
@@ -86,8 +86,7 @@ static struct rte_sched_port_params port_param = {
 };
 
 #define NB_MBUF          32
-#define MAX_PACKET_SZ    2048
-#define MBUF_SZ (MAX_PACKET_SZ + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SZ     (2048 + RTE_PKTMBUF_HEADROOM)
 #define PKT_BURST_SZ     32
 #define MEMPOOL_CACHE_SZ PKT_BURST_SZ
 #define SOCKET           0
@@ -100,17 +99,8 @@ create_mempool(void)
 
 	mp = rte_mempool_lookup("test_sched");
 	if (!mp)
-		mp = rte_mempool_create("test_sched",
-				NB_MBUF,
-				MBUF_SZ,
-				MEMPOOL_CACHE_SZ,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init,
-				NULL,
-				rte_pktmbuf_init,
-				NULL,
-				SOCKET,
-				0);
+		mp = rte_pktmbuf_pool_create("test_sched", NB_MBUF,
+			MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, SOCKET);
 
 	return mp;
 }
diff --git a/app/test/test_table.c b/app/test/test_table.c
index c3093cc..de6c27d 100644
--- a/app/test/test_table.c
+++ b/app/test/test_table.c
@@ -89,15 +89,10 @@ app_init_mbuf_pools(void)
 	printf("Getting/Creating the mempool ...\n");
 	pool = rte_mempool_lookup("mempool");
 	if (!pool) {
-		pool = rte_mempool_create(
+		pool = rte_pktmbuf_pool_create(
 			"mempool",
 			POOL_SIZE,
-			POOL_BUFFER_SIZE,
-			POOL_CACHE_SIZE,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL,
-			rte_pktmbuf_init, NULL,
-			0,
+			POOL_CACHE_SIZE, 0, POOL_BUFFER_SIZE,
 			0);
 		if (pool == NULL)
 			rte_panic("Cannot create mbuf pool\n");
diff --git a/app/test/test_table.h b/app/test/test_table.h
index 64e9427..be331c0 100644
--- a/app/test/test_table.h
+++ b/app/test/test_table.h
@@ -65,7 +65,7 @@
 #define PORT_TX_RING_SIZE   512
 #define RING_RX_SIZE        128
 #define RING_TX_SIZE        128
-#define POOL_BUFFER_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define POOL_BUFFER_SIZE    (2048 + RTE_PKTMBUF_HEADROOM)
 #define POOL_SIZE           (32 * 1024)
 #define POOL_CACHE_SIZE     256
 #define BURST_SIZE          8
@@ -73,7 +73,6 @@
 #define MAX_DUMMY_PORTS     2
 #define MP_NAME             "dummy_port_mempool"
 #define MBUF_COUNT          (8000 * MAX_DUMMY_PORTS)
-#define MBUF_SIZE        (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
 #define MP_CACHE_SZ         256
 #define MP_SOCKET           0
 #define MP_FLAGS            0
diff --git a/examples/bond/main.c b/examples/bond/main.c
index 67c283d..fcb4c4e 100644
--- a/examples/bond/main.c
+++ b/examples/bond/main.c
@@ -96,7 +96,7 @@
 
 #define RTE_LOGTYPE_DCB RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   (1024*8)
 
 #define MAX_PKT_BURST 32
@@ -738,12 +738,8 @@ main(int argc, char *argv[])
 	else if (nb_ports > MAX_PORTS)
 		rte_exit(EXIT_FAILURE, "You can have max 4 ports\n");
 
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NB_MBUF,
-				       MBUF_SIZE, 32,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init, NULL,
-				       rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NB_MBUF, 32,
+		0, MBUF_DATA_SIZE, rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/examples/distributor/main.c b/examples/distributor/main.c
index 13fb04d..78fe3e9 100644
--- a/examples/distributor/main.c
+++ b/examples/distributor/main.c
@@ -47,7 +47,7 @@
 #define RX_RING_SIZE 256
 #define TX_RING_SIZE 512
 #define NUM_MBUFS ((64*1024)-1)
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE 250
 #define BURST_SIZE 32
 #define RTE_RING_SZ 1024
@@ -528,12 +528,9 @@ main(int argc, char *argv[])
 		rte_exit(EXIT_FAILURE, "Error: number of ports must be even, except "
 				"when using a single port\n");
 
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
-			MBUF_SIZE, MBUF_CACHE_SIZE,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL,
-			rte_pktmbuf_init, NULL,
-			rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+		NUM_MBUFS * nb_ports, MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+		rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 	nb_ports_available = nb_ports;
diff --git a/examples/dpdk_qat/main.c b/examples/dpdk_qat/main.c
index 20e78bc..053be91 100644
--- a/examples/dpdk_qat/main.c
+++ b/examples/dpdk_qat/main.c
@@ -70,7 +70,7 @@
 
 #include "crypto.h"
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   (32 * 1024)
 
 #define MAX_PKT_BURST 32
@@ -598,7 +598,6 @@ print_ethaddr(const char *name, const struct ether_addr *eth_addr)
 static int
 init_mem(void)
 {
-	const unsigned flags = 0;
 	int socketid;
 	unsigned lcoreid;
 	char s[64];
@@ -613,11 +612,8 @@ init_mem(void)
 		if (pktmbuf_pool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
 			pktmbuf_pool[socketid] =
-				rte_mempool_create(s, NB_MBUF, MBUF_SIZE, 32,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, flags);
+				rte_pktmbuf_pool_create(s, NB_MBUF, 32, 0,
+					MBUF_DATA_SIZE, socketid);
 			if (pktmbuf_pool[socketid] == NULL) {
 				printf("Cannot init mbuf pool on socket %d\n", socketid);
 				return -1;
diff --git a/examples/exception_path/main.c b/examples/exception_path/main.c
index 14582de..b3fe170 100644
--- a/examples/exception_path/main.c
+++ b/examples/exception_path/main.c
@@ -81,11 +81,10 @@
 #define MAX_PORTS               (RTE_MAX_LCORE / 2)
 
 /* Max size of a single packet */
-#define MAX_PACKET_SZ           2048
+#define MAX_PACKET_SZ (2048)
 
-/* Number of bytes needed for each mbuf */
-#define MBUF_SZ \
-	(MAX_PACKET_SZ + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+/* Size of the data buffer in each mbuf */
+#define MBUF_DATA_SZ (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM)
 
 /* Number of mbufs in mempool that is created */
 #define NB_MBUF                 8192
@@ -532,11 +531,8 @@ main(int argc, char** argv)
 	parse_args(argc, argv);
 
 	/* Create the mbuf pool */
-	pktmbuf_pool = rte_mempool_create("mbuf_pool", NB_MBUF, MBUF_SZ,
-			MEMPOOL_CACHE_SZ,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-			rte_socket_id(), 0);
+	pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
+			MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, rte_socket_id());
 	if (pktmbuf_pool == NULL) {
 		FATAL_ERROR("Could not initialise mbuf pool");
 		return -1;
diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index cf63718..c702fdd 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -76,7 +76,7 @@
 
 #define RTE_LOGTYPE_IP_FRAG RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /* allow max jumbo frame 9.5 KB */
 #define JUMBO_FRAME_MAX_SIZE	0x2600
@@ -744,12 +744,8 @@ init_mem(void)
 					socket);
 			snprintf(buf, sizeof(buf), "pool_direct_%i", socket);
 
-			mp = rte_mempool_create(buf, NB_MBUF,
-						   MBUF_SIZE, 32,
-						   sizeof(struct rte_pktmbuf_pool_private),
-						   rte_pktmbuf_pool_init, NULL,
-						   rte_pktmbuf_init, NULL,
-						   socket, 0);
+			mp = rte_pktmbuf_pool_create(buf, NB_MBUF, 32,
+				0, MBUF_DATA_SIZE, socket);
 			if (mp == NULL) {
 				RTE_LOG(ERR, IP_FRAG, "Cannot create direct mempool\n");
 				return -1;
@@ -762,12 +758,8 @@ init_mem(void)
 					socket);
 			snprintf(buf, sizeof(buf), "pool_indirect_%i", socket);
 
-			mp = rte_mempool_create(buf, NB_MBUF,
-							   sizeof(struct rte_mbuf), 32,
-							   sizeof(struct rte_pktmbuf_pool_private),
-							   rte_pktmbuf_pool_init, NULL,
-							   rte_pktmbuf_init, NULL,
-							   socket, 0);
+			mp = rte_pktmbuf_pool_create(buf, NB_MBUF, 32, 0, 0,
+				socket);
 			if (mp == NULL) {
 				RTE_LOG(ERR, IP_FRAG, "Cannot create indirect mempool\n");
 				return -1;
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index 61d71c3..275fb35 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -146,8 +146,7 @@ struct app_params app = {
 	.bsz_swq_wr = 64,
 
 	/* Buffer pool */
-	.pool_buffer_size = 2048 + sizeof(struct rte_mbuf) +
-		RTE_PKTMBUF_HEADROOM,
+	.pool_buffer_size = 2048 + RTE_PKTMBUF_HEADROOM,
 	.pool_size = 32 * 1024,
 	.pool_cache_size = 256,
 
@@ -363,37 +362,18 @@ app_get_ring_resp(uint32_t core_id)
 static void
 app_init_mbuf_pools(void)
 {
-	struct rte_pktmbuf_pool_private indirect_mbp_priv;
-
 	/* Init the buffer pool */
 	RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n");
-	app.pool = rte_mempool_create(
-		"mempool",
-		app.pool_size,
-		app.pool_buffer_size,
-		app.pool_cache_size,
-		sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, NULL,
-		rte_pktmbuf_init, NULL,
-		rte_socket_id(),
-		0);
+	app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size,
+		app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id());
 	if (app.pool == NULL)
 		rte_panic("Cannot create mbuf pool\n");
 
 	/* Init the indirect buffer pool */
 	RTE_LOG(INFO, USER1, "Creating the indirect mbuf pool ...\n");
-	indirect_mbp_priv.mbuf_data_room_size = 0;
-	indirect_mbp_priv.mbuf_priv_size = sizeof(struct app_pkt_metadata);
-	app.indirect_pool = rte_mempool_create(
-		"indirect mempool",
-		app.pool_size,
-		sizeof(struct rte_mbuf) + sizeof(struct app_pkt_metadata),
-		app.pool_cache_size,
-		sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, &indirect_mbp_priv,
-		rte_pktmbuf_init, NULL,
-		rte_socket_id(),
-		0);
+	app.indirect_pool = rte_pktmbuf_pool_create("indirect mempool",
+		app.pool_size, app.pool_cache_size,
+		sizeof(struct app_pkt_metadata), 0, rte_socket_id());
 	if (app.indirect_pool == NULL)
 		rte_panic("Cannot create mbuf pool\n");
 
diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index 19832d8..575e989 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -77,13 +77,12 @@
 #define	MCAST_CLONE_PORTS	2
 #define	MCAST_CLONE_SEGS	2
 
-#define	PKT_MBUF_SIZE	(2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define	PKT_MBUF_DATA_SIZE	(2048 + RTE_PKTMBUF_HEADROOM)
 #define	NB_PKT_MBUF	8192
 
-#define	HDR_MBUF_SIZE	(sizeof(struct rte_mbuf) + 2 * RTE_PKTMBUF_HEADROOM)
+#define	HDR_MBUF_DATA_SIZE	(2 * RTE_PKTMBUF_HEADROOM)
 #define	NB_HDR_MBUF	(NB_PKT_MBUF * MAX_PORTS)
 
-#define	CLONE_MBUF_SIZE	(sizeof(struct rte_mbuf))
 #define	NB_CLONE_MBUF	(NB_PKT_MBUF * MCAST_CLONE_PORTS * MCAST_CLONE_SEGS * 2)
 
 /* allow max jumbo frame 9.5 KB */
@@ -690,26 +689,20 @@ main(int argc, char **argv)
 		rte_exit(EXIT_FAILURE, "Invalid IPV4_MULTICAST parameters\n");
 
 	/* create the mbuf pools */
-	packet_pool = rte_mempool_create("packet_pool", NB_PKT_MBUF,
-	    PKT_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
-	    rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-	    rte_socket_id(), 0);
+	packet_pool = rte_pktmbuf_pool_create("packet_pool", NB_PKT_MBUF, 32,
+		0, PKT_MBUF_DATA_SIZE, rte_socket_id());
 
 	if (packet_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init packet mbuf pool\n");
 
-	header_pool = rte_mempool_create("header_pool", NB_HDR_MBUF,
-	    HDR_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
-	    rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-	    rte_socket_id(), 0);
+	header_pool = rte_pktmbuf_pool_create("header_pool", NB_HDR_MBUF, 32,
+		0, HDR_MBUF_DATA_SIZE, rte_socket_id());
 
 	if (header_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init header mbuf pool\n");
 
-	clone_pool = rte_mempool_create("clone_pool", NB_CLONE_MBUF,
-	    CLONE_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
-	    rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-	    rte_socket_id(), 0);
+	clone_pool = rte_pktmbuf_pool_create("clone_pool", NB_CLONE_MBUF, 32,
+		0, 0, rte_socket_id());
 
 	if (clone_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init clone mbuf pool\n");
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 19d25d4..96ca473 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -80,9 +80,8 @@
 /* Max size of a single packet */
 #define MAX_PACKET_SZ           2048
 
-/* Number of bytes needed for each mbuf */
-#define MBUF_SZ \
-	(MAX_PACKET_SZ + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+/* Size of the data buffer in each mbuf */
+#define MBUF_DATA_SZ (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM)
 
 /* Number of mbufs in mempool that is created */
 #define NB_MBUF                 (8192 * 16)
@@ -867,11 +866,8 @@ main(int argc, char** argv)
 		rte_exit(EXIT_FAILURE, "Could not parse input parameters\n");
 
 	/* Create the mbuf pool */
-	pktmbuf_pool = rte_mempool_create("mbuf_pool", NB_MBUF, MBUF_SZ,
-			MEMPOOL_CACHE_SZ,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-			rte_socket_id(), 0);
+	pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
+		MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, rte_socket_id());
 	if (pktmbuf_pool == NULL) {
 		rte_exit(EXIT_FAILURE, "Could not initialise mbuf pool\n");
 		return -1;
diff --git a/examples/l2fwd-ivshmem/host/host.c b/examples/l2fwd-ivshmem/host/host.c
index 4f8d23e..197f22b 100644
--- a/examples/l2fwd-ivshmem/host/host.c
+++ b/examples/l2fwd-ivshmem/host/host.c
@@ -71,7 +71,7 @@ static uint32_t l2fwd_ivshmem_enabled_port_mask = 0;
 static struct ether_addr l2fwd_ivshmem_ports_eth_addr[RTE_MAX_ETHPORTS];
 
 #define NB_MBUF   8192
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 #define MAX_RX_QUEUE_PER_LCORE 16
 #define MAX_TX_QUEUE_PER_PORT 16
@@ -670,12 +670,8 @@ int main(int argc, char **argv)
 
 	/* create a shared mbuf pool */
 	l2fwd_ivshmem_pktmbuf_pool =
-		rte_mempool_create(MBUF_MP_NAME, NB_MBUF,
-				   MBUF_SIZE, 32,
-				   sizeof(struct rte_pktmbuf_pool_private),
-				   rte_pktmbuf_pool_init, NULL,
-				   rte_pktmbuf_init, NULL,
-				   rte_socket_id(), 0);
+		rte_pktmbuf_pool_create(MBUF_MP_NAME, NB_MBUF, 32,
+			0, MBUF_DATA_SIZE, rte_socket_id());
 	if (l2fwd_ivshmem_pktmbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
 
diff --git a/examples/l2fwd-jobstats/main.c b/examples/l2fwd-jobstats/main.c
index f990045..fcebbda 100644
--- a/examples/l2fwd-jobstats/main.c
+++ b/examples/l2fwd-jobstats/main.c
@@ -70,7 +70,7 @@
 
 #define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   8192
 
 #define MAX_PKT_BURST 32
@@ -833,12 +833,8 @@ main(int argc, char **argv)
 
 	/* create the mbuf pool */
 	l2fwd_pktmbuf_pool =
-		rte_mempool_create("mbuf_pool", NB_MBUF,
-				   MBUF_SIZE, 32,
-				   sizeof(struct rte_pktmbuf_pool_private),
-				   rte_pktmbuf_pool_init, NULL,
-				   rte_pktmbuf_init, NULL,
-				   rte_socket_id(), 0);
+		rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32,
+			0, MBUF_DATA_SIZE, rte_socket_id());
 	if (l2fwd_pktmbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
 
diff --git a/examples/l2fwd/main.c b/examples/l2fwd/main.c
index 17621ee..d0a1ec8 100644
--- a/examples/l2fwd/main.c
+++ b/examples/l2fwd/main.c
@@ -71,7 +71,7 @@
 
 #define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   8192
 
 #define MAX_PKT_BURST 32
@@ -560,13 +560,8 @@ main(int argc, char **argv)
 		rte_exit(EXIT_FAILURE, "Invalid L2FWD arguments\n");
 
 	/* create the mbuf pool */
-	l2fwd_pktmbuf_pool =
-		rte_mempool_create("mbuf_pool", NB_MBUF,
-				   MBUF_SIZE, 32,
-				   sizeof(struct rte_pktmbuf_pool_private),
-				   rte_pktmbuf_pool_init, NULL,
-				   rte_pktmbuf_init, NULL,
-				   rte_socket_id(), 0);
+	l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32,
+		0, MBUF_DATA_SIZE, rte_socket_id());
 	if (l2fwd_pktmbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
 
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index fce55f3..1a04004 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -80,7 +80,7 @@
 
 #define MEMPOOL_CACHE_SIZE 256
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * This expression is used to calculate the number of mbufs needed
@@ -1848,12 +1848,9 @@ init_mem(unsigned nb_mbuf)
 		if (pktmbuf_pool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
 			pktmbuf_pool[socketid] =
-				rte_mempool_create(s, nb_mbuf, MBUF_SIZE,
-					MEMPOOL_CACHE_SIZE,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, 0);
+				rte_pktmbuf_pool_create(s, nb_mbuf,
+					MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+					socketid);
 			if (pktmbuf_pool[socketid] == NULL)
 				rte_exit(EXIT_FAILURE,
 					"Cannot init mbuf pool on socket %d\n",
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 4221239..bb0b66f 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -121,7 +121,7 @@
 
 #define MEMPOOL_CACHE_SIZE 256
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * This expression is used to calculate the number of mbufs needed depending on
@@ -1379,12 +1379,9 @@ init_mem(unsigned nb_mbuf)
 		if (pktmbuf_pool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
 			pktmbuf_pool[socketid] =
-				rte_mempool_create(s, nb_mbuf,
-					MBUF_SIZE, MEMPOOL_CACHE_SIZE,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, 0);
+				rte_pktmbuf_pool_create(s, nb_mbuf,
+					MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+					socketid);
 			if (pktmbuf_pool[socketid] == NULL)
 				rte_exit(EXIT_FAILURE,
 					"Cannot init mbuf pool on socket %d\n",
diff --git a/examples/l3fwd-vf/main.c b/examples/l3fwd-vf/main.c
index 20ba03a..f007bc1 100644
--- a/examples/l3fwd-vf/main.c
+++ b/examples/l3fwd-vf/main.c
@@ -94,7 +94,7 @@
 
 #define MEMPOOL_CACHE_SIZE 256
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * This expression is used to calculate the number of mbufs needed depending on user input, taking
@@ -924,13 +924,9 @@ init_mem(unsigned nb_mbuf)
 		}
 		if (pktmbuf_pool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
-			pktmbuf_pool[socketid] =
-				rte_mempool_create(s, nb_mbuf, MBUF_SIZE,
-						   MEMPOOL_CACHE_SIZE,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, 0);
+			pktmbuf_pool[socketid] = rte_pktmbuf_pool_create(s,
+				nb_mbuf, MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+				socketid);
 			if (pktmbuf_pool[socketid] == NULL)
 				rte_exit(EXIT_FAILURE, "Cannot init mbuf pool on socket %d\n", socketid);
 			else
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 90e177f..7871038 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -119,7 +119,7 @@
 
 #define MEMPOOL_CACHE_SIZE 256
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * This expression is used to calculate the number of mbufs needed depending on user input, taking
@@ -2315,11 +2315,9 @@ init_mem(unsigned nb_mbuf)
 		if (pktmbuf_pool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
 			pktmbuf_pool[socketid] =
-				rte_mempool_create(s, nb_mbuf, MBUF_SIZE, MEMPOOL_CACHE_SIZE,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, 0);
+				rte_pktmbuf_pool_create(s, nb_mbuf,
+					MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+					socketid);
 			if (pktmbuf_pool[socketid] == NULL)
 				rte_exit(EXIT_FAILURE,
 						"Cannot init mbuf pool on socket %d\n", socketid);
diff --git a/examples/link_status_interrupt/main.c b/examples/link_status_interrupt/main.c
index e6fb218..6adbd79 100644
--- a/examples/link_status_interrupt/main.c
+++ b/examples/link_status_interrupt/main.c
@@ -72,7 +72,7 @@
 
 #define RTE_LOGTYPE_LSI RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   8192
 
 #define MAX_PKT_BURST 32
@@ -614,12 +614,8 @@ main(int argc, char **argv)
 
 	/* create the mbuf pool */
 	lsi_pktmbuf_pool =
-		rte_mempool_create("mbuf_pool", NB_MBUF,
-				   MBUF_SIZE, 32,
-				   sizeof(struct rte_pktmbuf_pool_private),
-				   rte_pktmbuf_pool_init, NULL,
-				   rte_pktmbuf_init, NULL,
-				   rte_socket_id(), 0);
+		rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32, 0,
+			MBUF_DATA_SIZE, rte_socket_id());
 	if (lsi_pktmbuf_pool == NULL)
 		rte_panic("Cannot init mbuf pool\n");
 
diff --git a/examples/load_balancer/init.c b/examples/load_balancer/init.c
index b35f797..5a56078 100644
--- a/examples/load_balancer/init.c
+++ b/examples/load_balancer/init.c
@@ -127,16 +127,10 @@ app_init_mbuf_pools(void)
 
 		snprintf(name, sizeof(name), "mbuf_pool_%u", socket);
 		printf("Creating the mbuf pool for socket %u ...\n", socket);
-		app.pools[socket] = rte_mempool_create(
-			name,
-			APP_DEFAULT_MEMPOOL_BUFFERS,
-			APP_DEFAULT_MBUF_SIZE,
+		app.pools[socket] = rte_pktmbuf_pool_create(
+			name, APP_DEFAULT_MEMPOOL_BUFFERS,
 			APP_DEFAULT_MEMPOOL_CACHE_SIZE,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL,
-			rte_pktmbuf_init, NULL,
-			socket,
-			0);
+			0, APP_DEFAULT_MBUF_DATA_SIZE, socket);
 		if (app.pools[socket] == NULL) {
 			rte_panic("Cannot create mbuf pool on socket %u\n", socket);
 		}
diff --git a/examples/load_balancer/main.h b/examples/load_balancer/main.h
index d9f878b..17c0f77 100644
--- a/examples/load_balancer/main.h
+++ b/examples/load_balancer/main.h
@@ -82,8 +82,8 @@
 
 
 /* Mempools */
-#ifndef APP_DEFAULT_MBUF_SIZE
-#define APP_DEFAULT_MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#ifndef APP_DEFAULT_MBUF_DATA_SIZE
+#define APP_DEFAULT_MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #endif
 
 #ifndef APP_DEFAULT_MEMPOOL_BUFFERS
diff --git a/examples/multi_process/client_server_mp/mp_server/init.c b/examples/multi_process/client_server_mp/mp_server/init.c
index aadee76..dc3647d 100644
--- a/examples/multi_process/client_server_mp/mp_server/init.c
+++ b/examples/multi_process/client_server_mp/mp_server/init.c
@@ -71,9 +71,7 @@
 #define MBUFS_PER_CLIENT 1536
 #define MBUFS_PER_PORT 1536
 #define MBUF_CACHE_SIZE 512
-#define MBUF_OVERHEAD (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
-#define RX_MBUF_DATA_SIZE 2048
-#define MBUF_SIZE (RX_MBUF_DATA_SIZE + MBUF_OVERHEAD)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 #define RTE_MP_RX_DESC_DEFAULT 512
 #define RTE_MP_TX_DESC_DEFAULT 512
@@ -104,10 +102,8 @@ init_mbuf_pools(void)
 	 * seems faster to use a cache instead */
 	printf("Creating mbuf pool '%s' [%u mbufs] ...\n",
 			PKTMBUF_POOL_NAME, num_mbufs);
-	pktmbuf_pool = rte_mempool_create(PKTMBUF_POOL_NAME, num_mbufs,
-			MBUF_SIZE, MBUF_CACHE_SIZE,
-			sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init,
-			NULL, rte_pktmbuf_init, NULL, rte_socket_id(), NO_FLAGS );
+	pktmbuf_pool = rte_pktmbuf_pool_create(PKTMBUF_POOL_NAME, num_mbufs,
+		MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE, rte_socket_id());
 
 	return (pktmbuf_pool == NULL); /* 0  on success */
 }
diff --git a/examples/multi_process/symmetric_mp/main.c b/examples/multi_process/symmetric_mp/main.c
index 48448b4..7829c86 100644
--- a/examples/multi_process/symmetric_mp/main.c
+++ b/examples/multi_process/symmetric_mp/main.c
@@ -78,7 +78,7 @@
 
 #define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUFS 64*1024 /* use 64k mbufs */
 #define MBUF_CACHE_SIZE 256
 #define PKT_BURST 32
@@ -446,11 +446,9 @@ main(int argc, char **argv)
 	proc_type = rte_eal_process_type();
 	mp = (proc_type == RTE_PROC_SECONDARY) ?
 			rte_mempool_lookup(_SMP_MBUF_POOL) :
-			rte_mempool_create(_SMP_MBUF_POOL, NB_MBUFS, MBUF_SIZE,
-					MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					rte_socket_id(), 0);
+			rte_pktmbuf_pool_create(_SMP_MBUF_POOL, NB_MBUFS,
+				MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+				rte_socket_id());
 	if (mp == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot get memory pool for buffers\n");
 
diff --git a/examples/netmap_compat/bridge/bridge.c b/examples/netmap_compat/bridge/bridge.c
index 0a8efbe..2d935cb 100644
--- a/examples/netmap_compat/bridge/bridge.c
+++ b/examples/netmap_compat/bridge/bridge.c
@@ -47,9 +47,8 @@
 #include "compat_netmap.h"
 
 
-#define	BUF_SIZE	2048
-#define MBUF_SIZE	(BUF_SIZE + sizeof(struct rte_mbuf) + \
-	RTE_PKTMBUF_HEADROOM)
+#define BUF_SIZE	(2048)
+#define MBUF_DATA_SIZE	(BUF_SIZE + RTE_PKTMBUF_HEADROOM)
 
 #define MBUF_PER_POOL	8192
 
@@ -272,11 +271,8 @@ int main(int argc, char *argv[])
 	if (rte_eth_dev_count() < 1)
 		rte_exit(EXIT_FAILURE, "Not enough ethernet ports available\n");
 
-	pool = rte_mempool_create("mbuf_pool", MBUF_PER_POOL, MBUF_SIZE, 32,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL,
-				rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+	pool = rte_pktmbuf_pool_create("mbuf_pool", MBUF_PER_POOL, 32, 0,
+		MBUF_DATA_SIZE, rte_socket_id());
 	if (pool == NULL)
 		rte_exit(EXIT_FAILURE, "Couldn't create mempool\n");
 
diff --git a/examples/packet_ordering/main.c b/examples/packet_ordering/main.c
index f0a1b5a..5403c33 100644
--- a/examples/packet_ordering/main.c
+++ b/examples/packet_ordering/main.c
@@ -50,7 +50,7 @@
 #define MAX_PKTS_BURST 32
 #define REORDER_BUFFER_SIZE 8192
 #define MBUF_PER_POOL 65535
-#define MBUF_SIZE (1600 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (1600 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_POOL_CACHE_SIZE 250
 
 #define RING_SIZE 16384
@@ -622,12 +622,9 @@ main(int argc, char **argv)
 		rte_exit(EXIT_FAILURE, "Error: number of ports must be even, except "
 				"when using a single port\n");
 
-	mbuf_pool = rte_mempool_create("mbuf_pool", MBUF_PER_POOL, MBUF_SIZE,
-			MBUF_POOL_CACHE_SIZE,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL,
-			rte_pktmbuf_init, NULL,
-			rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", MBUF_PER_POOL,
+			MBUF_POOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+			rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno));
 
diff --git a/examples/qos_meter/main.c b/examples/qos_meter/main.c
index 4a981c6..a5e2510 100644
--- a/examples/qos_meter/main.c
+++ b/examples/qos_meter/main.c
@@ -70,7 +70,7 @@
  * Buffer pool configuration
  *
  ***/
-#define MBUF_SIZE           (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE      (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF             8192
 #define MEMPOOL_CACHE_SIZE  256
 
@@ -360,9 +360,8 @@ main(int argc, char **argv)
 		rte_exit(EXIT_FAILURE, "Invalid input arguments\n");
 
 	/* Buffer pool init */
-	pool = rte_mempool_create("pool", NB_MBUF, MBUF_SIZE, MEMPOOL_CACHE_SIZE,
-		sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL,
-		rte_pktmbuf_init, NULL, rte_socket_id(), 0);
+	pool = rte_pktmbuf_pool_create("pool", NB_MBUF, MEMPOOL_CACHE_SIZE,
+		0, MBUF_DATA_SIZE, rte_socket_id());
 	if (pool == NULL)
 		rte_exit(EXIT_FAILURE, "Buffer pool creation error\n");
 
diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c
index f38802e..aaf3466 100644
--- a/examples/qos_sched/init.c
+++ b/examples/qos_sched/init.c
@@ -335,13 +335,9 @@ int app_init(void)
 
 		/* create the mbuf pools for each RX Port */
 		snprintf(pool_name, MAX_NAME_LEN, "mbuf_pool%u", i);
-		qos_conf[i].mbuf_pool = rte_mempool_create(pool_name, mp_size, MBUF_SIZE,
-						burst_conf.rx_burst * 4,
-						sizeof(struct rte_pktmbuf_pool_private),
-						rte_pktmbuf_pool_init, NULL,
-						rte_pktmbuf_init, NULL,
-						rte_eth_dev_socket_id(qos_conf[i].rx_port),
-						0);
+		qos_conf[i].mbuf_pool = rte_pktmbuf_pool_create(pool_name,
+			mp_size, burst_conf.rx_burst * 4, 0, MBUF_DATA_SIZE,
+			rte_eth_dev_socket_id(qos_conf[i].rx_port));
 		if (qos_conf[i].mbuf_pool == NULL)
 			rte_exit(EXIT_FAILURE, "Cannot init mbuf pool for socket %u\n", i);
 
diff --git a/examples/qos_sched/main.h b/examples/qos_sched/main.h
index 971ec27..0e6f264 100644
--- a/examples/qos_sched/main.h
+++ b/examples/qos_sched/main.h
@@ -50,7 +50,7 @@ extern "C" {
 #define APP_RX_DESC_DEFAULT 128
 #define APP_TX_DESC_DEFAULT 256
 
-#define MBUF_SIZE (1528 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (1528 + RTE_PKTMBUF_HEADROOM)
 #define APP_RING_SIZE (8*1024)
 #define NB_MBUF   (2*1024*1024)
 
diff --git a/examples/quota_watermark/include/conf.h b/examples/quota_watermark/include/conf.h
index 8d95aaa..e80aca5 100644
--- a/examples/quota_watermark/include/conf.h
+++ b/examples/quota_watermark/include/conf.h
@@ -40,7 +40,7 @@
 #define RX_DESC_PER_QUEUE   128
 #define TX_DESC_PER_QUEUE   512
 
-#define MBUF_SIZE     (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE     (2048 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_PER_POOL 8192
 
 #define QUOTA_WATERMARK_MEMZONE_NAME "qw_global_vars"
diff --git a/examples/quota_watermark/qw/main.c b/examples/quota_watermark/qw/main.c
index f269546..8ed0214 100644
--- a/examples/quota_watermark/qw/main.c
+++ b/examples/quota_watermark/qw/main.c
@@ -335,11 +335,8 @@ main(int argc, char **argv)
         rte_exit(EXIT_FAILURE, "Invalid quota/watermark argument(s)\n");
 
     /* Create a pool of mbuf to store packets */
-    mbuf_pool = rte_mempool_create("mbuf_pool", MBUF_PER_POOL, MBUF_SIZE, 32,
-                                   sizeof(struct rte_pktmbuf_pool_private),
-                                   rte_pktmbuf_pool_init, NULL,
-                                   rte_pktmbuf_init, NULL,
-                                   rte_socket_id(), 0);
+    mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", MBUF_PER_POOL, 32, 0,
+	    MBUF_DATA_SIZE, rte_socket_id());
     if (mbuf_pool == NULL)
         rte_panic("%s\n", rte_strerror(rte_errno));
 
diff --git a/examples/rxtx_callbacks/main.c b/examples/rxtx_callbacks/main.c
index 21117ce..fb8da51 100644
--- a/examples/rxtx_callbacks/main.c
+++ b/examples/rxtx_callbacks/main.c
@@ -43,7 +43,7 @@
 #define TX_RING_SIZE 512
 
 #define NUM_MBUFS 8191
-#define MBUF_SIZE (1600 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (1600 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE 250
 #define BURST_SIZE 32
 
@@ -204,12 +204,9 @@ main(int argc, char *argv[])
 	if (nb_ports < 2 || (nb_ports & 1))
 		rte_exit(EXIT_FAILURE, "Error: number of ports must be even\n");
 
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
-				       MBUF_SIZE, MBUF_CACHE_SIZE,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init, NULL,
-				       rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+		NUM_MBUFS * nb_ports, MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+		rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/examples/skeleton/basicfwd.c b/examples/skeleton/basicfwd.c
index 1bce6e7..ae606bf 100644
--- a/examples/skeleton/basicfwd.c
+++ b/examples/skeleton/basicfwd.c
@@ -43,7 +43,7 @@
 #define TX_RING_SIZE 512
 
 #define NUM_MBUFS 8191
-#define MBUF_SIZE (1600 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (1600 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE 250
 #define BURST_SIZE 32
 
@@ -190,15 +190,8 @@ main(int argc, char *argv[])
 		rte_exit(EXIT_FAILURE, "Error: number of ports must be even\n");
 
 	/* Creates a new mempool in memory to hold the mbufs. */
-	mbuf_pool = rte_mempool_create("MBUF_POOL",
-				       NUM_MBUFS * nb_ports,
-				       MBUF_SIZE,
-				       MBUF_CACHE_SIZE,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init,      NULL,
-				       rte_socket_id(),
-				       0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
+		MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE, rte_socket_id());
 
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index fc73d1e..22d6a4b 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -67,7 +67,7 @@
 							(num_switching_cores*MBUF_CACHE_SIZE))
 
 #define MBUF_CACHE_SIZE 128
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * No frame data buffer allocated from host are required for zero copy
@@ -75,8 +75,7 @@
  * directly use it.
  */
 #define VIRTIO_DESCRIPTOR_LEN_ZCP 1518
-#define MBUF_SIZE_ZCP (VIRTIO_DESCRIPTOR_LEN_ZCP + sizeof(struct rte_mbuf) \
-	+ RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE_ZCP (VIRTIO_DESCRIPTOR_LEN_ZCP + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE_ZCP 0
 
 #define MAX_PKT_BURST 32 		/* Max burst size for RX/TX */
@@ -2844,11 +2843,8 @@ static void
 setup_mempool_tbl(int socket, uint32_t index, char *pool_name,
 	char *ring_name, uint32_t nb_mbuf)
 {
-	vpool_array[index].pool
-		= rte_mempool_create(pool_name, nb_mbuf, MBUF_SIZE_ZCP,
-		MBUF_CACHE_SIZE_ZCP, sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, NULL,
-		rte_pktmbuf_init, NULL, socket, 0);
+	vpool_array[index].pool	= rte_pktmbuf_pool_create(pool_name, nb_mbuf,
+		MBUF_CACHE_SIZE_ZCP, 0, MBUF_DATA_SIZE_ZCP, socket);
 	if (vpool_array[index].pool != NULL) {
 		vpool_array[index].ring
 			= rte_ring_create(ring_name,
@@ -2932,15 +2928,9 @@ main(int argc, char *argv[])
 
 	if (zero_copy == 0) {
 		/* Create the mbuf pool. */
-		mbuf_pool = rte_mempool_create(
-				"MBUF_POOL",
-				NUM_MBUFS_PER_PORT
-				* valid_num_ports,
-				MBUF_SIZE, MBUF_CACHE_SIZE,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL,
-				rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+		mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+			NUM_MBUFS_PER_PORT * valid_num_ports, MBUF_CACHE_SIZE,
+			0, MBUF_DATA_SIZE, rte_socket_id());
 		if (mbuf_pool == NULL)
 			rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/examples/vhost_xen/main.c b/examples/vhost_xen/main.c
index b4a86e3..b672bf3 100644
--- a/examples/vhost_xen/main.c
+++ b/examples/vhost_xen/main.c
@@ -67,7 +67,7 @@
 							(num_switching_cores*MBUF_CACHE_SIZE))
 
 #define MBUF_CACHE_SIZE 64
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * RX and TX Prefetch, Host, and Write-back threshold values should be
@@ -1474,12 +1474,9 @@ main(int argc, char *argv[])
 	}
 
 	/* Create the mbuf pool. */
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS_PER_PORT * valid_num_ports,
-				       MBUF_SIZE, MBUF_CACHE_SIZE,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init, NULL,
-				       rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+		NUM_MBUFS_PER_PORT * valid_num_ports, MBUF_CACHE_SIZE, 0,
+		MBUF_DATA_SIZE, rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/examples/vmdq/main.c b/examples/vmdq/main.c
index 7001860..7596bac 100644
--- a/examples/vmdq/main.c
+++ b/examples/vmdq/main.c
@@ -76,7 +76,7 @@
  */
 #define NUM_MBUFS_PER_PORT (128*512)
 #define MBUF_CACHE_SIZE 64
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 #define MAX_PKT_BURST 32
 
@@ -613,12 +613,9 @@ main(int argc, char *argv[])
 		rte_exit(EXIT_FAILURE, "Error with valid ports number is not even or less than 2\n");
 	}
 
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS_PER_PORT * nb_ports,
-				       MBUF_SIZE, MBUF_CACHE_SIZE,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init, NULL,
-				       rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+		NUM_MBUFS_PER_PORT * nb_ports, MBUF_CACHE_SIZE,
+		0, MBUF_DATA_SIZE, rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/examples/vmdq_dcb/main.c b/examples/vmdq_dcb/main.c
index 048c167..3c7f2b3 100644
--- a/examples/vmdq_dcb/main.c
+++ b/examples/vmdq_dcb/main.c
@@ -74,7 +74,7 @@
 
 #define NUM_MBUFS 64*1024
 #define MBUF_CACHE_SIZE 64
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 #define INVALID_PORT_ID 0xFF
 
@@ -441,12 +441,8 @@ main(int argc, char *argv[])
 		rte_exit(EXIT_FAILURE, "Error with valid ports number is not even or less than 2\n");
 	}
 
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
-				       MBUF_SIZE, MBUF_CACHE_SIZE,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init, NULL,
-				       rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
+		MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE, rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/lib/librte_pmd_bond/rte_eth_bond_alb.c b/lib/librte_pmd_bond/rte_eth_bond_alb.c
index 5778b25..6df318e 100644
--- a/lib/librte_pmd_bond/rte_eth_bond_alb.c
+++ b/lib/librte_pmd_bond/rte_eth_bond_alb.c
@@ -63,7 +63,7 @@ bond_mode_alb_enable(struct rte_eth_dev *bond_dev)
 	struct bond_dev_private *internals = bond_dev->data->dev_private;
 	struct client_data *hash_table = internals->mode6.client_table;
 
-	uint16_t element_size;
+	uint16_t data_size;
 	char mem_name[RTE_ETH_NAME_MAX_LEN];
 	int socket_id = bond_dev->pci_dev->numa_node;
 
@@ -79,15 +79,13 @@ bond_mode_alb_enable(struct rte_eth_dev *bond_dev)
 		 * 256 is size of ETH header, ARP header and nested VLAN headers.
 		 * The value is chosen to be cache aligned.
 		 */
-		element_size = 256 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM;
+		data_size = 256 + RTE_PKTMBUF_HEADROOM;
 		snprintf(mem_name, sizeof(mem_name), "%s_MODE6", bond_dev->data->name);
-		internals->mode6.mempool = rte_mempool_create(mem_name,
-				512 * RTE_MAX_ETHPORTS,
-				element_size,
-				RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
-						32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
-				sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init,
-				NULL, rte_pktmbuf_init, NULL, socket_id, 0);
+		internals->mode6.mempool = rte_pktmbuf_pool_create(mem_name,
+			512 * RTE_MAX_ETHPORTS,
+			RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
+				32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
+			0, data_size, socket_id);
 
 		if (internals->mode6.mempool == NULL) {
 			RTE_LOG(ERR, PMD, "%s: Failed to initialize ALB mempool.\n",
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v5 08/12] mbuf: fix clone support when application uses private mbuf data
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
                             ` (6 preceding siblings ...)
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 07/12] apps: use rte_pktmbuf_pool_create to create mbuf pools Olivier Matz
@ 2015-04-21  9:55           ` Olivier Matz
  2015-04-21 15:01             ` Ananyev, Konstantin
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 09/12] mbuf: allow to clone an indirect mbuf Olivier Matz
                             ` (5 subsequent siblings)
  13 siblings, 1 reply; 101+ messages in thread
From: Olivier Matz @ 2015-04-21  9:55 UTC (permalink / raw)
  To: dev

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 <olivier.matz@6wind.com>
Reviewed-by: Zoltan Kiss <zoltan.kiss@linaro.org>
---
 examples/vhost/main.c      |  4 ++--
 lib/librte_mbuf/rte_mbuf.c |  2 +-
 lib/librte_mbuf/rte_mbuf.h | 59 +++++++++++++++++++++++++++++++---------------
 3 files changed, 43 insertions(+), 22 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 22d6a4b..195d82f 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -138,7 +138,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;
@@ -1549,7 +1549,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 b013607..784ae8b 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -129,7 +129,7 @@ rte_pktmbuf_init(struct rte_mempool *mp,
 
 	memset(m, 0, mp->elt_size);
 
-	/* start of buffer is just after mbuf structure */
+	/* start of buffer is after mbuf structure and priv data */
 	m->buf_addr = (char *)m + mbuf_size;
 	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mbuf_size;
 	m->buf_len = (uint16_t)buf_len;
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 42db8e3..5c01c5b 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -320,16 +320,40 @@ struct rte_mbuf {
 	};
 } __rte_cache_aligned;
 
+static inline uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp);
+
 /**
- * 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;
+       md = (struct rte_mbuf *)((char *)mi->buf_addr -
+	       sizeof(*mi) - rte_pktmbuf_priv_size(mi->pool));
+       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.
+ *
+ * @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) + rte_pktmbuf_priv_size(md->pool);
+       return buffer_addr;
+}
 
 /**
  * Returns TRUE if given mbuf is indirect, or FALSE otherwise.
@@ -771,6 +795,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:
@@ -784,7 +809,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) &&
@@ -815,7 +839,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.
@@ -823,22 +848,18 @@ 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_mempool *mp = m->pool;
+	uint32_t mbuf_size, buf_len;
 
-	m->buf_addr = buf;
+	mbuf_size = sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(mp);
+	buf_len = rte_pktmbuf_data_room_size(mp);
+	m->buf_addr = rte_mbuf_to_baddr(m);
+	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mbuf_size;
 	m->buf_len = (uint16_t)buf_len;
-
-	m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
-			RTE_PKTMBUF_HEADROOM : m->buf_len;
-
+	m->data_off = RTE_MIN(RTE_PKTMBUF_HEADROOM, (uint16_t)m->buf_len);
 	m->data_len = 0;
-
 	m->ol_flags = 0;
 }
 
@@ -867,7 +888,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);
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v5 09/12] mbuf: allow to clone an indirect mbuf
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
                             ` (7 preceding siblings ...)
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 08/12] mbuf: fix clone support when application uses private mbuf data Olivier Matz
@ 2015-04-21  9:55           ` Olivier Matz
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 10/12] test/mbuf: rename mc variable in m Olivier Matz
                             ` (4 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-21  9:55 UTC (permalink / raw)
  To: dev

Remove one limitation of rte_pktmbuf_attach(): "mbuf we're attaching to
must be direct".

Now, when we attach to an indirect mbuf:
- copy the all relevant fields (addr, len, offload, ...) as before
- get the pointer to the mbuf that embeds the data buffer (direct mbuf),
  and increase the reference counter of this one.

When detaching the mbuf, we can retrieve this direct mbuf as the pointer
is determined from the buffer address.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_mbuf/rte_mbuf.h | 46 ++++++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 20 deletions(-)

diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 5c01c5b..df54a46 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -799,43 +799,49 @@ static inline struct rte_mbuf *rte_pktmbuf_alloc(struct rte_mempool *mp)
  * After attachment we refer the mbuf we attached as 'indirect',
  * while mbuf we attached to as 'direct'.
  * Right now, not supported:
- *  - attachment to indirect mbuf (e.g. - md  has to be direct).
  *  - attachment for already indirect mbuf (e.g. - mi has to be direct).
  *  - mbuf we trying to attach (mi) is used by someone else
  *    e.g. it's reference counter is greater then 1.
  *
  * @param mi
  *   The indirect packet mbuf.
- * @param md
- *   The direct packet mbuf.
+ * @param m
+ *   The packet mbuf we're attaching to.
  */
-static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md)
+static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
 {
-	RTE_MBUF_ASSERT(RTE_MBUF_DIRECT(md) &&
-	    RTE_MBUF_DIRECT(mi) &&
+	struct rte_mbuf *md;
+
+	RTE_MBUF_ASSERT(RTE_MBUF_DIRECT(mi) &&
 	    rte_mbuf_refcnt_read(mi) == 1);
 
+	/* if m is not direct, get the mbuf that embeds the data */
+	if (RTE_MBUF_DIRECT(m))
+		md = m;
+	else
+		md = rte_mbuf_from_indirect(m);
+
 	rte_mbuf_refcnt_update(md, 1);
-	mi->buf_physaddr = md->buf_physaddr;
-	mi->buf_addr = md->buf_addr;
-	mi->buf_len = md->buf_len;
-
-	mi->next = md->next;
-	mi->data_off = md->data_off;
-	mi->data_len = md->data_len;
-	mi->port = md->port;
-	mi->vlan_tci = md->vlan_tci;
-	mi->tx_offload = md->tx_offload;
-	mi->hash = md->hash;
+	mi->buf_physaddr = m->buf_physaddr;
+	mi->buf_addr = m->buf_addr;
+	mi->buf_len = m->buf_len;
+
+	mi->next = m->next;
+	mi->data_off = m->data_off;
+	mi->data_len = m->data_len;
+	mi->port = m->port;
+	mi->vlan_tci = m->vlan_tci;
+	mi->tx_offload = m->tx_offload;
+	mi->hash = m->hash;
 
 	mi->next = NULL;
 	mi->pkt_len = mi->data_len;
 	mi->nb_segs = 1;
-	mi->ol_flags = md->ol_flags | IND_ATTACHED_MBUF;
-	mi->packet_type = md->packet_type;
+	mi->ol_flags = m->ol_flags | IND_ATTACHED_MBUF;
+	mi->packet_type = m->packet_type;
 
 	__rte_mbuf_sanity_check(mi, 1);
-	__rte_mbuf_sanity_check(md, 0);
+	__rte_mbuf_sanity_check(m, 0);
 }
 
 /**
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v5 10/12] test/mbuf: rename mc variable in m
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
                             ` (8 preceding siblings ...)
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 09/12] mbuf: allow to clone an indirect mbuf Olivier Matz
@ 2015-04-21  9:55           ` Olivier Matz
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 11/12] test/mbuf: enhance mbuf refcnt test Olivier Matz
                             ` (3 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-21  9:55 UTC (permalink / raw)
  To: dev

It's better to name the mbuf 'm' instead of 'mc' as it's not a clone.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 4774263..2614598 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -320,43 +320,42 @@ fail:
 static int
 testclone_testupdate_testdetach(void)
 {
-	struct rte_mbuf *mc = NULL;
+	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
 
 	/* alloc a mbuf */
-
-	mc = rte_pktmbuf_alloc(pktmbuf_pool);
-	if (mc == NULL)
+	m = rte_pktmbuf_alloc(pktmbuf_pool);
+	if (m == NULL)
 		GOTO_FAIL("ooops not allocating mbuf");
 
-	if (rte_pktmbuf_pkt_len(mc) != 0)
+	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("Bad length");
 
 
 	/* clone the allocated mbuf */
-	clone = rte_pktmbuf_clone(mc, pktmbuf_pool);
+	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 	rte_pktmbuf_free(clone);
 
-	mc->next = rte_pktmbuf_alloc(pktmbuf_pool);
-	if(mc->next == NULL)
+	m->next = rte_pktmbuf_alloc(pktmbuf_pool);
+	if (m->next == NULL)
 		GOTO_FAIL("Next Pkt Null\n");
 
-	clone = rte_pktmbuf_clone(mc, pktmbuf_pool);
+	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 
 	/* free mbuf */
-	rte_pktmbuf_free(mc);
+	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
-	mc = NULL;
+	m = NULL;
 	clone = NULL;
 	return 0;
 
 fail:
-	if (mc)
-		rte_pktmbuf_free(mc);
+	if (m)
+		rte_pktmbuf_free(m);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v5 11/12] test/mbuf: enhance mbuf refcnt test
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
                             ` (9 preceding siblings ...)
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 10/12] test/mbuf: rename mc variable in m Olivier Matz
@ 2015-04-21  9:55           ` Olivier Matz
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 12/12] test/mbuf: verify that cloning a clone works properly Olivier Matz
                             ` (2 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-21  9:55 UTC (permalink / raw)
  To: dev

Check that the data in the cloned mbuf is the same than in the
reference mbuf.
Check that the reference counter is incremented for each segment.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 2614598..01838c6 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -75,6 +75,8 @@
 #define REFCNT_MBUF_NUM         64
 #define REFCNT_RING_SIZE        (REFCNT_MBUF_NUM * REFCNT_MAX_REF)
 
+#define MAGIC_DATA              0x42424242
+
 #define MAKE_STRING(x)          # x
 
 static struct rte_mempool *pktmbuf_pool = NULL;
@@ -322,6 +324,7 @@ testclone_testupdate_testdetach(void)
 {
 	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
+	uint32_t *data;
 
 	/* alloc a mbuf */
 	m = rte_pktmbuf_alloc(pktmbuf_pool);
@@ -331,21 +334,53 @@ testclone_testupdate_testdetach(void)
 	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("Bad length");
 
+	rte_pktmbuf_append(m, sizeof(uint32_t));
+	data = rte_pktmbuf_mtod(m, uint32_t *);
+	*data = MAGIC_DATA;
 
 	/* clone the allocated mbuf */
 	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
+
+	data = rte_pktmbuf_mtod(clone, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone\n");
+
+	if (rte_mbuf_refcnt_read(m) != 2)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	/* free the clone */
 	rte_pktmbuf_free(clone);
+	clone = NULL;
 
+	/* same test with a chained mbuf */
 	m->next = rte_pktmbuf_alloc(pktmbuf_pool);
 	if (m->next == NULL)
 		GOTO_FAIL("Next Pkt Null\n");
 
+	rte_pktmbuf_append(m->next, sizeof(uint32_t));
+	data = rte_pktmbuf_mtod(m->next, uint32_t *);
+	*data = MAGIC_DATA;
+
 	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 
+	data = rte_pktmbuf_mtod(clone, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone\n");
+
+	data = rte_pktmbuf_mtod(clone->next, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone->next\n");
+
+	if (rte_mbuf_refcnt_read(m) != 2)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	if (rte_mbuf_refcnt_read(m->next) != 2)
+		GOTO_FAIL("invalid refcnt in m->next\n");
+
 	/* free mbuf */
 	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
@@ -356,6 +391,8 @@ testclone_testupdate_testdetach(void)
 fail:
 	if (m)
 		rte_pktmbuf_free(m);
+	if (clone)
+		rte_pktmbuf_free(clone);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v5 12/12] test/mbuf: verify that cloning a clone works properly
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
                             ` (10 preceding siblings ...)
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 11/12] test/mbuf: enhance mbuf refcnt test Olivier Matz
@ 2015-04-21  9:55           ` Olivier Matz
  2015-04-21 11:50           ` [dpdk-dev] [PATCH v5 00/12] mbuf: enhancements of mbuf clones Neil Horman
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-21  9:55 UTC (permalink / raw)
  To: dev

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 01838c6..b5ae5b7 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -324,6 +324,7 @@ testclone_testupdate_testdetach(void)
 {
 	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
+	struct rte_mbuf *clone2 = NULL;
 	uint32_t *data;
 
 	/* alloc a mbuf */
@@ -381,11 +382,34 @@ testclone_testupdate_testdetach(void)
 	if (rte_mbuf_refcnt_read(m->next) != 2)
 		GOTO_FAIL("invalid refcnt in m->next\n");
 
+	/* try to clone the clone */
+
+	clone2 = rte_pktmbuf_clone(clone, pktmbuf_pool);
+	if (clone2 == NULL)
+		GOTO_FAIL("cannot clone the clone\n");
+
+	data = rte_pktmbuf_mtod(clone2, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone2\n");
+
+	data = rte_pktmbuf_mtod(clone2->next, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone2->next\n");
+
+	if (rte_mbuf_refcnt_read(m) != 3)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	if (rte_mbuf_refcnt_read(m->next) != 3)
+		GOTO_FAIL("invalid refcnt in m->next\n");
+
 	/* free mbuf */
 	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
+	rte_pktmbuf_free(clone2);
+
 	m = NULL;
 	clone = NULL;
+	clone2 = NULL;
 	return 0;
 
 fail:
@@ -393,6 +417,8 @@ fail:
 		rte_pktmbuf_free(m);
 	if (clone)
 		rte_pktmbuf_free(clone);
+	if (clone2)
+		rte_pktmbuf_free(clone2);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v5 00/12] mbuf: enhancements of mbuf clones
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
                             ` (11 preceding siblings ...)
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 12/12] test/mbuf: verify that cloning a clone works properly Olivier Matz
@ 2015-04-21 11:50           ` Neil Horman
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
  13 siblings, 0 replies; 101+ messages in thread
From: Neil Horman @ 2015-04-21 11:50 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

On Tue, Apr 21, 2015 at 11:55:10AM +0200, Olivier Matz wrote:
> The first objective of this series is to fix the support of indirect
> mbufs when the application reserves a private area in mbufs. It also
> removes the limitation that rte_pktmbuf_clone() is only allowed on
> direct (non-cloned) mbufs. The series also contains some enhancements
> and fixes in the mbuf area that makes the implementation of the
> last patches easier.
> 
> Changes in v5:
> - update rte_mbuf_version.map to fix compilation with shared libraries
> 
> Changes in v4:
> - do not add a priv_size in mbuf structure, having a proper accessor
>   to read it from the pool private area is clearer
> - prepend some reworks in the mbuf area to simplify the implementation
>   (fix mbuf initialization by not using a hardcoded mbuf size, add
>   accessors for mbuf pool private area, add a helper to create a
>   mbuf pool)
> 
> Changes in v3:
> - a mbuf can now attach to another one that have a different private
>   size. In this case, the m->priv_size corresponds to the size of the
>   private area of the direct mbuf.
> - add comments to reflect these changes
> - minor style modifications
> 
> Changes in v2:
> - do not change the use of MBUF_EXT_MEM() in vhost
> - change rte_mbuf_from_baddr() to rte_mbuf_from_indirect(), removing
>   one parameter
> - fix and rework rte_pktmbuf_detach()
> - move m->priv_size in second mbuf cache line
> - fix mbuf free in test error case
> 
> Olivier Matz (12):
>   mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
>   examples: always initialize mbuf_pool private area
>   mbuf: add accessors to get data room size and private size
>   mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
>   testpmd: use standard functions to initialize mbufs and mbuf pool
>   mbuf: introduce a new helper to create a mbuf pool
>   apps: use rte_pktmbuf_pool_create to create mbuf pools
>   mbuf: fix clone support when application uses private mbuf data
>   mbuf: allow to clone an indirect mbuf
>   test/mbuf: rename mc variable in m
>   test/mbuf: enhance mbuf refcnt test
>   test/mbuf: verify that cloning a clone works properly
> 
>  app/test-pipeline/init.c                           |  15 +-
>  app/test-pmd/testpmd.c                             |  78 +--------
>  app/test/test_distributor.c                        |  10 +-
>  app/test/test_distributor_perf.c                   |  10 +-
>  app/test/test_kni.c                                |  16 +-
>  app/test/test_link_bonding.c                       |  10 +-
>  app/test/test_link_bonding_mode4.c                 |  12 +-
>  app/test/test_mbuf.c                               | 110 +++++++++---
>  app/test/test_pmd_perf.c                           |  11 +-
>  app/test/test_pmd_ring.c                           |  10 +-
>  app/test/test_reorder.c                            |  10 +-
>  app/test/test_sched.c                              |  16 +-
>  app/test/test_table.c                              |   9 +-
>  app/test/test_table.h                              |   3 +-
>  doc/guides/rel_notes/updating_apps.rst             |  16 ++
>  examples/bond/main.c                               |  10 +-
>  examples/distributor/main.c                        |  11 +-
>  examples/dpdk_qat/main.c                           |  10 +-
>  examples/exception_path/main.c                     |  14 +-
>  examples/ip_fragmentation/main.c                   |  18 +-
>  examples/ip_pipeline/init.c                        |  28 +--
>  examples/ipv4_multicast/main.c                     |  21 +--
>  examples/kni/main.c                                |  12 +-
>  examples/l2fwd-ivshmem/host/host.c                 |  10 +-
>  examples/l2fwd-jobstats/main.c                     |  10 +-
>  examples/l2fwd/main.c                              |  11 +-
>  examples/l3fwd-acl/main.c                          |  11 +-
>  examples/l3fwd-power/main.c                        |  11 +-
>  examples/l3fwd-vf/main.c                           |  12 +-
>  examples/l3fwd/main.c                              |  10 +-
>  examples/link_status_interrupt/main.c              |  10 +-
>  examples/load_balancer/init.c                      |  12 +-
>  examples/load_balancer/main.h                      |   4 +-
>  .../client_server_mp/mp_server/init.c              |  10 +-
>  examples/multi_process/symmetric_mp/main.c         |  10 +-
>  examples/netmap_compat/bridge/bridge.c             |  12 +-
>  examples/packet_ordering/main.c                    |  11 +-
>  examples/qos_meter/main.c                          |   7 +-
>  examples/qos_sched/init.c                          |  10 +-
>  examples/qos_sched/main.h                          |   2 +-
>  examples/quota_watermark/include/conf.h            |   2 +-
>  examples/quota_watermark/qw/main.c                 |   7 +-
>  examples/rxtx_callbacks/main.c                     |  11 +-
>  examples/skeleton/basicfwd.c                       |  13 +-
>  examples/vhost/main.c                              |  31 ++--
>  examples/vhost_xen/main.c                          |  11 +-
>  examples/vmdq/main.c                               |  11 +-
>  examples/vmdq_dcb/main.c                           |  10 +-
>  lib/librte_ether/rte_ethdev.c                      |   4 +-
>  lib/librte_mbuf/rte_mbuf.c                         |  63 +++++--
>  lib/librte_mbuf/rte_mbuf.h                         | 189 ++++++++++++++++-----
>  lib/librte_mbuf/rte_mbuf_version.map               |   8 +
>  lib/librte_pmd_af_packet/rte_eth_af_packet.c       |   6 +-
>  lib/librte_pmd_bond/rte_eth_bond_alb.c             |  16 +-
>  lib/librte_pmd_e1000/em_rxtx.c                     |   5 +-
>  lib/librte_pmd_e1000/igb_rxtx.c                    |  12 +-
>  lib/librte_pmd_fm10k/fm10k_ethdev.c                |   6 +-
>  lib/librte_pmd_i40e/i40e_ethdev_vf.c               |   6 +-
>  lib/librte_pmd_i40e/i40e_rxtx.c                    |  15 +-
>  lib/librte_pmd_ixgbe/ixgbe_rxtx.c                  |  12 +-
>  lib/librte_pmd_pcap/rte_eth_pcap.c                 |   5 +-
>  lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c              |   7 +-
>  62 files changed, 507 insertions(+), 566 deletions(-)
> 
> -- 
> 2.1.4
> 
> 


applies,builds, maintains ABI.  Seems to work in test app cases.
Series
Acked-by: Neil Horman <nhorman@tuxdriver.com>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v5 08/12] mbuf: fix clone support when application uses private mbuf data
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 08/12] mbuf: fix clone support when application uses private mbuf data Olivier Matz
@ 2015-04-21 15:01             ` Ananyev, Konstantin
  2015-04-21 15:26               ` Olivier MATZ
  0 siblings, 1 reply; 101+ messages in thread
From: Ananyev, Konstantin @ 2015-04-21 15:01 UTC (permalink / raw)
  To: Olivier Matz, dev

Hi Olivier,

> -----Original Message-----
> From: Olivier Matz [mailto:olivier.matz@6wind.com]
> Sent: Tuesday, April 21, 2015 10:55 AM
> To: dev@dpdk.org
> Cc: Ananyev, Konstantin; zoltan.kiss@linaro.org; Richardson, Bruce; nhorman@tuxdriver.com; olivier.matz@6wind.com
> Subject: [PATCH v5 08/12] mbuf: fix clone support when application uses private mbuf data
> 
> 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 <olivier.matz@6wind.com>
> Reviewed-by: Zoltan Kiss <zoltan.kiss@linaro.org>
> ---
>  examples/vhost/main.c      |  4 ++--
>  lib/librte_mbuf/rte_mbuf.c |  2 +-
>  lib/librte_mbuf/rte_mbuf.h | 59 +++++++++++++++++++++++++++++++---------------
>  3 files changed, 43 insertions(+), 22 deletions(-)
> 
> diff --git a/examples/vhost/main.c b/examples/vhost/main.c
> index 22d6a4b..195d82f 100644
> --- a/examples/vhost/main.c
> +++ b/examples/vhost/main.c
> @@ -138,7 +138,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;
> @@ -1549,7 +1549,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 b013607..784ae8b 100644
> --- a/lib/librte_mbuf/rte_mbuf.c
> +++ b/lib/librte_mbuf/rte_mbuf.c
> @@ -129,7 +129,7 @@ rte_pktmbuf_init(struct rte_mempool *mp,
> 
>  	memset(m, 0, mp->elt_size);
> 
> -	/* start of buffer is just after mbuf structure */
> +	/* start of buffer is after mbuf structure and priv data */
>  	m->buf_addr = (char *)m + mbuf_size;
>  	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mbuf_size;
>  	m->buf_len = (uint16_t)buf_len;
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> index 42db8e3..5c01c5b 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -320,16 +320,40 @@ struct rte_mbuf {
>  	};
>  } __rte_cache_aligned;
> 
> +static inline uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp);
> +
>  /**
> - * 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;
> +       md = (struct rte_mbuf *)((char *)mi->buf_addr -
> +	       sizeof(*mi) - rte_pktmbuf_priv_size(mi->pool));
> +       return md;
> +}


Really puzzled, why do you remove prv_size from mbuf?
Now if let say we attach mbuf (mi) with priv_size == X to mbuf (md) with priv_size == Y,
then rte_mbuf_from_indirect(mi) would return: mi->buf_addr - 128 - X, while it should be: mi->buf_addr - 128 - Y.

Another thing, rte_mbuf_from_indirect() and rte_mbuf_to_baddr() would probably become a bit slower -
as another level of indirection is added.

Konstantin

> 
>  /**
> - * 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.
> + *
> + * @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) + rte_pktmbuf_priv_size(md->pool);
> +       return buffer_addr;
> +}
> 
>  /**
>   * Returns TRUE if given mbuf is indirect, or FALSE otherwise.
> @@ -771,6 +795,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:
> @@ -784,7 +809,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) &&
> @@ -815,7 +839,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.
> @@ -823,22 +848,18 @@ 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_mempool *mp = m->pool;
> +	uint32_t mbuf_size, buf_len;
> 
> -	m->buf_addr = buf;
> +	mbuf_size = sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(mp);
> +	buf_len = rte_pktmbuf_data_room_size(mp);
> +	m->buf_addr = rte_mbuf_to_baddr(m);
> +	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mbuf_size;
>  	m->buf_len = (uint16_t)buf_len;
> -
> -	m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
> -			RTE_PKTMBUF_HEADROOM : m->buf_len;
> -
> +	m->data_off = RTE_MIN(RTE_PKTMBUF_HEADROOM, (uint16_t)m->buf_len);
>  	m->data_len = 0;
> -
>  	m->ol_flags = 0;
>  }
> 
> @@ -867,7 +888,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);
> --
> 2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v5 04/12] mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
  2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 04/12] mbuf: fix rte_pktmbuf_init when mbuf private size is not zero Olivier Matz
@ 2015-04-21 15:07             ` Ananyev, Konstantin
  0 siblings, 0 replies; 101+ messages in thread
From: Ananyev, Konstantin @ 2015-04-21 15:07 UTC (permalink / raw)
  To: Olivier Matz, dev



> -----Original Message-----
> From: Olivier Matz [mailto:olivier.matz@6wind.com]
> Sent: Tuesday, April 21, 2015 10:55 AM
> To: dev@dpdk.org
> Cc: Ananyev, Konstantin; zoltan.kiss@linaro.org; Richardson, Bruce; nhorman@tuxdriver.com; olivier.matz@6wind.com
> Subject: [PATCH v5 04/12] mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
> 
> Allow the user to use the default rte_pktmbuf_init() function even
> if the mbuf private size is not 0.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> ---
>  lib/librte_mbuf/rte_mbuf.c | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
> index 231cfb8..d7f0380 100644
> --- a/lib/librte_mbuf/rte_mbuf.c
> +++ b/lib/librte_mbuf/rte_mbuf.c
> @@ -119,16 +119,19 @@ rte_pktmbuf_init(struct rte_mempool *mp,
>  		 __attribute__((unused)) unsigned i)
>  {
>  	struct rte_mbuf *m = _m;
> -	uint32_t buf_len = mp->elt_size - sizeof(struct rte_mbuf);
> +	uint32_t mbuf_size, buf_len;
> 
> -	RTE_MBUF_ASSERT(mp->elt_size >= sizeof(struct rte_mbuf));
> +	mbuf_size = sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(mp);
> +	buf_len = rte_pktmbuf_data_room_size(mp);
> +
> +	RTE_MBUF_ASSERT(mp->elt_size >= mbuf_size);
> +	RTE_MBUF_ASSERT(buf_len <= 0xffff);

As a nit: s/0xfff/UINT16_MAX/.
Konstantin

> 
>  	memset(m, 0, mp->elt_size);
> 
>  	/* start of buffer is just after mbuf structure */
> -	m->buf_addr = (char *)m + sizeof(struct rte_mbuf);
> -	m->buf_physaddr = rte_mempool_virt2phy(mp, m) +
> -			sizeof(struct rte_mbuf);
> +	m->buf_addr = (char *)m + mbuf_size;
> +	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mbuf_size;
>  	m->buf_len = (uint16_t)buf_len;
> 
>  	/* keep some headroom between start of buffer and data */
> --
> 2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v5 08/12] mbuf: fix clone support when application uses private mbuf data
  2015-04-21 15:01             ` Ananyev, Konstantin
@ 2015-04-21 15:26               ` Olivier MATZ
  0 siblings, 0 replies; 101+ messages in thread
From: Olivier MATZ @ 2015-04-21 15:26 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

On 04/21/2015 05:01 PM, Ananyev, Konstantin wrote:
> Hi Olivier,
>
>> -----Original Message-----
>> From: Olivier Matz [mailto:olivier.matz@6wind.com]
>> Sent: Tuesday, April 21, 2015 10:55 AM
>> To: dev@dpdk.org
>> Cc: Ananyev, Konstantin; zoltan.kiss@linaro.org; Richardson, Bruce; nhorman@tuxdriver.com; olivier.matz@6wind.com
>> Subject: [PATCH v5 08/12] mbuf: fix clone support when application uses private mbuf data
>>
>> 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 <olivier.matz@6wind.com>
>> Reviewed-by: Zoltan Kiss <zoltan.kiss@linaro.org>
>> ---
>>   examples/vhost/main.c      |  4 ++--
>>   lib/librte_mbuf/rte_mbuf.c |  2 +-
>>   lib/librte_mbuf/rte_mbuf.h | 59 +++++++++++++++++++++++++++++++---------------
>>   3 files changed, 43 insertions(+), 22 deletions(-)
>>
>> diff --git a/examples/vhost/main.c b/examples/vhost/main.c
>> index 22d6a4b..195d82f 100644
>> --- a/examples/vhost/main.c
>> +++ b/examples/vhost/main.c
>> @@ -138,7 +138,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;
>> @@ -1549,7 +1549,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 b013607..784ae8b 100644
>> --- a/lib/librte_mbuf/rte_mbuf.c
>> +++ b/lib/librte_mbuf/rte_mbuf.c
>> @@ -129,7 +129,7 @@ rte_pktmbuf_init(struct rte_mempool *mp,
>>
>>   	memset(m, 0, mp->elt_size);
>>
>> -	/* start of buffer is just after mbuf structure */
>> +	/* start of buffer is after mbuf structure and priv data */
>>   	m->buf_addr = (char *)m + mbuf_size;
>>   	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mbuf_size;
>>   	m->buf_len = (uint16_t)buf_len;
>> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
>> index 42db8e3..5c01c5b 100644
>> --- a/lib/librte_mbuf/rte_mbuf.h
>> +++ b/lib/librte_mbuf/rte_mbuf.h
>> @@ -320,16 +320,40 @@ struct rte_mbuf {
>>   	};
>>   } __rte_cache_aligned;
>>
>> +static inline uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp);
>> +
>>   /**
>> - * 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;
>> +       md = (struct rte_mbuf *)((char *)mi->buf_addr -
>> +	       sizeof(*mi) - rte_pktmbuf_priv_size(mi->pool));
>> +       return md;
>> +}
>
>
> Really puzzled, why do you remove prv_size from mbuf?
> Now if let say we attach mbuf (mi) with priv_size == X to mbuf (md) with priv_size == Y,
> then rte_mbuf_from_indirect(mi) would return: mi->buf_addr - 128 - X, while it should be: mi->buf_addr - 128 - Y.
>
> Another thing, rte_mbuf_from_indirect() and rte_mbuf_to_baddr() would probably become a bit slower -
> as another level of indirection is added.

You're right, I forgot this use case, it cannot work like this.
I think I will add a new test case, it will avoid me to break
it again in a version of the next patch series :)

Thanks,
Olivier



>
> Konstantin
>
>>
>>   /**
>> - * 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.
>> + *
>> + * @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) + rte_pktmbuf_priv_size(md->pool);
>> +       return buffer_addr;
>> +}
>>
>>   /**
>>    * Returns TRUE if given mbuf is indirect, or FALSE otherwise.
>> @@ -771,6 +795,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:
>> @@ -784,7 +809,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) &&
>> @@ -815,7 +839,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.
>> @@ -823,22 +848,18 @@ 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_mempool *mp = m->pool;
>> +	uint32_t mbuf_size, buf_len;
>>
>> -	m->buf_addr = buf;
>> +	mbuf_size = sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(mp);
>> +	buf_len = rte_pktmbuf_data_room_size(mp);
>> +	m->buf_addr = rte_mbuf_to_baddr(m);
>> +	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mbuf_size;
>>   	m->buf_len = (uint16_t)buf_len;
>> -
>> -	m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
>> -			RTE_PKTMBUF_HEADROOM : m->buf_len;
>> -
>> +	m->data_off = RTE_MIN(RTE_PKTMBUF_HEADROOM, (uint16_t)m->buf_len);
>>   	m->data_len = 0;
>> -
>>   	m->ol_flags = 0;
>>   }
>>
>> @@ -867,7 +888,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);
>> --
>> 2.1.4
>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones
  2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
                             ` (12 preceding siblings ...)
  2015-04-21 11:50           ` [dpdk-dev] [PATCH v5 00/12] mbuf: enhancements of mbuf clones Neil Horman
@ 2015-04-22  9:57           ` Olivier Matz
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 01/13] mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init Olivier Matz
                               ` (13 more replies)
  13 siblings, 14 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-22  9:57 UTC (permalink / raw)
  To: dev

The first objective of this series is to fix the support of indirect
mbufs when the application reserves a private area in mbufs. It also
removes the limitation that rte_pktmbuf_clone() is only allowed on
direct (non-cloned) mbufs. The series also contains some enhancements
and fixes in the mbuf area that makes the implementation of the
last patches easier.

Changes in v6:
- restore the priv_size in mbuf structure, version 4 broke the
  attachment between mbufs having different private size
- add a test case to ensure it won't be broken again
- replace 0xffff by UINT16_MAX
- fix some minor checkpatch issues

Changes in v5:
- update rte_mbuf_version.map to fix compilation with shared libraries

Changes in v4:
- do not add a priv_size in mbuf structure, having a proper accessor
  to read it from the pool private area is clearer
- prepend some reworks in the mbuf area to simplify the implementation
  (fix mbuf initialization by not using a hardcoded mbuf size, add
  accessors for mbuf pool private area, add a helper to create a
  mbuf pool)

Changes in v3:
- a mbuf can now attach to another one that have a different private
  size. In this case, the m->priv_size corresponds to the size of the
  private area of the direct mbuf.
- add comments to reflect these changes
- minor style modifications

Changes in v2:
- do not change the use of MBUF_EXT_MEM() in vhost
- change rte_mbuf_from_baddr() to rte_mbuf_from_indirect(), removing
  one parameter
- fix and rework rte_pktmbuf_detach()
- move m->priv_size in second mbuf cache line
- fix mbuf free in test error case

Olivier Matz (13):
  mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
  examples: always initialize mbuf_pool private area
  mbuf: add accessors to get data room size and private size
  mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
  testpmd: use standard functions to initialize mbufs and mbuf pool
  mbuf: introduce a new helper to create a mbuf pool
  apps: use rte_pktmbuf_pool_create to create mbuf pools
  mbuf: fix clone support when application uses private mbuf data
  mbuf: allow to clone an indirect mbuf
  test/mbuf: rename mc variable in m
  test/mbuf: enhance mbuf refcnt test
  test/mbuf: verify that cloning a clone works properly
  test/mbuf: add a test case for clone with different priv size

 app/test-pipeline/init.c                           |  15 +-
 app/test-pmd/testpmd.c                             |  84 +-------
 app/test/test_distributor.c                        |  10 +-
 app/test/test_distributor_perf.c                   |  10 +-
 app/test/test_kni.c                                |  16 +-
 app/test/test_link_bonding.c                       |  10 +-
 app/test/test_link_bonding_mode4.c                 |  12 +-
 app/test/test_mbuf.c                               | 238 ++++++++++++++++++---
 app/test/test_pmd_perf.c                           |  11 +-
 app/test/test_pmd_ring.c                           |  10 +-
 app/test/test_reorder.c                            |  10 +-
 app/test/test_sched.c                              |  16 +-
 app/test/test_table.c                              |   9 +-
 app/test/test_table.h                              |   3 +-
 doc/guides/rel_notes/updating_apps.rst             |  16 ++
 examples/bond/main.c                               |  10 +-
 examples/distributor/main.c                        |  11 +-
 examples/dpdk_qat/main.c                           |  10 +-
 examples/exception_path/main.c                     |  14 +-
 examples/ip_fragmentation/main.c                   |  18 +-
 examples/ip_pipeline/init.c                        |  28 +--
 examples/ipv4_multicast/main.c                     |  21 +-
 examples/kni/main.c                                |  12 +-
 examples/l2fwd-ivshmem/host/host.c                 |  10 +-
 examples/l2fwd-jobstats/main.c                     |  10 +-
 examples/l2fwd/main.c                              |  11 +-
 examples/l3fwd-acl/main.c                          |  11 +-
 examples/l3fwd-power/main.c                        |  11 +-
 examples/l3fwd-vf/main.c                           |  12 +-
 examples/l3fwd/main.c                              |  10 +-
 examples/link_status_interrupt/main.c              |  10 +-
 examples/load_balancer/init.c                      |  12 +-
 examples/load_balancer/main.h                      |   4 +-
 .../client_server_mp/mp_server/init.c              |  10 +-
 examples/multi_process/symmetric_mp/main.c         |  10 +-
 examples/netmap_compat/bridge/bridge.c             |  12 +-
 examples/packet_ordering/main.c                    |  11 +-
 examples/qos_meter/main.c                          |   7 +-
 examples/qos_sched/init.c                          |  10 +-
 examples/qos_sched/main.h                          |   2 +-
 examples/quota_watermark/include/conf.h            |   2 +-
 examples/quota_watermark/qw/main.c                 |   7 +-
 examples/rxtx_callbacks/main.c                     |  11 +-
 examples/skeleton/basicfwd.c                       |  13 +-
 examples/vhost/main.c                              |  31 +--
 examples/vhost_xen/main.c                          |  11 +-
 examples/vmdq/main.c                               |  11 +-
 examples/vmdq_dcb/main.c                           |  10 +-
 lib/librte_ether/rte_ethdev.c                      |   4 +-
 lib/librte_mbuf/rte_mbuf.c                         |  65 ++++--
 lib/librte_mbuf/rte_mbuf.h                         | 200 +++++++++++++----
 lib/librte_mbuf/rte_mbuf_version.map               |   8 +
 lib/librte_pmd_af_packet/rte_eth_af_packet.c       |   6 +-
 lib/librte_pmd_bond/rte_eth_bond_alb.c             |  16 +-
 lib/librte_pmd_e1000/em_rxtx.c                     |   5 +-
 lib/librte_pmd_e1000/igb_rxtx.c                    |  12 +-
 lib/librte_pmd_fm10k/fm10k_ethdev.c                |   6 +-
 lib/librte_pmd_i40e/i40e_ethdev_vf.c               |   6 +-
 lib/librte_pmd_i40e/i40e_rxtx.c                    |  15 +-
 lib/librte_pmd_ixgbe/ixgbe_rxtx.c                  |  12 +-
 lib/librte_pmd_pcap/rte_eth_pcap.c                 |   5 +-
 lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c              |   7 +-
 62 files changed, 650 insertions(+), 570 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v6 01/13] mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
@ 2015-04-22  9:57             ` Olivier Matz
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 02/13] examples: always initialize mbuf_pool private area Olivier Matz
                               ` (12 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-22  9:57 UTC (permalink / raw)
  To: dev

Deduct the mbuf data room size from mempool->elt_size and priv_size,
instead of using an hardcoded value that is not related to the real
buffer size.

To use rte_pktmbuf_pool_init(), the user can either:
- give a NULL parameter to rte_pktmbuf_pool_init(): in this case, the
  private size is assumed to be 0, and the room size is
  mp->elt_size - sizeof(struct rte_mbuf).
- give the rte_pktmbuf_pool_private filled with appropriate
  data_room_size and priv_size values.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
---
 app/test-pmd/testpmd.c                 |  1 +
 doc/guides/rel_notes/updating_apps.rst | 12 ++++++++++++
 examples/vhost/main.c                  |  5 ++---
 lib/librte_mbuf/rte_mbuf.c             | 27 ++++++++++++++++++++-------
 lib/librte_mbuf/rte_mbuf.h             |  3 ++-
 5 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 3057791..10e4347 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -443,6 +443,7 @@ testpmd_mbuf_pool_ctor(struct rte_mempool *mp,
 	mbp_ctor_arg = (struct mbuf_pool_ctor_arg *) opaque_arg;
 	mbp_priv = rte_mempool_get_priv(mp);
 	mbp_priv->mbuf_data_room_size = mbp_ctor_arg->seg_buf_size;
+	mbp_priv->mbuf_priv_size = 0;
 }
 
 static void
diff --git a/doc/guides/rel_notes/updating_apps.rst b/doc/guides/rel_notes/updating_apps.rst
index 4dbf268..f513615 100644
--- a/doc/guides/rel_notes/updating_apps.rst
+++ b/doc/guides/rel_notes/updating_apps.rst
@@ -4,6 +4,18 @@ Updating Applications from Previous Versions
 Although backward compatibility is being maintained across DPDK releases, code written for previous versions of the DPDK
 may require some code updates to benefit from performance and user experience enhancements provided in later DPDK releases.
 
+DPDK 2.0 to DPDK 2.1
+--------------------
+
+*   The second argument of rte_pktmbuf_pool_init(mempool, opaque) is now a
+    pointer to a struct rte_pktmbuf_pool_private instead of a uint16_t
+    casted into a pointer. Backward compatibility is preserved when the
+    argument was NULL which is the majority of use cases, but not if the
+    opaque pointer was not NULL, as it is not technically feasible. In
+    this case, the application has to be modified to properly fill a
+    rte_pktmbuf_pool_private structure and pass it to
+    rte_pktmbuf_pool_init().
+
 DPDK 1.7 to DPDK 1.8
 --------------------
 
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index ad10f82..fc73d1e 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -2844,11 +2844,10 @@ static void
 setup_mempool_tbl(int socket, uint32_t index, char *pool_name,
 	char *ring_name, uint32_t nb_mbuf)
 {
-	uint16_t roomsize = VIRTIO_DESCRIPTOR_LEN_ZCP + RTE_PKTMBUF_HEADROOM;
 	vpool_array[index].pool
 		= rte_mempool_create(pool_name, nb_mbuf, MBUF_SIZE_ZCP,
 		MBUF_CACHE_SIZE_ZCP, sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, (void *)(uintptr_t)roomsize,
+		rte_pktmbuf_pool_init, NULL,
 		rte_pktmbuf_init, NULL, socket, 0);
 	if (vpool_array[index].pool != NULL) {
 		vpool_array[index].ring
@@ -2870,7 +2869,7 @@ setup_mempool_tbl(int socket, uint32_t index, char *pool_name,
 		}
 
 		/* Need consider head room. */
-		vpool_array[index].buf_size = roomsize - RTE_PKTMBUF_HEADROOM;
+		vpool_array[index].buf_size = VIRTIO_DESCRIPTOR_LEN_ZCP;
 	} else {
 		rte_exit(EXIT_FAILURE, "mempool_create(%s) failed", pool_name);
 	}
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index 526b18d..231cfb8 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -81,17 +81,30 @@ rte_ctrlmbuf_init(struct rte_mempool *mp,
 void
 rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg)
 {
-	struct rte_pktmbuf_pool_private *mbp_priv;
+	struct rte_pktmbuf_pool_private *user_mbp_priv, *mbp_priv;
+	struct rte_pktmbuf_pool_private default_mbp_priv;
 	uint16_t roomsz;
 
-	mbp_priv = rte_mempool_get_priv(mp);
-	roomsz = (uint16_t)(uintptr_t)opaque_arg;
+	RTE_MBUF_ASSERT(mp->elt_size >= sizeof(struct rte_mbuf));
 
-	/* Use default data room size. */
-	if (0 == roomsz)
-		roomsz = 2048 + RTE_PKTMBUF_HEADROOM;
+	/* if no structure is provided, assume no mbuf private area */
+	user_mbp_priv = opaque_arg;
+	if (user_mbp_priv == NULL) {
+		default_mbp_priv.mbuf_priv_size = 0;
+		if (mp->elt_size > sizeof(struct rte_mbuf))
+			roomsz = mp->elt_size - sizeof(struct rte_mbuf);
+		else
+			roomsz = 0;
+		default_mbp_priv.mbuf_data_room_size = roomsz;
+		user_mbp_priv = &default_mbp_priv;
+	}
 
-	mbp_priv->mbuf_data_room_size = roomsz;
+	RTE_MBUF_ASSERT(mp->elt_size >= sizeof(struct rte_mbuf) +
+		user_mbp_priv->mbuf_data_room_size +
+		user_mbp_priv->mbuf_priv_size);
+
+	mbp_priv = rte_mempool_get_priv(mp);
+	memcpy(mbp_priv, user_mbp_priv, sizeof(*mbp_priv));
 }
 
 /*
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 45f73c2..13fd626 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -348,7 +348,8 @@ struct rte_mbuf {
  * appended after the mempool structure (in private data).
  */
 struct rte_pktmbuf_pool_private {
-	uint16_t mbuf_data_room_size; /**< Size of data space in each mbuf.*/
+	uint16_t mbuf_data_room_size; /**< Size of data space in each mbuf. */
+	uint16_t mbuf_priv_size;      /**< Size of private area in each mbuf. */
 };
 
 #ifdef RTE_LIBRTE_MBUF_DEBUG
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v6 02/13] examples: always initialize mbuf_pool private area
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 01/13] mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init Olivier Matz
@ 2015-04-22  9:57             ` Olivier Matz
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 03/13] mbuf: add accessors to get data room size and private size Olivier Matz
                               ` (11 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-22  9:57 UTC (permalink / raw)
  To: dev

The mbuf pool private area must always be populated in a mbuf pool.
The applications or drivers may expect that for a mbuf pool, the mbuf
pool private area (mbuf_data_room_size and mbuf_priv_size) are
properly filled.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
---
 examples/ip_fragmentation/main.c | 4 ++--
 examples/ip_pipeline/init.c      | 8 ++++++--
 examples/ipv4_multicast/main.c   | 6 ++++--
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 93ea2a1..cf63718 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -764,8 +764,8 @@ init_mem(void)
 
 			mp = rte_mempool_create(buf, NB_MBUF,
 							   sizeof(struct rte_mbuf), 32,
-							   0,
-							   NULL, NULL,
+							   sizeof(struct rte_pktmbuf_pool_private),
+							   rte_pktmbuf_pool_init, NULL,
 							   rte_pktmbuf_init, NULL,
 							   socket, 0);
 			if (mp == NULL) {
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index 96aee2b..61d71c3 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -363,6 +363,8 @@ app_get_ring_resp(uint32_t core_id)
 static void
 app_init_mbuf_pools(void)
 {
+	struct rte_pktmbuf_pool_private indirect_mbp_priv;
+
 	/* Init the buffer pool */
 	RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n");
 	app.pool = rte_mempool_create(
@@ -380,13 +382,15 @@ app_init_mbuf_pools(void)
 
 	/* Init the indirect buffer pool */
 	RTE_LOG(INFO, USER1, "Creating the indirect mbuf pool ...\n");
+	indirect_mbp_priv.mbuf_data_room_size = 0;
+	indirect_mbp_priv.mbuf_priv_size = sizeof(struct app_pkt_metadata);
 	app.indirect_pool = rte_mempool_create(
 		"indirect mempool",
 		app.pool_size,
 		sizeof(struct rte_mbuf) + sizeof(struct app_pkt_metadata),
 		app.pool_cache_size,
-		0,
-		NULL, NULL,
+		sizeof(struct rte_pktmbuf_pool_private),
+		rte_pktmbuf_pool_init, &indirect_mbp_priv,
 		rte_pktmbuf_init, NULL,
 		rte_socket_id(),
 		0);
diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index eed5611..19832d8 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -699,14 +699,16 @@ main(int argc, char **argv)
 		rte_exit(EXIT_FAILURE, "Cannot init packet mbuf pool\n");
 
 	header_pool = rte_mempool_create("header_pool", NB_HDR_MBUF,
-	    HDR_MBUF_SIZE, 32, 0, NULL, NULL, rte_pktmbuf_init, NULL,
+	    HDR_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
+	    rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
 	    rte_socket_id(), 0);
 
 	if (header_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init header mbuf pool\n");
 
 	clone_pool = rte_mempool_create("clone_pool", NB_CLONE_MBUF,
-	    CLONE_MBUF_SIZE, 32, 0, NULL, NULL, rte_pktmbuf_init, NULL,
+	    CLONE_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
+	    rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
 	    rte_socket_id(), 0);
 
 	if (clone_pool == NULL)
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v6 03/13] mbuf: add accessors to get data room size and private size
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 01/13] mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init Olivier Matz
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 02/13] examples: always initialize mbuf_pool private area Olivier Matz
@ 2015-04-22  9:57             ` Olivier Matz
  2015-04-28  9:15               ` Thomas Monjalon
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 04/13] mbuf: fix rte_pktmbuf_init when mbuf private size is not zero Olivier Matz
                               ` (10 subsequent siblings)
  13 siblings, 1 reply; 101+ messages in thread
From: Olivier Matz @ 2015-04-22  9:57 UTC (permalink / raw)
  To: dev

This code retrieving the pool private area is duplicated in many
places, we can use of function for it.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
---
 lib/librte_ether/rte_ethdev.c                |  4 +--
 lib/librte_mbuf/rte_mbuf.h                   | 41 ++++++++++++++++++++++++++++
 lib/librte_pmd_af_packet/rte_eth_af_packet.c |  6 ++--
 lib/librte_pmd_e1000/em_rxtx.c               |  5 ++--
 lib/librte_pmd_e1000/igb_rxtx.c              | 12 +++-----
 lib/librte_pmd_fm10k/fm10k_ethdev.c          |  6 ++--
 lib/librte_pmd_i40e/i40e_ethdev_vf.c         |  6 ++--
 lib/librte_pmd_i40e/i40e_rxtx.c              | 15 ++++------
 lib/librte_pmd_ixgbe/ixgbe_rxtx.c            | 12 +++-----
 lib/librte_pmd_pcap/rte_eth_pcap.c           |  5 +---
 lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c        |  7 ++---
 11 files changed, 67 insertions(+), 52 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index e20cca5..ff06256 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1439,7 +1439,6 @@ rte_eth_rx_queue_setup(uint8_t port_id, uint16_t rx_queue_id,
 	int ret;
 	uint32_t mbp_buf_size;
 	struct rte_eth_dev *dev;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	struct rte_eth_dev_info dev_info;
 
 	/* This function is only safe when called from the primary process
@@ -1478,8 +1477,7 @@ rte_eth_rx_queue_setup(uint8_t port_id, uint16_t rx_queue_id,
 				(int) sizeof(struct rte_pktmbuf_pool_private));
 		return (-ENOSPC);
 	}
-	mbp_priv = rte_mempool_get_priv(mp);
-	mbp_buf_size = mbp_priv->mbuf_data_room_size;
+	mbp_buf_size = rte_pktmbuf_data_room_size(mp);
 
 	if ((mbp_buf_size - RTE_PKTMBUF_HEADROOM) < dev_info.min_rx_bufsize) {
 		PMD_DEBUG_TRACE("%s mbuf_data_room_size %d < %d "
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 13fd626..a4146fa 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -642,6 +642,47 @@ void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg,
 void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
 
 /**
+ * Get the data room size of mbufs stored in a pktmbuf_pool
+ *
+ * The data room size is the amount of data that can be stored in a
+ * mbuf including the headroom (RTE_PKTMBUF_HEADROOM).
+ *
+ * @param mp
+ *   The packet mbuf pool.
+ * @return
+ *   The data room size of mbufs stored in this mempool.
+ */
+static inline uint16_t
+rte_pktmbuf_data_room_size(struct rte_mempool *mp)
+{
+	struct rte_pktmbuf_pool_private *mbp_priv;
+
+	mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
+	return mbp_priv->mbuf_data_room_size;
+}
+
+/**
+ * Get the application private size of mbufs stored in a pktmbuf_pool
+ *
+ * The private size of mbuf is a zone located between the rte_mbuf
+ * structure and the data buffer where an application can store data
+ * associated to a packet.
+ *
+ * @param mp
+ *   The packet mbuf pool.
+ * @return
+ *   The private size of mbufs stored in this mempool.
+ */
+static inline uint16_t
+rte_pktmbuf_priv_size(struct rte_mempool *mp)
+{
+	struct rte_pktmbuf_pool_private *mbp_priv;
+
+	mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
+	return mbp_priv->mbuf_priv_size;
+}
+
+/**
  * Reset the fields of a packet mbuf to their default values.
  *
  * The given mbuf must have only one segment.
diff --git a/lib/librte_pmd_af_packet/rte_eth_af_packet.c b/lib/librte_pmd_af_packet/rte_eth_af_packet.c
index f7e9ec9..bdd9628 100644
--- a/lib/librte_pmd_af_packet/rte_eth_af_packet.c
+++ b/lib/librte_pmd_af_packet/rte_eth_af_packet.c
@@ -348,15 +348,13 @@ eth_rx_queue_setup(struct rte_eth_dev *dev,
 {
 	struct pmd_internals *internals = dev->data->dev_private;
 	struct pkt_rx_queue *pkt_q = &internals->rx_queue[rx_queue_id];
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint16_t buf_size;
 
 	pkt_q->mb_pool = mb_pool;
 
 	/* Now get the space available for data in the mbuf */
-	mbp_priv = rte_mempool_get_priv(pkt_q->mb_pool);
-	buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-	                       RTE_PKTMBUF_HEADROOM);
+	buf_size = (uint16_t)(rte_pktmbuf_data_room_size(pkt_q->mb_pool) -
+		RTE_PKTMBUF_HEADROOM);
 
 	if (ETH_FRAME_LEN > buf_size) {
 		RTE_LOG(ERR, PMD,
diff --git a/lib/librte_pmd_e1000/em_rxtx.c b/lib/librte_pmd_e1000/em_rxtx.c
index 8e20920..64d067c 100644
--- a/lib/librte_pmd_e1000/em_rxtx.c
+++ b/lib/librte_pmd_e1000/em_rxtx.c
@@ -1668,12 +1668,11 @@ eth_em_rx_init(struct rte_eth_dev *dev)
 	/* Determine RX bufsize. */
 	rctl_bsize = EM_MAX_BUF_SIZE;
 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
-		struct rte_pktmbuf_pool_private *mbp_priv;
 		uint32_t buf_size;
 
 		rxq = dev->data->rx_queues[i];
-		mbp_priv = rte_mempool_get_priv(rxq->mb_pool);
-		buf_size = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM;
+		buf_size = rte_pktmbuf_data_room_size(rxq->mb_pool) -
+			RTE_PKTMBUF_HEADROOM;
 		rctl_bsize = RTE_MIN(rctl_bsize, buf_size);
 	}
 
diff --git a/lib/librte_pmd_e1000/igb_rxtx.c b/lib/librte_pmd_e1000/igb_rxtx.c
index 084e45a..80d05c0 100644
--- a/lib/librte_pmd_e1000/igb_rxtx.c
+++ b/lib/librte_pmd_e1000/igb_rxtx.c
@@ -1921,7 +1921,6 @@ eth_igb_rx_init(struct rte_eth_dev *dev)
 {
 	struct e1000_hw     *hw;
 	struct igb_rx_queue *rxq;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint32_t rctl;
 	uint32_t rxcsum;
 	uint32_t srrctl;
@@ -1991,9 +1990,8 @@ eth_igb_rx_init(struct rte_eth_dev *dev)
 		/*
 		 * Configure RX buffer size.
 		 */
-		mbp_priv = rte_mempool_get_priv(rxq->mb_pool);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-				       RTE_PKTMBUF_HEADROOM);
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) -
+			RTE_PKTMBUF_HEADROOM);
 		if (buf_size >= 1024) {
 			/*
 			 * Configure the BSIZEPACKET field of the SRRCTL
@@ -2221,7 +2219,6 @@ eth_igbvf_rx_init(struct rte_eth_dev *dev)
 {
 	struct e1000_hw     *hw;
 	struct igb_rx_queue *rxq;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint32_t srrctl;
 	uint16_t buf_size;
 	uint16_t rctl_bsize;
@@ -2262,9 +2259,8 @@ eth_igbvf_rx_init(struct rte_eth_dev *dev)
 		/*
 		 * Configure RX buffer size.
 		 */
-		mbp_priv = rte_mempool_get_priv(rxq->mb_pool);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-				       RTE_PKTMBUF_HEADROOM);
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) -
+			RTE_PKTMBUF_HEADROOM);
 		if (buf_size >= 1024) {
 			/*
 			 * Configure the BSIZEPACKET field of the SRRCTL
diff --git a/lib/librte_pmd_fm10k/fm10k_ethdev.c b/lib/librte_pmd_fm10k/fm10k_ethdev.c
index 1a96cf2..dd4454c 100644
--- a/lib/librte_pmd_fm10k/fm10k_ethdev.c
+++ b/lib/librte_pmd_fm10k/fm10k_ethdev.c
@@ -397,7 +397,6 @@ fm10k_dev_rx_init(struct rte_eth_dev *dev)
 	uint32_t size;
 	uint32_t rxdctl = FM10K_RXDCTL_WRITE_BACK_MIN_DELAY;
 	uint16_t buf_size;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 
 	/* Disable RXINT to avoid possible interrupt */
 	for (i = 0; i < hw->mac.max_queues; i++)
@@ -425,9 +424,8 @@ fm10k_dev_rx_init(struct rte_eth_dev *dev)
 		FM10K_WRITE_REG(hw, FM10K_RDLEN(i), size);
 
 		/* Configure the Rx buffer size for one buff without split */
-		mbp_priv = rte_mempool_get_priv(rxq->mp);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-					RTE_PKTMBUF_HEADROOM);
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mp) -
+			RTE_PKTMBUF_HEADROOM);
 		FM10K_WRITE_REG(hw, FM10K_SRRCTL(i),
 				buf_size >> FM10K_SRRCTL_BSIZEPKT_SHIFT);
 
diff --git a/lib/librte_pmd_i40e/i40e_ethdev_vf.c b/lib/librte_pmd_i40e/i40e_ethdev_vf.c
index 4581c5b..473d441 100644
--- a/lib/librte_pmd_i40e/i40e_ethdev_vf.c
+++ b/lib/librte_pmd_i40e/i40e_ethdev_vf.c
@@ -571,13 +571,11 @@ i40evf_fill_virtchnl_vsi_rxq_info(struct i40e_virtchnl_rxq_info *rxq_info,
 	rxq_info->queue_id = queue_id;
 	rxq_info->max_pkt_size = max_pkt_size;
 	if (queue_id < nb_rxq) {
-		struct rte_pktmbuf_pool_private *mbp_priv;
-
 		rxq_info->ring_len = rxq->nb_rx_desc;
 		rxq_info->dma_ring_addr = rxq->rx_ring_phys_addr;
-		mbp_priv = rte_mempool_get_priv(rxq->mp);
 		rxq_info->databuffer_size =
-			mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM;
+			(rte_pktmbuf_data_room_size(rxq->mp) -
+				RTE_PKTMBUF_HEADROOM);
 	}
 }
 
diff --git a/lib/librte_pmd_i40e/i40e_rxtx.c b/lib/librte_pmd_i40e/i40e_rxtx.c
index abe68f4..493cfa3 100644
--- a/lib/librte_pmd_i40e/i40e_rxtx.c
+++ b/lib/librte_pmd_i40e/i40e_rxtx.c
@@ -2444,11 +2444,10 @@ i40e_rx_queue_config(struct i40e_rx_queue *rxq)
 	struct i40e_pf *pf = I40E_VSI_TO_PF(rxq->vsi);
 	struct i40e_hw *hw = I40E_VSI_TO_HW(rxq->vsi);
 	struct rte_eth_dev_data *data = pf->dev_data;
-	struct rte_pktmbuf_pool_private *mbp_priv =
-			rte_mempool_get_priv(rxq->mp);
-	uint16_t buf_size = (uint16_t)(mbp_priv->mbuf_data_room_size -
-						RTE_PKTMBUF_HEADROOM);
-	uint16_t len;
+	uint16_t buf_size, len;
+
+	buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mp) -
+		RTE_PKTMBUF_HEADROOM);
 
 	switch (pf->flags & (I40E_FLAG_HEADER_SPLIT_DISABLED |
 			I40E_FLAG_HEADER_SPLIT_ENABLED)) {
@@ -2506,7 +2505,6 @@ i40e_rx_queue_init(struct i40e_rx_queue *rxq)
 	uint16_t pf_q = rxq->reg_idx;
 	uint16_t buf_size;
 	struct i40e_hmc_obj_rxq rx_ctx;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 
 	err = i40e_rx_queue_config(rxq);
 	if (err < 0) {
@@ -2553,9 +2551,8 @@ i40e_rx_queue_init(struct i40e_rx_queue *rxq)
 
 	rxq->qrx_tail = hw->hw_addr + I40E_QRX_TAIL(pf_q);
 
-	mbp_priv = rte_mempool_get_priv(rxq->mp);
-	buf_size = (uint16_t)(mbp_priv->mbuf_data_room_size -
-					RTE_PKTMBUF_HEADROOM);
+	buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mp) -
+		RTE_PKTMBUF_HEADROOM);
 
 	/* Check if scattered RX needs to be used. */
 	if ((rxq->max_pkt_len + 2 * I40E_VLAN_TAG_SIZE) > buf_size) {
diff --git a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c
index 3c61d1c..7f15f15 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c
+++ b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c
@@ -4203,7 +4203,6 @@ ixgbe_dev_rx_init(struct rte_eth_dev *dev)
 {
 	struct ixgbe_hw     *hw;
 	struct ixgbe_rx_queue *rxq;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint64_t bus_addr;
 	uint32_t rxctrl;
 	uint32_t fctrl;
@@ -4320,9 +4319,8 @@ ixgbe_dev_rx_init(struct rte_eth_dev *dev)
 		 * The value is in 1 KB resolution. Valid values can be from
 		 * 1 KB to 16 KB.
 		 */
-		mbp_priv = rte_mempool_get_priv(rxq->mb_pool);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-				       RTE_PKTMBUF_HEADROOM);
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) -
+			RTE_PKTMBUF_HEADROOM);
 		srrctl |= ((buf_size >> IXGBE_SRRCTL_BSIZEPKT_SHIFT) &
 			   IXGBE_SRRCTL_BSIZEPKT_MASK);
 
@@ -4738,7 +4736,6 @@ ixgbevf_dev_rx_init(struct rte_eth_dev *dev)
 {
 	struct ixgbe_hw     *hw;
 	struct ixgbe_rx_queue *rxq;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint64_t bus_addr;
 	uint32_t srrctl, psrtype = 0;
 	uint16_t buf_size;
@@ -4825,9 +4822,8 @@ ixgbevf_dev_rx_init(struct rte_eth_dev *dev)
 		 * The value is in 1 KB resolution. Valid values can be from
 		 * 1 KB to 16 KB.
 		 */
-		mbp_priv = rte_mempool_get_priv(rxq->mb_pool);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-				       RTE_PKTMBUF_HEADROOM);
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) -
+			RTE_PKTMBUF_HEADROOM);
 		srrctl |= ((buf_size >> IXGBE_SRRCTL_BSIZEPKT_SHIFT) &
 			   IXGBE_SRRCTL_BSIZEPKT_MASK);
 
diff --git a/lib/librte_pmd_pcap/rte_eth_pcap.c b/lib/librte_pmd_pcap/rte_eth_pcap.c
index e5d2279..e1aea34 100644
--- a/lib/librte_pmd_pcap/rte_eth_pcap.c
+++ b/lib/librte_pmd_pcap/rte_eth_pcap.c
@@ -136,9 +136,7 @@ eth_pcap_rx(void *queue,
 	const u_char *packet;
 	struct rte_mbuf *mbuf;
 	struct pcap_rx_queue *pcap_q = queue;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 	uint16_t num_rx = 0;
-	uint16_t buf_size;
 
 	if (unlikely(pcap_q->pcap == NULL || nb_pkts == 0))
 		return 0;
@@ -157,8 +155,7 @@ eth_pcap_rx(void *queue,
 			break;
 
 		/* Now get the space available for data in the mbuf */
-		mbp_priv =  rte_mempool_get_priv(pcap_q->mb_pool);
-		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
+		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(pcap_q->mb_pool) -
 				RTE_PKTMBUF_HEADROOM);
 
 		if (header.len <= buf_size) {
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
index a530c80..d8019f5 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
@@ -838,14 +838,11 @@ vmxnet3_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint8_t i;
 	char mem_name[32];
 	uint16_t buf_size;
-	struct rte_pktmbuf_pool_private *mbp_priv;
 
 	PMD_INIT_FUNC_TRACE();
 
-	mbp_priv = (struct rte_pktmbuf_pool_private *)
-		rte_mempool_get_priv(mp);
-	buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
-			       RTE_PKTMBUF_HEADROOM);
+	buf_size = rte_pktmbuf_data_room_size(mp) -
+		RTE_PKTMBUF_HEADROOM;
 
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len > buf_size) {
 		PMD_INIT_LOG(ERR, "buf_size = %u, max_pkt_len = %u, "
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v6 04/13] mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
                               ` (2 preceding siblings ...)
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 03/13] mbuf: add accessors to get data room size and private size Olivier Matz
@ 2015-04-22  9:57             ` Olivier Matz
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 05/13] testpmd: use standard functions to initialize mbufs and mbuf pool Olivier Matz
                               ` (9 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-22  9:57 UTC (permalink / raw)
  To: dev

Allow the user to use the default rte_pktmbuf_init() function even
if the mbuf private size is not 0.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
---
 lib/librte_mbuf/rte_mbuf.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index 231cfb8..d1f2a6f 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -119,16 +119,19 @@ rte_pktmbuf_init(struct rte_mempool *mp,
 		 __attribute__((unused)) unsigned i)
 {
 	struct rte_mbuf *m = _m;
-	uint32_t buf_len = mp->elt_size - sizeof(struct rte_mbuf);
+	uint32_t mbuf_size, buf_len;
 
-	RTE_MBUF_ASSERT(mp->elt_size >= sizeof(struct rte_mbuf));
+	mbuf_size = sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(mp);
+	buf_len = rte_pktmbuf_data_room_size(mp);
+
+	RTE_MBUF_ASSERT(mp->elt_size >= mbuf_size);
+	RTE_MBUF_ASSERT(buf_len <= UINT16_MAX);
 
 	memset(m, 0, mp->elt_size);
 
 	/* start of buffer is just after mbuf structure */
-	m->buf_addr = (char *)m + sizeof(struct rte_mbuf);
-	m->buf_physaddr = rte_mempool_virt2phy(mp, m) +
-			sizeof(struct rte_mbuf);
+	m->buf_addr = (char *)m + mbuf_size;
+	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mbuf_size;
 	m->buf_len = (uint16_t)buf_len;
 
 	/* keep some headroom between start of buffer and data */
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v6 05/13] testpmd: use standard functions to initialize mbufs and mbuf pool
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
                               ` (3 preceding siblings ...)
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 04/13] mbuf: fix rte_pktmbuf_init when mbuf private size is not zero Olivier Matz
@ 2015-04-22  9:57             ` Olivier Matz
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 06/13] mbuf: introduce a new helper to create a " Olivier Matz
                               ` (8 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-22  9:57 UTC (permalink / raw)
  To: dev

The rte_pktmbuf_pool_init() and rte_pktmbuf_init() functions now
support to have a non-hardcoded buffer length. We can remove the
specific functions used in testpmd and replace them by the standard
ones.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
---
 app/test-pmd/testpmd.c | 74 +++++---------------------------------------------
 1 file changed, 7 insertions(+), 67 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 10e4347..1f2445e 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -393,83 +393,23 @@ set_def_fwd_config(void)
 /*
  * Configuration initialisation done once at init time.
  */
-struct mbuf_ctor_arg {
-	uint16_t seg_buf_offset; /**< offset of data in data segment of mbuf. */
-	uint16_t seg_buf_size;   /**< size of data segment in mbuf. */
-};
-
-struct mbuf_pool_ctor_arg {
-	uint16_t seg_buf_size; /**< size of data segment in mbuf. */
-};
-
-static void
-testpmd_mbuf_ctor(struct rte_mempool *mp,
-		  void *opaque_arg,
-		  void *raw_mbuf,
-		  __attribute__((unused)) unsigned i)
-{
-	struct mbuf_ctor_arg *mb_ctor_arg;
-	struct rte_mbuf    *mb;
-
-	mb_ctor_arg = (struct mbuf_ctor_arg *) opaque_arg;
-	mb = (struct rte_mbuf *) raw_mbuf;
-
-	mb->pool         = mp;
-	mb->buf_addr     = (void *) ((char *)mb + mb_ctor_arg->seg_buf_offset);
-	mb->buf_physaddr = (uint64_t) (rte_mempool_virt2phy(mp, mb) +
-			mb_ctor_arg->seg_buf_offset);
-	mb->buf_len      = mb_ctor_arg->seg_buf_size;
-	mb->ol_flags     = 0;
-	mb->data_off     = RTE_PKTMBUF_HEADROOM;
-	mb->nb_segs      = 1;
-	mb->tx_offload   = 0;
-	mb->vlan_tci     = 0;
-	mb->hash.rss     = 0;
-}
-
-static void
-testpmd_mbuf_pool_ctor(struct rte_mempool *mp,
-		       void *opaque_arg)
-{
-	struct mbuf_pool_ctor_arg      *mbp_ctor_arg;
-	struct rte_pktmbuf_pool_private *mbp_priv;
-
-	if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) {
-		printf("%s(%s) private_data_size %d < %d\n",
-		       __func__, mp->name, (int) mp->private_data_size,
-		       (int) sizeof(struct rte_pktmbuf_pool_private));
-		return;
-	}
-	mbp_ctor_arg = (struct mbuf_pool_ctor_arg *) opaque_arg;
-	mbp_priv = rte_mempool_get_priv(mp);
-	mbp_priv->mbuf_data_room_size = mbp_ctor_arg->seg_buf_size;
-	mbp_priv->mbuf_priv_size = 0;
-}
-
 static void
 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 		 unsigned int socket_id)
 {
 	char pool_name[RTE_MEMPOOL_NAMESIZE];
 	struct rte_mempool *rte_mp;
-	struct mbuf_pool_ctor_arg mbp_ctor_arg;
-	struct mbuf_ctor_arg mb_ctor_arg;
 	uint32_t mb_size;
 
-	mbp_ctor_arg.seg_buf_size = (uint16_t) (RTE_PKTMBUF_HEADROOM +
-						mbuf_seg_size);
-	mb_ctor_arg.seg_buf_offset =
-		(uint16_t) RTE_CACHE_LINE_ROUNDUP(sizeof(struct rte_mbuf));
-	mb_ctor_arg.seg_buf_size = mbp_ctor_arg.seg_buf_size;
-	mb_size = mb_ctor_arg.seg_buf_offset + mb_ctor_arg.seg_buf_size;
+	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
 
 #ifdef RTE_LIBRTE_PMD_XENVIRT
 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
                                    (unsigned) mb_mempool_cache,
                                    sizeof(struct rte_pktmbuf_pool_private),
-                                   testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
-                                   testpmd_mbuf_ctor, &mb_ctor_arg,
+                                   rte_pktmbuf_pool_init, NULL,
+                                   rte_pktmbuf_init, NULL,
                                    socket_id, 0);
 
 
@@ -479,15 +419,15 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 		rte_mp = mempool_anon_create(pool_name, nb_mbuf, mb_size,
 				    (unsigned) mb_mempool_cache,
 				    sizeof(struct rte_pktmbuf_pool_private),
-				    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
-				    testpmd_mbuf_ctor, &mb_ctor_arg,
+				    rte_pktmbuf_pool_init, NULL,
+				    rte_pktmbuf_init, NULL,
 				    socket_id, 0);
 	else
 		rte_mp = rte_mempool_create(pool_name, nb_mbuf, mb_size,
 				    (unsigned) mb_mempool_cache,
 				    sizeof(struct rte_pktmbuf_pool_private),
-				    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
-				    testpmd_mbuf_ctor, &mb_ctor_arg,
+				    rte_pktmbuf_pool_init, NULL,
+				    rte_pktmbuf_init, NULL,
 				    socket_id, 0);
 
 #endif
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v6 06/13] mbuf: introduce a new helper to create a mbuf pool
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
                               ` (4 preceding siblings ...)
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 05/13] testpmd: use standard functions to initialize mbufs and mbuf pool Olivier Matz
@ 2015-04-22  9:57             ` Olivier Matz
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 07/13] apps: use rte_pktmbuf_pool_create to create mbuf pools Olivier Matz
                               ` (7 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-22  9:57 UTC (permalink / raw)
  To: dev

Add a new wrapper to rte_mempool_create() to simplify the creation
of a packet mbuf pool.

This wrapper can be used if there is no specific mempool flags, and
no specific mbuf or pool constructor function, which is most of the
use cases.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
---
 doc/guides/rel_notes/updating_apps.rst |  4 ++++
 lib/librte_mbuf/rte_mbuf.c             | 21 ++++++++++++++++++
 lib/librte_mbuf/rte_mbuf.h             | 40 ++++++++++++++++++++++++++++++++++
 lib/librte_mbuf/rte_mbuf_version.map   |  8 +++++++
 4 files changed, 73 insertions(+)

diff --git a/doc/guides/rel_notes/updating_apps.rst b/doc/guides/rel_notes/updating_apps.rst
index f513615..f4dd196 100644
--- a/doc/guides/rel_notes/updating_apps.rst
+++ b/doc/guides/rel_notes/updating_apps.rst
@@ -16,6 +16,10 @@ DPDK 2.0 to DPDK 2.1
     rte_pktmbuf_pool_private structure and pass it to
     rte_pktmbuf_pool_init().
 
+*   A simpler helper rte_pktmbuf_pool_create() can be used to create a
+    packet mbuf pool. The old way using rte_mempool_create() is still
+    supported though and is still used for more specific cases.
+
 DPDK 1.7 to DPDK 1.8
 --------------------
 
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index d1f2a6f..26b6f12 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -143,6 +143,27 @@ rte_pktmbuf_init(struct rte_mempool *mp,
 	m->port = 0xff;
 }
 
+/* helper to create a mbuf pool */
+struct rte_mempool *
+rte_pktmbuf_pool_create(const char *name, unsigned n,
+	unsigned cache_size, uint16_t priv_size, uint16_t data_room_size,
+	int socket_id)
+{
+	struct rte_pktmbuf_pool_private mbp_priv;
+	unsigned elt_size;
+
+
+	elt_size = sizeof(struct rte_mbuf) + (unsigned)priv_size +
+		(unsigned)data_room_size;
+	mbp_priv.mbuf_data_room_size = data_room_size;
+	mbp_priv.mbuf_priv_size = priv_size;
+
+	return rte_mempool_create(name, n, elt_size,
+		cache_size, sizeof(struct rte_pktmbuf_pool_private),
+		rte_pktmbuf_pool_init, &mbp_priv, rte_pktmbuf_init, NULL,
+		socket_id, 0);
+}
+
 /* do some sanity checks on a mbuf: panic if it fails */
 void
 rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header)
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index a4146fa..42db8e3 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -642,6 +642,46 @@ void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg,
 void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
 
 /**
+ * Create a mbuf pool.
+ *
+ * This function creates and initializes a packet mbuf pool. It is
+ * a wrapper to rte_mempool_create() with the proper packet constructor
+ * and mempool constructor.
+ *
+ * @param name
+ *   The name of the mbuf pool.
+ * @param n
+ *   The number of elements in the mbuf pool. The optimum size (in terms
+ *   of memory usage) for a mempool is when n is a power of two minus one:
+ *   n = (2^q - 1).
+ * @param cache_size
+ *   Size of the per-core object cache. See rte_mempool_create() for
+ *   details.
+ * @param priv_size
+ *   Size of application private are between the rte_mbuf structure
+ *   and the data buffer.
+ * @param data_room_size
+ *   Size of data buffer in each mbuf, including RTE_PKTMBUF_HEADROOM.
+ * @param socket_id
+ *   The socket identifier where the memory should be allocated. The
+ *   value can be *SOCKET_ID_ANY* if there is no NUMA constraint for the
+ *   reserved zone.
+ * @return
+ *   The pointer to the new allocated mempool, on success. NULL on error
+ *   with rte_errno set appropriately. Possible rte_errno values include:
+ *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
+ *    - E_RTE_SECONDARY - function was called from a secondary process instance
+ *    - EINVAL - cache size provided is too large
+ *    - ENOSPC - the maximum number of memzones has already been allocated
+ *    - EEXIST - a memzone with the same name already exists
+ *    - ENOMEM - no appropriate memory area found in which to create memzone
+ */
+struct rte_mempool *
+rte_pktmbuf_pool_create(const char *name, unsigned n,
+	unsigned cache_size, uint16_t priv_size, uint16_t data_room_size,
+	int socket_id);
+
+/**
  * Get the data room size of mbufs stored in a pktmbuf_pool
  *
  * The data room size is the amount of data that can be stored in a
diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map
index c4be3df..7ae2244 100644
--- a/lib/librte_mbuf/rte_mbuf_version.map
+++ b/lib/librte_mbuf/rte_mbuf_version.map
@@ -11,3 +11,11 @@ DPDK_2.0 {
 
 	local: *;
 };
+
+DPDK_2.1 {
+       global:
+
+       rte_pktmbuf_pool_create;
+
+       local: *;
+} DPDK_2.0;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v6 07/13] apps: use rte_pktmbuf_pool_create to create mbuf pools
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
                               ` (5 preceding siblings ...)
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 06/13] mbuf: introduce a new helper to create a " Olivier Matz
@ 2015-04-22  9:57             ` Olivier Matz
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 08/13] mbuf: fix clone support when application uses private mbuf data Olivier Matz
                               ` (6 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-22  9:57 UTC (permalink / raw)
  To: dev

When it's possible, use the new helper to create the mbuf pools.
Most of the patch is trivial, except for the following files that
have some specifics (indirect mbufs):
- ip_fragmentation
- ip_pipeline
- ipv4_multicast
- vhost

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
---
 app/test-pipeline/init.c                           | 15 ++--------
 app/test-pmd/testpmd.c                             | 19 ++++++-------
 app/test/test_distributor.c                        | 10 ++-----
 app/test/test_distributor_perf.c                   | 10 ++-----
 app/test/test_kni.c                                | 16 +++--------
 app/test/test_link_bonding.c                       | 10 +++----
 app/test/test_link_bonding_mode4.c                 | 12 +++-----
 app/test/test_mbuf.c                               | 22 +++++----------
 app/test/test_pmd_perf.c                           | 11 +++-----
 app/test/test_pmd_ring.c                           | 10 ++-----
 app/test/test_reorder.c                            | 10 ++-----
 app/test/test_sched.c                              | 16 ++---------
 app/test/test_table.c                              |  9 ++----
 app/test/test_table.h                              |  3 +-
 examples/bond/main.c                               | 10 ++-----
 examples/distributor/main.c                        | 11 +++-----
 examples/dpdk_qat/main.c                           | 10 ++-----
 examples/exception_path/main.c                     | 14 ++++------
 examples/ip_fragmentation/main.c                   | 18 ++++--------
 examples/ip_pipeline/init.c                        | 32 ++++------------------
 examples/ipv4_multicast/main.c                     | 23 ++++++----------
 examples/kni/main.c                                | 12 +++-----
 examples/l2fwd-ivshmem/host/host.c                 | 10 ++-----
 examples/l2fwd-jobstats/main.c                     | 10 ++-----
 examples/l2fwd/main.c                              | 11 ++------
 examples/l3fwd-acl/main.c                          | 11 +++-----
 examples/l3fwd-power/main.c                        | 11 +++-----
 examples/l3fwd-vf/main.c                           | 12 +++-----
 examples/l3fwd/main.c                              | 10 +++----
 examples/link_status_interrupt/main.c              | 10 ++-----
 examples/load_balancer/init.c                      | 12 ++------
 examples/load_balancer/main.h                      |  4 +--
 .../client_server_mp/mp_server/init.c              | 10 ++-----
 examples/multi_process/symmetric_mp/main.c         | 10 +++----
 examples/netmap_compat/bridge/bridge.c             | 12 +++-----
 examples/packet_ordering/main.c                    | 11 +++-----
 examples/qos_meter/main.c                          |  7 ++---
 examples/qos_sched/init.c                          | 10 ++-----
 examples/qos_sched/main.h                          |  2 +-
 examples/quota_watermark/include/conf.h            |  2 +-
 examples/quota_watermark/qw/main.c                 |  7 ++---
 examples/rxtx_callbacks/main.c                     | 11 +++-----
 examples/skeleton/basicfwd.c                       | 13 ++-------
 examples/vhost/main.c                              | 24 +++++-----------
 examples/vhost_xen/main.c                          | 11 +++-----
 examples/vmdq/main.c                               | 11 +++-----
 examples/vmdq_dcb/main.c                           | 10 ++-----
 lib/librte_pmd_bond/rte_eth_bond_alb.c             | 16 +++++------
 48 files changed, 180 insertions(+), 391 deletions(-)

diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index 05f4503..db2196b 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -85,8 +85,7 @@ struct app_params app = {
 	.ring_tx_size = 128,
 
 	/* Buffer pool */
-	.pool_buffer_size = 2048 + sizeof(struct rte_mbuf) +
-		RTE_PKTMBUF_HEADROOM,
+	.pool_buffer_size = 2048 + RTE_PKTMBUF_HEADROOM,
 	.pool_size = 32 * 1024,
 	.pool_cache_size = 256,
 
@@ -144,16 +143,8 @@ app_init_mbuf_pools(void)
 {
 	/* Init the buffer pool */
 	RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n");
-	app.pool = rte_mempool_create(
-		"mempool",
-		app.pool_size,
-		app.pool_buffer_size,
-		app.pool_cache_size,
-		sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, NULL,
-		rte_pktmbuf_init, NULL,
-		rte_socket_id(),
-		0);
+	app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size,
+		app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id());
 	if (app.pool == NULL)
 		rte_panic("Cannot create mbuf pool\n");
 }
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 1f2445e..83a3d74 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -406,11 +406,11 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 
 #ifdef RTE_LIBRTE_PMD_XENVIRT
 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
-                                   (unsigned) mb_mempool_cache,
-                                   sizeof(struct rte_pktmbuf_pool_private),
-                                   rte_pktmbuf_pool_init, NULL,
-                                   rte_pktmbuf_init, NULL,
-                                   socket_id, 0);
+		(unsigned) mb_mempool_cache,
+		sizeof(struct rte_pktmbuf_pool_private),
+		rte_pktmbuf_pool_init, NULL,
+		rte_pktmbuf_init, NULL,
+		socket_id, 0);
 
 
 
@@ -423,12 +423,9 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 				    rte_pktmbuf_init, NULL,
 				    socket_id, 0);
 	else
-		rte_mp = rte_mempool_create(pool_name, nb_mbuf, mb_size,
-				    (unsigned) mb_mempool_cache,
-				    sizeof(struct rte_pktmbuf_pool_private),
-				    rte_pktmbuf_pool_init, NULL,
-				    rte_pktmbuf_init, NULL,
-				    socket_id, 0);
+		/* wrapper to rte_mempool_create() */
+		rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
+			mb_mempool_cache, 0, mbuf_seg_size, socket_id);
 
 #endif
 
diff --git a/app/test/test_distributor.c b/app/test/test_distributor.c
index 9e8c06d..ad46987 100644
--- a/app/test/test_distributor.c
+++ b/app/test/test_distributor.c
@@ -500,7 +500,7 @@ quit_workers(struct rte_distributor *d, struct rte_mempool *p)
 	worker_idx = 0;
 }
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 static int
 test_distributor(void)
@@ -528,12 +528,8 @@ test_distributor(void)
 	const unsigned nb_bufs = (511 * rte_lcore_count()) < BIG_BATCH ?
 			(BIG_BATCH * 2) - 1 : (511 * rte_lcore_count());
 	if (p == NULL) {
-		p = rte_mempool_create("DT_MBUF_POOL", nb_bufs,
-				MBUF_SIZE, BURST,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL,
-				rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+		p = rte_pktmbuf_pool_create("DT_MBUF_POOL", nb_bufs, BURST,
+			0, MBUF_DATA_SIZE, rte_socket_id());
 		if (p == NULL) {
 			printf("Error creating mempool\n");
 			return -1;
diff --git a/app/test/test_distributor_perf.c b/app/test/test_distributor_perf.c
index 31431bb..f04cb15 100644
--- a/app/test/test_distributor_perf.c
+++ b/app/test/test_distributor_perf.c
@@ -209,7 +209,7 @@ quit_workers(struct rte_distributor *d, struct rte_mempool *p)
 	worker_idx = 0;
 }
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 static int
 test_distributor_perf(void)
@@ -240,12 +240,8 @@ test_distributor_perf(void)
 	const unsigned nb_bufs = (511 * rte_lcore_count()) < BIG_BATCH ?
 			(BIG_BATCH * 2) - 1 : (511 * rte_lcore_count());
 	if (p == NULL) {
-		p = rte_mempool_create("DPT_MBUF_POOL", nb_bufs,
-				MBUF_SIZE, BURST,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL,
-				rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+		p = rte_pktmbuf_pool_create("DPT_MBUF_POOL", nb_bufs, BURST,
+			0, MBUF_DATA_SIZE, rte_socket_id());
 		if (p == NULL) {
 			printf("Error creating mempool\n");
 			return -1;
diff --git a/app/test/test_kni.c b/app/test/test_kni.c
index 608901d..506b543 100644
--- a/app/test/test_kni.c
+++ b/app/test/test_kni.c
@@ -47,8 +47,7 @@
 
 #define NB_MBUF          8192
 #define MAX_PACKET_SZ    2048
-#define MBUF_SZ \
-	(MAX_PACKET_SZ + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SZ     (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM)
 #define PKT_BURST_SZ     32
 #define MEMPOOL_CACHE_SZ PKT_BURST_SZ
 #define SOCKET           0
@@ -118,17 +117,10 @@ test_kni_create_mempool(void)
 
 	mp = rte_mempool_lookup("kni_mempool");
 	if (!mp)
-		mp = rte_mempool_create("kni_mempool",
+		mp = rte_pktmbuf_pool_create("kni_mempool",
 				NB_MBUF,
-				MBUF_SZ,
-				MEMPOOL_CACHE_SZ,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init,
-				NULL,
-				rte_pktmbuf_init,
-				NULL,
-				SOCKET,
-				0);
+				MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ,
+				SOCKET);
 
 	return mp;
 }
diff --git a/app/test/test_link_bonding.c b/app/test/test_link_bonding.c
index 8c24314..674d8dd 100644
--- a/app/test/test_link_bonding.c
+++ b/app/test/test_link_bonding.c
@@ -75,8 +75,7 @@
 	ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \
 	ETH_TXQ_FLAGS_NOXSUMTCP)
 
-#define MBUF_PAYLOAD_SIZE	(2048)
-#define MBUF_SIZE (MBUF_PAYLOAD_SIZE + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE (250)
 #define BURST_SIZE (32)
 
@@ -280,10 +279,9 @@ test_setup(void)
 	nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
 			RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
 	if (test_params->mbuf_pool == NULL) {
-		test_params->mbuf_pool = rte_mempool_create("MBUF_POOL", nb_mbuf_per_pool,
-				MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+		test_params->mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+			nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+			rte_socket_id());
 		TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
 				"rte_mempool_create failed");
 	}
diff --git a/app/test/test_link_bonding_mode4.c b/app/test/test_link_bonding_mode4.c
index 02380f9..590daad 100644
--- a/app/test/test_link_bonding_mode4.c
+++ b/app/test/test_link_bonding_mode4.c
@@ -65,9 +65,7 @@
 #define RX_RING_SIZE 128
 #define TX_RING_SIZE 512
 
-#define MBUF_PAYLOAD_SIZE	    (2048)
-#define MBUF_SIZE (MBUF_PAYLOAD_SIZE + sizeof(struct rte_mbuf) + \
-	RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE          (2048 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE         (250)
 #define BURST_SIZE              (32)
 
@@ -390,11 +388,9 @@ test_setup(void)
 	if (test_params.mbuf_pool == NULL) {
 		nb_mbuf_per_pool = TEST_RX_DESC_MAX + DEF_PKT_BURST +
 					TEST_TX_DESC_MAX + MAX_PKT_BURST;
-		test_params.mbuf_pool = rte_mempool_create("TEST_MODE4",
-				nb_mbuf_per_pool, MBUF_SIZE, MBUF_CACHE_SIZE,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-				socket_id, 0);
+		test_params.mbuf_pool = rte_pktmbuf_pool_create("TEST_MODE4",
+			nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+			socket_id);
 
 		TEST_ASSERT(test_params.mbuf_pool != NULL,
 			"rte_mempool_create failed\n");
diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 1ff66cb..4774263 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -61,7 +61,7 @@
 
 #include "test.h"
 
-#define MBUF_SIZE               2048
+#define MBUF_DATA_SIZE          2048
 #define NB_MBUF                 128
 #define MBUF_TEST_DATA_LEN      1464
 #define MBUF_TEST_DATA_LEN2     50
@@ -73,7 +73,6 @@
 #define REFCNT_MAX_TIMEOUT      10
 #define REFCNT_MAX_REF          (RTE_MAX_LCORE)
 #define REFCNT_MBUF_NUM         64
-#define REFCNT_MBUF_SIZE        (sizeof (struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
 #define REFCNT_RING_SIZE        (REFCNT_MBUF_NUM * REFCNT_MAX_REF)
 
 #define MAKE_STRING(x)          # x
@@ -622,12 +621,10 @@ test_refcnt_mbuf(void)
 	/* create refcnt pool & ring if they don't exist */
 
 	if (refcnt_pool == NULL &&
-			(refcnt_pool = rte_mempool_create(
-			MAKE_STRING(refcnt_pool),
-			REFCNT_MBUF_NUM, REFCNT_MBUF_SIZE, 0,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-			SOCKET_ID_ANY, 0)) == NULL) {
+			(refcnt_pool = rte_pktmbuf_pool_create(
+				MAKE_STRING(refcnt_pool),
+				REFCNT_MBUF_NUM, 0, 0, 0,
+				SOCKET_ID_ANY)) == NULL) {
 		printf("%s: cannot allocate " MAKE_STRING(refcnt_pool) "\n",
 		    __func__);
 		return (-1);
@@ -764,13 +761,8 @@ test_mbuf(void)
 
 	/* create pktmbuf pool if it does not exist */
 	if (pktmbuf_pool == NULL) {
-		pktmbuf_pool =
-			rte_mempool_create("test_pktmbuf_pool", NB_MBUF,
-					   MBUF_SIZE, 32,
-					   sizeof(struct rte_pktmbuf_pool_private),
-					   rte_pktmbuf_pool_init, NULL,
-					   rte_pktmbuf_init, NULL,
-					   SOCKET_ID_ANY, 0);
+		pktmbuf_pool = rte_pktmbuf_pool_create("test_pktmbuf_pool",
+			NB_MBUF, 32, 0, MBUF_DATA_SIZE, SOCKET_ID_ANY);
 	}
 
 	if (pktmbuf_pool == NULL) {
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index d6a4a45..49a494d 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -47,7 +47,7 @@
 #define NB_ETHPORTS_USED                (1)
 #define NB_SOCKETS                      (2)
 #define MEMPOOL_CACHE_SIZE 250
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define MAX_PKT_BURST                   (32)
 #define RTE_TEST_RX_DESC_DEFAULT        (128)
 #define RTE_TEST_TX_DESC_DEFAULT        (512)
@@ -289,12 +289,9 @@ init_mbufpool(unsigned nb_mbuf)
 		if (mbufpool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
 			mbufpool[socketid] =
-				rte_mempool_create(s, nb_mbuf, MBUF_SIZE,
-					MEMPOOL_CACHE_SIZE,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, 0);
+				rte_pktmbuf_pool_create(s, nb_mbuf,
+					MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+					socketid);
 			if (mbufpool[socketid] == NULL)
 				rte_exit(EXIT_FAILURE,
 					"Cannot init mbuf pool on socket %d\n",
diff --git a/app/test/test_pmd_ring.c b/app/test/test_pmd_ring.c
index 7490112..53897f7 100644
--- a/app/test/test_pmd_ring.c
+++ b/app/test/test_pmd_ring.c
@@ -48,7 +48,7 @@ static struct rte_mempool *mp;
 
 #define RING_SIZE 256
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   512
 
 static int
@@ -406,12 +406,8 @@ test_pmd_ring_pair_create_attach(void)
 static int
 test_pmd_ring(void)
 {
-	mp = rte_mempool_create("mbuf_pool", NB_MBUF,
-			MBUF_SIZE, 32,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL,
-			rte_pktmbuf_init, NULL,
-			rte_socket_id(), 0);
+	mp = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32,
+		0, MBUF_DATA_SIZE, rte_socket_id());
 	if (mp == NULL)
 		return -1;
 
diff --git a/app/test/test_reorder.c b/app/test/test_reorder.c
index 61cf8d3..91fbe9a 100644
--- a/app/test/test_reorder.c
+++ b/app/test/test_reorder.c
@@ -50,7 +50,7 @@
 #define REORDER_BUFFER_SIZE 16384
 #define NUM_MBUFS (2*REORDER_BUFFER_SIZE)
 #define REORDER_BUFFER_SIZE_INVALID 2049
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 struct reorder_unittest_params {
 	struct rte_mempool *p;
@@ -351,12 +351,8 @@ test_setup(void)
 
 	/* mempool creation */
 	if (test_params->p == NULL) {
-		test_params->p = rte_mempool_create("RO_MBUF_POOL", NUM_MBUFS,
-				MBUF_SIZE, BURST,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL,
-				rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+		test_params->p = rte_pktmbuf_pool_create("RO_MBUF_POOL",
+			NUM_MBUFS, BURST, 0, MBUF_DATA_SIZE, rte_socket_id());
 		if (test_params->p == NULL) {
 			printf("%s: Error creating mempool\n", __func__);
 			return -1;
diff --git a/app/test/test_sched.c b/app/test/test_sched.c
index 60c62de..c7239f8 100644
--- a/app/test/test_sched.c
+++ b/app/test/test_sched.c
@@ -86,8 +86,7 @@ static struct rte_sched_port_params port_param = {
 };
 
 #define NB_MBUF          32
-#define MAX_PACKET_SZ    2048
-#define MBUF_SZ (MAX_PACKET_SZ + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SZ     (2048 + RTE_PKTMBUF_HEADROOM)
 #define PKT_BURST_SZ     32
 #define MEMPOOL_CACHE_SZ PKT_BURST_SZ
 #define SOCKET           0
@@ -100,17 +99,8 @@ create_mempool(void)
 
 	mp = rte_mempool_lookup("test_sched");
 	if (!mp)
-		mp = rte_mempool_create("test_sched",
-				NB_MBUF,
-				MBUF_SZ,
-				MEMPOOL_CACHE_SZ,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init,
-				NULL,
-				rte_pktmbuf_init,
-				NULL,
-				SOCKET,
-				0);
+		mp = rte_pktmbuf_pool_create("test_sched", NB_MBUF,
+			MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, SOCKET);
 
 	return mp;
 }
diff --git a/app/test/test_table.c b/app/test/test_table.c
index c3093cc..de6c27d 100644
--- a/app/test/test_table.c
+++ b/app/test/test_table.c
@@ -89,15 +89,10 @@ app_init_mbuf_pools(void)
 	printf("Getting/Creating the mempool ...\n");
 	pool = rte_mempool_lookup("mempool");
 	if (!pool) {
-		pool = rte_mempool_create(
+		pool = rte_pktmbuf_pool_create(
 			"mempool",
 			POOL_SIZE,
-			POOL_BUFFER_SIZE,
-			POOL_CACHE_SIZE,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL,
-			rte_pktmbuf_init, NULL,
-			0,
+			POOL_CACHE_SIZE, 0, POOL_BUFFER_SIZE,
 			0);
 		if (pool == NULL)
 			rte_panic("Cannot create mbuf pool\n");
diff --git a/app/test/test_table.h b/app/test/test_table.h
index 64e9427..be331c0 100644
--- a/app/test/test_table.h
+++ b/app/test/test_table.h
@@ -65,7 +65,7 @@
 #define PORT_TX_RING_SIZE   512
 #define RING_RX_SIZE        128
 #define RING_TX_SIZE        128
-#define POOL_BUFFER_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define POOL_BUFFER_SIZE    (2048 + RTE_PKTMBUF_HEADROOM)
 #define POOL_SIZE           (32 * 1024)
 #define POOL_CACHE_SIZE     256
 #define BURST_SIZE          8
@@ -73,7 +73,6 @@
 #define MAX_DUMMY_PORTS     2
 #define MP_NAME             "dummy_port_mempool"
 #define MBUF_COUNT          (8000 * MAX_DUMMY_PORTS)
-#define MBUF_SIZE        (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
 #define MP_CACHE_SZ         256
 #define MP_SOCKET           0
 #define MP_FLAGS            0
diff --git a/examples/bond/main.c b/examples/bond/main.c
index 67c283d..fcb4c4e 100644
--- a/examples/bond/main.c
+++ b/examples/bond/main.c
@@ -96,7 +96,7 @@
 
 #define RTE_LOGTYPE_DCB RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   (1024*8)
 
 #define MAX_PKT_BURST 32
@@ -738,12 +738,8 @@ main(int argc, char *argv[])
 	else if (nb_ports > MAX_PORTS)
 		rte_exit(EXIT_FAILURE, "You can have max 4 ports\n");
 
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NB_MBUF,
-				       MBUF_SIZE, 32,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init, NULL,
-				       rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NB_MBUF, 32,
+		0, MBUF_DATA_SIZE, rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/examples/distributor/main.c b/examples/distributor/main.c
index 13fb04d..78fe3e9 100644
--- a/examples/distributor/main.c
+++ b/examples/distributor/main.c
@@ -47,7 +47,7 @@
 #define RX_RING_SIZE 256
 #define TX_RING_SIZE 512
 #define NUM_MBUFS ((64*1024)-1)
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE 250
 #define BURST_SIZE 32
 #define RTE_RING_SZ 1024
@@ -528,12 +528,9 @@ main(int argc, char *argv[])
 		rte_exit(EXIT_FAILURE, "Error: number of ports must be even, except "
 				"when using a single port\n");
 
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
-			MBUF_SIZE, MBUF_CACHE_SIZE,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL,
-			rte_pktmbuf_init, NULL,
-			rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+		NUM_MBUFS * nb_ports, MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+		rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 	nb_ports_available = nb_ports;
diff --git a/examples/dpdk_qat/main.c b/examples/dpdk_qat/main.c
index 20e78bc..053be91 100644
--- a/examples/dpdk_qat/main.c
+++ b/examples/dpdk_qat/main.c
@@ -70,7 +70,7 @@
 
 #include "crypto.h"
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   (32 * 1024)
 
 #define MAX_PKT_BURST 32
@@ -598,7 +598,6 @@ print_ethaddr(const char *name, const struct ether_addr *eth_addr)
 static int
 init_mem(void)
 {
-	const unsigned flags = 0;
 	int socketid;
 	unsigned lcoreid;
 	char s[64];
@@ -613,11 +612,8 @@ init_mem(void)
 		if (pktmbuf_pool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
 			pktmbuf_pool[socketid] =
-				rte_mempool_create(s, NB_MBUF, MBUF_SIZE, 32,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, flags);
+				rte_pktmbuf_pool_create(s, NB_MBUF, 32, 0,
+					MBUF_DATA_SIZE, socketid);
 			if (pktmbuf_pool[socketid] == NULL) {
 				printf("Cannot init mbuf pool on socket %d\n", socketid);
 				return -1;
diff --git a/examples/exception_path/main.c b/examples/exception_path/main.c
index 14582de..b3fe170 100644
--- a/examples/exception_path/main.c
+++ b/examples/exception_path/main.c
@@ -81,11 +81,10 @@
 #define MAX_PORTS               (RTE_MAX_LCORE / 2)
 
 /* Max size of a single packet */
-#define MAX_PACKET_SZ           2048
+#define MAX_PACKET_SZ (2048)
 
-/* Number of bytes needed for each mbuf */
-#define MBUF_SZ \
-	(MAX_PACKET_SZ + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+/* Size of the data buffer in each mbuf */
+#define MBUF_DATA_SZ (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM)
 
 /* Number of mbufs in mempool that is created */
 #define NB_MBUF                 8192
@@ -532,11 +531,8 @@ main(int argc, char** argv)
 	parse_args(argc, argv);
 
 	/* Create the mbuf pool */
-	pktmbuf_pool = rte_mempool_create("mbuf_pool", NB_MBUF, MBUF_SZ,
-			MEMPOOL_CACHE_SZ,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-			rte_socket_id(), 0);
+	pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
+			MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, rte_socket_id());
 	if (pktmbuf_pool == NULL) {
 		FATAL_ERROR("Could not initialise mbuf pool");
 		return -1;
diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index cf63718..c702fdd 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -76,7 +76,7 @@
 
 #define RTE_LOGTYPE_IP_FRAG RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /* allow max jumbo frame 9.5 KB */
 #define JUMBO_FRAME_MAX_SIZE	0x2600
@@ -744,12 +744,8 @@ init_mem(void)
 					socket);
 			snprintf(buf, sizeof(buf), "pool_direct_%i", socket);
 
-			mp = rte_mempool_create(buf, NB_MBUF,
-						   MBUF_SIZE, 32,
-						   sizeof(struct rte_pktmbuf_pool_private),
-						   rte_pktmbuf_pool_init, NULL,
-						   rte_pktmbuf_init, NULL,
-						   socket, 0);
+			mp = rte_pktmbuf_pool_create(buf, NB_MBUF, 32,
+				0, MBUF_DATA_SIZE, socket);
 			if (mp == NULL) {
 				RTE_LOG(ERR, IP_FRAG, "Cannot create direct mempool\n");
 				return -1;
@@ -762,12 +758,8 @@ init_mem(void)
 					socket);
 			snprintf(buf, sizeof(buf), "pool_indirect_%i", socket);
 
-			mp = rte_mempool_create(buf, NB_MBUF,
-							   sizeof(struct rte_mbuf), 32,
-							   sizeof(struct rte_pktmbuf_pool_private),
-							   rte_pktmbuf_pool_init, NULL,
-							   rte_pktmbuf_init, NULL,
-							   socket, 0);
+			mp = rte_pktmbuf_pool_create(buf, NB_MBUF, 32, 0, 0,
+				socket);
 			if (mp == NULL) {
 				RTE_LOG(ERR, IP_FRAG, "Cannot create indirect mempool\n");
 				return -1;
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index 61d71c3..275fb35 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -146,8 +146,7 @@ struct app_params app = {
 	.bsz_swq_wr = 64,
 
 	/* Buffer pool */
-	.pool_buffer_size = 2048 + sizeof(struct rte_mbuf) +
-		RTE_PKTMBUF_HEADROOM,
+	.pool_buffer_size = 2048 + RTE_PKTMBUF_HEADROOM,
 	.pool_size = 32 * 1024,
 	.pool_cache_size = 256,
 
@@ -363,37 +362,18 @@ app_get_ring_resp(uint32_t core_id)
 static void
 app_init_mbuf_pools(void)
 {
-	struct rte_pktmbuf_pool_private indirect_mbp_priv;
-
 	/* Init the buffer pool */
 	RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n");
-	app.pool = rte_mempool_create(
-		"mempool",
-		app.pool_size,
-		app.pool_buffer_size,
-		app.pool_cache_size,
-		sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, NULL,
-		rte_pktmbuf_init, NULL,
-		rte_socket_id(),
-		0);
+	app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size,
+		app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id());
 	if (app.pool == NULL)
 		rte_panic("Cannot create mbuf pool\n");
 
 	/* Init the indirect buffer pool */
 	RTE_LOG(INFO, USER1, "Creating the indirect mbuf pool ...\n");
-	indirect_mbp_priv.mbuf_data_room_size = 0;
-	indirect_mbp_priv.mbuf_priv_size = sizeof(struct app_pkt_metadata);
-	app.indirect_pool = rte_mempool_create(
-		"indirect mempool",
-		app.pool_size,
-		sizeof(struct rte_mbuf) + sizeof(struct app_pkt_metadata),
-		app.pool_cache_size,
-		sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, &indirect_mbp_priv,
-		rte_pktmbuf_init, NULL,
-		rte_socket_id(),
-		0);
+	app.indirect_pool = rte_pktmbuf_pool_create("indirect mempool",
+		app.pool_size, app.pool_cache_size,
+		sizeof(struct app_pkt_metadata), 0, rte_socket_id());
 	if (app.indirect_pool == NULL)
 		rte_panic("Cannot create mbuf pool\n");
 
diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index 19832d8..575e989 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -77,13 +77,12 @@
 #define	MCAST_CLONE_PORTS	2
 #define	MCAST_CLONE_SEGS	2
 
-#define	PKT_MBUF_SIZE	(2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define	PKT_MBUF_DATA_SIZE	(2048 + RTE_PKTMBUF_HEADROOM)
 #define	NB_PKT_MBUF	8192
 
-#define	HDR_MBUF_SIZE	(sizeof(struct rte_mbuf) + 2 * RTE_PKTMBUF_HEADROOM)
+#define	HDR_MBUF_DATA_SIZE	(2 * RTE_PKTMBUF_HEADROOM)
 #define	NB_HDR_MBUF	(NB_PKT_MBUF * MAX_PORTS)
 
-#define	CLONE_MBUF_SIZE	(sizeof(struct rte_mbuf))
 #define	NB_CLONE_MBUF	(NB_PKT_MBUF * MCAST_CLONE_PORTS * MCAST_CLONE_SEGS * 2)
 
 /* allow max jumbo frame 9.5 KB */
@@ -690,26 +689,20 @@ main(int argc, char **argv)
 		rte_exit(EXIT_FAILURE, "Invalid IPV4_MULTICAST parameters\n");
 
 	/* create the mbuf pools */
-	packet_pool = rte_mempool_create("packet_pool", NB_PKT_MBUF,
-	    PKT_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
-	    rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-	    rte_socket_id(), 0);
+	packet_pool = rte_pktmbuf_pool_create("packet_pool", NB_PKT_MBUF, 32,
+		0, PKT_MBUF_DATA_SIZE, rte_socket_id());
 
 	if (packet_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init packet mbuf pool\n");
 
-	header_pool = rte_mempool_create("header_pool", NB_HDR_MBUF,
-	    HDR_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
-	    rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-	    rte_socket_id(), 0);
+	header_pool = rte_pktmbuf_pool_create("header_pool", NB_HDR_MBUF, 32,
+		0, HDR_MBUF_DATA_SIZE, rte_socket_id());
 
 	if (header_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init header mbuf pool\n");
 
-	clone_pool = rte_mempool_create("clone_pool", NB_CLONE_MBUF,
-	    CLONE_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
-	    rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-	    rte_socket_id(), 0);
+	clone_pool = rte_pktmbuf_pool_create("clone_pool", NB_CLONE_MBUF, 32,
+		0, 0, rte_socket_id());
 
 	if (clone_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init clone mbuf pool\n");
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 19d25d4..96ca473 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -80,9 +80,8 @@
 /* Max size of a single packet */
 #define MAX_PACKET_SZ           2048
 
-/* Number of bytes needed for each mbuf */
-#define MBUF_SZ \
-	(MAX_PACKET_SZ + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+/* Size of the data buffer in each mbuf */
+#define MBUF_DATA_SZ (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM)
 
 /* Number of mbufs in mempool that is created */
 #define NB_MBUF                 (8192 * 16)
@@ -867,11 +866,8 @@ main(int argc, char** argv)
 		rte_exit(EXIT_FAILURE, "Could not parse input parameters\n");
 
 	/* Create the mbuf pool */
-	pktmbuf_pool = rte_mempool_create("mbuf_pool", NB_MBUF, MBUF_SZ,
-			MEMPOOL_CACHE_SZ,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
-			rte_socket_id(), 0);
+	pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
+		MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, rte_socket_id());
 	if (pktmbuf_pool == NULL) {
 		rte_exit(EXIT_FAILURE, "Could not initialise mbuf pool\n");
 		return -1;
diff --git a/examples/l2fwd-ivshmem/host/host.c b/examples/l2fwd-ivshmem/host/host.c
index 4f8d23e..197f22b 100644
--- a/examples/l2fwd-ivshmem/host/host.c
+++ b/examples/l2fwd-ivshmem/host/host.c
@@ -71,7 +71,7 @@ static uint32_t l2fwd_ivshmem_enabled_port_mask = 0;
 static struct ether_addr l2fwd_ivshmem_ports_eth_addr[RTE_MAX_ETHPORTS];
 
 #define NB_MBUF   8192
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 #define MAX_RX_QUEUE_PER_LCORE 16
 #define MAX_TX_QUEUE_PER_PORT 16
@@ -670,12 +670,8 @@ int main(int argc, char **argv)
 
 	/* create a shared mbuf pool */
 	l2fwd_ivshmem_pktmbuf_pool =
-		rte_mempool_create(MBUF_MP_NAME, NB_MBUF,
-				   MBUF_SIZE, 32,
-				   sizeof(struct rte_pktmbuf_pool_private),
-				   rte_pktmbuf_pool_init, NULL,
-				   rte_pktmbuf_init, NULL,
-				   rte_socket_id(), 0);
+		rte_pktmbuf_pool_create(MBUF_MP_NAME, NB_MBUF, 32,
+			0, MBUF_DATA_SIZE, rte_socket_id());
 	if (l2fwd_ivshmem_pktmbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
 
diff --git a/examples/l2fwd-jobstats/main.c b/examples/l2fwd-jobstats/main.c
index f990045..fcebbda 100644
--- a/examples/l2fwd-jobstats/main.c
+++ b/examples/l2fwd-jobstats/main.c
@@ -70,7 +70,7 @@
 
 #define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   8192
 
 #define MAX_PKT_BURST 32
@@ -833,12 +833,8 @@ main(int argc, char **argv)
 
 	/* create the mbuf pool */
 	l2fwd_pktmbuf_pool =
-		rte_mempool_create("mbuf_pool", NB_MBUF,
-				   MBUF_SIZE, 32,
-				   sizeof(struct rte_pktmbuf_pool_private),
-				   rte_pktmbuf_pool_init, NULL,
-				   rte_pktmbuf_init, NULL,
-				   rte_socket_id(), 0);
+		rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32,
+			0, MBUF_DATA_SIZE, rte_socket_id());
 	if (l2fwd_pktmbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
 
diff --git a/examples/l2fwd/main.c b/examples/l2fwd/main.c
index 17621ee..d0a1ec8 100644
--- a/examples/l2fwd/main.c
+++ b/examples/l2fwd/main.c
@@ -71,7 +71,7 @@
 
 #define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   8192
 
 #define MAX_PKT_BURST 32
@@ -560,13 +560,8 @@ main(int argc, char **argv)
 		rte_exit(EXIT_FAILURE, "Invalid L2FWD arguments\n");
 
 	/* create the mbuf pool */
-	l2fwd_pktmbuf_pool =
-		rte_mempool_create("mbuf_pool", NB_MBUF,
-				   MBUF_SIZE, 32,
-				   sizeof(struct rte_pktmbuf_pool_private),
-				   rte_pktmbuf_pool_init, NULL,
-				   rte_pktmbuf_init, NULL,
-				   rte_socket_id(), 0);
+	l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32,
+		0, MBUF_DATA_SIZE, rte_socket_id());
 	if (l2fwd_pktmbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
 
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index fce55f3..1a04004 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -80,7 +80,7 @@
 
 #define MEMPOOL_CACHE_SIZE 256
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * This expression is used to calculate the number of mbufs needed
@@ -1848,12 +1848,9 @@ init_mem(unsigned nb_mbuf)
 		if (pktmbuf_pool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
 			pktmbuf_pool[socketid] =
-				rte_mempool_create(s, nb_mbuf, MBUF_SIZE,
-					MEMPOOL_CACHE_SIZE,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, 0);
+				rte_pktmbuf_pool_create(s, nb_mbuf,
+					MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+					socketid);
 			if (pktmbuf_pool[socketid] == NULL)
 				rte_exit(EXIT_FAILURE,
 					"Cannot init mbuf pool on socket %d\n",
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 4221239..bb0b66f 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -121,7 +121,7 @@
 
 #define MEMPOOL_CACHE_SIZE 256
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * This expression is used to calculate the number of mbufs needed depending on
@@ -1379,12 +1379,9 @@ init_mem(unsigned nb_mbuf)
 		if (pktmbuf_pool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
 			pktmbuf_pool[socketid] =
-				rte_mempool_create(s, nb_mbuf,
-					MBUF_SIZE, MEMPOOL_CACHE_SIZE,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, 0);
+				rte_pktmbuf_pool_create(s, nb_mbuf,
+					MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+					socketid);
 			if (pktmbuf_pool[socketid] == NULL)
 				rte_exit(EXIT_FAILURE,
 					"Cannot init mbuf pool on socket %d\n",
diff --git a/examples/l3fwd-vf/main.c b/examples/l3fwd-vf/main.c
index 20ba03a..f007bc1 100644
--- a/examples/l3fwd-vf/main.c
+++ b/examples/l3fwd-vf/main.c
@@ -94,7 +94,7 @@
 
 #define MEMPOOL_CACHE_SIZE 256
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * This expression is used to calculate the number of mbufs needed depending on user input, taking
@@ -924,13 +924,9 @@ init_mem(unsigned nb_mbuf)
 		}
 		if (pktmbuf_pool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
-			pktmbuf_pool[socketid] =
-				rte_mempool_create(s, nb_mbuf, MBUF_SIZE,
-						   MEMPOOL_CACHE_SIZE,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, 0);
+			pktmbuf_pool[socketid] = rte_pktmbuf_pool_create(s,
+				nb_mbuf, MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+				socketid);
 			if (pktmbuf_pool[socketid] == NULL)
 				rte_exit(EXIT_FAILURE, "Cannot init mbuf pool on socket %d\n", socketid);
 			else
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 90e177f..7871038 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -119,7 +119,7 @@
 
 #define MEMPOOL_CACHE_SIZE 256
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * This expression is used to calculate the number of mbufs needed depending on user input, taking
@@ -2315,11 +2315,9 @@ init_mem(unsigned nb_mbuf)
 		if (pktmbuf_pool[socketid] == NULL) {
 			snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
 			pktmbuf_pool[socketid] =
-				rte_mempool_create(s, nb_mbuf, MBUF_SIZE, MEMPOOL_CACHE_SIZE,
-					sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					socketid, 0);
+				rte_pktmbuf_pool_create(s, nb_mbuf,
+					MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+					socketid);
 			if (pktmbuf_pool[socketid] == NULL)
 				rte_exit(EXIT_FAILURE,
 						"Cannot init mbuf pool on socket %d\n", socketid);
diff --git a/examples/link_status_interrupt/main.c b/examples/link_status_interrupt/main.c
index e6fb218..6adbd79 100644
--- a/examples/link_status_interrupt/main.c
+++ b/examples/link_status_interrupt/main.c
@@ -72,7 +72,7 @@
 
 #define RTE_LOGTYPE_LSI RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF   8192
 
 #define MAX_PKT_BURST 32
@@ -614,12 +614,8 @@ main(int argc, char **argv)
 
 	/* create the mbuf pool */
 	lsi_pktmbuf_pool =
-		rte_mempool_create("mbuf_pool", NB_MBUF,
-				   MBUF_SIZE, 32,
-				   sizeof(struct rte_pktmbuf_pool_private),
-				   rte_pktmbuf_pool_init, NULL,
-				   rte_pktmbuf_init, NULL,
-				   rte_socket_id(), 0);
+		rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32, 0,
+			MBUF_DATA_SIZE, rte_socket_id());
 	if (lsi_pktmbuf_pool == NULL)
 		rte_panic("Cannot init mbuf pool\n");
 
diff --git a/examples/load_balancer/init.c b/examples/load_balancer/init.c
index b35f797..5a56078 100644
--- a/examples/load_balancer/init.c
+++ b/examples/load_balancer/init.c
@@ -127,16 +127,10 @@ app_init_mbuf_pools(void)
 
 		snprintf(name, sizeof(name), "mbuf_pool_%u", socket);
 		printf("Creating the mbuf pool for socket %u ...\n", socket);
-		app.pools[socket] = rte_mempool_create(
-			name,
-			APP_DEFAULT_MEMPOOL_BUFFERS,
-			APP_DEFAULT_MBUF_SIZE,
+		app.pools[socket] = rte_pktmbuf_pool_create(
+			name, APP_DEFAULT_MEMPOOL_BUFFERS,
 			APP_DEFAULT_MEMPOOL_CACHE_SIZE,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL,
-			rte_pktmbuf_init, NULL,
-			socket,
-			0);
+			0, APP_DEFAULT_MBUF_DATA_SIZE, socket);
 		if (app.pools[socket] == NULL) {
 			rte_panic("Cannot create mbuf pool on socket %u\n", socket);
 		}
diff --git a/examples/load_balancer/main.h b/examples/load_balancer/main.h
index d9f878b..17c0f77 100644
--- a/examples/load_balancer/main.h
+++ b/examples/load_balancer/main.h
@@ -82,8 +82,8 @@
 
 
 /* Mempools */
-#ifndef APP_DEFAULT_MBUF_SIZE
-#define APP_DEFAULT_MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#ifndef APP_DEFAULT_MBUF_DATA_SIZE
+#define APP_DEFAULT_MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #endif
 
 #ifndef APP_DEFAULT_MEMPOOL_BUFFERS
diff --git a/examples/multi_process/client_server_mp/mp_server/init.c b/examples/multi_process/client_server_mp/mp_server/init.c
index aadee76..dc3647d 100644
--- a/examples/multi_process/client_server_mp/mp_server/init.c
+++ b/examples/multi_process/client_server_mp/mp_server/init.c
@@ -71,9 +71,7 @@
 #define MBUFS_PER_CLIENT 1536
 #define MBUFS_PER_PORT 1536
 #define MBUF_CACHE_SIZE 512
-#define MBUF_OVERHEAD (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
-#define RX_MBUF_DATA_SIZE 2048
-#define MBUF_SIZE (RX_MBUF_DATA_SIZE + MBUF_OVERHEAD)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 #define RTE_MP_RX_DESC_DEFAULT 512
 #define RTE_MP_TX_DESC_DEFAULT 512
@@ -104,10 +102,8 @@ init_mbuf_pools(void)
 	 * seems faster to use a cache instead */
 	printf("Creating mbuf pool '%s' [%u mbufs] ...\n",
 			PKTMBUF_POOL_NAME, num_mbufs);
-	pktmbuf_pool = rte_mempool_create(PKTMBUF_POOL_NAME, num_mbufs,
-			MBUF_SIZE, MBUF_CACHE_SIZE,
-			sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init,
-			NULL, rte_pktmbuf_init, NULL, rte_socket_id(), NO_FLAGS );
+	pktmbuf_pool = rte_pktmbuf_pool_create(PKTMBUF_POOL_NAME, num_mbufs,
+		MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE, rte_socket_id());
 
 	return (pktmbuf_pool == NULL); /* 0  on success */
 }
diff --git a/examples/multi_process/symmetric_mp/main.c b/examples/multi_process/symmetric_mp/main.c
index 48448b4..7829c86 100644
--- a/examples/multi_process/symmetric_mp/main.c
+++ b/examples/multi_process/symmetric_mp/main.c
@@ -78,7 +78,7 @@
 
 #define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1
 
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUFS 64*1024 /* use 64k mbufs */
 #define MBUF_CACHE_SIZE 256
 #define PKT_BURST 32
@@ -446,11 +446,9 @@ main(int argc, char **argv)
 	proc_type = rte_eal_process_type();
 	mp = (proc_type == RTE_PROC_SECONDARY) ?
 			rte_mempool_lookup(_SMP_MBUF_POOL) :
-			rte_mempool_create(_SMP_MBUF_POOL, NB_MBUFS, MBUF_SIZE,
-					MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
-					rte_pktmbuf_pool_init, NULL,
-					rte_pktmbuf_init, NULL,
-					rte_socket_id(), 0);
+			rte_pktmbuf_pool_create(_SMP_MBUF_POOL, NB_MBUFS,
+				MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+				rte_socket_id());
 	if (mp == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot get memory pool for buffers\n");
 
diff --git a/examples/netmap_compat/bridge/bridge.c b/examples/netmap_compat/bridge/bridge.c
index 0a8efbe..2d935cb 100644
--- a/examples/netmap_compat/bridge/bridge.c
+++ b/examples/netmap_compat/bridge/bridge.c
@@ -47,9 +47,8 @@
 #include "compat_netmap.h"
 
 
-#define	BUF_SIZE	2048
-#define MBUF_SIZE	(BUF_SIZE + sizeof(struct rte_mbuf) + \
-	RTE_PKTMBUF_HEADROOM)
+#define BUF_SIZE	(2048)
+#define MBUF_DATA_SIZE	(BUF_SIZE + RTE_PKTMBUF_HEADROOM)
 
 #define MBUF_PER_POOL	8192
 
@@ -272,11 +271,8 @@ int main(int argc, char *argv[])
 	if (rte_eth_dev_count() < 1)
 		rte_exit(EXIT_FAILURE, "Not enough ethernet ports available\n");
 
-	pool = rte_mempool_create("mbuf_pool", MBUF_PER_POOL, MBUF_SIZE, 32,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL,
-				rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+	pool = rte_pktmbuf_pool_create("mbuf_pool", MBUF_PER_POOL, 32, 0,
+		MBUF_DATA_SIZE, rte_socket_id());
 	if (pool == NULL)
 		rte_exit(EXIT_FAILURE, "Couldn't create mempool\n");
 
diff --git a/examples/packet_ordering/main.c b/examples/packet_ordering/main.c
index f0a1b5a..5403c33 100644
--- a/examples/packet_ordering/main.c
+++ b/examples/packet_ordering/main.c
@@ -50,7 +50,7 @@
 #define MAX_PKTS_BURST 32
 #define REORDER_BUFFER_SIZE 8192
 #define MBUF_PER_POOL 65535
-#define MBUF_SIZE (1600 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (1600 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_POOL_CACHE_SIZE 250
 
 #define RING_SIZE 16384
@@ -622,12 +622,9 @@ main(int argc, char **argv)
 		rte_exit(EXIT_FAILURE, "Error: number of ports must be even, except "
 				"when using a single port\n");
 
-	mbuf_pool = rte_mempool_create("mbuf_pool", MBUF_PER_POOL, MBUF_SIZE,
-			MBUF_POOL_CACHE_SIZE,
-			sizeof(struct rte_pktmbuf_pool_private),
-			rte_pktmbuf_pool_init, NULL,
-			rte_pktmbuf_init, NULL,
-			rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", MBUF_PER_POOL,
+			MBUF_POOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+			rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno));
 
diff --git a/examples/qos_meter/main.c b/examples/qos_meter/main.c
index 4a981c6..a5e2510 100644
--- a/examples/qos_meter/main.c
+++ b/examples/qos_meter/main.c
@@ -70,7 +70,7 @@
  * Buffer pool configuration
  *
  ***/
-#define MBUF_SIZE           (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE      (2048 + RTE_PKTMBUF_HEADROOM)
 #define NB_MBUF             8192
 #define MEMPOOL_CACHE_SIZE  256
 
@@ -360,9 +360,8 @@ main(int argc, char **argv)
 		rte_exit(EXIT_FAILURE, "Invalid input arguments\n");
 
 	/* Buffer pool init */
-	pool = rte_mempool_create("pool", NB_MBUF, MBUF_SIZE, MEMPOOL_CACHE_SIZE,
-		sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL,
-		rte_pktmbuf_init, NULL, rte_socket_id(), 0);
+	pool = rte_pktmbuf_pool_create("pool", NB_MBUF, MEMPOOL_CACHE_SIZE,
+		0, MBUF_DATA_SIZE, rte_socket_id());
 	if (pool == NULL)
 		rte_exit(EXIT_FAILURE, "Buffer pool creation error\n");
 
diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c
index f38802e..aaf3466 100644
--- a/examples/qos_sched/init.c
+++ b/examples/qos_sched/init.c
@@ -335,13 +335,9 @@ int app_init(void)
 
 		/* create the mbuf pools for each RX Port */
 		snprintf(pool_name, MAX_NAME_LEN, "mbuf_pool%u", i);
-		qos_conf[i].mbuf_pool = rte_mempool_create(pool_name, mp_size, MBUF_SIZE,
-						burst_conf.rx_burst * 4,
-						sizeof(struct rte_pktmbuf_pool_private),
-						rte_pktmbuf_pool_init, NULL,
-						rte_pktmbuf_init, NULL,
-						rte_eth_dev_socket_id(qos_conf[i].rx_port),
-						0);
+		qos_conf[i].mbuf_pool = rte_pktmbuf_pool_create(pool_name,
+			mp_size, burst_conf.rx_burst * 4, 0, MBUF_DATA_SIZE,
+			rte_eth_dev_socket_id(qos_conf[i].rx_port));
 		if (qos_conf[i].mbuf_pool == NULL)
 			rte_exit(EXIT_FAILURE, "Cannot init mbuf pool for socket %u\n", i);
 
diff --git a/examples/qos_sched/main.h b/examples/qos_sched/main.h
index 971ec27..0e6f264 100644
--- a/examples/qos_sched/main.h
+++ b/examples/qos_sched/main.h
@@ -50,7 +50,7 @@ extern "C" {
 #define APP_RX_DESC_DEFAULT 128
 #define APP_TX_DESC_DEFAULT 256
 
-#define MBUF_SIZE (1528 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (1528 + RTE_PKTMBUF_HEADROOM)
 #define APP_RING_SIZE (8*1024)
 #define NB_MBUF   (2*1024*1024)
 
diff --git a/examples/quota_watermark/include/conf.h b/examples/quota_watermark/include/conf.h
index 8d95aaa..e80aca5 100644
--- a/examples/quota_watermark/include/conf.h
+++ b/examples/quota_watermark/include/conf.h
@@ -40,7 +40,7 @@
 #define RX_DESC_PER_QUEUE   128
 #define TX_DESC_PER_QUEUE   512
 
-#define MBUF_SIZE     (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE     (2048 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_PER_POOL 8192
 
 #define QUOTA_WATERMARK_MEMZONE_NAME "qw_global_vars"
diff --git a/examples/quota_watermark/qw/main.c b/examples/quota_watermark/qw/main.c
index f269546..8ed0214 100644
--- a/examples/quota_watermark/qw/main.c
+++ b/examples/quota_watermark/qw/main.c
@@ -335,11 +335,8 @@ main(int argc, char **argv)
         rte_exit(EXIT_FAILURE, "Invalid quota/watermark argument(s)\n");
 
     /* Create a pool of mbuf to store packets */
-    mbuf_pool = rte_mempool_create("mbuf_pool", MBUF_PER_POOL, MBUF_SIZE, 32,
-                                   sizeof(struct rte_pktmbuf_pool_private),
-                                   rte_pktmbuf_pool_init, NULL,
-                                   rte_pktmbuf_init, NULL,
-                                   rte_socket_id(), 0);
+    mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", MBUF_PER_POOL, 32, 0,
+	    MBUF_DATA_SIZE, rte_socket_id());
     if (mbuf_pool == NULL)
         rte_panic("%s\n", rte_strerror(rte_errno));
 
diff --git a/examples/rxtx_callbacks/main.c b/examples/rxtx_callbacks/main.c
index 21117ce..fb8da51 100644
--- a/examples/rxtx_callbacks/main.c
+++ b/examples/rxtx_callbacks/main.c
@@ -43,7 +43,7 @@
 #define TX_RING_SIZE 512
 
 #define NUM_MBUFS 8191
-#define MBUF_SIZE (1600 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (1600 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE 250
 #define BURST_SIZE 32
 
@@ -204,12 +204,9 @@ main(int argc, char *argv[])
 	if (nb_ports < 2 || (nb_ports & 1))
 		rte_exit(EXIT_FAILURE, "Error: number of ports must be even\n");
 
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
-				       MBUF_SIZE, MBUF_CACHE_SIZE,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init, NULL,
-				       rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+		NUM_MBUFS * nb_ports, MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+		rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/examples/skeleton/basicfwd.c b/examples/skeleton/basicfwd.c
index 1bce6e7..ae606bf 100644
--- a/examples/skeleton/basicfwd.c
+++ b/examples/skeleton/basicfwd.c
@@ -43,7 +43,7 @@
 #define TX_RING_SIZE 512
 
 #define NUM_MBUFS 8191
-#define MBUF_SIZE (1600 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (1600 + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE 250
 #define BURST_SIZE 32
 
@@ -190,15 +190,8 @@ main(int argc, char *argv[])
 		rte_exit(EXIT_FAILURE, "Error: number of ports must be even\n");
 
 	/* Creates a new mempool in memory to hold the mbufs. */
-	mbuf_pool = rte_mempool_create("MBUF_POOL",
-				       NUM_MBUFS * nb_ports,
-				       MBUF_SIZE,
-				       MBUF_CACHE_SIZE,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init,      NULL,
-				       rte_socket_id(),
-				       0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
+		MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE, rte_socket_id());
 
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index fc73d1e..22d6a4b 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -67,7 +67,7 @@
 							(num_switching_cores*MBUF_CACHE_SIZE))
 
 #define MBUF_CACHE_SIZE 128
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * No frame data buffer allocated from host are required for zero copy
@@ -75,8 +75,7 @@
  * directly use it.
  */
 #define VIRTIO_DESCRIPTOR_LEN_ZCP 1518
-#define MBUF_SIZE_ZCP (VIRTIO_DESCRIPTOR_LEN_ZCP + sizeof(struct rte_mbuf) \
-	+ RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE_ZCP (VIRTIO_DESCRIPTOR_LEN_ZCP + RTE_PKTMBUF_HEADROOM)
 #define MBUF_CACHE_SIZE_ZCP 0
 
 #define MAX_PKT_BURST 32 		/* Max burst size for RX/TX */
@@ -2844,11 +2843,8 @@ static void
 setup_mempool_tbl(int socket, uint32_t index, char *pool_name,
 	char *ring_name, uint32_t nb_mbuf)
 {
-	vpool_array[index].pool
-		= rte_mempool_create(pool_name, nb_mbuf, MBUF_SIZE_ZCP,
-		MBUF_CACHE_SIZE_ZCP, sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, NULL,
-		rte_pktmbuf_init, NULL, socket, 0);
+	vpool_array[index].pool	= rte_pktmbuf_pool_create(pool_name, nb_mbuf,
+		MBUF_CACHE_SIZE_ZCP, 0, MBUF_DATA_SIZE_ZCP, socket);
 	if (vpool_array[index].pool != NULL) {
 		vpool_array[index].ring
 			= rte_ring_create(ring_name,
@@ -2932,15 +2928,9 @@ main(int argc, char *argv[])
 
 	if (zero_copy == 0) {
 		/* Create the mbuf pool. */
-		mbuf_pool = rte_mempool_create(
-				"MBUF_POOL",
-				NUM_MBUFS_PER_PORT
-				* valid_num_ports,
-				MBUF_SIZE, MBUF_CACHE_SIZE,
-				sizeof(struct rte_pktmbuf_pool_private),
-				rte_pktmbuf_pool_init, NULL,
-				rte_pktmbuf_init, NULL,
-				rte_socket_id(), 0);
+		mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+			NUM_MBUFS_PER_PORT * valid_num_ports, MBUF_CACHE_SIZE,
+			0, MBUF_DATA_SIZE, rte_socket_id());
 		if (mbuf_pool == NULL)
 			rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/examples/vhost_xen/main.c b/examples/vhost_xen/main.c
index b4a86e3..b672bf3 100644
--- a/examples/vhost_xen/main.c
+++ b/examples/vhost_xen/main.c
@@ -67,7 +67,7 @@
 							(num_switching_cores*MBUF_CACHE_SIZE))
 
 #define MBUF_CACHE_SIZE 64
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 /*
  * RX and TX Prefetch, Host, and Write-back threshold values should be
@@ -1474,12 +1474,9 @@ main(int argc, char *argv[])
 	}
 
 	/* Create the mbuf pool. */
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS_PER_PORT * valid_num_ports,
-				       MBUF_SIZE, MBUF_CACHE_SIZE,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init, NULL,
-				       rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+		NUM_MBUFS_PER_PORT * valid_num_ports, MBUF_CACHE_SIZE, 0,
+		MBUF_DATA_SIZE, rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/examples/vmdq/main.c b/examples/vmdq/main.c
index 7001860..7596bac 100644
--- a/examples/vmdq/main.c
+++ b/examples/vmdq/main.c
@@ -76,7 +76,7 @@
  */
 #define NUM_MBUFS_PER_PORT (128*512)
 #define MBUF_CACHE_SIZE 64
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 #define MAX_PKT_BURST 32
 
@@ -613,12 +613,9 @@ main(int argc, char *argv[])
 		rte_exit(EXIT_FAILURE, "Error with valid ports number is not even or less than 2\n");
 	}
 
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS_PER_PORT * nb_ports,
-				       MBUF_SIZE, MBUF_CACHE_SIZE,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init, NULL,
-				       rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+		NUM_MBUFS_PER_PORT * nb_ports, MBUF_CACHE_SIZE,
+		0, MBUF_DATA_SIZE, rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/examples/vmdq_dcb/main.c b/examples/vmdq_dcb/main.c
index 048c167..3c7f2b3 100644
--- a/examples/vmdq_dcb/main.c
+++ b/examples/vmdq_dcb/main.c
@@ -74,7 +74,7 @@
 
 #define NUM_MBUFS 64*1024
 #define MBUF_CACHE_SIZE 64
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
 
 #define INVALID_PORT_ID 0xFF
 
@@ -441,12 +441,8 @@ main(int argc, char *argv[])
 		rte_exit(EXIT_FAILURE, "Error with valid ports number is not even or less than 2\n");
 	}
 
-	mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
-				       MBUF_SIZE, MBUF_CACHE_SIZE,
-				       sizeof(struct rte_pktmbuf_pool_private),
-				       rte_pktmbuf_pool_init, NULL,
-				       rte_pktmbuf_init, NULL,
-				       rte_socket_id(), 0);
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
+		MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE, rte_socket_id());
 	if (mbuf_pool == NULL)
 		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
 
diff --git a/lib/librte_pmd_bond/rte_eth_bond_alb.c b/lib/librte_pmd_bond/rte_eth_bond_alb.c
index 5778b25..6df318e 100644
--- a/lib/librte_pmd_bond/rte_eth_bond_alb.c
+++ b/lib/librte_pmd_bond/rte_eth_bond_alb.c
@@ -63,7 +63,7 @@ bond_mode_alb_enable(struct rte_eth_dev *bond_dev)
 	struct bond_dev_private *internals = bond_dev->data->dev_private;
 	struct client_data *hash_table = internals->mode6.client_table;
 
-	uint16_t element_size;
+	uint16_t data_size;
 	char mem_name[RTE_ETH_NAME_MAX_LEN];
 	int socket_id = bond_dev->pci_dev->numa_node;
 
@@ -79,15 +79,13 @@ bond_mode_alb_enable(struct rte_eth_dev *bond_dev)
 		 * 256 is size of ETH header, ARP header and nested VLAN headers.
 		 * The value is chosen to be cache aligned.
 		 */
-		element_size = 256 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM;
+		data_size = 256 + RTE_PKTMBUF_HEADROOM;
 		snprintf(mem_name, sizeof(mem_name), "%s_MODE6", bond_dev->data->name);
-		internals->mode6.mempool = rte_mempool_create(mem_name,
-				512 * RTE_MAX_ETHPORTS,
-				element_size,
-				RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
-						32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
-				sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init,
-				NULL, rte_pktmbuf_init, NULL, socket_id, 0);
+		internals->mode6.mempool = rte_pktmbuf_pool_create(mem_name,
+			512 * RTE_MAX_ETHPORTS,
+			RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
+				32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
+			0, data_size, socket_id);
 
 		if (internals->mode6.mempool == NULL) {
 			RTE_LOG(ERR, PMD, "%s: Failed to initialize ALB mempool.\n",
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v6 08/13] mbuf: fix clone support when application uses private mbuf data
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
                               ` (6 preceding siblings ...)
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 07/13] apps: use rte_pktmbuf_pool_create to create mbuf pools Olivier Matz
@ 2015-04-22  9:57             ` Olivier Matz
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 09/13] mbuf: allow to clone an indirect mbuf Olivier Matz
                               ` (5 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-22  9:57 UTC (permalink / raw)
  To: dev

Add a new priv_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 <olivier.matz@6wind.com>
Reviewed-by: Zoltan Kiss <zoltan.kiss@linaro.org>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
---
 examples/vhost/main.c      |  4 +--
 lib/librte_mbuf/rte_mbuf.c |  8 ++++--
 lib/librte_mbuf/rte_mbuf.h | 70 +++++++++++++++++++++++++++++++++-------------
 3 files changed, 58 insertions(+), 24 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 22d6a4b..195d82f 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -138,7 +138,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;
@@ -1549,7 +1549,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 26b6f12..f506517 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -119,9 +119,10 @@ rte_pktmbuf_init(struct rte_mempool *mp,
 		 __attribute__((unused)) unsigned i)
 {
 	struct rte_mbuf *m = _m;
-	uint32_t mbuf_size, buf_len;
+	uint32_t mbuf_size, buf_len, priv_size;
 
-	mbuf_size = sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(mp);
+	priv_size = rte_pktmbuf_priv_size(mp);
+	mbuf_size = sizeof(struct rte_mbuf) + priv_size;
 	buf_len = rte_pktmbuf_data_room_size(mp);
 
 	RTE_MBUF_ASSERT(mp->elt_size >= mbuf_size);
@@ -129,7 +130,8 @@ rte_pktmbuf_init(struct rte_mempool *mp,
 
 	memset(m, 0, mp->elt_size);
 
-	/* start of buffer is just after mbuf structure */
+	/* start of buffer is after mbuf structure and priv data */
+	m->priv_size = priv_size;
 	m->buf_addr = (char *)m + mbuf_size;
 	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mbuf_size;
 	m->buf_len = (uint16_t)buf_len;
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 42db8e3..17d39ae 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -318,18 +318,49 @@ 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;
 
+static inline uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp);
+
 /**
- * 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.
+ *
+ * @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) + rte_pktmbuf_priv_size(md->pool);
+	return buffer_addr;
+}
 
 /**
  * Returns TRUE if given mbuf is indirect, or FALSE otherwise.
@@ -771,6 +802,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:
@@ -784,7 +816,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) &&
@@ -795,6 +826,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;
@@ -815,7 +847,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.
@@ -823,22 +856,21 @@ 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_mempool *mp = m->pool;
+	uint32_t mbuf_size, buf_len, priv_size;
 
-	m->buf_addr = buf;
-	m->buf_len = (uint16_t)buf_len;
-
-	m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
-			RTE_PKTMBUF_HEADROOM : m->buf_len;
+	priv_size = rte_pktmbuf_priv_size(mp);
+	mbuf_size = sizeof(struct rte_mbuf) + priv_size;
+	buf_len = rte_pktmbuf_data_room_size(mp);
 
+	m->priv_size = priv_size;
+	m->buf_addr = (char *)m + mbuf_size;
+	m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mbuf_size;
+	m->buf_len = (uint16_t)buf_len;
+	m->data_off = RTE_MIN(RTE_PKTMBUF_HEADROOM, (uint16_t)m->buf_len);
 	m->data_len = 0;
-
 	m->ol_flags = 0;
 }
 
@@ -867,7 +899,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);
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v6 09/13] mbuf: allow to clone an indirect mbuf
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
                               ` (7 preceding siblings ...)
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 08/13] mbuf: fix clone support when application uses private mbuf data Olivier Matz
@ 2015-04-22  9:57             ` Olivier Matz
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 10/13] test/mbuf: rename mc variable in m Olivier Matz
                               ` (4 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-22  9:57 UTC (permalink / raw)
  To: dev

Remove one limitation of rte_pktmbuf_attach(): "mbuf we're attaching to
must be direct".

Now, when we attach to an indirect mbuf:
- copy the all relevant fields (addr, len, offload, ...) as before
- get the pointer to the mbuf that embeds the data buffer (direct mbuf),
  and increase the reference counter of this one.

When detaching the mbuf, we can retrieve this direct mbuf as the pointer
is determined from the buffer address.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
---
 lib/librte_mbuf/rte_mbuf.h | 48 ++++++++++++++++++++++++++--------------------
 1 file changed, 27 insertions(+), 21 deletions(-)

diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 17d39ae..70b0987 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -806,44 +806,50 @@ static inline struct rte_mbuf *rte_pktmbuf_alloc(struct rte_mempool *mp)
  * After attachment we refer the mbuf we attached as 'indirect',
  * while mbuf we attached to as 'direct'.
  * Right now, not supported:
- *  - attachment to indirect mbuf (e.g. - md  has to be direct).
  *  - attachment for already indirect mbuf (e.g. - mi has to be direct).
  *  - mbuf we trying to attach (mi) is used by someone else
  *    e.g. it's reference counter is greater then 1.
  *
  * @param mi
  *   The indirect packet mbuf.
- * @param md
- *   The direct packet mbuf.
+ * @param m
+ *   The packet mbuf we're attaching to.
  */
-static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md)
+static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
 {
-	RTE_MBUF_ASSERT(RTE_MBUF_DIRECT(md) &&
-	    RTE_MBUF_DIRECT(mi) &&
+	struct rte_mbuf *md;
+
+	RTE_MBUF_ASSERT(RTE_MBUF_DIRECT(mi) &&
 	    rte_mbuf_refcnt_read(mi) == 1);
 
+	/* if m is not direct, get the mbuf that embeds the data */
+	if (RTE_MBUF_DIRECT(m))
+		md = m;
+	else
+		md = rte_mbuf_from_indirect(m);
+
 	rte_mbuf_refcnt_update(md, 1);
-	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;
-	mi->data_len = md->data_len;
-	mi->port = md->port;
-	mi->vlan_tci = md->vlan_tci;
-	mi->tx_offload = md->tx_offload;
-	mi->hash = md->hash;
+	mi->priv_size = m->priv_size;
+	mi->buf_physaddr = m->buf_physaddr;
+	mi->buf_addr = m->buf_addr;
+	mi->buf_len = m->buf_len;
+
+	mi->next = m->next;
+	mi->data_off = m->data_off;
+	mi->data_len = m->data_len;
+	mi->port = m->port;
+	mi->vlan_tci = m->vlan_tci;
+	mi->tx_offload = m->tx_offload;
+	mi->hash = m->hash;
 
 	mi->next = NULL;
 	mi->pkt_len = mi->data_len;
 	mi->nb_segs = 1;
-	mi->ol_flags = md->ol_flags | IND_ATTACHED_MBUF;
-	mi->packet_type = md->packet_type;
+	mi->ol_flags = m->ol_flags | IND_ATTACHED_MBUF;
+	mi->packet_type = m->packet_type;
 
 	__rte_mbuf_sanity_check(mi, 1);
-	__rte_mbuf_sanity_check(md, 0);
+	__rte_mbuf_sanity_check(m, 0);
 }
 
 /**
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v6 10/13] test/mbuf: rename mc variable in m
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
                               ` (8 preceding siblings ...)
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 09/13] mbuf: allow to clone an indirect mbuf Olivier Matz
@ 2015-04-22  9:57             ` Olivier Matz
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 11/13] test/mbuf: enhance mbuf refcnt test Olivier Matz
                               ` (3 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-22  9:57 UTC (permalink / raw)
  To: dev

It's better to name the mbuf 'm' instead of 'mc' as it's not a clone.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
---
 app/test/test_mbuf.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 4774263..2614598 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -320,43 +320,42 @@ fail:
 static int
 testclone_testupdate_testdetach(void)
 {
-	struct rte_mbuf *mc = NULL;
+	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
 
 	/* alloc a mbuf */
-
-	mc = rte_pktmbuf_alloc(pktmbuf_pool);
-	if (mc == NULL)
+	m = rte_pktmbuf_alloc(pktmbuf_pool);
+	if (m == NULL)
 		GOTO_FAIL("ooops not allocating mbuf");
 
-	if (rte_pktmbuf_pkt_len(mc) != 0)
+	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("Bad length");
 
 
 	/* clone the allocated mbuf */
-	clone = rte_pktmbuf_clone(mc, pktmbuf_pool);
+	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 	rte_pktmbuf_free(clone);
 
-	mc->next = rte_pktmbuf_alloc(pktmbuf_pool);
-	if(mc->next == NULL)
+	m->next = rte_pktmbuf_alloc(pktmbuf_pool);
+	if (m->next == NULL)
 		GOTO_FAIL("Next Pkt Null\n");
 
-	clone = rte_pktmbuf_clone(mc, pktmbuf_pool);
+	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 
 	/* free mbuf */
-	rte_pktmbuf_free(mc);
+	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
-	mc = NULL;
+	m = NULL;
 	clone = NULL;
 	return 0;
 
 fail:
-	if (mc)
-		rte_pktmbuf_free(mc);
+	if (m)
+		rte_pktmbuf_free(m);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v6 11/13] test/mbuf: enhance mbuf refcnt test
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
                               ` (9 preceding siblings ...)
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 10/13] test/mbuf: rename mc variable in m Olivier Matz
@ 2015-04-22  9:57             ` Olivier Matz
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 12/13] test/mbuf: verify that cloning a clone works properly Olivier Matz
                               ` (2 subsequent siblings)
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-22  9:57 UTC (permalink / raw)
  To: dev

Check that the data in the cloned mbuf is the same than in the
reference mbuf.
Check that the reference counter is incremented for each segment.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
---
 app/test/test_mbuf.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 2614598..a16ec53 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -75,6 +75,8 @@
 #define REFCNT_MBUF_NUM         64
 #define REFCNT_RING_SIZE        (REFCNT_MBUF_NUM * REFCNT_MAX_REF)
 
+#define MAGIC_DATA              0x42424242
+
 #define MAKE_STRING(x)          # x
 
 static struct rte_mempool *pktmbuf_pool = NULL;
@@ -122,6 +124,8 @@ static unsigned refcnt_lcore[RTE_MAX_LCORE];
  *    - Repeat the test to check that allocation operations
  *      reinitialize the mbuf correctly.
  *
+ * #. Test packet cloning
+ *    - Clone a mbuf and verify the data
  */
 
 #define GOTO_FAIL(str, ...) do {					\
@@ -322,6 +326,7 @@ testclone_testupdate_testdetach(void)
 {
 	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
+	uint32_t *data;
 
 	/* alloc a mbuf */
 	m = rte_pktmbuf_alloc(pktmbuf_pool);
@@ -331,21 +336,53 @@ testclone_testupdate_testdetach(void)
 	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("Bad length");
 
+	rte_pktmbuf_append(m, sizeof(uint32_t));
+	data = rte_pktmbuf_mtod(m, uint32_t *);
+	*data = MAGIC_DATA;
 
 	/* clone the allocated mbuf */
 	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
+
+	data = rte_pktmbuf_mtod(clone, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone\n");
+
+	if (rte_mbuf_refcnt_read(m) != 2)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	/* free the clone */
 	rte_pktmbuf_free(clone);
+	clone = NULL;
 
+	/* same test with a chained mbuf */
 	m->next = rte_pktmbuf_alloc(pktmbuf_pool);
 	if (m->next == NULL)
 		GOTO_FAIL("Next Pkt Null\n");
 
+	rte_pktmbuf_append(m->next, sizeof(uint32_t));
+	data = rte_pktmbuf_mtod(m->next, uint32_t *);
+	*data = MAGIC_DATA;
+
 	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
 	if (clone == NULL)
 		GOTO_FAIL("cannot clone data\n");
 
+	data = rte_pktmbuf_mtod(clone, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone\n");
+
+	data = rte_pktmbuf_mtod(clone->next, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone->next\n");
+
+	if (rte_mbuf_refcnt_read(m) != 2)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	if (rte_mbuf_refcnt_read(m->next) != 2)
+		GOTO_FAIL("invalid refcnt in m->next\n");
+
 	/* free mbuf */
 	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
@@ -356,6 +393,8 @@ testclone_testupdate_testdetach(void)
 fail:
 	if (m)
 		rte_pktmbuf_free(m);
+	if (clone)
+		rte_pktmbuf_free(clone);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v6 12/13] test/mbuf: verify that cloning a clone works properly
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
                               ` (10 preceding siblings ...)
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 11/13] test/mbuf: enhance mbuf refcnt test Olivier Matz
@ 2015-04-22  9:57             ` Olivier Matz
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 13/13] test/mbuf: add a test case for clone with different priv size Olivier Matz
  2015-04-22 11:59             ` [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones Ananyev, Konstantin
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-22  9:57 UTC (permalink / raw)
  To: dev

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
---
 app/test/test_mbuf.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index a16ec53..68564ee 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -126,6 +126,7 @@ static unsigned refcnt_lcore[RTE_MAX_LCORE];
  *
  * #. Test packet cloning
  *    - Clone a mbuf and verify the data
+ *    - Clone the cloned mbuf and verify the data
  */
 
 #define GOTO_FAIL(str, ...) do {					\
@@ -326,6 +327,7 @@ testclone_testupdate_testdetach(void)
 {
 	struct rte_mbuf *m = NULL;
 	struct rte_mbuf *clone = NULL;
+	struct rte_mbuf *clone2 = NULL;
 	uint32_t *data;
 
 	/* alloc a mbuf */
@@ -383,11 +385,35 @@ testclone_testupdate_testdetach(void)
 	if (rte_mbuf_refcnt_read(m->next) != 2)
 		GOTO_FAIL("invalid refcnt in m->next\n");
 
+	/* try to clone the clone */
+
+	clone2 = rte_pktmbuf_clone(clone, pktmbuf_pool);
+	if (clone2 == NULL)
+		GOTO_FAIL("cannot clone the clone\n");
+
+	data = rte_pktmbuf_mtod(clone2, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone2\n");
+
+	data = rte_pktmbuf_mtod(clone2->next, uint32_t *);
+	if (*data != MAGIC_DATA)
+		GOTO_FAIL("invalid data in clone2->next\n");
+
+	if (rte_mbuf_refcnt_read(m) != 3)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	if (rte_mbuf_refcnt_read(m->next) != 3)
+		GOTO_FAIL("invalid refcnt in m->next\n");
+
 	/* free mbuf */
 	rte_pktmbuf_free(m);
 	rte_pktmbuf_free(clone);
+	rte_pktmbuf_free(clone2);
+
 	m = NULL;
 	clone = NULL;
+	clone2 = NULL;
+	printf("%s ok\n", __func__);
 	return 0;
 
 fail:
@@ -395,6 +421,8 @@ fail:
 		rte_pktmbuf_free(m);
 	if (clone)
 		rte_pktmbuf_free(clone);
+	if (clone2)
+		rte_pktmbuf_free(clone2);
 	return -1;
 }
 #undef GOTO_FAIL
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [dpdk-dev] [PATCH v6 13/13] test/mbuf: add a test case for clone with different priv size
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
                               ` (11 preceding siblings ...)
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 12/13] test/mbuf: verify that cloning a clone works properly Olivier Matz
@ 2015-04-22  9:57             ` Olivier Matz
  2015-04-22 11:59             ` [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones Ananyev, Konstantin
  13 siblings, 0 replies; 101+ messages in thread
From: Olivier Matz @ 2015-04-22  9:57 UTC (permalink / raw)
  To: dev

Verify that we can attach a mbuf to another one that does not have
the same data room size and priv_size.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_mbuf.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 123 insertions(+), 1 deletion(-)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index 68564ee..5e8a377 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -69,6 +69,9 @@
 #define MBUF_TEST_HDR2_LEN      30
 #define MBUF_TEST_ALL_HDRS_LEN  (MBUF_TEST_HDR1_LEN+MBUF_TEST_HDR2_LEN)
 
+/* size of private data for mbuf in pktmbuf_pool2 */
+#define MBUF2_PRIV_SIZE         128
+
 #define REFCNT_MAX_ITER         64
 #define REFCNT_MAX_TIMEOUT      10
 #define REFCNT_MAX_REF          (RTE_MAX_LCORE)
@@ -80,6 +83,7 @@
 #define MAKE_STRING(x)          # x
 
 static struct rte_mempool *pktmbuf_pool = NULL;
+static struct rte_mempool *pktmbuf_pool2 = NULL;
 
 #ifdef RTE_MBUF_REFCNT_ATOMIC
 
@@ -127,6 +131,7 @@ static unsigned refcnt_lcore[RTE_MAX_LCORE];
  * #. Test packet cloning
  *    - Clone a mbuf and verify the data
  *    - Clone the cloned mbuf and verify the data
+ *    - Attach a mbuf to another that does not have the same priv_size.
  */
 
 #define GOTO_FAIL(str, ...) do {					\
@@ -425,9 +430,109 @@ fail:
 		rte_pktmbuf_free(clone2);
 	return -1;
 }
-#undef GOTO_FAIL
 
+static int
+test_attach_from_different_pool(void)
+{
+	struct rte_mbuf *m = NULL;
+	struct rte_mbuf *clone = NULL;
+	struct rte_mbuf *clone2 = NULL;
+	char *data, *c_data, *c_data2;
+
+	/* alloc a mbuf */
+	m = rte_pktmbuf_alloc(pktmbuf_pool);
+	if (m == NULL)
+		GOTO_FAIL("cannot allocate mbuf");
+
+	if (rte_pktmbuf_pkt_len(m) != 0)
+		GOTO_FAIL("Bad length");
+
+	data = rte_pktmbuf_mtod(m, char *);
+
+	/* allocate a new mbuf from the second pool, and attach it to the first
+	 * mbuf */
+	clone = rte_pktmbuf_alloc(pktmbuf_pool2);
+	if (clone == NULL)
+		GOTO_FAIL("cannot allocate mbuf from second pool\n");
+
+	/* check data room size and priv size, and erase priv */
+	if (rte_pktmbuf_data_room_size(clone->pool) != 0)
+		GOTO_FAIL("data room size should be 0\n");
+	if (rte_pktmbuf_priv_size(clone->pool) != MBUF2_PRIV_SIZE)
+		GOTO_FAIL("data room size should be %d\n", MBUF2_PRIV_SIZE);
+	memset(clone + 1, 0, MBUF2_PRIV_SIZE);
+
+	/* save data pointer to compare it after detach() */
+	c_data = rte_pktmbuf_mtod(clone, char *);
+	if (c_data != (char *)clone + sizeof(*clone) + MBUF2_PRIV_SIZE)
+		GOTO_FAIL("bad data pointer in clone");
+	if (rte_pktmbuf_headroom(clone) != 0)
+		GOTO_FAIL("bad headroom in clone");
+
+	rte_pktmbuf_attach(clone, m);
+
+	if (rte_pktmbuf_mtod(clone, char *) != data)
+		GOTO_FAIL("clone was not attached properly\n");
+	if (rte_pktmbuf_headroom(clone) != RTE_PKTMBUF_HEADROOM)
+		GOTO_FAIL("bad headroom in clone after attach");
+	if (rte_mbuf_refcnt_read(m) != 2)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	/* allocate a new mbuf from the second pool, and attach it to the first
+	 * cloned mbuf */
+	clone2 = rte_pktmbuf_alloc(pktmbuf_pool2);
+	if (clone2 == NULL)
+		GOTO_FAIL("cannot allocate clone2 from second pool\n");
+
+	/* check data room size and priv size, and erase priv */
+	if (rte_pktmbuf_data_room_size(clone2->pool) != 0)
+		GOTO_FAIL("data room size should be 0\n");
+	if (rte_pktmbuf_priv_size(clone2->pool) != MBUF2_PRIV_SIZE)
+		GOTO_FAIL("data room size should be %d\n", MBUF2_PRIV_SIZE);
+	memset(clone2 + 1, 0, MBUF2_PRIV_SIZE);
+
+	/* save data pointer to compare it after detach() */
+	c_data2 = rte_pktmbuf_mtod(clone2, char *);
+	if (c_data2 != (char *)clone2 + sizeof(*clone2) + MBUF2_PRIV_SIZE)
+		GOTO_FAIL("bad data pointer in clone2");
+	if (rte_pktmbuf_headroom(clone2) != 0)
+		GOTO_FAIL("bad headroom in clone2");
+
+	rte_pktmbuf_attach(clone2, clone);
+
+	if (rte_pktmbuf_mtod(clone2, char *) != data)
+		GOTO_FAIL("clone2 was not attached properly\n");
+	if (rte_pktmbuf_headroom(clone2) != RTE_PKTMBUF_HEADROOM)
+		GOTO_FAIL("bad headroom in clone2 after attach");
+	if (rte_mbuf_refcnt_read(m) != 3)
+		GOTO_FAIL("invalid refcnt in m\n");
+
+	/* detach the clones */
+	rte_pktmbuf_detach(clone);
+	if (c_data != rte_pktmbuf_mtod(clone, char *))
+		GOTO_FAIL("clone was not detached properly\n");
+
+	rte_pktmbuf_detach(clone2);
+	if (c_data2 != rte_pktmbuf_mtod(clone2, char *))
+		GOTO_FAIL("clone2 was not detached properly\n");
 
+	/* free the clones and the initial mbuf */
+	rte_pktmbuf_free(clone2);
+	rte_pktmbuf_free(clone);
+	rte_pktmbuf_free(m);
+	printf("%s ok\n", __func__);
+	return 0;
+
+fail:
+	if (m)
+		rte_pktmbuf_free(m);
+	if (clone)
+		rte_pktmbuf_free(clone);
+	if (clone2)
+		rte_pktmbuf_free(clone2);
+	return -1;
+}
+#undef GOTO_FAIL
 
 /*
  * test allocation and free of mbufs
@@ -836,6 +941,18 @@ test_mbuf(void)
 		return -1;
 	}
 
+	/* create a specific pktmbuf pool with a priv_size != 0 and no data
+	 * room size */
+	if (pktmbuf_pool2 == NULL) {
+		pktmbuf_pool2 = rte_pktmbuf_pool_create("test_pktmbuf_pool2",
+			NB_MBUF, 32, MBUF2_PRIV_SIZE, 0, SOCKET_ID_ANY);
+	}
+
+	if (pktmbuf_pool2 == NULL) {
+		printf("cannot allocate mbuf pool\n");
+		return -1;
+	}
+
 	/* test multiple mbuf alloc */
 	if (test_pktmbuf_pool() < 0) {
 		printf("test_mbuf_pool() failed\n");
@@ -886,6 +1003,11 @@ test_mbuf(void)
 		return -1;
 	}
 
+	if (test_attach_from_different_pool() < 0) {
+		printf("test_attach_from_different_pool() failed\n");
+		return -1;
+	}
+
 	if (test_refcnt_mbuf()<0){
 		printf("test_refcnt_mbuf() failed \n");
 		return -1;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones
  2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
                               ` (12 preceding siblings ...)
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 13/13] test/mbuf: add a test case for clone with different priv size Olivier Matz
@ 2015-04-22 11:59             ` Ananyev, Konstantin
  2015-04-24 10:38               ` Zoltan Kiss
  2015-04-28  9:50               ` Thomas Monjalon
  13 siblings, 2 replies; 101+ messages in thread
From: Ananyev, Konstantin @ 2015-04-22 11:59 UTC (permalink / raw)
  To: Olivier Matz, dev



> -----Original Message-----
> From: Olivier Matz [mailto:olivier.matz@6wind.com]
> Sent: Wednesday, April 22, 2015 10:57 AM
> To: dev@dpdk.org
> Cc: Ananyev, Konstantin; zoltan.kiss@linaro.org; Richardson, Bruce; nhorman@tuxdriver.com; olivier.matz@6wind.com
> Subject: [PATCH v6 00/13] mbuf: enhancements of mbuf clones
> 
> The first objective of this series is to fix the support of indirect
> mbufs when the application reserves a private area in mbufs. It also
> removes the limitation that rte_pktmbuf_clone() is only allowed on
> direct (non-cloned) mbufs. The series also contains some enhancements
> and fixes in the mbuf area that makes the implementation of the
> last patches easier.
> 
> Changes in v6:
> - restore the priv_size in mbuf structure, version 4 broke the
>   attachment between mbufs having different private size
> - add a test case to ensure it won't be broken again
> - replace 0xffff by UINT16_MAX
> - fix some minor checkpatch issues
> 
> Changes in v5:
> - update rte_mbuf_version.map to fix compilation with shared libraries
> 
> Changes in v4:
> - do not add a priv_size in mbuf structure, having a proper accessor
>   to read it from the pool private area is clearer
> - prepend some reworks in the mbuf area to simplify the implementation
>   (fix mbuf initialization by not using a hardcoded mbuf size, add
>   accessors for mbuf pool private area, add a helper to create a
>   mbuf pool)
> 
> Changes in v3:
> - a mbuf can now attach to another one that have a different private
>   size. In this case, the m->priv_size corresponds to the size of the
>   private area of the direct mbuf.
> - add comments to reflect these changes
> - minor style modifications
> 
> Changes in v2:
> - do not change the use of MBUF_EXT_MEM() in vhost
> - change rte_mbuf_from_baddr() to rte_mbuf_from_indirect(), removing
>   one parameter
> - fix and rework rte_pktmbuf_detach()
> - move m->priv_size in second mbuf cache line
> - fix mbuf free in test error case
> 
> Olivier Matz (13):
>   mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
>   examples: always initialize mbuf_pool private area
>   mbuf: add accessors to get data room size and private size
>   mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
>   testpmd: use standard functions to initialize mbufs and mbuf pool
>   mbuf: introduce a new helper to create a mbuf pool
>   apps: use rte_pktmbuf_pool_create to create mbuf pools
>   mbuf: fix clone support when application uses private mbuf data
>   mbuf: allow to clone an indirect mbuf
>   test/mbuf: rename mc variable in m
>   test/mbuf: enhance mbuf refcnt test
>   test/mbuf: verify that cloning a clone works properly
>   test/mbuf: add a test case for clone with different priv size
> 
>  app/test-pipeline/init.c                           |  15 +-
>  app/test-pmd/testpmd.c                             |  84 +-------
>  app/test/test_distributor.c                        |  10 +-
>  app/test/test_distributor_perf.c                   |  10 +-
>  app/test/test_kni.c                                |  16 +-
>  app/test/test_link_bonding.c                       |  10 +-
>  app/test/test_link_bonding_mode4.c                 |  12 +-
>  app/test/test_mbuf.c                               | 238 ++++++++++++++++++---
>  app/test/test_pmd_perf.c                           |  11 +-
>  app/test/test_pmd_ring.c                           |  10 +-
>  app/test/test_reorder.c                            |  10 +-
>  app/test/test_sched.c                              |  16 +-
>  app/test/test_table.c                              |   9 +-
>  app/test/test_table.h                              |   3 +-
>  doc/guides/rel_notes/updating_apps.rst             |  16 ++
>  examples/bond/main.c                               |  10 +-
>  examples/distributor/main.c                        |  11 +-
>  examples/dpdk_qat/main.c                           |  10 +-
>  examples/exception_path/main.c                     |  14 +-
>  examples/ip_fragmentation/main.c                   |  18 +-
>  examples/ip_pipeline/init.c                        |  28 +--
>  examples/ipv4_multicast/main.c                     |  21 +-
>  examples/kni/main.c                                |  12 +-
>  examples/l2fwd-ivshmem/host/host.c                 |  10 +-
>  examples/l2fwd-jobstats/main.c                     |  10 +-
>  examples/l2fwd/main.c                              |  11 +-
>  examples/l3fwd-acl/main.c                          |  11 +-
>  examples/l3fwd-power/main.c                        |  11 +-
>  examples/l3fwd-vf/main.c                           |  12 +-
>  examples/l3fwd/main.c                              |  10 +-
>  examples/link_status_interrupt/main.c              |  10 +-
>  examples/load_balancer/init.c                      |  12 +-
>  examples/load_balancer/main.h                      |   4 +-
>  .../client_server_mp/mp_server/init.c              |  10 +-
>  examples/multi_process/symmetric_mp/main.c         |  10 +-
>  examples/netmap_compat/bridge/bridge.c             |  12 +-
>  examples/packet_ordering/main.c                    |  11 +-
>  examples/qos_meter/main.c                          |   7 +-
>  examples/qos_sched/init.c                          |  10 +-
>  examples/qos_sched/main.h                          |   2 +-
>  examples/quota_watermark/include/conf.h            |   2 +-
>  examples/quota_watermark/qw/main.c                 |   7 +-
>  examples/rxtx_callbacks/main.c                     |  11 +-
>  examples/skeleton/basicfwd.c                       |  13 +-
>  examples/vhost/main.c                              |  31 +--
>  examples/vhost_xen/main.c                          |  11 +-
>  examples/vmdq/main.c                               |  11 +-
>  examples/vmdq_dcb/main.c                           |  10 +-
>  lib/librte_ether/rte_ethdev.c                      |   4 +-
>  lib/librte_mbuf/rte_mbuf.c                         |  65 ++++--
>  lib/librte_mbuf/rte_mbuf.h                         | 200 +++++++++++++----
>  lib/librte_mbuf/rte_mbuf_version.map               |   8 +
>  lib/librte_pmd_af_packet/rte_eth_af_packet.c       |   6 +-
>  lib/librte_pmd_bond/rte_eth_bond_alb.c             |  16 +-
>  lib/librte_pmd_e1000/em_rxtx.c                     |   5 +-
>  lib/librte_pmd_e1000/igb_rxtx.c                    |  12 +-
>  lib/librte_pmd_fm10k/fm10k_ethdev.c                |   6 +-
>  lib/librte_pmd_i40e/i40e_ethdev_vf.c               |   6 +-
>  lib/librte_pmd_i40e/i40e_rxtx.c                    |  15 +-
>  lib/librte_pmd_ixgbe/ixgbe_rxtx.c                  |  12 +-
>  lib/librte_pmd_pcap/rte_eth_pcap.c                 |   5 +-
>  lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c              |   7 +-
>  62 files changed, 650 insertions(+), 570 deletions(-)
> 

Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

> --
> 2.1.4

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones
  2015-04-22 11:59             ` [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones Ananyev, Konstantin
@ 2015-04-24 10:38               ` Zoltan Kiss
  2015-04-27 17:38                 ` Thomas Monjalon
  2015-05-07  1:57                 ` Xu, HuilongX
  2015-04-28  9:50               ` Thomas Monjalon
  1 sibling, 2 replies; 101+ messages in thread
From: Zoltan Kiss @ 2015-04-24 10:38 UTC (permalink / raw)
  To: Ananyev, Konstantin, Olivier Matz, dev

Hi,

On 22/04/15 12:59, Ananyev, Konstantin wrote:
>
>
>> -----Original Message-----
>> From: Olivier Matz [mailto:olivier.matz@6wind.com]
>> Sent: Wednesday, April 22, 2015 10:57 AM
>> To: dev@dpdk.org
>> Cc: Ananyev, Konstantin; zoltan.kiss@linaro.org; Richardson, Bruce; nhorman@tuxdriver.com; olivier.matz@6wind.com
>> Subject: [PATCH v6 00/13] mbuf: enhancements of mbuf clones
>>
>> The first objective of this series is to fix the support of indirect
>> mbufs when the application reserves a private area in mbufs. It also
>> removes the limitation that rte_pktmbuf_clone() is only allowed on
>> direct (non-cloned) mbufs. The series also contains some enhancements
>> and fixes in the mbuf area that makes the implementation of the
>> last patches easier.
>>
>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

When does this series get merged?

Regards,

Zoltan

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones
  2015-04-24 10:38               ` Zoltan Kiss
@ 2015-04-27 17:38                 ` Thomas Monjalon
  2015-04-28 11:15                   ` Zoltan Kiss
  2015-05-07  1:57                 ` Xu, HuilongX
  1 sibling, 1 reply; 101+ messages in thread
From: Thomas Monjalon @ 2015-04-27 17:38 UTC (permalink / raw)
  To: Zoltan Kiss; +Cc: dev

2015-04-24 11:38, Zoltan Kiss:
> On 22/04/15 12:59, Ananyev, Konstantin wrote:
> > From: Olivier Matz [mailto:olivier.matz@6wind.com]
> > Sent: Wednesday, April 22, 2015 10:57 AM
> >> The first objective of this series is to fix the support of indirect
> >> mbufs when the application reserves a private area in mbufs. It also
> >> removes the limitation that rte_pktmbuf_clone() is only allowed on
> >> direct (non-cloned) mbufs. The series also contains some enhancements
> >> and fixes in the mbuf area that makes the implementation of the
> >> last patches easier.
> >
> > Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> 
> When does this series get merged?

It was acked on April 22  and your question was 2 days later on April 24.
Does it mean you are expecting it to be merged the day it is acked?
Or do you fear the merging because of a local dev you are working on?
Anyway, everybody seems happy with this version so it's going to be merged.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v6 03/13] mbuf: add accessors to get data room size and private size
  2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 03/13] mbuf: add accessors to get data room size and private size Olivier Matz
@ 2015-04-28  9:15               ` Thomas Monjalon
  0 siblings, 0 replies; 101+ messages in thread
From: Thomas Monjalon @ 2015-04-28  9:15 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2015-04-22 11:57, Olivier Matz:
> This code retrieving the pool private area is duplicated in many
> places, we can use of function for it.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> Acked-by: Neil Horman <nhorman@tuxdriver.com>
[...]
> --- a/lib/librte_pmd_pcap/rte_eth_pcap.c
> +++ b/lib/librte_pmd_pcap/rte_eth_pcap.c
> @@ -136,9 +136,7 @@ eth_pcap_rx(void *queue,
>  	const u_char *packet;
>  	struct rte_mbuf *mbuf;
>  	struct pcap_rx_queue *pcap_q = queue;
> -	struct rte_pktmbuf_pool_private *mbp_priv;
>  	uint16_t num_rx = 0;
> -	uint16_t buf_size;
>  
>  	if (unlikely(pcap_q->pcap == NULL || nb_pkts == 0))
>  		return 0;
> @@ -157,8 +155,7 @@ eth_pcap_rx(void *queue,
>  			break;
>  
>  		/* Now get the space available for data in the mbuf */
> -		mbp_priv =  rte_mempool_get_priv(pcap_q->mb_pool);
> -		buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
> +		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(pcap_q->mb_pool) -
>  				RTE_PKTMBUF_HEADROOM);
>  
>  		if (header.len <= buf_size) {

It doesn't compile because buf_size is removed by error:
lib/librte_pmd_pcap/rte_eth_pcap.c: In function ‘eth_pcap_rx’:
lib/librte_pmd_pcap/rte_eth_pcap.c:158:3: error: ‘buf_size’ undeclared (first use in this function)

I fix it while applying patches.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones
  2015-04-22 11:59             ` [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones Ananyev, Konstantin
  2015-04-24 10:38               ` Zoltan Kiss
@ 2015-04-28  9:50               ` Thomas Monjalon
  1 sibling, 0 replies; 101+ messages in thread
From: Thomas Monjalon @ 2015-04-28  9:50 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

> > The first objective of this series is to fix the support of indirect
> > mbufs when the application reserves a private area in mbufs. It also
> > removes the limitation that rte_pktmbuf_clone() is only allowed on
> > direct (non-cloned) mbufs. The series also contains some enhancements
> > and fixes in the mbuf area that makes the implementation of the
> > last patches easier.
> > 
> > Changes in v6:
> > - restore the priv_size in mbuf structure, version 4 broke the
> >   attachment between mbufs having different private size
> > - add a test case to ensure it won't be broken again
> > - replace 0xffff by UINT16_MAX
> > - fix some minor checkpatch issues
> > 
> > Changes in v5:
> > - update rte_mbuf_version.map to fix compilation with shared libraries
> > 
> > Changes in v4:
> > - do not add a priv_size in mbuf structure, having a proper accessor
> >   to read it from the pool private area is clearer
> > - prepend some reworks in the mbuf area to simplify the implementation
> >   (fix mbuf initialization by not using a hardcoded mbuf size, add
> >   accessors for mbuf pool private area, add a helper to create a
> >   mbuf pool)
> > 
> > Changes in v3:
> > - a mbuf can now attach to another one that have a different private
> >   size. In this case, the m->priv_size corresponds to the size of the
> >   private area of the direct mbuf.
> > - add comments to reflect these changes
> > - minor style modifications
> > 
> > Changes in v2:
> > - do not change the use of MBUF_EXT_MEM() in vhost
> > - change rte_mbuf_from_baddr() to rte_mbuf_from_indirect(), removing
> >   one parameter
> > - fix and rework rte_pktmbuf_detach()
> > - move m->priv_size in second mbuf cache line
> > - fix mbuf free in test error case
> > 
> > Olivier Matz (13):
> >   mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init
> >   examples: always initialize mbuf_pool private area
> >   mbuf: add accessors to get data room size and private size
> >   mbuf: fix rte_pktmbuf_init when mbuf private size is not zero
> >   testpmd: use standard functions to initialize mbufs and mbuf pool
> >   mbuf: introduce a new helper to create a mbuf pool
> >   apps: use rte_pktmbuf_pool_create to create mbuf pools
> >   mbuf: fix clone support when application uses private mbuf data
> >   mbuf: allow to clone an indirect mbuf
> >   test/mbuf: rename mc variable in m
> >   test/mbuf: enhance mbuf refcnt test
> >   test/mbuf: verify that cloning a clone works properly
> >   test/mbuf: add a test case for clone with different priv size
> 
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

Applied, thanks

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones
  2015-04-27 17:38                 ` Thomas Monjalon
@ 2015-04-28 11:15                   ` Zoltan Kiss
  0 siblings, 0 replies; 101+ messages in thread
From: Zoltan Kiss @ 2015-04-28 11:15 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev



On 27/04/15 18:38, Thomas Monjalon wrote:
> 2015-04-24 11:38, Zoltan Kiss:
>> On 22/04/15 12:59, Ananyev, Konstantin wrote:
>>> From: Olivier Matz [mailto:olivier.matz@6wind.com]
>>> Sent: Wednesday, April 22, 2015 10:57 AM
>>>> The first objective of this series is to fix the support of indirect
>>>> mbufs when the application reserves a private area in mbufs. It also
>>>> removes the limitation that rte_pktmbuf_clone() is only allowed on
>>>> direct (non-cloned) mbufs. The series also contains some enhancements
>>>> and fixes in the mbuf area that makes the implementation of the
>>>> last patches easier.
>>>
>>> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
>>
>> When does this series get merged?
>
> It was acked on April 22  and your question was 2 days later on April 24.
> Does it mean you are expecting it to be merged the day it is acked?

I was just curious about when to expect it, so I can plan to do some 
further work based on it, but nothing pressing.

Regards,

Zoltan

> Or do you fear the merging because of a local dev you are working on?
> Anyway, everybody seems happy with this version so it's going to be merged.
>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones
  2015-04-24 10:38               ` Zoltan Kiss
  2015-04-27 17:38                 ` Thomas Monjalon
@ 2015-05-07  1:57                 ` Xu, HuilongX
  2015-05-07  7:32                   ` Olivier MATZ
  1 sibling, 1 reply; 101+ messages in thread
From: Xu, HuilongX @ 2015-05-07  1:57 UTC (permalink / raw)
  To: Zoltan Kiss, Ananyev, Konstantin, Olivier Matz, dev

Hi Olivier,
Today I find a compile error, when I test ip fragment on dpdk.org. would you check this?  thanks a lot.
My dpdk.org commit: a6d71fa7146cc04320c2485d6dde44c1d888d652
The compile error as below:
CC main.o
/root/dpdk/examples/ip_fragmentation/main.c: In function 'init_mem':
/root/dpdk/examples/ip_fragmentation/main.c:748:8: error: 'MBUF_DATA_SIZE' undeclared (first use in this function)
     0, MBUF_DATA_SIZE, socket);
        ^
/root/dpdk/examples/ip_fragmentation/main.c:748:8: note: each undeclared identifier is reported only once for each function it appears in


Best regards

huilong

-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Zoltan Kiss
Sent: Friday, April 24, 2015 6:39 PM
To: Ananyev, Konstantin; Olivier Matz; dev@dpdk.org
Subject: Re: [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones

Hi,

On 22/04/15 12:59, Ananyev, Konstantin wrote:
>
>
>> -----Original Message-----
>> From: Olivier Matz [mailto:olivier.matz@6wind.com]
>> Sent: Wednesday, April 22, 2015 10:57 AM
>> To: dev@dpdk.org
>> Cc: Ananyev, Konstantin; zoltan.kiss@linaro.org; Richardson, Bruce; nhorman@tuxdriver.com; olivier.matz@6wind.com
>> Subject: [PATCH v6 00/13] mbuf: enhancements of mbuf clones
>>
>> The first objective of this series is to fix the support of indirect
>> mbufs when the application reserves a private area in mbufs. It also
>> removes the limitation that rte_pktmbuf_clone() is only allowed on
>> direct (non-cloned) mbufs. The series also contains some enhancements
>> and fixes in the mbuf area that makes the implementation of the
>> last patches easier.
>>
>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

When does this series get merged?

Regards,

Zoltan

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones
  2015-05-07  1:57                 ` Xu, HuilongX
@ 2015-05-07  7:32                   ` Olivier MATZ
  2015-05-07  9:39                     ` Ananyev, Konstantin
  0 siblings, 1 reply; 101+ messages in thread
From: Olivier MATZ @ 2015-05-07  7:32 UTC (permalink / raw)
  To: Xu, HuilongX, Zoltan Kiss, Ananyev, Konstantin, dev

Hi Huilong,

On 05/07/2015 03:57 AM, Xu, HuilongX wrote:
> Hi Olivier,
> Today I find a compile error, when I test ip fragment on dpdk.org. would you check this?  thanks a lot.
> My dpdk.org commit: a6d71fa7146cc04320c2485d6dde44c1d888d652
> The compile error as below:
> CC main.o
> /root/dpdk/examples/ip_fragmentation/main.c: In function 'init_mem':
> /root/dpdk/examples/ip_fragmentation/main.c:748:8: error: 'MBUF_DATA_SIZE' undeclared (first use in this function)
>       0, MBUF_DATA_SIZE, socket);
>          ^
> /root/dpdk/examples/ip_fragmentation/main.c:748:8: note: each undeclared identifier is reported only once for each function it appears in

Sure, I'll have a look. Thanks for reporting.

Regards,
Olivier


>
>
> Best regards
>
> huilong
>
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Zoltan Kiss
> Sent: Friday, April 24, 2015 6:39 PM
> To: Ananyev, Konstantin; Olivier Matz; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones
>
> Hi,
>
> On 22/04/15 12:59, Ananyev, Konstantin wrote:
>>
>>
>>> -----Original Message-----
>>> From: Olivier Matz [mailto:olivier.matz@6wind.com]
>>> Sent: Wednesday, April 22, 2015 10:57 AM
>>> To: dev@dpdk.org
>>> Cc: Ananyev, Konstantin; zoltan.kiss@linaro.org; Richardson, Bruce; nhorman@tuxdriver.com; olivier.matz@6wind.com
>>> Subject: [PATCH v6 00/13] mbuf: enhancements of mbuf clones
>>>
>>> The first objective of this series is to fix the support of indirect
>>> mbufs when the application reserves a private area in mbufs. It also
>>> removes the limitation that rte_pktmbuf_clone() is only allowed on
>>> direct (non-cloned) mbufs. The series also contains some enhancements
>>> and fixes in the mbuf area that makes the implementation of the
>>> last patches easier.
>>>
>>
>> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
>
> When does this series get merged?
>
> Regards,
>
> Zoltan
>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones
  2015-05-07  7:32                   ` Olivier MATZ
@ 2015-05-07  9:39                     ` Ananyev, Konstantin
  0 siblings, 0 replies; 101+ messages in thread
From: Ananyev, Konstantin @ 2015-05-07  9:39 UTC (permalink / raw)
  To: Olivier MATZ, Xu, HuilongX, Zoltan Kiss, dev



> -----Original Message-----
> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> Sent: Thursday, May 07, 2015 8:32 AM
> To: Xu, HuilongX; Zoltan Kiss; Ananyev, Konstantin; dev@dpdk.org
> Cc: Cao, Waterman; Cao, Min; Zhang, Helin
> Subject: Re: [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones
> 
> Hi Huilong,
> 
> On 05/07/2015 03:57 AM, Xu, HuilongX wrote:
> > Hi Olivier,
> > Today I find a compile error, when I test ip fragment on dpdk.org. would you check this?  thanks a lot.
> > My dpdk.org commit: a6d71fa7146cc04320c2485d6dde44c1d888d652
> > The compile error as below:
> > CC main.o
> > /root/dpdk/examples/ip_fragmentation/main.c: In function 'init_mem':
> > /root/dpdk/examples/ip_fragmentation/main.c:748:8: error: 'MBUF_DATA_SIZE' undeclared (first use in this function)
> >       0, MBUF_DATA_SIZE, socket);
> >          ^
> > /root/dpdk/examples/ip_fragmentation/main.c:748:8: note: each undeclared identifier is reported only once for each function it
> appears in
> 
> Sure, I'll have a look. Thanks for reporting.

Looks like a typo here.
Should be fixed by http://dpdk.org/ml/archives/dev/2015-April/017119.html.
Konstantin

> 
> Regards,
> Olivier
> 
> 
> >
> >
> > Best regards
> >
> > huilong
> >
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Zoltan Kiss
> > Sent: Friday, April 24, 2015 6:39 PM
> > To: Ananyev, Konstantin; Olivier Matz; dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones
> >
> > Hi,
> >
> > On 22/04/15 12:59, Ananyev, Konstantin wrote:
> >>
> >>
> >>> -----Original Message-----
> >>> From: Olivier Matz [mailto:olivier.matz@6wind.com]
> >>> Sent: Wednesday, April 22, 2015 10:57 AM
> >>> To: dev@dpdk.org
> >>> Cc: Ananyev, Konstantin; zoltan.kiss@linaro.org; Richardson, Bruce; nhorman@tuxdriver.com; olivier.matz@6wind.com
> >>> Subject: [PATCH v6 00/13] mbuf: enhancements of mbuf clones
> >>>
> >>> The first objective of this series is to fix the support of indirect
> >>> mbufs when the application reserves a private area in mbufs. It also
> >>> removes the limitation that rte_pktmbuf_clone() is only allowed on
> >>> direct (non-cloned) mbufs. The series also contains some enhancements
> >>> and fixes in the mbuf area that makes the implementation of the
> >>> last patches easier.
> >>>
> >>
> >> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> >
> > When does this series get merged?
> >
> > Regards,
> >
> > Zoltan
> >

^ permalink raw reply	[flat|nested] 101+ messages in thread

end of thread, other threads:[~2015-05-07  9:39 UTC | newest]

Thread overview: 101+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-25 17:00 [dpdk-dev] [PATCH 0/5] mbuf: enhancements of mbuf clones Olivier Matz
2015-03-25 17:00 ` [dpdk-dev] [PATCH 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
2015-03-26 13:35   ` Bruce Richardson
2015-03-26 15:30     ` Olivier MATZ
2015-03-25 17:00 ` [dpdk-dev] [PATCH 2/5] mbuf: allow to clone an indirect mbuf Olivier Matz
2015-03-25 17:00 ` [dpdk-dev] [PATCH 3/5] test/mbuf: rename mc variable in m Olivier Matz
2015-03-25 17:00 ` [dpdk-dev] [PATCH 4/5] test/mbuf: enhance mbuf refcnt test Olivier Matz
2015-03-25 17:00 ` [dpdk-dev] [PATCH 5/5] test/mbuf: verify that cloning a clone works properly Olivier Matz
2015-03-26  8:48   ` Olivier MATZ
2015-03-26 15:59 ` [dpdk-dev] [PATCH v2 0/5] mbuf: enhancements of mbuf clones Olivier Matz
2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
2015-03-26 17:13     ` Zoltan Kiss
2015-03-27  0:24     ` Ananyev, Konstantin
2015-03-27  9:07       ` Olivier MATZ
2015-03-27 13:56         ` Olivier MATZ
2015-03-27 14:25           ` Ananyev, Konstantin
2015-03-27 15:17             ` Olivier MATZ
2015-03-27 18:11               ` Zoltan Kiss
2015-03-28 21:19                 ` Olivier MATZ
2015-03-30 12:34               ` Ananyev, Konstantin
2015-03-30 19:55                 ` Olivier MATZ
2015-03-30 23:17                   ` Ananyev, Konstantin
2015-03-31 19:01                     ` Olivier MATZ
2015-04-01 13:48                       ` Ananyev, Konstantin
2015-04-01 15:18                         ` Olivier MATZ
2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 2/5] mbuf: allow to clone an indirect mbuf Olivier Matz
2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 3/5] test/mbuf: rename mc variable in m Olivier Matz
2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 4/5] test/mbuf: enhance mbuf refcnt test Olivier Matz
2015-03-26 15:59   ` [dpdk-dev] [PATCH v2 5/5] test/mbuf: verify that cloning a clone works properly Olivier Matz
2015-03-31 19:22   ` [dpdk-dev] [PATCH v3 0/5] mbuf: enhancements of mbuf clones Olivier Matz
2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 1/5] mbuf: fix clone support when application uses private mbuf data Olivier Matz
2015-04-02 14:32       ` Zoltan Kiss
2015-04-02 17:21       ` Ananyev, Konstantin
2015-04-06 21:49         ` Olivier MATZ
2015-04-07 12:40           ` Ananyev, Konstantin
2015-04-07 15:45             ` Olivier MATZ
2015-04-07 17:17               ` Ananyev, Konstantin
2015-04-08  9:44                 ` Olivier MATZ
2015-04-08 13:45                   ` Ananyev, Konstantin
2015-04-09 13:06                     ` Olivier MATZ
2015-04-20 15:41       ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Olivier Matz
2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 01/12] mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init Olivier Matz
2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 02/12] examples: always initialize mbuf_pool private area Olivier Matz
2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 03/12] mbuf: add accessors to get data room size and private size Olivier Matz
2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 04/12] mbuf: fix rte_pktmbuf_init when mbuf private size is not zero Olivier Matz
2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 05/12] testpmd: use standard functions to initialize mbufs and mbuf pool Olivier Matz
2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 06/12] mbuf: introduce a new helper to create a " Olivier Matz
2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 07/12] apps: use rte_pktmbuf_pool_create to create mbuf pools Olivier Matz
2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 08/12] mbuf: fix clone support when application uses private mbuf data Olivier Matz
2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 09/12] mbuf: allow to clone an indirect mbuf Olivier Matz
2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 10/12] test/mbuf: rename mc variable in m Olivier Matz
2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 11/12] test/mbuf: enhance mbuf refcnt test Olivier Matz
2015-04-20 15:41         ` [dpdk-dev] [PATCH v4 12/12] test/mbuf: verify that cloning a clone works properly Olivier Matz
2015-04-20 16:53         ` [dpdk-dev] [PATCH v4 00/12] mbuf: enhancements of mbuf clones Neil Horman
2015-04-20 17:07           ` Olivier MATZ
2015-04-20 17:21             ` Neil Horman
2015-04-20 18:24               ` Olivier MATZ
2015-04-21  9:55         ` [dpdk-dev] [PATCH v5 " Olivier Matz
2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 01/12] mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init Olivier Matz
2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 02/12] examples: always initialize mbuf_pool private area Olivier Matz
2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 03/12] mbuf: add accessors to get data room size and private size Olivier Matz
2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 04/12] mbuf: fix rte_pktmbuf_init when mbuf private size is not zero Olivier Matz
2015-04-21 15:07             ` Ananyev, Konstantin
2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 05/12] testpmd: use standard functions to initialize mbufs and mbuf pool Olivier Matz
2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 06/12] mbuf: introduce a new helper to create a " Olivier Matz
2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 07/12] apps: use rte_pktmbuf_pool_create to create mbuf pools Olivier Matz
2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 08/12] mbuf: fix clone support when application uses private mbuf data Olivier Matz
2015-04-21 15:01             ` Ananyev, Konstantin
2015-04-21 15:26               ` Olivier MATZ
2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 09/12] mbuf: allow to clone an indirect mbuf Olivier Matz
2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 10/12] test/mbuf: rename mc variable in m Olivier Matz
2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 11/12] test/mbuf: enhance mbuf refcnt test Olivier Matz
2015-04-21  9:55           ` [dpdk-dev] [PATCH v5 12/12] test/mbuf: verify that cloning a clone works properly Olivier Matz
2015-04-21 11:50           ` [dpdk-dev] [PATCH v5 00/12] mbuf: enhancements of mbuf clones Neil Horman
2015-04-22  9:57           ` [dpdk-dev] [PATCH v6 00/13] " Olivier Matz
2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 01/13] mbuf: fix mbuf data room size calculation rte_pktmbuf_pool_init Olivier Matz
2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 02/13] examples: always initialize mbuf_pool private area Olivier Matz
2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 03/13] mbuf: add accessors to get data room size and private size Olivier Matz
2015-04-28  9:15               ` Thomas Monjalon
2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 04/13] mbuf: fix rte_pktmbuf_init when mbuf private size is not zero Olivier Matz
2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 05/13] testpmd: use standard functions to initialize mbufs and mbuf pool Olivier Matz
2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 06/13] mbuf: introduce a new helper to create a " Olivier Matz
2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 07/13] apps: use rte_pktmbuf_pool_create to create mbuf pools Olivier Matz
2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 08/13] mbuf: fix clone support when application uses private mbuf data Olivier Matz
2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 09/13] mbuf: allow to clone an indirect mbuf Olivier Matz
2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 10/13] test/mbuf: rename mc variable in m Olivier Matz
2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 11/13] test/mbuf: enhance mbuf refcnt test Olivier Matz
2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 12/13] test/mbuf: verify that cloning a clone works properly Olivier Matz
2015-04-22  9:57             ` [dpdk-dev] [PATCH v6 13/13] test/mbuf: add a test case for clone with different priv size Olivier Matz
2015-04-22 11:59             ` [dpdk-dev] [PATCH v6 00/13] mbuf: enhancements of mbuf clones Ananyev, Konstantin
2015-04-24 10:38               ` Zoltan Kiss
2015-04-27 17:38                 ` Thomas Monjalon
2015-04-28 11:15                   ` Zoltan Kiss
2015-05-07  1:57                 ` Xu, HuilongX
2015-05-07  7:32                   ` Olivier MATZ
2015-05-07  9:39                     ` Ananyev, Konstantin
2015-04-28  9:50               ` Thomas Monjalon
2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 2/5] mbuf: allow to clone an indirect mbuf Olivier Matz
2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 3/5] test/mbuf: rename mc variable in m Olivier Matz
2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 4/5] test/mbuf: enhance mbuf refcnt test Olivier Matz
2015-03-31 19:23     ` [dpdk-dev] [PATCH v3 5/5] test/mbuf: verify that cloning a clone works properly Olivier Matz

DPDK patches and discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://inbox.dpdk.org/dev/0 dev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dev dev/ https://inbox.dpdk.org/dev \
		dev@dpdk.org
	public-inbox-index dev

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.dev


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git