xref: /dpdk/app/test/test_mbuf.c (revision 6dbaa4ee67135ac6ff8ef35fa98a93e0f08af494)
1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2a9de470cSBruce Richardson  * Copyright(c) 2010-2014 Intel Corporation
3a9de470cSBruce Richardson  */
4a9de470cSBruce Richardson 
53c60274cSJie Zhou #include "test.h"
63c60274cSJie Zhou 
7a9de470cSBruce Richardson #include <string.h>
808966fe7STyler Retzlaff #include <stdalign.h>
9a9de470cSBruce Richardson #include <stdarg.h>
10a9de470cSBruce Richardson #include <stdio.h>
11a9de470cSBruce Richardson #include <stdlib.h>
12a9de470cSBruce Richardson #include <stdint.h>
13a9de470cSBruce Richardson #include <inttypes.h>
14a9de470cSBruce Richardson #include <errno.h>
15a9de470cSBruce Richardson #include <sys/queue.h>
16a9de470cSBruce Richardson 
17a9de470cSBruce Richardson #include <rte_common.h>
18824b67c2SMorten Brørup #include <rte_errno.h>
19a9de470cSBruce Richardson #include <rte_debug.h>
20a9de470cSBruce Richardson #include <rte_log.h>
21a9de470cSBruce Richardson #include <rte_memory.h>
22a9de470cSBruce Richardson #include <rte_memcpy.h>
23a9de470cSBruce Richardson #include <rte_launch.h>
24a9de470cSBruce Richardson #include <rte_eal.h>
25a9de470cSBruce Richardson #include <rte_per_lcore.h>
26a9de470cSBruce Richardson #include <rte_lcore.h>
27a9de470cSBruce Richardson #include <rte_branch_prediction.h>
28a9de470cSBruce Richardson #include <rte_ring.h>
29a9de470cSBruce Richardson #include <rte_mempool.h>
30a9de470cSBruce Richardson #include <rte_mbuf.h>
31a9de470cSBruce Richardson #include <rte_random.h>
32a9de470cSBruce Richardson #include <rte_cycles.h>
338d9c2c3aSKonstantin Ananyev #include <rte_malloc.h>
347b295dceSLavanya Govindarajan #include <rte_ether.h>
357b295dceSLavanya Govindarajan #include <rte_ip.h>
367b295dceSLavanya Govindarajan #include <rte_tcp.h>
374958ca3aSOlivier Matz #include <rte_mbuf_dyn.h>
38a9de470cSBruce Richardson 
397b295dceSLavanya Govindarajan #define MEMPOOL_CACHE_SIZE      32
40a9de470cSBruce Richardson #define MBUF_DATA_SIZE          2048
41a9de470cSBruce Richardson #define NB_MBUF                 128
42a9de470cSBruce Richardson #define MBUF_TEST_DATA_LEN      1464
43a9de470cSBruce Richardson #define MBUF_TEST_DATA_LEN2     50
447b295dceSLavanya Govindarajan #define MBUF_TEST_DATA_LEN3     256
45a9de470cSBruce Richardson #define MBUF_TEST_HDR1_LEN      20
46a9de470cSBruce Richardson #define MBUF_TEST_HDR2_LEN      30
47a9de470cSBruce Richardson #define MBUF_TEST_ALL_HDRS_LEN  (MBUF_TEST_HDR1_LEN+MBUF_TEST_HDR2_LEN)
487b295dceSLavanya Govindarajan #define MBUF_TEST_SEG_SIZE      64
497b295dceSLavanya Govindarajan #define MBUF_TEST_BURST         8
507b295dceSLavanya Govindarajan #define EXT_BUF_TEST_DATA_LEN   1024
517b295dceSLavanya Govindarajan #define MBUF_MAX_SEG            16
527b295dceSLavanya Govindarajan #define MBUF_NO_HEADER		0
537b295dceSLavanya Govindarajan #define MBUF_HEADER		1
547b295dceSLavanya Govindarajan #define MBUF_NEG_TEST_READ	2
55b364bc9eSPallantla Poornima #define VAL_NAME(flag)          { flag, #flag }
56a9de470cSBruce Richardson 
57824b67c2SMorten Brørup /* chain length in bulk test */
58824b67c2SMorten Brørup #define CHAIN_LEN 16
59824b67c2SMorten Brørup 
60a9de470cSBruce Richardson /* size of private data for mbuf in pktmbuf_pool2 */
61a9de470cSBruce Richardson #define MBUF2_PRIV_SIZE         128
62a9de470cSBruce Richardson 
63a9de470cSBruce Richardson #define REFCNT_MAX_ITER         64
64a9de470cSBruce Richardson #define REFCNT_MAX_TIMEOUT      10
65a9de470cSBruce Richardson #define REFCNT_MAX_REF          (RTE_MAX_LCORE)
66a9de470cSBruce Richardson #define REFCNT_MBUF_NUM         64
67a9de470cSBruce Richardson #define REFCNT_RING_SIZE        (REFCNT_MBUF_NUM * REFCNT_MAX_REF)
68a9de470cSBruce Richardson 
69a9de470cSBruce Richardson #define MAGIC_DATA              0x42424242
70a9de470cSBruce Richardson 
71a9de470cSBruce Richardson #define MAKE_STRING(x)          # x
72a9de470cSBruce Richardson 
73a9de470cSBruce Richardson #ifdef RTE_MBUF_REFCNT_ATOMIC
74a9de470cSBruce Richardson 
75cb056611SStephen Hemminger static volatile uint32_t refcnt_stop_workers;
76a9de470cSBruce Richardson static unsigned refcnt_lcore[RTE_MAX_LCORE];
77a9de470cSBruce Richardson 
78a9de470cSBruce Richardson #endif
79a9de470cSBruce Richardson 
80a9de470cSBruce Richardson /*
81a9de470cSBruce Richardson  * MBUF
82a9de470cSBruce Richardson  * ====
83a9de470cSBruce Richardson  *
84a9de470cSBruce Richardson  * #. Allocate a mbuf pool.
85a9de470cSBruce Richardson  *
86a9de470cSBruce Richardson  *    - The pool contains NB_MBUF elements, where each mbuf is MBUF_SIZE
87a9de470cSBruce Richardson  *      bytes long.
88a9de470cSBruce Richardson  *
89a9de470cSBruce Richardson  * #. Test multiple allocations of mbufs from this pool.
90a9de470cSBruce Richardson  *
91a9de470cSBruce Richardson  *    - Allocate NB_MBUF and store pointers in a table.
92a9de470cSBruce Richardson  *    - If an allocation fails, return an error.
93a9de470cSBruce Richardson  *    - Free all these mbufs.
94a9de470cSBruce Richardson  *    - Repeat the same test to check that mbufs were freed correctly.
95a9de470cSBruce Richardson  *
96a9de470cSBruce Richardson  * #. Test data manipulation in pktmbuf.
97a9de470cSBruce Richardson  *
98a9de470cSBruce Richardson  *    - Alloc an mbuf.
99a9de470cSBruce Richardson  *    - Append data using rte_pktmbuf_append().
100a9de470cSBruce Richardson  *    - Test for error in rte_pktmbuf_append() when len is too large.
101a9de470cSBruce Richardson  *    - Trim data at the end of mbuf using rte_pktmbuf_trim().
102a9de470cSBruce Richardson  *    - Test for error in rte_pktmbuf_trim() when len is too large.
103a9de470cSBruce Richardson  *    - Prepend a header using rte_pktmbuf_prepend().
104a9de470cSBruce Richardson  *    - Test for error in rte_pktmbuf_prepend() when len is too large.
105a9de470cSBruce Richardson  *    - Remove data at the beginning of mbuf using rte_pktmbuf_adj().
106a9de470cSBruce Richardson  *    - Test for error in rte_pktmbuf_adj() when len is too large.
107a9de470cSBruce Richardson  *    - Check that appended data is not corrupt.
108a9de470cSBruce Richardson  *    - Free the mbuf.
109a9de470cSBruce Richardson  *    - Between all these tests, check data_len and pkt_len, and
110a9de470cSBruce Richardson  *      that the mbuf is contiguous.
111a9de470cSBruce Richardson  *    - Repeat the test to check that allocation operations
112a9de470cSBruce Richardson  *      reinitialize the mbuf correctly.
113a9de470cSBruce Richardson  *
114a9de470cSBruce Richardson  * #. Test packet cloning
115a9de470cSBruce Richardson  *    - Clone a mbuf and verify the data
116a9de470cSBruce Richardson  *    - Clone the cloned mbuf and verify the data
117a9de470cSBruce Richardson  *    - Attach a mbuf to another that does not have the same priv_size.
118a9de470cSBruce Richardson  */
119a9de470cSBruce Richardson 
120a9de470cSBruce Richardson #define GOTO_FAIL(str, ...) do {					\
121a9de470cSBruce Richardson 		printf("mbuf test FAILED (l.%d): <" str ">\n",		\
122a9de470cSBruce Richardson 		       __LINE__,  ##__VA_ARGS__);			\
123a9de470cSBruce Richardson 		goto fail;						\
124a9de470cSBruce Richardson } while(0)
125a9de470cSBruce Richardson 
126a9de470cSBruce Richardson /*
127a9de470cSBruce Richardson  * test data manipulation in mbuf with non-ascii data
128a9de470cSBruce Richardson  */
129a9de470cSBruce Richardson static int
test_pktmbuf_with_non_ascii_data(struct rte_mempool * pktmbuf_pool)130a9de470cSBruce Richardson test_pktmbuf_with_non_ascii_data(struct rte_mempool *pktmbuf_pool)
131a9de470cSBruce Richardson {
132a9de470cSBruce Richardson 	struct rte_mbuf *m = NULL;
133a9de470cSBruce Richardson 	char *data;
134a9de470cSBruce Richardson 
135a9de470cSBruce Richardson 	m = rte_pktmbuf_alloc(pktmbuf_pool);
136a9de470cSBruce Richardson 	if (m == NULL)
137a9de470cSBruce Richardson 		GOTO_FAIL("Cannot allocate mbuf");
138a9de470cSBruce Richardson 	if (rte_pktmbuf_pkt_len(m) != 0)
139a9de470cSBruce Richardson 		GOTO_FAIL("Bad length");
140a9de470cSBruce Richardson 
141a9de470cSBruce Richardson 	data = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN);
142a9de470cSBruce Richardson 	if (data == NULL)
143a9de470cSBruce Richardson 		GOTO_FAIL("Cannot append data");
144a9de470cSBruce Richardson 	if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN)
145a9de470cSBruce Richardson 		GOTO_FAIL("Bad pkt length");
146a9de470cSBruce Richardson 	if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN)
147a9de470cSBruce Richardson 		GOTO_FAIL("Bad data length");
148a9de470cSBruce Richardson 	memset(data, 0xff, rte_pktmbuf_pkt_len(m));
149a9de470cSBruce Richardson 	if (!rte_pktmbuf_is_contiguous(m))
150a9de470cSBruce Richardson 		GOTO_FAIL("Buffer should be continuous");
151a9de470cSBruce Richardson 	rte_pktmbuf_dump(stdout, m, MBUF_TEST_DATA_LEN);
152a9de470cSBruce Richardson 
153a9de470cSBruce Richardson 	rte_pktmbuf_free(m);
154a9de470cSBruce Richardson 
155a9de470cSBruce Richardson 	return 0;
156a9de470cSBruce Richardson 
157a9de470cSBruce Richardson fail:
158a9de470cSBruce Richardson 	if(m) {
159a9de470cSBruce Richardson 		rte_pktmbuf_free(m);
160a9de470cSBruce Richardson 	}
161a9de470cSBruce Richardson 	return -1;
162a9de470cSBruce Richardson }
163a9de470cSBruce Richardson 
164a9de470cSBruce Richardson /*
165a9de470cSBruce Richardson  * test data manipulation in mbuf
166a9de470cSBruce Richardson  */
167a9de470cSBruce Richardson static int
test_one_pktmbuf(struct rte_mempool * pktmbuf_pool)168a9de470cSBruce Richardson test_one_pktmbuf(struct rte_mempool *pktmbuf_pool)
169a9de470cSBruce Richardson {
170a9de470cSBruce Richardson 	struct rte_mbuf *m = NULL;
171a9de470cSBruce Richardson 	char *data, *data2, *hdr;
172a9de470cSBruce Richardson 	unsigned i;
173a9de470cSBruce Richardson 
174a9de470cSBruce Richardson 	printf("Test pktmbuf API\n");
175a9de470cSBruce Richardson 
176a9de470cSBruce Richardson 	/* alloc a mbuf */
177a9de470cSBruce Richardson 
178a9de470cSBruce Richardson 	m = rte_pktmbuf_alloc(pktmbuf_pool);
179a9de470cSBruce Richardson 	if (m == NULL)
180a9de470cSBruce Richardson 		GOTO_FAIL("Cannot allocate mbuf");
181a9de470cSBruce Richardson 	if (rte_pktmbuf_pkt_len(m) != 0)
182a9de470cSBruce Richardson 		GOTO_FAIL("Bad length");
183a9de470cSBruce Richardson 
184a9de470cSBruce Richardson 	rte_pktmbuf_dump(stdout, m, 0);
185a9de470cSBruce Richardson 
186a9de470cSBruce Richardson 	/* append data */
187a9de470cSBruce Richardson 
188a9de470cSBruce Richardson 	data = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN);
189a9de470cSBruce Richardson 	if (data == NULL)
190a9de470cSBruce Richardson 		GOTO_FAIL("Cannot append data");
191a9de470cSBruce Richardson 	if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN)
192a9de470cSBruce Richardson 		GOTO_FAIL("Bad pkt length");
193a9de470cSBruce Richardson 	if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN)
194a9de470cSBruce Richardson 		GOTO_FAIL("Bad data length");
195a9de470cSBruce Richardson 	memset(data, 0x66, rte_pktmbuf_pkt_len(m));
196a9de470cSBruce Richardson 	if (!rte_pktmbuf_is_contiguous(m))
197a9de470cSBruce Richardson 		GOTO_FAIL("Buffer should be continuous");
198a9de470cSBruce Richardson 	rte_pktmbuf_dump(stdout, m, MBUF_TEST_DATA_LEN);
199a9de470cSBruce Richardson 	rte_pktmbuf_dump(stdout, m, 2*MBUF_TEST_DATA_LEN);
200a9de470cSBruce Richardson 
201a9de470cSBruce Richardson 	/* this append should fail */
202a9de470cSBruce Richardson 
203a9de470cSBruce Richardson 	data2 = rte_pktmbuf_append(m, (uint16_t)(rte_pktmbuf_tailroom(m) + 1));
204a9de470cSBruce Richardson 	if (data2 != NULL)
205a9de470cSBruce Richardson 		GOTO_FAIL("Append should not succeed");
206a9de470cSBruce Richardson 
207a9de470cSBruce Richardson 	/* append some more data */
208a9de470cSBruce Richardson 
209a9de470cSBruce Richardson 	data2 = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN2);
210a9de470cSBruce Richardson 	if (data2 == NULL)
211a9de470cSBruce Richardson 		GOTO_FAIL("Cannot append data");
212a9de470cSBruce Richardson 	if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_DATA_LEN2)
213a9de470cSBruce Richardson 		GOTO_FAIL("Bad pkt length");
214a9de470cSBruce Richardson 	if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_DATA_LEN2)
215a9de470cSBruce Richardson 		GOTO_FAIL("Bad data length");
216a9de470cSBruce Richardson 	if (!rte_pktmbuf_is_contiguous(m))
217a9de470cSBruce Richardson 		GOTO_FAIL("Buffer should be continuous");
218a9de470cSBruce Richardson 
219a9de470cSBruce Richardson 	/* trim data at the end of mbuf */
220a9de470cSBruce Richardson 
221a9de470cSBruce Richardson 	if (rte_pktmbuf_trim(m, MBUF_TEST_DATA_LEN2) < 0)
222a9de470cSBruce Richardson 		GOTO_FAIL("Cannot trim data");
223a9de470cSBruce Richardson 	if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN)
224a9de470cSBruce Richardson 		GOTO_FAIL("Bad pkt length");
225a9de470cSBruce Richardson 	if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN)
226a9de470cSBruce Richardson 		GOTO_FAIL("Bad data length");
227a9de470cSBruce Richardson 	if (!rte_pktmbuf_is_contiguous(m))
228a9de470cSBruce Richardson 		GOTO_FAIL("Buffer should be continuous");
229a9de470cSBruce Richardson 
230a9de470cSBruce Richardson 	/* this trim should fail */
231a9de470cSBruce Richardson 
232a9de470cSBruce Richardson 	if (rte_pktmbuf_trim(m, (uint16_t)(rte_pktmbuf_data_len(m) + 1)) == 0)
233a9de470cSBruce Richardson 		GOTO_FAIL("trim should not succeed");
234a9de470cSBruce Richardson 
235a9de470cSBruce Richardson 	/* prepend one header */
236a9de470cSBruce Richardson 
237a9de470cSBruce Richardson 	hdr = rte_pktmbuf_prepend(m, MBUF_TEST_HDR1_LEN);
238a9de470cSBruce Richardson 	if (hdr == NULL)
239a9de470cSBruce Richardson 		GOTO_FAIL("Cannot prepend");
240a9de470cSBruce Richardson 	if (data - hdr != MBUF_TEST_HDR1_LEN)
241a9de470cSBruce Richardson 		GOTO_FAIL("Prepend failed");
242a9de470cSBruce Richardson 	if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_HDR1_LEN)
243a9de470cSBruce Richardson 		GOTO_FAIL("Bad pkt length");
244a9de470cSBruce Richardson 	if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_HDR1_LEN)
245a9de470cSBruce Richardson 		GOTO_FAIL("Bad data length");
246a9de470cSBruce Richardson 	if (!rte_pktmbuf_is_contiguous(m))
247a9de470cSBruce Richardson 		GOTO_FAIL("Buffer should be continuous");
248a9de470cSBruce Richardson 	memset(hdr, 0x55, MBUF_TEST_HDR1_LEN);
249a9de470cSBruce Richardson 
250a9de470cSBruce Richardson 	/* prepend another header */
251a9de470cSBruce Richardson 
252a9de470cSBruce Richardson 	hdr = rte_pktmbuf_prepend(m, MBUF_TEST_HDR2_LEN);
253a9de470cSBruce Richardson 	if (hdr == NULL)
254a9de470cSBruce Richardson 		GOTO_FAIL("Cannot prepend");
255a9de470cSBruce Richardson 	if (data - hdr != MBUF_TEST_ALL_HDRS_LEN)
256a9de470cSBruce Richardson 		GOTO_FAIL("Prepend failed");
257a9de470cSBruce Richardson 	if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_ALL_HDRS_LEN)
258a9de470cSBruce Richardson 		GOTO_FAIL("Bad pkt length");
259a9de470cSBruce Richardson 	if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_ALL_HDRS_LEN)
260a9de470cSBruce Richardson 		GOTO_FAIL("Bad data length");
261a9de470cSBruce Richardson 	if (!rte_pktmbuf_is_contiguous(m))
262a9de470cSBruce Richardson 		GOTO_FAIL("Buffer should be continuous");
263a9de470cSBruce Richardson 	memset(hdr, 0x55, MBUF_TEST_HDR2_LEN);
264a9de470cSBruce Richardson 
265a9de470cSBruce Richardson 	rte_mbuf_sanity_check(m, 1);
266a9de470cSBruce Richardson 	rte_mbuf_sanity_check(m, 0);
267a9de470cSBruce Richardson 	rte_pktmbuf_dump(stdout, m, 0);
268a9de470cSBruce Richardson 
269a9de470cSBruce Richardson 	/* this prepend should fail */
270a9de470cSBruce Richardson 
271a9de470cSBruce Richardson 	hdr = rte_pktmbuf_prepend(m, (uint16_t)(rte_pktmbuf_headroom(m) + 1));
272a9de470cSBruce Richardson 	if (hdr != NULL)
273a9de470cSBruce Richardson 		GOTO_FAIL("prepend should not succeed");
274a9de470cSBruce Richardson 
275a9de470cSBruce Richardson 	/* remove data at beginning of mbuf (adj) */
276a9de470cSBruce Richardson 
277a9de470cSBruce Richardson 	if (data != rte_pktmbuf_adj(m, MBUF_TEST_ALL_HDRS_LEN))
278a9de470cSBruce Richardson 		GOTO_FAIL("rte_pktmbuf_adj failed");
279a9de470cSBruce Richardson 	if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN)
280a9de470cSBruce Richardson 		GOTO_FAIL("Bad pkt length");
281a9de470cSBruce Richardson 	if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN)
282a9de470cSBruce Richardson 		GOTO_FAIL("Bad data length");
283a9de470cSBruce Richardson 	if (!rte_pktmbuf_is_contiguous(m))
284a9de470cSBruce Richardson 		GOTO_FAIL("Buffer should be continuous");
285a9de470cSBruce Richardson 
286a9de470cSBruce Richardson 	/* this adj should fail */
287a9de470cSBruce Richardson 
288a9de470cSBruce Richardson 	if (rte_pktmbuf_adj(m, (uint16_t)(rte_pktmbuf_data_len(m) + 1)) != NULL)
289a9de470cSBruce Richardson 		GOTO_FAIL("rte_pktmbuf_adj should not succeed");
290a9de470cSBruce Richardson 
291a9de470cSBruce Richardson 	/* check data */
292a9de470cSBruce Richardson 
293a9de470cSBruce Richardson 	if (!rte_pktmbuf_is_contiguous(m))
294a9de470cSBruce Richardson 		GOTO_FAIL("Buffer should be continuous");
295a9de470cSBruce Richardson 
296a9de470cSBruce Richardson 	for (i=0; i<MBUF_TEST_DATA_LEN; i++) {
297a9de470cSBruce Richardson 		if (data[i] != 0x66)
298a9de470cSBruce Richardson 			GOTO_FAIL("Data corrupted at offset %u", i);
299a9de470cSBruce Richardson 	}
300a9de470cSBruce Richardson 
301a9de470cSBruce Richardson 	/* free mbuf */
302a9de470cSBruce Richardson 
303a9de470cSBruce Richardson 	rte_pktmbuf_free(m);
304a9de470cSBruce Richardson 	m = NULL;
305a9de470cSBruce Richardson 	return 0;
306a9de470cSBruce Richardson 
307a9de470cSBruce Richardson fail:
308a9de470cSBruce Richardson 	rte_pktmbuf_free(m);
309a9de470cSBruce Richardson 	return -1;
310a9de470cSBruce Richardson }
311a9de470cSBruce Richardson 
3125d3e7176SViacheslav Ovsiienko static uint16_t
testclone_refcnt_read(struct rte_mbuf * m)3135d3e7176SViacheslav Ovsiienko testclone_refcnt_read(struct rte_mbuf *m)
3145d3e7176SViacheslav Ovsiienko {
3155d3e7176SViacheslav Ovsiienko 	return RTE_MBUF_HAS_PINNED_EXTBUF(m) ?
3165d3e7176SViacheslav Ovsiienko 	       rte_mbuf_ext_refcnt_read(m->shinfo) :
3175d3e7176SViacheslav Ovsiienko 	       rte_mbuf_refcnt_read(m);
3185d3e7176SViacheslav Ovsiienko }
3195d3e7176SViacheslav Ovsiienko 
320a9de470cSBruce Richardson static int
testclone_testupdate_testdetach(struct rte_mempool * pktmbuf_pool,struct rte_mempool * clone_pool)3215d3e7176SViacheslav Ovsiienko testclone_testupdate_testdetach(struct rte_mempool *pktmbuf_pool,
3225d3e7176SViacheslav Ovsiienko 				struct rte_mempool *clone_pool)
323a9de470cSBruce Richardson {
324a9de470cSBruce Richardson 	struct rte_mbuf *m = NULL;
325a9de470cSBruce Richardson 	struct rte_mbuf *clone = NULL;
326a9de470cSBruce Richardson 	struct rte_mbuf *clone2 = NULL;
327a9de470cSBruce Richardson 	unaligned_uint32_t *data;
328a9de470cSBruce Richardson 
329a9de470cSBruce Richardson 	/* alloc a mbuf */
330a9de470cSBruce Richardson 	m = rte_pktmbuf_alloc(pktmbuf_pool);
331a9de470cSBruce Richardson 	if (m == NULL)
332a9de470cSBruce Richardson 		GOTO_FAIL("ooops not allocating mbuf");
333a9de470cSBruce Richardson 
334a9de470cSBruce Richardson 	if (rte_pktmbuf_pkt_len(m) != 0)
335a9de470cSBruce Richardson 		GOTO_FAIL("Bad length");
336a9de470cSBruce Richardson 
337a9de470cSBruce Richardson 	rte_pktmbuf_append(m, sizeof(uint32_t));
338a9de470cSBruce Richardson 	data = rte_pktmbuf_mtod(m, unaligned_uint32_t *);
339a9de470cSBruce Richardson 	*data = MAGIC_DATA;
340a9de470cSBruce Richardson 
341a9de470cSBruce Richardson 	/* clone the allocated mbuf */
3425d3e7176SViacheslav Ovsiienko 	clone = rte_pktmbuf_clone(m, clone_pool);
343a9de470cSBruce Richardson 	if (clone == NULL)
344a9de470cSBruce Richardson 		GOTO_FAIL("cannot clone data\n");
345a9de470cSBruce Richardson 
346a9de470cSBruce Richardson 	data = rte_pktmbuf_mtod(clone, unaligned_uint32_t *);
347a9de470cSBruce Richardson 	if (*data != MAGIC_DATA)
348a9de470cSBruce Richardson 		GOTO_FAIL("invalid data in clone\n");
349a9de470cSBruce Richardson 
3505d3e7176SViacheslav Ovsiienko 	if (testclone_refcnt_read(m) != 2)
351a9de470cSBruce Richardson 		GOTO_FAIL("invalid refcnt in m\n");
352a9de470cSBruce Richardson 
353a9de470cSBruce Richardson 	/* free the clone */
354a9de470cSBruce Richardson 	rte_pktmbuf_free(clone);
355a9de470cSBruce Richardson 	clone = NULL;
356a9de470cSBruce Richardson 
357a9de470cSBruce Richardson 	/* same test with a chained mbuf */
358a9de470cSBruce Richardson 	m->next = rte_pktmbuf_alloc(pktmbuf_pool);
359a9de470cSBruce Richardson 	if (m->next == NULL)
360a9de470cSBruce Richardson 		GOTO_FAIL("Next Pkt Null\n");
36116367754SStephen Hemminger 	m->nb_segs = 2;
362a9de470cSBruce Richardson 
363a9de470cSBruce Richardson 	rte_pktmbuf_append(m->next, sizeof(uint32_t));
36416367754SStephen Hemminger 	m->pkt_len = 2 * sizeof(uint32_t);
36516367754SStephen Hemminger 
366a9de470cSBruce Richardson 	data = rte_pktmbuf_mtod(m->next, unaligned_uint32_t *);
367a9de470cSBruce Richardson 	*data = MAGIC_DATA;
368a9de470cSBruce Richardson 
3695d3e7176SViacheslav Ovsiienko 	clone = rte_pktmbuf_clone(m, clone_pool);
370a9de470cSBruce Richardson 	if (clone == NULL)
371a9de470cSBruce Richardson 		GOTO_FAIL("cannot clone data\n");
372a9de470cSBruce Richardson 
373a9de470cSBruce Richardson 	data = rte_pktmbuf_mtod(clone, unaligned_uint32_t *);
374a9de470cSBruce Richardson 	if (*data != MAGIC_DATA)
375a9de470cSBruce Richardson 		GOTO_FAIL("invalid data in clone\n");
376a9de470cSBruce Richardson 
377a9de470cSBruce Richardson 	data = rte_pktmbuf_mtod(clone->next, unaligned_uint32_t *);
378a9de470cSBruce Richardson 	if (*data != MAGIC_DATA)
379a9de470cSBruce Richardson 		GOTO_FAIL("invalid data in clone->next\n");
380a9de470cSBruce Richardson 
3815d3e7176SViacheslav Ovsiienko 	if (testclone_refcnt_read(m) != 2)
382a9de470cSBruce Richardson 		GOTO_FAIL("invalid refcnt in m\n");
383a9de470cSBruce Richardson 
3845d3e7176SViacheslav Ovsiienko 	if (testclone_refcnt_read(m->next) != 2)
385a9de470cSBruce Richardson 		GOTO_FAIL("invalid refcnt in m->next\n");
386a9de470cSBruce Richardson 
387a9de470cSBruce Richardson 	/* try to clone the clone */
388a9de470cSBruce Richardson 
3895d3e7176SViacheslav Ovsiienko 	clone2 = rte_pktmbuf_clone(clone, clone_pool);
390a9de470cSBruce Richardson 	if (clone2 == NULL)
391a9de470cSBruce Richardson 		GOTO_FAIL("cannot clone the clone\n");
392a9de470cSBruce Richardson 
393a9de470cSBruce Richardson 	data = rte_pktmbuf_mtod(clone2, unaligned_uint32_t *);
394a9de470cSBruce Richardson 	if (*data != MAGIC_DATA)
395a9de470cSBruce Richardson 		GOTO_FAIL("invalid data in clone2\n");
396a9de470cSBruce Richardson 
397a9de470cSBruce Richardson 	data = rte_pktmbuf_mtod(clone2->next, unaligned_uint32_t *);
398a9de470cSBruce Richardson 	if (*data != MAGIC_DATA)
399a9de470cSBruce Richardson 		GOTO_FAIL("invalid data in clone2->next\n");
400a9de470cSBruce Richardson 
4015d3e7176SViacheslav Ovsiienko 	if (testclone_refcnt_read(m) != 3)
402a9de470cSBruce Richardson 		GOTO_FAIL("invalid refcnt in m\n");
403a9de470cSBruce Richardson 
4045d3e7176SViacheslav Ovsiienko 	if (testclone_refcnt_read(m->next) != 3)
405a9de470cSBruce Richardson 		GOTO_FAIL("invalid refcnt in m->next\n");
406a9de470cSBruce Richardson 
407a9de470cSBruce Richardson 	/* free mbuf */
408a9de470cSBruce Richardson 	rte_pktmbuf_free(m);
409a9de470cSBruce Richardson 	rte_pktmbuf_free(clone);
410a9de470cSBruce Richardson 	rte_pktmbuf_free(clone2);
411a9de470cSBruce Richardson 
412a9de470cSBruce Richardson 	m = NULL;
413a9de470cSBruce Richardson 	clone = NULL;
414a9de470cSBruce Richardson 	clone2 = NULL;
415a9de470cSBruce Richardson 	printf("%s ok\n", __func__);
416a9de470cSBruce Richardson 	return 0;
417a9de470cSBruce Richardson 
418a9de470cSBruce Richardson fail:
419a9de470cSBruce Richardson 	rte_pktmbuf_free(m);
420a9de470cSBruce Richardson 	rte_pktmbuf_free(clone);
421a9de470cSBruce Richardson 	rte_pktmbuf_free(clone2);
422a9de470cSBruce Richardson 	return -1;
423a9de470cSBruce Richardson }
424a9de470cSBruce Richardson 
425a9de470cSBruce Richardson static int
test_pktmbuf_copy(struct rte_mempool * pktmbuf_pool,struct rte_mempool * clone_pool)4265d3e7176SViacheslav Ovsiienko test_pktmbuf_copy(struct rte_mempool *pktmbuf_pool,
4275d3e7176SViacheslav Ovsiienko 		  struct rte_mempool *clone_pool)
428c3a90c38SStephen Hemminger {
429c3a90c38SStephen Hemminger 	struct rte_mbuf *m = NULL;
430c3a90c38SStephen Hemminger 	struct rte_mbuf *copy = NULL;
431c3a90c38SStephen Hemminger 	struct rte_mbuf *copy2 = NULL;
432c3a90c38SStephen Hemminger 	struct rte_mbuf *clone = NULL;
433c3a90c38SStephen Hemminger 	unaligned_uint32_t *data;
434c3a90c38SStephen Hemminger 
435c3a90c38SStephen Hemminger 	/* alloc a mbuf */
436c3a90c38SStephen Hemminger 	m = rte_pktmbuf_alloc(pktmbuf_pool);
437c3a90c38SStephen Hemminger 	if (m == NULL)
438c3a90c38SStephen Hemminger 		GOTO_FAIL("ooops not allocating mbuf");
439c3a90c38SStephen Hemminger 
440c3a90c38SStephen Hemminger 	if (rte_pktmbuf_pkt_len(m) != 0)
441c3a90c38SStephen Hemminger 		GOTO_FAIL("Bad length");
442c3a90c38SStephen Hemminger 
443c3a90c38SStephen Hemminger 	rte_pktmbuf_append(m, sizeof(uint32_t));
444c3a90c38SStephen Hemminger 	data = rte_pktmbuf_mtod(m, unaligned_uint32_t *);
445c3a90c38SStephen Hemminger 	*data = MAGIC_DATA;
446c3a90c38SStephen Hemminger 
447c3a90c38SStephen Hemminger 	/* copy the allocated mbuf */
448c3a90c38SStephen Hemminger 	copy = rte_pktmbuf_copy(m, pktmbuf_pool, 0, UINT32_MAX);
449c3a90c38SStephen Hemminger 	if (copy == NULL)
450c3a90c38SStephen Hemminger 		GOTO_FAIL("cannot copy data\n");
451c3a90c38SStephen Hemminger 
452c3a90c38SStephen Hemminger 	if (rte_pktmbuf_pkt_len(copy) != sizeof(uint32_t))
453c3a90c38SStephen Hemminger 		GOTO_FAIL("copy length incorrect\n");
454c3a90c38SStephen Hemminger 
455c3a90c38SStephen Hemminger 	if (rte_pktmbuf_data_len(copy) != sizeof(uint32_t))
456c3a90c38SStephen Hemminger 		GOTO_FAIL("copy data length incorrect\n");
457c3a90c38SStephen Hemminger 
458c3a90c38SStephen Hemminger 	data = rte_pktmbuf_mtod(copy, unaligned_uint32_t *);
459c3a90c38SStephen Hemminger 	if (*data != MAGIC_DATA)
460c3a90c38SStephen Hemminger 		GOTO_FAIL("invalid data in copy\n");
461c3a90c38SStephen Hemminger 
462c3a90c38SStephen Hemminger 	/* free the copy */
463c3a90c38SStephen Hemminger 	rte_pktmbuf_free(copy);
464c3a90c38SStephen Hemminger 	copy = NULL;
465c3a90c38SStephen Hemminger 
466c3a90c38SStephen Hemminger 	/* same test with a cloned mbuf */
4675d3e7176SViacheslav Ovsiienko 	clone = rte_pktmbuf_clone(m, clone_pool);
468c3a90c38SStephen Hemminger 	if (clone == NULL)
469c3a90c38SStephen Hemminger 		GOTO_FAIL("cannot clone data\n");
470c3a90c38SStephen Hemminger 
4715d3e7176SViacheslav Ovsiienko 	if ((!RTE_MBUF_HAS_PINNED_EXTBUF(m) &&
4725d3e7176SViacheslav Ovsiienko 	     !RTE_MBUF_CLONED(clone)) ||
4735d3e7176SViacheslav Ovsiienko 	    (RTE_MBUF_HAS_PINNED_EXTBUF(m) &&
4745d3e7176SViacheslav Ovsiienko 	     !RTE_MBUF_HAS_EXTBUF(clone)))
475c3a90c38SStephen Hemminger 		GOTO_FAIL("clone did not give a cloned mbuf\n");
476c3a90c38SStephen Hemminger 
477c3a90c38SStephen Hemminger 	copy = rte_pktmbuf_copy(clone, pktmbuf_pool, 0, UINT32_MAX);
478c3a90c38SStephen Hemminger 	if (copy == NULL)
479c3a90c38SStephen Hemminger 		GOTO_FAIL("cannot copy cloned mbuf\n");
480c3a90c38SStephen Hemminger 
481c3a90c38SStephen Hemminger 	if (RTE_MBUF_CLONED(copy))
482c3a90c38SStephen Hemminger 		GOTO_FAIL("copy of clone is cloned?\n");
483c3a90c38SStephen Hemminger 
484c3a90c38SStephen Hemminger 	if (rte_pktmbuf_pkt_len(copy) != sizeof(uint32_t))
485c3a90c38SStephen Hemminger 		GOTO_FAIL("copy clone length incorrect\n");
486c3a90c38SStephen Hemminger 
487c3a90c38SStephen Hemminger 	if (rte_pktmbuf_data_len(copy) != sizeof(uint32_t))
488c3a90c38SStephen Hemminger 		GOTO_FAIL("copy clone data length incorrect\n");
489c3a90c38SStephen Hemminger 
490c3a90c38SStephen Hemminger 	data = rte_pktmbuf_mtod(copy, unaligned_uint32_t *);
491c3a90c38SStephen Hemminger 	if (*data != MAGIC_DATA)
492c3a90c38SStephen Hemminger 		GOTO_FAIL("invalid data in clone copy\n");
493c3a90c38SStephen Hemminger 	rte_pktmbuf_free(clone);
494c3a90c38SStephen Hemminger 	rte_pktmbuf_free(copy);
495c3a90c38SStephen Hemminger 	copy = NULL;
496c3a90c38SStephen Hemminger 	clone = NULL;
497c3a90c38SStephen Hemminger 
498c3a90c38SStephen Hemminger 
499c3a90c38SStephen Hemminger 	/* same test with a chained mbuf */
500c3a90c38SStephen Hemminger 	m->next = rte_pktmbuf_alloc(pktmbuf_pool);
501c3a90c38SStephen Hemminger 	if (m->next == NULL)
502c3a90c38SStephen Hemminger 		GOTO_FAIL("Next Pkt Null\n");
503c3a90c38SStephen Hemminger 	m->nb_segs = 2;
504c3a90c38SStephen Hemminger 
505c3a90c38SStephen Hemminger 	rte_pktmbuf_append(m->next, sizeof(uint32_t));
506c3a90c38SStephen Hemminger 	m->pkt_len = 2 * sizeof(uint32_t);
507c3a90c38SStephen Hemminger 	data = rte_pktmbuf_mtod(m->next, unaligned_uint32_t *);
508c3a90c38SStephen Hemminger 	*data = MAGIC_DATA + 1;
509c3a90c38SStephen Hemminger 
510c3a90c38SStephen Hemminger 	copy = rte_pktmbuf_copy(m, pktmbuf_pool, 0, UINT32_MAX);
511c3a90c38SStephen Hemminger 	if (copy == NULL)
512c3a90c38SStephen Hemminger 		GOTO_FAIL("cannot copy data\n");
513c3a90c38SStephen Hemminger 
514c3a90c38SStephen Hemminger 	if (rte_pktmbuf_pkt_len(copy) != 2 * sizeof(uint32_t))
515c3a90c38SStephen Hemminger 		GOTO_FAIL("chain copy length incorrect\n");
516c3a90c38SStephen Hemminger 
517c3a90c38SStephen Hemminger 	if (rte_pktmbuf_data_len(copy) != 2 * sizeof(uint32_t))
518c3a90c38SStephen Hemminger 		GOTO_FAIL("chain copy data length incorrect\n");
519c3a90c38SStephen Hemminger 
520c3a90c38SStephen Hemminger 	data = rte_pktmbuf_mtod(copy, unaligned_uint32_t *);
521c3a90c38SStephen Hemminger 	if (data[0] != MAGIC_DATA || data[1] != MAGIC_DATA + 1)
522c3a90c38SStephen Hemminger 		GOTO_FAIL("invalid data in copy\n");
523c3a90c38SStephen Hemminger 
524c3a90c38SStephen Hemminger 	rte_pktmbuf_free(copy2);
525c3a90c38SStephen Hemminger 
526c3a90c38SStephen Hemminger 	/* test offset copy */
527c3a90c38SStephen Hemminger 	copy2 = rte_pktmbuf_copy(copy, pktmbuf_pool,
528c3a90c38SStephen Hemminger 				 sizeof(uint32_t), UINT32_MAX);
529c3a90c38SStephen Hemminger 	if (copy2 == NULL)
530c3a90c38SStephen Hemminger 		GOTO_FAIL("cannot copy the copy\n");
531c3a90c38SStephen Hemminger 
532c3a90c38SStephen Hemminger 	if (rte_pktmbuf_pkt_len(copy2) != sizeof(uint32_t))
533c3a90c38SStephen Hemminger 		GOTO_FAIL("copy with offset, length incorrect\n");
534c3a90c38SStephen Hemminger 
535c3a90c38SStephen Hemminger 	if (rte_pktmbuf_data_len(copy2) != sizeof(uint32_t))
536c3a90c38SStephen Hemminger 		GOTO_FAIL("copy with offset, data length incorrect\n");
537c3a90c38SStephen Hemminger 
538c3a90c38SStephen Hemminger 	data = rte_pktmbuf_mtod(copy2, unaligned_uint32_t *);
539c3a90c38SStephen Hemminger 	if (data[0] != MAGIC_DATA + 1)
540c3a90c38SStephen Hemminger 		GOTO_FAIL("copy with offset, invalid data\n");
541c3a90c38SStephen Hemminger 
542c3a90c38SStephen Hemminger 	rte_pktmbuf_free(copy2);
543c3a90c38SStephen Hemminger 
544c3a90c38SStephen Hemminger 	/* test truncation copy */
545c3a90c38SStephen Hemminger 	copy2 = rte_pktmbuf_copy(copy, pktmbuf_pool,
546c3a90c38SStephen Hemminger 				 0, sizeof(uint32_t));
547c3a90c38SStephen Hemminger 	if (copy2 == NULL)
548c3a90c38SStephen Hemminger 		GOTO_FAIL("cannot copy the copy\n");
549c3a90c38SStephen Hemminger 
550c3a90c38SStephen Hemminger 	if (rte_pktmbuf_pkt_len(copy2) != sizeof(uint32_t))
551c3a90c38SStephen Hemminger 		GOTO_FAIL("copy with truncate, length incorrect\n");
552c3a90c38SStephen Hemminger 
553c3a90c38SStephen Hemminger 	if (rte_pktmbuf_data_len(copy2) != sizeof(uint32_t))
554c3a90c38SStephen Hemminger 		GOTO_FAIL("copy with truncate, data length incorrect\n");
555c3a90c38SStephen Hemminger 
556c3a90c38SStephen Hemminger 	data = rte_pktmbuf_mtod(copy2, unaligned_uint32_t *);
557c3a90c38SStephen Hemminger 	if (data[0] != MAGIC_DATA)
558c3a90c38SStephen Hemminger 		GOTO_FAIL("copy with truncate, invalid data\n");
559c3a90c38SStephen Hemminger 
560c3a90c38SStephen Hemminger 	/* free mbuf */
561c3a90c38SStephen Hemminger 	rte_pktmbuf_free(m);
562c3a90c38SStephen Hemminger 	rte_pktmbuf_free(copy);
563c3a90c38SStephen Hemminger 	rte_pktmbuf_free(copy2);
564c3a90c38SStephen Hemminger 
565c3a90c38SStephen Hemminger 	m = NULL;
566c3a90c38SStephen Hemminger 	copy = NULL;
567c3a90c38SStephen Hemminger 	copy2 = NULL;
568c3a90c38SStephen Hemminger 	printf("%s ok\n", __func__);
569c3a90c38SStephen Hemminger 	return 0;
570c3a90c38SStephen Hemminger 
571c3a90c38SStephen Hemminger fail:
572c3a90c38SStephen Hemminger 	rte_pktmbuf_free(m);
573c3a90c38SStephen Hemminger 	rte_pktmbuf_free(copy);
574c3a90c38SStephen Hemminger 	rte_pktmbuf_free(copy2);
575c3a90c38SStephen Hemminger 	return -1;
576c3a90c38SStephen Hemminger }
577c3a90c38SStephen Hemminger 
578c3a90c38SStephen Hemminger static int
test_attach_from_different_pool(struct rte_mempool * pktmbuf_pool,struct rte_mempool * pktmbuf_pool2)579a9de470cSBruce Richardson test_attach_from_different_pool(struct rte_mempool *pktmbuf_pool,
580a9de470cSBruce Richardson 				struct rte_mempool *pktmbuf_pool2)
581a9de470cSBruce Richardson {
582a9de470cSBruce Richardson 	struct rte_mbuf *m = NULL;
583a9de470cSBruce Richardson 	struct rte_mbuf *clone = NULL;
584a9de470cSBruce Richardson 	struct rte_mbuf *clone2 = NULL;
585a9de470cSBruce Richardson 	char *data, *c_data, *c_data2;
586a9de470cSBruce Richardson 
587a9de470cSBruce Richardson 	/* alloc a mbuf */
588a9de470cSBruce Richardson 	m = rte_pktmbuf_alloc(pktmbuf_pool);
589a9de470cSBruce Richardson 	if (m == NULL)
590a9de470cSBruce Richardson 		GOTO_FAIL("cannot allocate mbuf");
591a9de470cSBruce Richardson 
592a9de470cSBruce Richardson 	if (rte_pktmbuf_pkt_len(m) != 0)
593a9de470cSBruce Richardson 		GOTO_FAIL("Bad length");
594a9de470cSBruce Richardson 
595a9de470cSBruce Richardson 	data = rte_pktmbuf_mtod(m, char *);
596a9de470cSBruce Richardson 
597a9de470cSBruce Richardson 	/* allocate a new mbuf from the second pool, and attach it to the first
598a9de470cSBruce Richardson 	 * mbuf */
599a9de470cSBruce Richardson 	clone = rte_pktmbuf_alloc(pktmbuf_pool2);
600a9de470cSBruce Richardson 	if (clone == NULL)
601a9de470cSBruce Richardson 		GOTO_FAIL("cannot allocate mbuf from second pool\n");
602a9de470cSBruce Richardson 
603a9de470cSBruce Richardson 	/* check data room size and priv size, and erase priv */
604a9de470cSBruce Richardson 	if (rte_pktmbuf_data_room_size(clone->pool) != 0)
605a9de470cSBruce Richardson 		GOTO_FAIL("data room size should be 0\n");
606a9de470cSBruce Richardson 	if (rte_pktmbuf_priv_size(clone->pool) != MBUF2_PRIV_SIZE)
607a9de470cSBruce Richardson 		GOTO_FAIL("data room size should be %d\n", MBUF2_PRIV_SIZE);
608a9de470cSBruce Richardson 	memset(clone + 1, 0, MBUF2_PRIV_SIZE);
609a9de470cSBruce Richardson 
610a9de470cSBruce Richardson 	/* save data pointer to compare it after detach() */
611a9de470cSBruce Richardson 	c_data = rte_pktmbuf_mtod(clone, char *);
612a9de470cSBruce Richardson 	if (c_data != (char *)clone + sizeof(*clone) + MBUF2_PRIV_SIZE)
613a9de470cSBruce Richardson 		GOTO_FAIL("bad data pointer in clone");
614a9de470cSBruce Richardson 	if (rte_pktmbuf_headroom(clone) != 0)
615a9de470cSBruce Richardson 		GOTO_FAIL("bad headroom in clone");
616a9de470cSBruce Richardson 
617a9de470cSBruce Richardson 	rte_pktmbuf_attach(clone, m);
618a9de470cSBruce Richardson 
619a9de470cSBruce Richardson 	if (rte_pktmbuf_mtod(clone, char *) != data)
620a9de470cSBruce Richardson 		GOTO_FAIL("clone was not attached properly\n");
621a9de470cSBruce Richardson 	if (rte_pktmbuf_headroom(clone) != RTE_PKTMBUF_HEADROOM)
622a9de470cSBruce Richardson 		GOTO_FAIL("bad headroom in clone after attach");
623a9de470cSBruce Richardson 	if (rte_mbuf_refcnt_read(m) != 2)
624a9de470cSBruce Richardson 		GOTO_FAIL("invalid refcnt in m\n");
625a9de470cSBruce Richardson 
626a9de470cSBruce Richardson 	/* allocate a new mbuf from the second pool, and attach it to the first
627a9de470cSBruce Richardson 	 * cloned mbuf */
628a9de470cSBruce Richardson 	clone2 = rte_pktmbuf_alloc(pktmbuf_pool2);
629a9de470cSBruce Richardson 	if (clone2 == NULL)
630a9de470cSBruce Richardson 		GOTO_FAIL("cannot allocate clone2 from second pool\n");
631a9de470cSBruce Richardson 
632a9de470cSBruce Richardson 	/* check data room size and priv size, and erase priv */
633a9de470cSBruce Richardson 	if (rte_pktmbuf_data_room_size(clone2->pool) != 0)
634a9de470cSBruce Richardson 		GOTO_FAIL("data room size should be 0\n");
635a9de470cSBruce Richardson 	if (rte_pktmbuf_priv_size(clone2->pool) != MBUF2_PRIV_SIZE)
636a9de470cSBruce Richardson 		GOTO_FAIL("data room size should be %d\n", MBUF2_PRIV_SIZE);
637a9de470cSBruce Richardson 	memset(clone2 + 1, 0, MBUF2_PRIV_SIZE);
638a9de470cSBruce Richardson 
639a9de470cSBruce Richardson 	/* save data pointer to compare it after detach() */
640a9de470cSBruce Richardson 	c_data2 = rte_pktmbuf_mtod(clone2, char *);
641a9de470cSBruce Richardson 	if (c_data2 != (char *)clone2 + sizeof(*clone2) + MBUF2_PRIV_SIZE)
642a9de470cSBruce Richardson 		GOTO_FAIL("bad data pointer in clone2");
643a9de470cSBruce Richardson 	if (rte_pktmbuf_headroom(clone2) != 0)
644a9de470cSBruce Richardson 		GOTO_FAIL("bad headroom in clone2");
645a9de470cSBruce Richardson 
646a9de470cSBruce Richardson 	rte_pktmbuf_attach(clone2, clone);
647a9de470cSBruce Richardson 
648a9de470cSBruce Richardson 	if (rte_pktmbuf_mtod(clone2, char *) != data)
649a9de470cSBruce Richardson 		GOTO_FAIL("clone2 was not attached properly\n");
650a9de470cSBruce Richardson 	if (rte_pktmbuf_headroom(clone2) != RTE_PKTMBUF_HEADROOM)
651a9de470cSBruce Richardson 		GOTO_FAIL("bad headroom in clone2 after attach");
652a9de470cSBruce Richardson 	if (rte_mbuf_refcnt_read(m) != 3)
653a9de470cSBruce Richardson 		GOTO_FAIL("invalid refcnt in m\n");
654a9de470cSBruce Richardson 
655a9de470cSBruce Richardson 	/* detach the clones */
656a9de470cSBruce Richardson 	rte_pktmbuf_detach(clone);
657a9de470cSBruce Richardson 	if (c_data != rte_pktmbuf_mtod(clone, char *))
658a9de470cSBruce Richardson 		GOTO_FAIL("clone was not detached properly\n");
659a9de470cSBruce Richardson 	if (rte_mbuf_refcnt_read(m) != 2)
660a9de470cSBruce Richardson 		GOTO_FAIL("invalid refcnt in m\n");
661a9de470cSBruce Richardson 
662a9de470cSBruce Richardson 	rte_pktmbuf_detach(clone2);
663a9de470cSBruce Richardson 	if (c_data2 != rte_pktmbuf_mtod(clone2, char *))
664a9de470cSBruce Richardson 		GOTO_FAIL("clone2 was not detached properly\n");
665a9de470cSBruce Richardson 	if (rte_mbuf_refcnt_read(m) != 1)
666a9de470cSBruce Richardson 		GOTO_FAIL("invalid refcnt in m\n");
667a9de470cSBruce Richardson 
668a9de470cSBruce Richardson 	/* free the clones and the initial mbuf */
669a9de470cSBruce Richardson 	rte_pktmbuf_free(clone2);
670a9de470cSBruce Richardson 	rte_pktmbuf_free(clone);
671a9de470cSBruce Richardson 	rte_pktmbuf_free(m);
672a9de470cSBruce Richardson 	printf("%s ok\n", __func__);
673a9de470cSBruce Richardson 	return 0;
674a9de470cSBruce Richardson 
675a9de470cSBruce Richardson fail:
676a9de470cSBruce Richardson 	rte_pktmbuf_free(m);
677a9de470cSBruce Richardson 	rte_pktmbuf_free(clone);
678a9de470cSBruce Richardson 	rte_pktmbuf_free(clone2);
679a9de470cSBruce Richardson 	return -1;
680a9de470cSBruce Richardson }
681a9de470cSBruce Richardson 
682a9de470cSBruce Richardson /*
683a9de470cSBruce Richardson  * test allocation and free of mbufs
684a9de470cSBruce Richardson  */
685a9de470cSBruce Richardson static int
test_pktmbuf_pool(struct rte_mempool * pktmbuf_pool)686a9de470cSBruce Richardson test_pktmbuf_pool(struct rte_mempool *pktmbuf_pool)
687a9de470cSBruce Richardson {
688a9de470cSBruce Richardson 	unsigned i;
689a9de470cSBruce Richardson 	struct rte_mbuf *m[NB_MBUF];
690a9de470cSBruce Richardson 	int ret = 0;
691a9de470cSBruce Richardson 
692a9de470cSBruce Richardson 	for (i=0; i<NB_MBUF; i++)
693a9de470cSBruce Richardson 		m[i] = NULL;
694a9de470cSBruce Richardson 
695a9de470cSBruce Richardson 	/* alloc NB_MBUF mbufs */
696a9de470cSBruce Richardson 	for (i=0; i<NB_MBUF; i++) {
697a9de470cSBruce Richardson 		m[i] = rte_pktmbuf_alloc(pktmbuf_pool);
698a9de470cSBruce Richardson 		if (m[i] == NULL) {
699a9de470cSBruce Richardson 			printf("rte_pktmbuf_alloc() failed (%u)\n", i);
700a9de470cSBruce Richardson 			ret = -1;
701a9de470cSBruce Richardson 		}
702a9de470cSBruce Richardson 	}
703a9de470cSBruce Richardson 	struct rte_mbuf *extra = NULL;
704a9de470cSBruce Richardson 	extra = rte_pktmbuf_alloc(pktmbuf_pool);
705a9de470cSBruce Richardson 	if(extra != NULL) {
706a9de470cSBruce Richardson 		printf("Error pool not empty");
707a9de470cSBruce Richardson 		ret = -1;
708a9de470cSBruce Richardson 	}
709a9de470cSBruce Richardson 	extra = rte_pktmbuf_clone(m[0], pktmbuf_pool);
710a9de470cSBruce Richardson 	if(extra != NULL) {
711a9de470cSBruce Richardson 		printf("Error pool not empty");
712a9de470cSBruce Richardson 		ret = -1;
713a9de470cSBruce Richardson 	}
714a9de470cSBruce Richardson 	/* free them */
715a9de470cSBruce Richardson 	for (i=0; i<NB_MBUF; i++) {
716a9de470cSBruce Richardson 		rte_pktmbuf_free(m[i]);
717a9de470cSBruce Richardson 	}
718a9de470cSBruce Richardson 
719a9de470cSBruce Richardson 	return ret;
720a9de470cSBruce Richardson }
721a9de470cSBruce Richardson 
722a9de470cSBruce Richardson /*
723824b67c2SMorten Brørup  * test bulk allocation and bulk free of mbufs
724824b67c2SMorten Brørup  */
725824b67c2SMorten Brørup static int
test_pktmbuf_pool_bulk(void)726824b67c2SMorten Brørup test_pktmbuf_pool_bulk(void)
727824b67c2SMorten Brørup {
728824b67c2SMorten Brørup 	struct rte_mempool *pool = NULL;
729824b67c2SMorten Brørup 	struct rte_mempool *pool2 = NULL;
730824b67c2SMorten Brørup 	unsigned int i;
731824b67c2SMorten Brørup 	struct rte_mbuf *m;
732824b67c2SMorten Brørup 	struct rte_mbuf *mbufs[NB_MBUF];
733824b67c2SMorten Brørup 	int ret = 0;
734824b67c2SMorten Brørup 
735824b67c2SMorten Brørup 	/* We cannot use the preallocated mbuf pools because their caches
736824b67c2SMorten Brørup 	 * prevent us from bulk allocating all objects in them.
737824b67c2SMorten Brørup 	 * So we create our own mbuf pools without caches.
738824b67c2SMorten Brørup 	 */
739824b67c2SMorten Brørup 	printf("Create mbuf pools for bulk allocation.\n");
740824b67c2SMorten Brørup 	pool = rte_pktmbuf_pool_create("test_pktmbuf_bulk",
741824b67c2SMorten Brørup 			NB_MBUF, 0, 0, MBUF_DATA_SIZE, SOCKET_ID_ANY);
742824b67c2SMorten Brørup 	if (pool == NULL) {
743824b67c2SMorten Brørup 		printf("rte_pktmbuf_pool_create() failed. rte_errno %d\n",
744824b67c2SMorten Brørup 		       rte_errno);
745824b67c2SMorten Brørup 		goto err;
746824b67c2SMorten Brørup 	}
747824b67c2SMorten Brørup 	pool2 = rte_pktmbuf_pool_create("test_pktmbuf_bulk2",
748824b67c2SMorten Brørup 			NB_MBUF, 0, 0, MBUF_DATA_SIZE, SOCKET_ID_ANY);
749824b67c2SMorten Brørup 	if (pool2 == NULL) {
750824b67c2SMorten Brørup 		printf("rte_pktmbuf_pool_create() failed. rte_errno %d\n",
751824b67c2SMorten Brørup 		       rte_errno);
752824b67c2SMorten Brørup 		goto err;
753824b67c2SMorten Brørup 	}
754824b67c2SMorten Brørup 
755824b67c2SMorten Brørup 	/* Preconditions: Mempools must be full. */
756824b67c2SMorten Brørup 	if (!(rte_mempool_full(pool) && rte_mempool_full(pool2))) {
757824b67c2SMorten Brørup 		printf("Test precondition failed: mempools not full\n");
758824b67c2SMorten Brørup 		goto err;
759824b67c2SMorten Brørup 	}
760824b67c2SMorten Brørup 	if (!(rte_mempool_avail_count(pool) == NB_MBUF &&
761824b67c2SMorten Brørup 			rte_mempool_avail_count(pool2) == NB_MBUF)) {
762824b67c2SMorten Brørup 		printf("Test precondition failed: mempools: %u+%u != %u+%u",
763824b67c2SMorten Brørup 		       rte_mempool_avail_count(pool),
764824b67c2SMorten Brørup 		       rte_mempool_avail_count(pool2),
765824b67c2SMorten Brørup 		       NB_MBUF, NB_MBUF);
766824b67c2SMorten Brørup 		goto err;
767824b67c2SMorten Brørup 	}
768824b67c2SMorten Brørup 
769824b67c2SMorten Brørup 	printf("Test single bulk alloc, followed by multiple bulk free.\n");
770824b67c2SMorten Brørup 
771824b67c2SMorten Brørup 	/* Bulk allocate all mbufs in the pool, in one go. */
772824b67c2SMorten Brørup 	ret = rte_pktmbuf_alloc_bulk(pool, mbufs, NB_MBUF);
773824b67c2SMorten Brørup 	if (ret != 0) {
774824b67c2SMorten Brørup 		printf("rte_pktmbuf_alloc_bulk() failed: %d\n", ret);
775824b67c2SMorten Brørup 		goto err;
776824b67c2SMorten Brørup 	}
777824b67c2SMorten Brørup 	/* Test that they have been removed from the pool. */
778824b67c2SMorten Brørup 	if (!rte_mempool_empty(pool)) {
779824b67c2SMorten Brørup 		printf("mempool not empty\n");
780824b67c2SMorten Brørup 		goto err;
781824b67c2SMorten Brørup 	}
782824b67c2SMorten Brørup 	/* Bulk free all mbufs, in four steps. */
783824b67c2SMorten Brørup 	RTE_BUILD_BUG_ON(NB_MBUF % 4 != 0);
784824b67c2SMorten Brørup 	for (i = 0; i < NB_MBUF; i += NB_MBUF / 4) {
785824b67c2SMorten Brørup 		rte_pktmbuf_free_bulk(&mbufs[i], NB_MBUF / 4);
786824b67c2SMorten Brørup 		/* Test that they have been returned to the pool. */
787824b67c2SMorten Brørup 		if (rte_mempool_avail_count(pool) != i + NB_MBUF / 4) {
788824b67c2SMorten Brørup 			printf("mempool avail count incorrect\n");
789824b67c2SMorten Brørup 			goto err;
790824b67c2SMorten Brørup 		}
791824b67c2SMorten Brørup 	}
792824b67c2SMorten Brørup 
793824b67c2SMorten Brørup 	printf("Test multiple bulk alloc, followed by single bulk free.\n");
794824b67c2SMorten Brørup 
795824b67c2SMorten Brørup 	/* Bulk allocate all mbufs in the pool, in four steps. */
796824b67c2SMorten Brørup 	for (i = 0; i < NB_MBUF; i += NB_MBUF / 4) {
797824b67c2SMorten Brørup 		ret = rte_pktmbuf_alloc_bulk(pool, &mbufs[i], NB_MBUF / 4);
798824b67c2SMorten Brørup 		if (ret != 0) {
799824b67c2SMorten Brørup 			printf("rte_pktmbuf_alloc_bulk() failed: %d\n", ret);
800824b67c2SMorten Brørup 			goto err;
801824b67c2SMorten Brørup 		}
802824b67c2SMorten Brørup 	}
803824b67c2SMorten Brørup 	/* Test that they have been removed from the pool. */
804824b67c2SMorten Brørup 	if (!rte_mempool_empty(pool)) {
805824b67c2SMorten Brørup 		printf("mempool not empty\n");
806824b67c2SMorten Brørup 		goto err;
807824b67c2SMorten Brørup 	}
808824b67c2SMorten Brørup 	/* Bulk free all mbufs, in one go. */
809824b67c2SMorten Brørup 	rte_pktmbuf_free_bulk(mbufs, NB_MBUF);
810824b67c2SMorten Brørup 	/* Test that they have been returned to the pool. */
811824b67c2SMorten Brørup 	if (!rte_mempool_full(pool)) {
812824b67c2SMorten Brørup 		printf("mempool not full\n");
813824b67c2SMorten Brørup 		goto err;
814824b67c2SMorten Brørup 	}
815824b67c2SMorten Brørup 
816824b67c2SMorten Brørup 	printf("Test bulk free of single long chain.\n");
817824b67c2SMorten Brørup 
818824b67c2SMorten Brørup 	/* Bulk allocate all mbufs in the pool, in one go. */
819824b67c2SMorten Brørup 	ret = rte_pktmbuf_alloc_bulk(pool, mbufs, NB_MBUF);
820824b67c2SMorten Brørup 	if (ret != 0) {
821824b67c2SMorten Brørup 		printf("rte_pktmbuf_alloc_bulk() failed: %d\n", ret);
822824b67c2SMorten Brørup 		goto err;
823824b67c2SMorten Brørup 	}
824824b67c2SMorten Brørup 	/* Create a long mbuf chain. */
825824b67c2SMorten Brørup 	for (i = 1; i < NB_MBUF; i++) {
826824b67c2SMorten Brørup 		ret = rte_pktmbuf_chain(mbufs[0], mbufs[i]);
827824b67c2SMorten Brørup 		if (ret != 0) {
828824b67c2SMorten Brørup 			printf("rte_pktmbuf_chain() failed: %d\n", ret);
829824b67c2SMorten Brørup 			goto err;
830824b67c2SMorten Brørup 		}
831824b67c2SMorten Brørup 		mbufs[i] = NULL;
832824b67c2SMorten Brørup 	}
833824b67c2SMorten Brørup 	/* Free the mbuf chain containing all the mbufs. */
834824b67c2SMorten Brørup 	rte_pktmbuf_free_bulk(mbufs, 1);
835824b67c2SMorten Brørup 	/* Test that they have been returned to the pool. */
836824b67c2SMorten Brørup 	if (!rte_mempool_full(pool)) {
837824b67c2SMorten Brørup 		printf("mempool not full\n");
838824b67c2SMorten Brørup 		goto err;
839824b67c2SMorten Brørup 	}
840824b67c2SMorten Brørup 
841824b67c2SMorten Brørup 	printf("Test bulk free of multiple chains using multiple pools.\n");
842824b67c2SMorten Brørup 
843824b67c2SMorten Brørup 	/* Create mbuf chains containing mbufs from different pools. */
844824b67c2SMorten Brørup 	RTE_BUILD_BUG_ON(CHAIN_LEN % 2 != 0);
845824b67c2SMorten Brørup 	RTE_BUILD_BUG_ON(NB_MBUF % (CHAIN_LEN / 2) != 0);
846824b67c2SMorten Brørup 	for (i = 0; i < NB_MBUF * 2; i++) {
847824b67c2SMorten Brørup 		m = rte_pktmbuf_alloc((i & 4) ? pool2 : pool);
848824b67c2SMorten Brørup 		if (m == NULL) {
849824b67c2SMorten Brørup 			printf("rte_pktmbuf_alloc() failed (%u)\n", i);
850824b67c2SMorten Brørup 			goto err;
851824b67c2SMorten Brørup 		}
852824b67c2SMorten Brørup 		if ((i % CHAIN_LEN) == 0)
853824b67c2SMorten Brørup 			mbufs[i / CHAIN_LEN] = m;
854824b67c2SMorten Brørup 		else
855824b67c2SMorten Brørup 			rte_pktmbuf_chain(mbufs[i / CHAIN_LEN], m);
856824b67c2SMorten Brørup 	}
857824b67c2SMorten Brørup 	/* Test that both pools have been emptied. */
858824b67c2SMorten Brørup 	if (!(rte_mempool_empty(pool) && rte_mempool_empty(pool2))) {
859824b67c2SMorten Brørup 		printf("mempools not empty\n");
860824b67c2SMorten Brørup 		goto err;
861824b67c2SMorten Brørup 	}
862824b67c2SMorten Brørup 	/* Free one mbuf chain. */
863824b67c2SMorten Brørup 	rte_pktmbuf_free_bulk(mbufs, 1);
864824b67c2SMorten Brørup 	/* Test that the segments have been returned to the pools. */
865824b67c2SMorten Brørup 	if (!(rte_mempool_avail_count(pool) == CHAIN_LEN / 2 &&
866824b67c2SMorten Brørup 			rte_mempool_avail_count(pool2) == CHAIN_LEN / 2)) {
867824b67c2SMorten Brørup 		printf("all segments of first mbuf have not been returned\n");
868824b67c2SMorten Brørup 		goto err;
869824b67c2SMorten Brørup 	}
870824b67c2SMorten Brørup 	/* Free the remaining mbuf chains. */
871824b67c2SMorten Brørup 	rte_pktmbuf_free_bulk(&mbufs[1], NB_MBUF * 2 / CHAIN_LEN - 1);
872824b67c2SMorten Brørup 	/* Test that they have been returned to the pools. */
873824b67c2SMorten Brørup 	if (!(rte_mempool_full(pool) && rte_mempool_full(pool2))) {
874824b67c2SMorten Brørup 		printf("mempools not full\n");
875824b67c2SMorten Brørup 		goto err;
876824b67c2SMorten Brørup 	}
877824b67c2SMorten Brørup 
878824b67c2SMorten Brørup 	ret = 0;
879824b67c2SMorten Brørup 	goto done;
880824b67c2SMorten Brørup 
881824b67c2SMorten Brørup err:
882824b67c2SMorten Brørup 	ret = -1;
883824b67c2SMorten Brørup 
884824b67c2SMorten Brørup done:
885824b67c2SMorten Brørup 	printf("Free mbuf pools for bulk allocation.\n");
886824b67c2SMorten Brørup 	rte_mempool_free(pool);
887824b67c2SMorten Brørup 	rte_mempool_free(pool2);
888824b67c2SMorten Brørup 	return ret;
889824b67c2SMorten Brørup }
890824b67c2SMorten Brørup 
891824b67c2SMorten Brørup /*
892a9de470cSBruce Richardson  * test that the pointer to the data on a packet mbuf is set properly
893a9de470cSBruce Richardson  */
894a9de470cSBruce Richardson static int
test_pktmbuf_pool_ptr(struct rte_mempool * pktmbuf_pool)895a9de470cSBruce Richardson test_pktmbuf_pool_ptr(struct rte_mempool *pktmbuf_pool)
896a9de470cSBruce Richardson {
897a9de470cSBruce Richardson 	unsigned i;
898a9de470cSBruce Richardson 	struct rte_mbuf *m[NB_MBUF];
899a9de470cSBruce Richardson 	int ret = 0;
900a9de470cSBruce Richardson 
901a9de470cSBruce Richardson 	for (i=0; i<NB_MBUF; i++)
902a9de470cSBruce Richardson 		m[i] = NULL;
903a9de470cSBruce Richardson 
904a9de470cSBruce Richardson 	/* alloc NB_MBUF mbufs */
905a9de470cSBruce Richardson 	for (i=0; i<NB_MBUF; i++) {
906a9de470cSBruce Richardson 		m[i] = rte_pktmbuf_alloc(pktmbuf_pool);
907a9de470cSBruce Richardson 		if (m[i] == NULL) {
908a9de470cSBruce Richardson 			printf("rte_pktmbuf_alloc() failed (%u)\n", i);
909a9de470cSBruce Richardson 			ret = -1;
910a9de470cSBruce Richardson 			break;
911a9de470cSBruce Richardson 		}
912a9de470cSBruce Richardson 		m[i]->data_off += 64;
913a9de470cSBruce Richardson 	}
914a9de470cSBruce Richardson 
915a9de470cSBruce Richardson 	/* free them */
916a9de470cSBruce Richardson 	for (i=0; i<NB_MBUF; i++) {
917a9de470cSBruce Richardson 		rte_pktmbuf_free(m[i]);
918a9de470cSBruce Richardson 	}
919a9de470cSBruce Richardson 
920a9de470cSBruce Richardson 	for (i=0; i<NB_MBUF; i++)
921a9de470cSBruce Richardson 		m[i] = NULL;
922a9de470cSBruce Richardson 
923a9de470cSBruce Richardson 	/* alloc NB_MBUF mbufs */
924a9de470cSBruce Richardson 	for (i=0; i<NB_MBUF; i++) {
925a9de470cSBruce Richardson 		m[i] = rte_pktmbuf_alloc(pktmbuf_pool);
926a9de470cSBruce Richardson 		if (m[i] == NULL) {
927a9de470cSBruce Richardson 			printf("rte_pktmbuf_alloc() failed (%u)\n", i);
928a9de470cSBruce Richardson 			ret = -1;
929a9de470cSBruce Richardson 			break;
930a9de470cSBruce Richardson 		}
931a9de470cSBruce Richardson 		if (m[i]->data_off != RTE_PKTMBUF_HEADROOM) {
932a9de470cSBruce Richardson 			printf("invalid data_off\n");
933a9de470cSBruce Richardson 			ret = -1;
934a9de470cSBruce Richardson 		}
935a9de470cSBruce Richardson 	}
936a9de470cSBruce Richardson 
937a9de470cSBruce Richardson 	/* free them */
938a9de470cSBruce Richardson 	for (i=0; i<NB_MBUF; i++) {
939a9de470cSBruce Richardson 		rte_pktmbuf_free(m[i]);
940a9de470cSBruce Richardson 	}
941a9de470cSBruce Richardson 
942a9de470cSBruce Richardson 	return ret;
943a9de470cSBruce Richardson }
944a9de470cSBruce Richardson 
945a9de470cSBruce Richardson static int
test_pktmbuf_free_segment(struct rte_mempool * pktmbuf_pool)946a9de470cSBruce Richardson test_pktmbuf_free_segment(struct rte_mempool *pktmbuf_pool)
947a9de470cSBruce Richardson {
948a9de470cSBruce Richardson 	unsigned i;
949a9de470cSBruce Richardson 	struct rte_mbuf *m[NB_MBUF];
950a9de470cSBruce Richardson 	int ret = 0;
951a9de470cSBruce Richardson 
952a9de470cSBruce Richardson 	for (i=0; i<NB_MBUF; i++)
953a9de470cSBruce Richardson 		m[i] = NULL;
954a9de470cSBruce Richardson 
955a9de470cSBruce Richardson 	/* alloc NB_MBUF mbufs */
956a9de470cSBruce Richardson 	for (i=0; i<NB_MBUF; i++) {
957a9de470cSBruce Richardson 		m[i] = rte_pktmbuf_alloc(pktmbuf_pool);
958a9de470cSBruce Richardson 		if (m[i] == NULL) {
959a9de470cSBruce Richardson 			printf("rte_pktmbuf_alloc() failed (%u)\n", i);
960a9de470cSBruce Richardson 			ret = -1;
961a9de470cSBruce Richardson 		}
962a9de470cSBruce Richardson 	}
963a9de470cSBruce Richardson 
964a9de470cSBruce Richardson 	/* free them */
965a9de470cSBruce Richardson 	for (i=0; i<NB_MBUF; i++) {
966a9de470cSBruce Richardson 		if (m[i] != NULL) {
967a9de470cSBruce Richardson 			struct rte_mbuf *mb, *mt;
968a9de470cSBruce Richardson 
969a9de470cSBruce Richardson 			mb = m[i];
970a9de470cSBruce Richardson 			while(mb != NULL) {
971a9de470cSBruce Richardson 				mt = mb;
972a9de470cSBruce Richardson 				mb = mb->next;
973a9de470cSBruce Richardson 				rte_pktmbuf_free_seg(mt);
974a9de470cSBruce Richardson 			}
975a9de470cSBruce Richardson 		}
976a9de470cSBruce Richardson 	}
977a9de470cSBruce Richardson 
978a9de470cSBruce Richardson 	return ret;
979a9de470cSBruce Richardson }
980a9de470cSBruce Richardson 
981a9de470cSBruce Richardson /*
982a9de470cSBruce Richardson  * Stress test for rte_mbuf atomic refcnt.
983a9de470cSBruce Richardson  * Implies that RTE_MBUF_REFCNT_ATOMIC is defined.
984a9de470cSBruce Richardson  * For more efficiency, recommended to run with RTE_LIBRTE_MBUF_DEBUG defined.
985a9de470cSBruce Richardson  */
986a9de470cSBruce Richardson 
987a9de470cSBruce Richardson #ifdef RTE_MBUF_REFCNT_ATOMIC
988a9de470cSBruce Richardson 
989a9de470cSBruce Richardson static int
test_refcnt_worker(void * arg)990cb056611SStephen Hemminger test_refcnt_worker(void *arg)
991a9de470cSBruce Richardson {
992a9de470cSBruce Richardson 	unsigned lcore, free;
993a9de470cSBruce Richardson 	void *mp = 0;
994a9de470cSBruce Richardson 	struct rte_ring *refcnt_mbuf_ring = arg;
995a9de470cSBruce Richardson 
996a9de470cSBruce Richardson 	lcore = rte_lcore_id();
997a9de470cSBruce Richardson 	printf("%s started at lcore %u\n", __func__, lcore);
998a9de470cSBruce Richardson 
999a9de470cSBruce Richardson 	free = 0;
1000cb056611SStephen Hemminger 	while (refcnt_stop_workers == 0) {
1001a9de470cSBruce Richardson 		if (rte_ring_dequeue(refcnt_mbuf_ring, &mp) == 0) {
1002a9de470cSBruce Richardson 			free++;
1003a9de470cSBruce Richardson 			rte_pktmbuf_free(mp);
1004a9de470cSBruce Richardson 		}
1005a9de470cSBruce Richardson 	}
1006a9de470cSBruce Richardson 
1007a9de470cSBruce Richardson 	refcnt_lcore[lcore] += free;
1008a9de470cSBruce Richardson 	printf("%s finished at lcore %u, "
1009a9de470cSBruce Richardson 	       "number of freed mbufs: %u\n",
1010a9de470cSBruce Richardson 	       __func__, lcore, free);
1011a9de470cSBruce Richardson 	return 0;
1012a9de470cSBruce Richardson }
1013a9de470cSBruce Richardson 
1014a9de470cSBruce Richardson static void
test_refcnt_iter(unsigned int lcore,unsigned int iter,struct rte_mempool * refcnt_pool,struct rte_ring * refcnt_mbuf_ring)1015a9de470cSBruce Richardson test_refcnt_iter(unsigned int lcore, unsigned int iter,
1016a9de470cSBruce Richardson 		 struct rte_mempool *refcnt_pool,
1017a9de470cSBruce Richardson 		 struct rte_ring *refcnt_mbuf_ring)
1018a9de470cSBruce Richardson {
1019a9de470cSBruce Richardson 	uint16_t ref;
1020a9de470cSBruce Richardson 	unsigned i, n, tref, wn;
1021a9de470cSBruce Richardson 	struct rte_mbuf *m;
1022a9de470cSBruce Richardson 
1023a9de470cSBruce Richardson 	tref = 0;
1024a9de470cSBruce Richardson 
1025a9de470cSBruce Richardson 	/* For each mbuf in the pool:
1026a9de470cSBruce Richardson 	 * - allocate mbuf,
1027a9de470cSBruce Richardson 	 * - increment it's reference up to N+1,
1028cb056611SStephen Hemminger 	 * - enqueue it N times into the ring for worker cores to free.
1029a9de470cSBruce Richardson 	 */
1030a9de470cSBruce Richardson 	for (i = 0, n = rte_mempool_avail_count(refcnt_pool);
1031a9de470cSBruce Richardson 	    i != n && (m = rte_pktmbuf_alloc(refcnt_pool)) != NULL;
1032a9de470cSBruce Richardson 	    i++) {
1033a9de470cSBruce Richardson 		ref = RTE_MAX(rte_rand() % REFCNT_MAX_REF, 1UL);
1034a9de470cSBruce Richardson 		tref += ref;
1035a9de470cSBruce Richardson 		if ((ref & 1) != 0) {
1036a9de470cSBruce Richardson 			rte_pktmbuf_refcnt_update(m, ref);
1037a9de470cSBruce Richardson 			while (ref-- != 0)
1038a9de470cSBruce Richardson 				rte_ring_enqueue(refcnt_mbuf_ring, m);
1039a9de470cSBruce Richardson 		} else {
1040a9de470cSBruce Richardson 			while (ref-- != 0) {
1041a9de470cSBruce Richardson 				rte_pktmbuf_refcnt_update(m, 1);
1042a9de470cSBruce Richardson 				rte_ring_enqueue(refcnt_mbuf_ring, m);
1043a9de470cSBruce Richardson 			}
1044a9de470cSBruce Richardson 		}
1045a9de470cSBruce Richardson 		rte_pktmbuf_free(m);
1046a9de470cSBruce Richardson 	}
1047a9de470cSBruce Richardson 
1048a9de470cSBruce Richardson 	if (i != n)
1049a9de470cSBruce Richardson 		rte_panic("(lcore=%u, iter=%u): was able to allocate only "
1050a9de470cSBruce Richardson 		          "%u from %u mbufs\n", lcore, iter, i, n);
1051a9de470cSBruce Richardson 
1052cb056611SStephen Hemminger 	/* wait till worker lcores  will consume all mbufs */
1053a9de470cSBruce Richardson 	while (!rte_ring_empty(refcnt_mbuf_ring))
1054a9de470cSBruce Richardson 		;
1055a9de470cSBruce Richardson 
1056a9de470cSBruce Richardson 	/* check that all mbufs are back into mempool by now */
1057a9de470cSBruce Richardson 	for (wn = 0; wn != REFCNT_MAX_TIMEOUT; wn++) {
1058a9de470cSBruce Richardson 		if ((i = rte_mempool_avail_count(refcnt_pool)) == n) {
1059a9de470cSBruce Richardson 			refcnt_lcore[lcore] += tref;
1060a9de470cSBruce Richardson 			printf("%s(lcore=%u, iter=%u) completed, "
1061a9de470cSBruce Richardson 			    "%u references processed\n",
1062a9de470cSBruce Richardson 			    __func__, lcore, iter, tref);
1063a9de470cSBruce Richardson 			return;
1064a9de470cSBruce Richardson 		}
1065a9de470cSBruce Richardson 		rte_delay_ms(100);
1066a9de470cSBruce Richardson 	}
1067a9de470cSBruce Richardson 
1068a9de470cSBruce Richardson 	rte_panic("(lcore=%u, iter=%u): after %us only "
1069a9de470cSBruce Richardson 	          "%u of %u mbufs left free\n", lcore, iter, wn, i, n);
1070a9de470cSBruce Richardson }
1071a9de470cSBruce Richardson 
1072a9de470cSBruce Richardson static int
test_refcnt_main(struct rte_mempool * refcnt_pool,struct rte_ring * refcnt_mbuf_ring)1073cb056611SStephen Hemminger test_refcnt_main(struct rte_mempool *refcnt_pool,
1074a9de470cSBruce Richardson 		   struct rte_ring *refcnt_mbuf_ring)
1075a9de470cSBruce Richardson {
1076a9de470cSBruce Richardson 	unsigned i, lcore;
1077a9de470cSBruce Richardson 
1078a9de470cSBruce Richardson 	lcore = rte_lcore_id();
1079a9de470cSBruce Richardson 	printf("%s started at lcore %u\n", __func__, lcore);
1080a9de470cSBruce Richardson 
1081a9de470cSBruce Richardson 	for (i = 0; i != REFCNT_MAX_ITER; i++)
1082a9de470cSBruce Richardson 		test_refcnt_iter(lcore, i, refcnt_pool, refcnt_mbuf_ring);
1083a9de470cSBruce Richardson 
1084cb056611SStephen Hemminger 	refcnt_stop_workers = 1;
1085a9de470cSBruce Richardson 	rte_wmb();
1086a9de470cSBruce Richardson 
1087a9de470cSBruce Richardson 	printf("%s finished at lcore %u\n", __func__, lcore);
1088a9de470cSBruce Richardson 	return 0;
1089a9de470cSBruce Richardson }
1090a9de470cSBruce Richardson 
1091a9de470cSBruce Richardson #endif
1092a9de470cSBruce Richardson 
1093a9de470cSBruce Richardson static int
test_refcnt_mbuf(void)1094a9de470cSBruce Richardson test_refcnt_mbuf(void)
1095a9de470cSBruce Richardson {
1096a9de470cSBruce Richardson #ifdef RTE_MBUF_REFCNT_ATOMIC
1097cb056611SStephen Hemminger 	unsigned int main_lcore, worker, tref;
1098a9de470cSBruce Richardson 	int ret = -1;
1099a9de470cSBruce Richardson 	struct rte_mempool *refcnt_pool = NULL;
1100a9de470cSBruce Richardson 	struct rte_ring *refcnt_mbuf_ring = NULL;
1101a9de470cSBruce Richardson 
1102e0f4a0edSDavid Marchand 	if (rte_lcore_count() < 2) {
1103e0f4a0edSDavid Marchand 		printf("Not enough cores for test_refcnt_mbuf, expecting at least 2\n");
1104e0f4a0edSDavid Marchand 		return TEST_SKIPPED;
1105a9de470cSBruce Richardson 	}
1106a9de470cSBruce Richardson 
1107e0f4a0edSDavid Marchand 	printf("starting %s, at %u lcores\n", __func__, rte_lcore_count());
1108a9de470cSBruce Richardson 
1109a9de470cSBruce Richardson 	/* create refcnt pool & ring if they don't exist */
1110a9de470cSBruce Richardson 
1111a9de470cSBruce Richardson 	refcnt_pool = rte_pktmbuf_pool_create(MAKE_STRING(refcnt_pool),
1112a9de470cSBruce Richardson 					      REFCNT_MBUF_NUM, 0, 0, 0,
1113a9de470cSBruce Richardson 					      SOCKET_ID_ANY);
1114a9de470cSBruce Richardson 	if (refcnt_pool == NULL) {
1115a9de470cSBruce Richardson 		printf("%s: cannot allocate " MAKE_STRING(refcnt_pool) "\n",
1116a9de470cSBruce Richardson 		       __func__);
1117a9de470cSBruce Richardson 		return -1;
1118a9de470cSBruce Richardson 	}
1119a9de470cSBruce Richardson 
1120a9de470cSBruce Richardson 	refcnt_mbuf_ring = rte_ring_create("refcnt_mbuf_ring",
1121a9de470cSBruce Richardson 					   rte_align32pow2(REFCNT_RING_SIZE), SOCKET_ID_ANY,
1122a9de470cSBruce Richardson 					   RING_F_SP_ENQ);
1123a9de470cSBruce Richardson 	if (refcnt_mbuf_ring == NULL) {
1124a9de470cSBruce Richardson 		printf("%s: cannot allocate " MAKE_STRING(refcnt_mbuf_ring)
1125a9de470cSBruce Richardson 		       "\n", __func__);
1126a9de470cSBruce Richardson 		goto err;
1127a9de470cSBruce Richardson 	}
1128a9de470cSBruce Richardson 
1129cb056611SStephen Hemminger 	refcnt_stop_workers = 0;
1130a9de470cSBruce Richardson 	memset(refcnt_lcore, 0, sizeof (refcnt_lcore));
1131a9de470cSBruce Richardson 
1132cb056611SStephen Hemminger 	rte_eal_mp_remote_launch(test_refcnt_worker, refcnt_mbuf_ring, SKIP_MAIN);
1133a9de470cSBruce Richardson 
1134cb056611SStephen Hemminger 	test_refcnt_main(refcnt_pool, refcnt_mbuf_ring);
1135a9de470cSBruce Richardson 
1136a9de470cSBruce Richardson 	rte_eal_mp_wait_lcore();
1137a9de470cSBruce Richardson 
11384a6672c2SStephen Hemminger 	/* check that we processed all references */
1139a9de470cSBruce Richardson 	tref = 0;
1140cb056611SStephen Hemminger 	main_lcore = rte_get_main_lcore();
1141a9de470cSBruce Richardson 
1142cb056611SStephen Hemminger 	RTE_LCORE_FOREACH_WORKER(worker)
1143cb056611SStephen Hemminger 		tref += refcnt_lcore[worker];
1144a9de470cSBruce Richardson 
1145cb056611SStephen Hemminger 	if (tref != refcnt_lcore[main_lcore])
1146611faa5fSLuca Boccassi 		rte_panic("referenced mbufs: %u, freed mbufs: %u\n",
1147cb056611SStephen Hemminger 			  tref, refcnt_lcore[main_lcore]);
1148a9de470cSBruce Richardson 
1149a9de470cSBruce Richardson 	rte_mempool_dump(stdout, refcnt_pool);
1150a9de470cSBruce Richardson 	rte_ring_dump(stdout, refcnt_mbuf_ring);
1151a9de470cSBruce Richardson 
1152a9de470cSBruce Richardson 	ret = 0;
1153a9de470cSBruce Richardson 
1154a9de470cSBruce Richardson err:
1155a9de470cSBruce Richardson 	rte_mempool_free(refcnt_pool);
1156a9de470cSBruce Richardson 	rte_ring_free(refcnt_mbuf_ring);
1157a9de470cSBruce Richardson 	return ret;
1158a9de470cSBruce Richardson #else
1159a9de470cSBruce Richardson 	return 0;
1160a9de470cSBruce Richardson #endif
1161a9de470cSBruce Richardson }
1162a9de470cSBruce Richardson 
11633c60274cSJie Zhou #ifdef RTE_EXEC_ENV_WINDOWS
11643c60274cSJie Zhou static int
test_failing_mbuf_sanity_check(struct rte_mempool * pktmbuf_pool)11653c60274cSJie Zhou test_failing_mbuf_sanity_check(struct rte_mempool *pktmbuf_pool)
11663c60274cSJie Zhou {
11673c60274cSJie Zhou 	RTE_SET_USED(pktmbuf_pool);
11683c60274cSJie Zhou 	return TEST_SKIPPED;
11693c60274cSJie Zhou }
11703c60274cSJie Zhou #else
1171b6c419ddSRuifeng Wang /* Verify if mbuf can pass the check */
1172b6c419ddSRuifeng Wang static bool
mbuf_check_pass(struct rte_mbuf * buf)1173b6c419ddSRuifeng Wang mbuf_check_pass(struct rte_mbuf *buf)
1174a9de470cSBruce Richardson {
1175b6c419ddSRuifeng Wang 	const char *reason;
1176a9de470cSBruce Richardson 
1177b6c419ddSRuifeng Wang 	if (rte_mbuf_check(buf, 1, &reason) == 0)
1178b6c419ddSRuifeng Wang 		return true;
1179a9de470cSBruce Richardson 
1180b6c419ddSRuifeng Wang 	return false;
1181a9de470cSBruce Richardson }
1182a9de470cSBruce Richardson 
1183a9de470cSBruce Richardson static int
test_failing_mbuf_sanity_check(struct rte_mempool * pktmbuf_pool)1184a9de470cSBruce Richardson test_failing_mbuf_sanity_check(struct rte_mempool *pktmbuf_pool)
1185a9de470cSBruce Richardson {
1186a9de470cSBruce Richardson 	struct rte_mbuf *buf;
1187a9de470cSBruce Richardson 	struct rte_mbuf badbuf;
1188a9de470cSBruce Richardson 
1189a9de470cSBruce Richardson 	printf("Checking rte_mbuf_sanity_check for failure conditions\n");
1190a9de470cSBruce Richardson 
1191a9de470cSBruce Richardson 	/* get a good mbuf to use to make copies */
1192a9de470cSBruce Richardson 	buf = rte_pktmbuf_alloc(pktmbuf_pool);
1193a9de470cSBruce Richardson 	if (buf == NULL)
1194a9de470cSBruce Richardson 		return -1;
11955d3e7176SViacheslav Ovsiienko 
1196a9de470cSBruce Richardson 	printf("Checking good mbuf initially\n");
1197b6c419ddSRuifeng Wang 	if (!mbuf_check_pass(buf))
1198a9de470cSBruce Richardson 		return -1;
1199a9de470cSBruce Richardson 
1200a9de470cSBruce Richardson 	printf("Now checking for error conditions\n");
1201a9de470cSBruce Richardson 
1202b6c419ddSRuifeng Wang 	if (mbuf_check_pass(NULL)) {
1203a9de470cSBruce Richardson 		printf("Error with NULL mbuf test\n");
1204a9de470cSBruce Richardson 		return -1;
1205a9de470cSBruce Richardson 	}
1206a9de470cSBruce Richardson 
1207a9de470cSBruce Richardson 	badbuf = *buf;
1208a9de470cSBruce Richardson 	badbuf.pool = NULL;
1209b6c419ddSRuifeng Wang 	if (mbuf_check_pass(&badbuf)) {
1210a9de470cSBruce Richardson 		printf("Error with bad-pool mbuf test\n");
1211a9de470cSBruce Richardson 		return -1;
1212a9de470cSBruce Richardson 	}
1213a9de470cSBruce Richardson 
1214d5d9e8feSThomas Monjalon 	if (RTE_IOVA_IN_MBUF) {
1215a9de470cSBruce Richardson 		badbuf = *buf;
1216e811e2d7SShijith Thotton 		rte_mbuf_iova_set(&badbuf, 0);
1217b6c419ddSRuifeng Wang 		if (mbuf_check_pass(&badbuf)) {
1218a9de470cSBruce Richardson 			printf("Error with bad-physaddr mbuf test\n");
1219a9de470cSBruce Richardson 			return -1;
1220a9de470cSBruce Richardson 		}
1221a986c2b7SShijith Thotton 	}
1222a9de470cSBruce Richardson 
1223a9de470cSBruce Richardson 	badbuf = *buf;
1224a9de470cSBruce Richardson 	badbuf.buf_addr = NULL;
1225b6c419ddSRuifeng Wang 	if (mbuf_check_pass(&badbuf)) {
1226a9de470cSBruce Richardson 		printf("Error with bad-addr mbuf test\n");
1227a9de470cSBruce Richardson 		return -1;
1228a9de470cSBruce Richardson 	}
1229a9de470cSBruce Richardson 
1230a9de470cSBruce Richardson 	badbuf = *buf;
1231a9de470cSBruce Richardson 	badbuf.refcnt = 0;
1232b6c419ddSRuifeng Wang 	if (mbuf_check_pass(&badbuf)) {
1233a9de470cSBruce Richardson 		printf("Error with bad-refcnt(0) mbuf test\n");
1234a9de470cSBruce Richardson 		return -1;
1235a9de470cSBruce Richardson 	}
1236a9de470cSBruce Richardson 
1237a9de470cSBruce Richardson 	badbuf = *buf;
1238a9de470cSBruce Richardson 	badbuf.refcnt = UINT16_MAX;
1239b6c419ddSRuifeng Wang 	if (mbuf_check_pass(&badbuf)) {
1240a9de470cSBruce Richardson 		printf("Error with bad-refcnt(MAX) mbuf test\n");
1241a9de470cSBruce Richardson 		return -1;
1242a9de470cSBruce Richardson 	}
1243a9de470cSBruce Richardson 
1244a9de470cSBruce Richardson 	return 0;
1245a9de470cSBruce Richardson }
1246a9de470cSBruce Richardson 
12473c60274cSJie Zhou #endif /* !RTE_EXEC_ENV_WINDOWS */
12483c60274cSJie Zhou 
1249a9de470cSBruce Richardson static int
test_mbuf_linearize(struct rte_mempool * pktmbuf_pool,int pkt_len,int nb_segs)1250a9de470cSBruce Richardson test_mbuf_linearize(struct rte_mempool *pktmbuf_pool, int pkt_len,
1251a9de470cSBruce Richardson 		    int nb_segs)
1252a9de470cSBruce Richardson {
1253a9de470cSBruce Richardson 
1254a9de470cSBruce Richardson 	struct rte_mbuf *m = NULL, *mbuf = NULL;
1255a9de470cSBruce Richardson 	uint8_t *data;
1256a9de470cSBruce Richardson 	int data_len = 0;
1257a9de470cSBruce Richardson 	int remain;
1258a9de470cSBruce Richardson 	int seg, seg_len;
1259a9de470cSBruce Richardson 	int i;
1260a9de470cSBruce Richardson 
1261a9de470cSBruce Richardson 	if (pkt_len < 1) {
1262a9de470cSBruce Richardson 		printf("Packet size must be 1 or more (is %d)\n", pkt_len);
1263a9de470cSBruce Richardson 		return -1;
1264a9de470cSBruce Richardson 	}
1265a9de470cSBruce Richardson 
1266a9de470cSBruce Richardson 	if (nb_segs < 1) {
1267a9de470cSBruce Richardson 		printf("Number of segments must be 1 or more (is %d)\n",
1268a9de470cSBruce Richardson 				nb_segs);
1269a9de470cSBruce Richardson 		return -1;
1270a9de470cSBruce Richardson 	}
1271a9de470cSBruce Richardson 
1272a9de470cSBruce Richardson 	seg_len = pkt_len / nb_segs;
1273a9de470cSBruce Richardson 	if (seg_len == 0)
1274a9de470cSBruce Richardson 		seg_len = 1;
1275a9de470cSBruce Richardson 
1276a9de470cSBruce Richardson 	remain = pkt_len;
1277a9de470cSBruce Richardson 
1278a9de470cSBruce Richardson 	/* Create chained mbuf_src and fill it generated data */
1279a9de470cSBruce Richardson 	for (seg = 0; remain > 0; seg++) {
1280a9de470cSBruce Richardson 
1281a9de470cSBruce Richardson 		m = rte_pktmbuf_alloc(pktmbuf_pool);
1282a9de470cSBruce Richardson 		if (m == NULL) {
1283a9de470cSBruce Richardson 			printf("Cannot create segment for source mbuf");
1284a9de470cSBruce Richardson 			goto fail;
1285a9de470cSBruce Richardson 		}
1286a9de470cSBruce Richardson 
1287a9de470cSBruce Richardson 		/* Make sure if tailroom is zeroed */
1288a9de470cSBruce Richardson 		memset(rte_pktmbuf_mtod(m, uint8_t *), 0,
1289a9de470cSBruce Richardson 				rte_pktmbuf_tailroom(m));
1290a9de470cSBruce Richardson 
1291a9de470cSBruce Richardson 		data_len = remain;
1292a9de470cSBruce Richardson 		if (data_len > seg_len)
1293a9de470cSBruce Richardson 			data_len = seg_len;
1294a9de470cSBruce Richardson 
1295a9de470cSBruce Richardson 		data = (uint8_t *)rte_pktmbuf_append(m, data_len);
1296a9de470cSBruce Richardson 		if (data == NULL) {
1297a9de470cSBruce Richardson 			printf("Cannot append %d bytes to the mbuf\n",
1298a9de470cSBruce Richardson 					data_len);
1299a9de470cSBruce Richardson 			goto fail;
1300a9de470cSBruce Richardson 		}
1301a9de470cSBruce Richardson 
1302a9de470cSBruce Richardson 		for (i = 0; i < data_len; i++)
1303a9de470cSBruce Richardson 			data[i] = (seg * seg_len + i) % 0x0ff;
1304a9de470cSBruce Richardson 
1305a9de470cSBruce Richardson 		if (seg == 0)
1306a9de470cSBruce Richardson 			mbuf = m;
1307a9de470cSBruce Richardson 		else
1308a9de470cSBruce Richardson 			rte_pktmbuf_chain(mbuf, m);
1309a9de470cSBruce Richardson 
1310a9de470cSBruce Richardson 		remain -= data_len;
1311a9de470cSBruce Richardson 	}
1312a9de470cSBruce Richardson 
1313a9de470cSBruce Richardson 	/* Create destination buffer to store coalesced data */
1314a9de470cSBruce Richardson 	if (rte_pktmbuf_linearize(mbuf)) {
1315a9de470cSBruce Richardson 		printf("Mbuf linearization failed\n");
1316a9de470cSBruce Richardson 		goto fail;
1317a9de470cSBruce Richardson 	}
1318a9de470cSBruce Richardson 
1319a9de470cSBruce Richardson 	if (!rte_pktmbuf_is_contiguous(mbuf)) {
1320a9de470cSBruce Richardson 		printf("Source buffer should be contiguous after "
1321a9de470cSBruce Richardson 				"linearization\n");
1322a9de470cSBruce Richardson 		goto fail;
1323a9de470cSBruce Richardson 	}
1324a9de470cSBruce Richardson 
1325a9de470cSBruce Richardson 	data = rte_pktmbuf_mtod(mbuf, uint8_t *);
1326a9de470cSBruce Richardson 
1327a9de470cSBruce Richardson 	for (i = 0; i < pkt_len; i++)
1328a9de470cSBruce Richardson 		if (data[i] != (i % 0x0ff)) {
1329a9de470cSBruce Richardson 			printf("Incorrect data in linearized mbuf\n");
1330a9de470cSBruce Richardson 			goto fail;
1331a9de470cSBruce Richardson 		}
1332a9de470cSBruce Richardson 
1333a9de470cSBruce Richardson 	rte_pktmbuf_free(mbuf);
1334a9de470cSBruce Richardson 	return 0;
1335a9de470cSBruce Richardson 
1336a9de470cSBruce Richardson fail:
1337a9de470cSBruce Richardson 	rte_pktmbuf_free(mbuf);
1338a9de470cSBruce Richardson 	return -1;
1339a9de470cSBruce Richardson }
1340a9de470cSBruce Richardson 
1341a9de470cSBruce Richardson static int
test_mbuf_linearize_check(struct rte_mempool * pktmbuf_pool)1342a9de470cSBruce Richardson test_mbuf_linearize_check(struct rte_mempool *pktmbuf_pool)
1343a9de470cSBruce Richardson {
1344a9de470cSBruce Richardson 	struct test_mbuf_array {
1345a9de470cSBruce Richardson 		int size;
1346a9de470cSBruce Richardson 		int nb_segs;
1347a9de470cSBruce Richardson 	} mbuf_array[] = {
1348a9de470cSBruce Richardson 			{ 128, 1 },
1349a9de470cSBruce Richardson 			{ 64, 64 },
1350a9de470cSBruce Richardson 			{ 512, 10 },
1351a9de470cSBruce Richardson 			{ 250, 11 },
1352a9de470cSBruce Richardson 			{ 123, 8 },
1353a9de470cSBruce Richardson 	};
1354a9de470cSBruce Richardson 	unsigned int i;
1355a9de470cSBruce Richardson 
1356a9de470cSBruce Richardson 	printf("Test mbuf linearize API\n");
1357a9de470cSBruce Richardson 
1358a9de470cSBruce Richardson 	for (i = 0; i < RTE_DIM(mbuf_array); i++)
1359a9de470cSBruce Richardson 		if (test_mbuf_linearize(pktmbuf_pool, mbuf_array[i].size,
1360a9de470cSBruce Richardson 				mbuf_array[i].nb_segs)) {
1361a9de470cSBruce Richardson 			printf("Test failed for %d, %d\n", mbuf_array[i].size,
1362a9de470cSBruce Richardson 					mbuf_array[i].nb_segs);
1363a9de470cSBruce Richardson 			return -1;
1364a9de470cSBruce Richardson 		}
1365a9de470cSBruce Richardson 
1366a9de470cSBruce Richardson 	return 0;
1367a9de470cSBruce Richardson }
1368a9de470cSBruce Richardson 
13698d9c2c3aSKonstantin Ananyev /*
13708d9c2c3aSKonstantin Ananyev  * Helper function for test_tx_ofload
13718d9c2c3aSKonstantin Ananyev  */
13728d9c2c3aSKonstantin Ananyev static inline void
set_tx_offload(struct rte_mbuf * mb,uint64_t il2,uint64_t il3,uint64_t il4,uint64_t tso,uint64_t ol3,uint64_t ol2)13738d9c2c3aSKonstantin Ananyev set_tx_offload(struct rte_mbuf *mb, uint64_t il2, uint64_t il3, uint64_t il4,
13748d9c2c3aSKonstantin Ananyev 	uint64_t tso, uint64_t ol3, uint64_t ol2)
13758d9c2c3aSKonstantin Ananyev {
13768d9c2c3aSKonstantin Ananyev 	mb->l2_len = il2;
13778d9c2c3aSKonstantin Ananyev 	mb->l3_len = il3;
13788d9c2c3aSKonstantin Ananyev 	mb->l4_len = il4;
13798d9c2c3aSKonstantin Ananyev 	mb->tso_segsz = tso;
13808d9c2c3aSKonstantin Ananyev 	mb->outer_l3_len = ol3;
13818d9c2c3aSKonstantin Ananyev 	mb->outer_l2_len = ol2;
13828d9c2c3aSKonstantin Ananyev }
13838d9c2c3aSKonstantin Ananyev 
13848d9c2c3aSKonstantin Ananyev static int
test_tx_offload(void)13858d9c2c3aSKonstantin Ananyev test_tx_offload(void)
13868d9c2c3aSKonstantin Ananyev {
13878d9c2c3aSKonstantin Ananyev 	struct rte_mbuf *mb;
13888d9c2c3aSKonstantin Ananyev 	uint64_t tm, v1, v2;
13898d9c2c3aSKonstantin Ananyev 	size_t sz;
13908d9c2c3aSKonstantin Ananyev 	uint32_t i;
13918d9c2c3aSKonstantin Ananyev 
13928d9c2c3aSKonstantin Ananyev 	static volatile struct {
13938d9c2c3aSKonstantin Ananyev 		uint16_t l2;
13948d9c2c3aSKonstantin Ananyev 		uint16_t l3;
13958d9c2c3aSKonstantin Ananyev 		uint16_t l4;
13968d9c2c3aSKonstantin Ananyev 		uint16_t tso;
13978d9c2c3aSKonstantin Ananyev 	} txof;
13988d9c2c3aSKonstantin Ananyev 
13998d9c2c3aSKonstantin Ananyev 	const uint32_t num = 0x10000;
14008d9c2c3aSKonstantin Ananyev 
14018d9c2c3aSKonstantin Ananyev 	txof.l2 = rte_rand() % (1 <<  RTE_MBUF_L2_LEN_BITS);
14028d9c2c3aSKonstantin Ananyev 	txof.l3 = rte_rand() % (1 <<  RTE_MBUF_L3_LEN_BITS);
14038d9c2c3aSKonstantin Ananyev 	txof.l4 = rte_rand() % (1 <<  RTE_MBUF_L4_LEN_BITS);
14048d9c2c3aSKonstantin Ananyev 	txof.tso = rte_rand() % (1 <<   RTE_MBUF_TSO_SEGSZ_BITS);
14058d9c2c3aSKonstantin Ananyev 
14068d9c2c3aSKonstantin Ananyev 	printf("%s started, tx_offload = {\n"
14078d9c2c3aSKonstantin Ananyev 		"\tl2_len=%#hx,\n"
14088d9c2c3aSKonstantin Ananyev 		"\tl3_len=%#hx,\n"
14098d9c2c3aSKonstantin Ananyev 		"\tl4_len=%#hx,\n"
14108d9c2c3aSKonstantin Ananyev 		"\ttso_segsz=%#hx,\n"
14118d9c2c3aSKonstantin Ananyev 		"\touter_l3_len=%#x,\n"
14128d9c2c3aSKonstantin Ananyev 		"\touter_l2_len=%#x,\n"
14138d9c2c3aSKonstantin Ananyev 		"};\n",
14148d9c2c3aSKonstantin Ananyev 		__func__,
14158d9c2c3aSKonstantin Ananyev 		txof.l2, txof.l3, txof.l4, txof.tso, txof.l3, txof.l2);
14168d9c2c3aSKonstantin Ananyev 
14178d9c2c3aSKonstantin Ananyev 	sz = sizeof(*mb) * num;
14188d9c2c3aSKonstantin Ananyev 	mb = rte_zmalloc(NULL, sz, RTE_CACHE_LINE_SIZE);
14198d9c2c3aSKonstantin Ananyev 	if (mb == NULL) {
14208d9c2c3aSKonstantin Ananyev 		printf("%s failed, out of memory\n", __func__);
14218d9c2c3aSKonstantin Ananyev 		return -ENOMEM;
14228d9c2c3aSKonstantin Ananyev 	}
14238d9c2c3aSKonstantin Ananyev 
14248d9c2c3aSKonstantin Ananyev 	memset(mb, 0, sz);
14258d9c2c3aSKonstantin Ananyev 	tm = rte_rdtsc_precise();
14268d9c2c3aSKonstantin Ananyev 
14278d9c2c3aSKonstantin Ananyev 	for (i = 0; i != num; i++)
14288d9c2c3aSKonstantin Ananyev 		set_tx_offload(mb + i, txof.l2, txof.l3, txof.l4,
14298d9c2c3aSKonstantin Ananyev 			txof.tso, txof.l3, txof.l2);
14308d9c2c3aSKonstantin Ananyev 
14318d9c2c3aSKonstantin Ananyev 	tm = rte_rdtsc_precise() - tm;
14328d9c2c3aSKonstantin Ananyev 	printf("%s set tx_offload by bit-fields: %u iterations, %"
14338d9c2c3aSKonstantin Ananyev 		PRIu64 " cycles, %#Lf cycles/iter\n",
14348d9c2c3aSKonstantin Ananyev 		__func__, num, tm, (long double)tm / num);
14358d9c2c3aSKonstantin Ananyev 
14368d9c2c3aSKonstantin Ananyev 	v1 = mb[rte_rand() % num].tx_offload;
14378d9c2c3aSKonstantin Ananyev 
14388d9c2c3aSKonstantin Ananyev 	memset(mb, 0, sz);
14398d9c2c3aSKonstantin Ananyev 	tm = rte_rdtsc_precise();
14408d9c2c3aSKonstantin Ananyev 
14418d9c2c3aSKonstantin Ananyev 	for (i = 0; i != num; i++)
14428d9c2c3aSKonstantin Ananyev 		mb[i].tx_offload = rte_mbuf_tx_offload(txof.l2, txof.l3,
14438d9c2c3aSKonstantin Ananyev 			txof.l4, txof.tso, txof.l3, txof.l2, 0);
14448d9c2c3aSKonstantin Ananyev 
14458d9c2c3aSKonstantin Ananyev 	tm = rte_rdtsc_precise() - tm;
14468d9c2c3aSKonstantin Ananyev 	printf("%s set raw tx_offload: %u iterations, %"
14478d9c2c3aSKonstantin Ananyev 		PRIu64 " cycles, %#Lf cycles/iter\n",
14488d9c2c3aSKonstantin Ananyev 		__func__, num, tm, (long double)tm / num);
14498d9c2c3aSKonstantin Ananyev 
14508d9c2c3aSKonstantin Ananyev 	v2 = mb[rte_rand() % num].tx_offload;
14518d9c2c3aSKonstantin Ananyev 
14528d9c2c3aSKonstantin Ananyev 	rte_free(mb);
14538d9c2c3aSKonstantin Ananyev 
14548d9c2c3aSKonstantin Ananyev 	printf("%s finished\n"
14558d9c2c3aSKonstantin Ananyev 		"expected tx_offload value: 0x%" PRIx64 ";\n"
14568d9c2c3aSKonstantin Ananyev 		"rte_mbuf_tx_offload value: 0x%" PRIx64 ";\n",
14578d9c2c3aSKonstantin Ananyev 		__func__, v1, v2);
14588d9c2c3aSKonstantin Ananyev 
14598d9c2c3aSKonstantin Ananyev 	return (v1 == v2) ? 0 : -EINVAL;
14608d9c2c3aSKonstantin Ananyev }
14618d9c2c3aSKonstantin Ananyev 
1462a9de470cSBruce Richardson static int
test_get_rx_ol_flag_list(void)1463b364bc9eSPallantla Poornima test_get_rx_ol_flag_list(void)
1464b364bc9eSPallantla Poornima {
1465b364bc9eSPallantla Poornima 	int len = 6, ret = 0;
1466b364bc9eSPallantla Poornima 	char buf[256] = "";
1467b364bc9eSPallantla Poornima 	int buflen = 0;
1468b364bc9eSPallantla Poornima 
1469b364bc9eSPallantla Poornima 	/* Test case to check with null buffer */
1470b364bc9eSPallantla Poornima 	ret = rte_get_rx_ol_flag_list(0, NULL, 0);
1471b364bc9eSPallantla Poornima 	if (ret != -1)
1472b364bc9eSPallantla Poornima 		GOTO_FAIL("%s expected: -1, received = %d\n", __func__, ret);
1473b364bc9eSPallantla Poornima 
1474b364bc9eSPallantla Poornima 	/* Test case to check with zero buffer len */
1475daa02b5cSOlivier Matz 	ret = rte_get_rx_ol_flag_list(RTE_MBUF_F_RX_L4_CKSUM_MASK, buf, 0);
1476b364bc9eSPallantla Poornima 	if (ret != -1)
1477b364bc9eSPallantla Poornima 		GOTO_FAIL("%s expected: -1, received = %d\n", __func__, ret);
1478b364bc9eSPallantla Poornima 
1479b364bc9eSPallantla Poornima 	buflen = strlen(buf);
1480b364bc9eSPallantla Poornima 	if (buflen != 0)
1481b364bc9eSPallantla Poornima 		GOTO_FAIL("%s buffer should be empty, received = %d\n",
1482b364bc9eSPallantla Poornima 				__func__, buflen);
1483b364bc9eSPallantla Poornima 
1484b364bc9eSPallantla Poornima 	/* Test case to check with reduced buffer len */
1485b364bc9eSPallantla Poornima 	ret = rte_get_rx_ol_flag_list(0, buf, len);
1486b364bc9eSPallantla Poornima 	if (ret != -1)
1487b364bc9eSPallantla Poornima 		GOTO_FAIL("%s expected: -1, received = %d\n", __func__, ret);
1488b364bc9eSPallantla Poornima 
1489b364bc9eSPallantla Poornima 	buflen = strlen(buf);
1490b364bc9eSPallantla Poornima 	if (buflen != (len - 1))
1491b364bc9eSPallantla Poornima 		GOTO_FAIL("%s invalid buffer length retrieved, expected: %d,"
1492b364bc9eSPallantla Poornima 				"received = %d\n", __func__,
1493b364bc9eSPallantla Poornima 				(len - 1), buflen);
1494b364bc9eSPallantla Poornima 
1495b364bc9eSPallantla Poornima 	/* Test case to check with zero mask value */
1496b364bc9eSPallantla Poornima 	ret = rte_get_rx_ol_flag_list(0, buf, sizeof(buf));
1497b364bc9eSPallantla Poornima 	if (ret != 0)
1498b364bc9eSPallantla Poornima 		GOTO_FAIL("%s expected: 0, received = %d\n", __func__, ret);
1499b364bc9eSPallantla Poornima 
1500b364bc9eSPallantla Poornima 	buflen = strlen(buf);
1501b364bc9eSPallantla Poornima 	if (buflen == 0)
1502b364bc9eSPallantla Poornima 		GOTO_FAIL("%s expected: %s, received length = 0\n", __func__,
1503b364bc9eSPallantla Poornima 				"non-zero, buffer should not be empty");
1504b364bc9eSPallantla Poornima 
1505b364bc9eSPallantla Poornima 	/* Test case to check with valid mask value */
1506daa02b5cSOlivier Matz 	ret = rte_get_rx_ol_flag_list(RTE_MBUF_F_RX_SEC_OFFLOAD, buf,
1507daa02b5cSOlivier Matz 				      sizeof(buf));
1508b364bc9eSPallantla Poornima 	if (ret != 0)
1509b364bc9eSPallantla Poornima 		GOTO_FAIL("%s expected: 0, received = %d\n", __func__, ret);
1510b364bc9eSPallantla Poornima 
1511b364bc9eSPallantla Poornima 	buflen = strlen(buf);
1512b364bc9eSPallantla Poornima 	if (buflen == 0)
1513b364bc9eSPallantla Poornima 		GOTO_FAIL("%s expected: %s, received length = 0\n", __func__,
1514b364bc9eSPallantla Poornima 				"non-zero, buffer should not be empty");
1515b364bc9eSPallantla Poornima 
1516b364bc9eSPallantla Poornima 	return 0;
1517b364bc9eSPallantla Poornima fail:
1518b364bc9eSPallantla Poornima 	return -1;
1519b364bc9eSPallantla Poornima }
1520b364bc9eSPallantla Poornima 
1521b364bc9eSPallantla Poornima static int
test_get_tx_ol_flag_list(void)1522b364bc9eSPallantla Poornima test_get_tx_ol_flag_list(void)
1523b364bc9eSPallantla Poornima {
1524b364bc9eSPallantla Poornima 	int len = 6, ret = 0;
1525b364bc9eSPallantla Poornima 	char buf[256] = "";
1526b364bc9eSPallantla Poornima 	int buflen = 0;
1527b364bc9eSPallantla Poornima 
1528b364bc9eSPallantla Poornima 	/* Test case to check with null buffer */
1529b364bc9eSPallantla Poornima 	ret = rte_get_tx_ol_flag_list(0, NULL, 0);
1530b364bc9eSPallantla Poornima 	if (ret != -1)
1531b364bc9eSPallantla Poornima 		GOTO_FAIL("%s expected: -1, received = %d\n", __func__, ret);
1532b364bc9eSPallantla Poornima 
1533b364bc9eSPallantla Poornima 	/* Test case to check with zero buffer len */
1534daa02b5cSOlivier Matz 	ret = rte_get_tx_ol_flag_list(RTE_MBUF_F_TX_IP_CKSUM, buf, 0);
1535b364bc9eSPallantla Poornima 	if (ret != -1)
1536b364bc9eSPallantla Poornima 		GOTO_FAIL("%s expected: -1, received = %d\n", __func__, ret);
1537b364bc9eSPallantla Poornima 
1538b364bc9eSPallantla Poornima 	buflen = strlen(buf);
1539b364bc9eSPallantla Poornima 	if (buflen != 0) {
1540b364bc9eSPallantla Poornima 		GOTO_FAIL("%s buffer should be empty, received = %d\n",
1541b364bc9eSPallantla Poornima 				__func__, buflen);
1542b364bc9eSPallantla Poornima 	}
1543b364bc9eSPallantla Poornima 
1544b364bc9eSPallantla Poornima 	/* Test case to check with reduced buffer len */
1545b364bc9eSPallantla Poornima 	ret = rte_get_tx_ol_flag_list(0, buf, len);
1546b364bc9eSPallantla Poornima 	if (ret != -1)
1547b364bc9eSPallantla Poornima 		GOTO_FAIL("%s expected: -1, received = %d\n", __func__, ret);
1548b364bc9eSPallantla Poornima 
1549b364bc9eSPallantla Poornima 	buflen = strlen(buf);
1550b364bc9eSPallantla Poornima 	if (buflen != (len - 1))
1551b364bc9eSPallantla Poornima 		GOTO_FAIL("%s invalid buffer length retrieved, expected: %d,"
1552b364bc9eSPallantla Poornima 				"received = %d\n", __func__,
1553b364bc9eSPallantla Poornima 				(len - 1), buflen);
1554b364bc9eSPallantla Poornima 
1555b364bc9eSPallantla Poornima 	/* Test case to check with zero mask value */
1556b364bc9eSPallantla Poornima 	ret = rte_get_tx_ol_flag_list(0, buf, sizeof(buf));
1557b364bc9eSPallantla Poornima 	if (ret != 0)
1558b364bc9eSPallantla Poornima 		GOTO_FAIL("%s expected: 0, received = %d\n", __func__, ret);
1559b364bc9eSPallantla Poornima 
1560b364bc9eSPallantla Poornima 	buflen = strlen(buf);
1561b364bc9eSPallantla Poornima 	if (buflen == 0)
1562b364bc9eSPallantla Poornima 		GOTO_FAIL("%s expected: %s, received length = 0\n", __func__,
1563b364bc9eSPallantla Poornima 				"non-zero, buffer should not be empty");
1564b364bc9eSPallantla Poornima 
1565b364bc9eSPallantla Poornima 	/* Test case to check with valid mask value */
1566daa02b5cSOlivier Matz 	ret = rte_get_tx_ol_flag_list(RTE_MBUF_F_TX_UDP_CKSUM, buf,
1567daa02b5cSOlivier Matz 				      sizeof(buf));
1568b364bc9eSPallantla Poornima 	if (ret != 0)
1569b364bc9eSPallantla Poornima 		GOTO_FAIL("%s expected: 0, received = %d\n", __func__, ret);
1570b364bc9eSPallantla Poornima 
1571b364bc9eSPallantla Poornima 	buflen = strlen(buf);
1572b364bc9eSPallantla Poornima 	if (buflen == 0)
1573b364bc9eSPallantla Poornima 		GOTO_FAIL("%s expected: %s, received length = 0\n", __func__,
1574b364bc9eSPallantla Poornima 				"non-zero, buffer should not be empty");
1575b364bc9eSPallantla Poornima 
1576b364bc9eSPallantla Poornima 	return 0;
1577b364bc9eSPallantla Poornima fail:
1578b364bc9eSPallantla Poornima 	return -1;
1579b364bc9eSPallantla Poornima 
1580b364bc9eSPallantla Poornima }
1581b364bc9eSPallantla Poornima 
1582b364bc9eSPallantla Poornima struct flag_name {
1583b364bc9eSPallantla Poornima 	uint64_t flag;
1584b364bc9eSPallantla Poornima 	const char *name;
1585b364bc9eSPallantla Poornima };
1586b364bc9eSPallantla Poornima 
1587b364bc9eSPallantla Poornima static int
test_get_rx_ol_flag_name(void)1588b364bc9eSPallantla Poornima test_get_rx_ol_flag_name(void)
1589b364bc9eSPallantla Poornima {
1590b364bc9eSPallantla Poornima 	uint16_t i;
1591b364bc9eSPallantla Poornima 	const char *flag_str = NULL;
1592b364bc9eSPallantla Poornima 	const struct flag_name rx_flags[] = {
1593daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_VLAN),
1594daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_RSS_HASH),
1595daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_FDIR),
1596daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_L4_CKSUM_BAD),
1597daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_L4_CKSUM_GOOD),
1598daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_L4_CKSUM_NONE),
1599daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_IP_CKSUM_BAD),
1600daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_IP_CKSUM_GOOD),
1601daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_IP_CKSUM_NONE),
1602daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD),
1603daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_VLAN_STRIPPED),
1604daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_IEEE1588_PTP),
1605daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_IEEE1588_TMST),
1606daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_FDIR_ID),
1607daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_FDIR_FLX),
1608daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_QINQ_STRIPPED),
1609daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_LRO),
1610daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_SEC_OFFLOAD),
1611daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED),
1612daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD),
1613daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD),
1614daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_RX_OUTER_L4_CKSUM_INVALID),
1615b364bc9eSPallantla Poornima 	};
1616b364bc9eSPallantla Poornima 
1617b364bc9eSPallantla Poornima 	/* Test case to check with valid flag */
1618b364bc9eSPallantla Poornima 	for (i = 0; i < RTE_DIM(rx_flags); i++) {
1619b364bc9eSPallantla Poornima 		flag_str = rte_get_rx_ol_flag_name(rx_flags[i].flag);
1620b364bc9eSPallantla Poornima 		if (flag_str == NULL)
1621b364bc9eSPallantla Poornima 			GOTO_FAIL("%s: Expected flagname = %s; received null\n",
1622b364bc9eSPallantla Poornima 					__func__, rx_flags[i].name);
1623b364bc9eSPallantla Poornima 		if (strcmp(flag_str, rx_flags[i].name) != 0)
1624b364bc9eSPallantla Poornima 			GOTO_FAIL("%s: Expected flagname = %s; received = %s\n",
1625b364bc9eSPallantla Poornima 				__func__, rx_flags[i].name, flag_str);
1626b364bc9eSPallantla Poornima 	}
1627b364bc9eSPallantla Poornima 	/* Test case to check with invalid flag */
1628b364bc9eSPallantla Poornima 	flag_str = rte_get_rx_ol_flag_name(0);
1629b364bc9eSPallantla Poornima 	if (flag_str != NULL) {
1630b364bc9eSPallantla Poornima 		GOTO_FAIL("%s: Expected flag name = null; received = %s\n",
1631b364bc9eSPallantla Poornima 				__func__, flag_str);
1632b364bc9eSPallantla Poornima 	}
1633b364bc9eSPallantla Poornima 
1634b364bc9eSPallantla Poornima 	return 0;
1635b364bc9eSPallantla Poornima fail:
1636b364bc9eSPallantla Poornima 	return -1;
1637b364bc9eSPallantla Poornima }
1638b364bc9eSPallantla Poornima 
1639b364bc9eSPallantla Poornima static int
test_get_tx_ol_flag_name(void)1640b364bc9eSPallantla Poornima test_get_tx_ol_flag_name(void)
1641b364bc9eSPallantla Poornima {
1642b364bc9eSPallantla Poornima 	uint16_t i;
1643b364bc9eSPallantla Poornima 	const char *flag_str = NULL;
1644b364bc9eSPallantla Poornima 	const struct flag_name tx_flags[] = {
1645daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_VLAN),
1646daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_IP_CKSUM),
1647daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_TCP_CKSUM),
1648daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_SCTP_CKSUM),
1649daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_UDP_CKSUM),
1650daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_IEEE1588_TMST),
1651daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_TCP_SEG),
1652daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_IPV4),
1653daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_IPV6),
1654daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_OUTER_IP_CKSUM),
1655daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_OUTER_IPV4),
1656daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_OUTER_IPV6),
1657daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_TUNNEL_VXLAN),
1658daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_TUNNEL_GRE),
1659daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_TUNNEL_IPIP),
1660daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_TUNNEL_GENEVE),
1661daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_TUNNEL_MPLSINUDP),
1662daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_TUNNEL_VXLAN_GPE),
1663daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_TUNNEL_IP),
1664daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_TUNNEL_UDP),
1665daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_QINQ),
1666daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_MACSEC),
1667daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_SEC_OFFLOAD),
1668daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_UDP_SEG),
1669daa02b5cSOlivier Matz 		VAL_NAME(RTE_MBUF_F_TX_OUTER_UDP_CKSUM),
1670b364bc9eSPallantla Poornima 	};
1671b364bc9eSPallantla Poornima 
1672b364bc9eSPallantla Poornima 	/* Test case to check with valid flag */
1673b364bc9eSPallantla Poornima 	for (i = 0; i < RTE_DIM(tx_flags); i++) {
1674b364bc9eSPallantla Poornima 		flag_str = rte_get_tx_ol_flag_name(tx_flags[i].flag);
1675b364bc9eSPallantla Poornima 		if (flag_str == NULL)
1676b364bc9eSPallantla Poornima 			GOTO_FAIL("%s: Expected flagname = %s; received null\n",
1677b364bc9eSPallantla Poornima 				__func__, tx_flags[i].name);
1678b364bc9eSPallantla Poornima 		if (strcmp(flag_str, tx_flags[i].name) != 0)
1679b364bc9eSPallantla Poornima 			GOTO_FAIL("%s: Expected flagname = %s; received = %s\n",
1680b364bc9eSPallantla Poornima 				__func__, tx_flags[i].name, flag_str);
1681b364bc9eSPallantla Poornima 	}
1682b364bc9eSPallantla Poornima 	/* Test case to check with invalid flag */
1683b364bc9eSPallantla Poornima 	flag_str = rte_get_tx_ol_flag_name(0);
1684b364bc9eSPallantla Poornima 	if (flag_str != NULL) {
1685b364bc9eSPallantla Poornima 		GOTO_FAIL("%s: Expected flag name = null; received = %s\n",
1686b364bc9eSPallantla Poornima 				__func__, flag_str);
1687b364bc9eSPallantla Poornima 	}
1688b364bc9eSPallantla Poornima 
1689b364bc9eSPallantla Poornima 	return 0;
1690b364bc9eSPallantla Poornima fail:
1691b364bc9eSPallantla Poornima 	return -1;
1692b364bc9eSPallantla Poornima 
1693b364bc9eSPallantla Poornima }
1694b364bc9eSPallantla Poornima 
1695b364bc9eSPallantla Poornima static int
test_mbuf_validate_tx_offload(const char * test_name,struct rte_mempool * pktmbuf_pool,uint64_t ol_flags,uint16_t segsize,int expected_retval)16967b295dceSLavanya Govindarajan test_mbuf_validate_tx_offload(const char *test_name,
16977b295dceSLavanya Govindarajan 		struct rte_mempool *pktmbuf_pool,
16987b295dceSLavanya Govindarajan 		uint64_t ol_flags,
16997b295dceSLavanya Govindarajan 		uint16_t segsize,
17007b295dceSLavanya Govindarajan 		int expected_retval)
17017b295dceSLavanya Govindarajan {
17027b295dceSLavanya Govindarajan 	struct rte_mbuf *m = NULL;
17037b295dceSLavanya Govindarajan 	int ret = 0;
17047b295dceSLavanya Govindarajan 
17057b295dceSLavanya Govindarajan 	/* alloc a mbuf and do sanity check */
17067b295dceSLavanya Govindarajan 	m = rte_pktmbuf_alloc(pktmbuf_pool);
17077b295dceSLavanya Govindarajan 	if (m == NULL)
17087b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: mbuf allocation failed!\n", __func__);
17097b295dceSLavanya Govindarajan 	if (rte_pktmbuf_pkt_len(m) != 0)
17107b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Bad packet length\n", __func__);
17117b295dceSLavanya Govindarajan 	rte_mbuf_sanity_check(m, 0);
17127b295dceSLavanya Govindarajan 	m->ol_flags = ol_flags;
17137b295dceSLavanya Govindarajan 	m->tso_segsz = segsize;
17147b295dceSLavanya Govindarajan 	ret = rte_validate_tx_offload(m);
17157b295dceSLavanya Govindarajan 	if (ret != expected_retval)
17167b295dceSLavanya Govindarajan 		GOTO_FAIL("%s(%s): expected ret val: %d; received: %d\n",
17177b295dceSLavanya Govindarajan 				__func__, test_name, expected_retval, ret);
17187b295dceSLavanya Govindarajan 	rte_pktmbuf_free(m);
17197b295dceSLavanya Govindarajan 	m = NULL;
17207b295dceSLavanya Govindarajan 	return 0;
17217b295dceSLavanya Govindarajan fail:
17227b295dceSLavanya Govindarajan 	if (m) {
17237b295dceSLavanya Govindarajan 		rte_pktmbuf_free(m);
17247b295dceSLavanya Govindarajan 		m = NULL;
17257b295dceSLavanya Govindarajan 	}
17267b295dceSLavanya Govindarajan 	return -1;
17277b295dceSLavanya Govindarajan }
17287b295dceSLavanya Govindarajan 
17297b295dceSLavanya Govindarajan static int
test_mbuf_validate_tx_offload_one(struct rte_mempool * pktmbuf_pool)17307b295dceSLavanya Govindarajan test_mbuf_validate_tx_offload_one(struct rte_mempool *pktmbuf_pool)
17317b295dceSLavanya Govindarajan {
17327b295dceSLavanya Govindarajan 	/* test to validate tx offload flags */
17337b295dceSLavanya Govindarajan 	uint64_t ol_flags = 0;
17347b295dceSLavanya Govindarajan 
17357b295dceSLavanya Govindarajan 	/* test to validate if IP checksum is counted only for IPV4 packet */
17367b295dceSLavanya Govindarajan 	/* set both IP checksum and IPV6 flags */
1737daa02b5cSOlivier Matz 	ol_flags |= RTE_MBUF_F_TX_IP_CKSUM;
1738daa02b5cSOlivier Matz 	ol_flags |= RTE_MBUF_F_TX_IPV6;
17397b295dceSLavanya Govindarajan 	if (test_mbuf_validate_tx_offload("MBUF_TEST_IP_CKSUM_IPV6_SET",
17407b295dceSLavanya Govindarajan 				pktmbuf_pool,
17417b295dceSLavanya Govindarajan 				ol_flags, 0, -EINVAL) < 0)
17427b295dceSLavanya Govindarajan 		GOTO_FAIL("%s failed: IP cksum is set incorrect.\n", __func__);
17437b295dceSLavanya Govindarajan 	/* resetting ol_flags for next testcase */
17447b295dceSLavanya Govindarajan 	ol_flags = 0;
17457b295dceSLavanya Govindarajan 
17467b295dceSLavanya Govindarajan 	/* test to validate if IP type is set when required */
1747daa02b5cSOlivier Matz 	ol_flags |= RTE_MBUF_F_TX_L4_MASK;
17487b295dceSLavanya Govindarajan 	if (test_mbuf_validate_tx_offload("MBUF_TEST_IP_TYPE_NOT_SET",
17497b295dceSLavanya Govindarajan 				pktmbuf_pool,
17507b295dceSLavanya Govindarajan 				ol_flags, 0, -EINVAL) < 0)
17517b295dceSLavanya Govindarajan 		GOTO_FAIL("%s failed: IP type is not set.\n", __func__);
17527b295dceSLavanya Govindarajan 
17537b295dceSLavanya Govindarajan 	/* test if IP type is set when TCP SEG is on */
1754daa02b5cSOlivier Matz 	ol_flags |= RTE_MBUF_F_TX_TCP_SEG;
17557b295dceSLavanya Govindarajan 	if (test_mbuf_validate_tx_offload("MBUF_TEST_IP_TYPE_NOT_SET",
17567b295dceSLavanya Govindarajan 				pktmbuf_pool,
17577b295dceSLavanya Govindarajan 				ol_flags, 0, -EINVAL) < 0)
17587b295dceSLavanya Govindarajan 		GOTO_FAIL("%s failed: IP type is not set.\n", __func__);
17597b295dceSLavanya Govindarajan 
17607b295dceSLavanya Govindarajan 	ol_flags = 0;
17617b295dceSLavanya Govindarajan 	/* test to confirm IP type (IPV4/IPV6) is set */
1762daa02b5cSOlivier Matz 	ol_flags = RTE_MBUF_F_TX_L4_MASK;
1763daa02b5cSOlivier Matz 	ol_flags |= RTE_MBUF_F_TX_IPV6;
17647b295dceSLavanya Govindarajan 	if (test_mbuf_validate_tx_offload("MBUF_TEST_IP_TYPE_SET",
17657b295dceSLavanya Govindarajan 				pktmbuf_pool,
17667b295dceSLavanya Govindarajan 				ol_flags, 0, 0) < 0)
17677b295dceSLavanya Govindarajan 		GOTO_FAIL("%s failed: tx offload flag error.\n", __func__);
17687b295dceSLavanya Govindarajan 
17697b295dceSLavanya Govindarajan 	ol_flags = 0;
17707b295dceSLavanya Govindarajan 	/* test to check TSO segment size is non-zero */
1771daa02b5cSOlivier Matz 	ol_flags |= RTE_MBUF_F_TX_IPV4;
1772daa02b5cSOlivier Matz 	ol_flags |= RTE_MBUF_F_TX_TCP_SEG;
17737b295dceSLavanya Govindarajan 	/* set 0 tso segment size */
17747b295dceSLavanya Govindarajan 	if (test_mbuf_validate_tx_offload("MBUF_TEST_NULL_TSO_SEGSZ",
17757b295dceSLavanya Govindarajan 				pktmbuf_pool,
17767b295dceSLavanya Govindarajan 				ol_flags, 0, -EINVAL) < 0)
17777b295dceSLavanya Govindarajan 		GOTO_FAIL("%s failed: tso segment size is null.\n", __func__);
17787b295dceSLavanya Govindarajan 
1779daa02b5cSOlivier Matz 	/* retain IPV4 and RTE_MBUF_F_TX_TCP_SEG mask */
17807b295dceSLavanya Govindarajan 	/* set valid tso segment size but IP CKSUM not set */
17817b295dceSLavanya Govindarajan 	if (test_mbuf_validate_tx_offload("MBUF_TEST_TSO_IP_CKSUM_NOT_SET",
17827b295dceSLavanya Govindarajan 				pktmbuf_pool,
17837b295dceSLavanya Govindarajan 				ol_flags, 512, -EINVAL) < 0)
17847b295dceSLavanya Govindarajan 		GOTO_FAIL("%s failed: IP CKSUM is not set.\n", __func__);
17857b295dceSLavanya Govindarajan 
17867b295dceSLavanya Govindarajan 	/* test to validate if IP checksum is set for TSO capability */
17877b295dceSLavanya Govindarajan 	/* retain IPV4, TCP_SEG, tso_seg size */
1788daa02b5cSOlivier Matz 	ol_flags |= RTE_MBUF_F_TX_IP_CKSUM;
17897b295dceSLavanya Govindarajan 	if (test_mbuf_validate_tx_offload("MBUF_TEST_TSO_IP_CKSUM_SET",
17907b295dceSLavanya Govindarajan 				pktmbuf_pool,
17917b295dceSLavanya Govindarajan 				ol_flags, 512, 0) < 0)
17927b295dceSLavanya Govindarajan 		GOTO_FAIL("%s failed: tx offload flag error.\n", __func__);
17937b295dceSLavanya Govindarajan 
17947b295dceSLavanya Govindarajan 	/* test to confirm TSO for IPV6 type */
17957b295dceSLavanya Govindarajan 	ol_flags = 0;
1796daa02b5cSOlivier Matz 	ol_flags |= RTE_MBUF_F_TX_IPV6;
1797daa02b5cSOlivier Matz 	ol_flags |= RTE_MBUF_F_TX_TCP_SEG;
17987b295dceSLavanya Govindarajan 	if (test_mbuf_validate_tx_offload("MBUF_TEST_TSO_IPV6_SET",
17997b295dceSLavanya Govindarajan 				pktmbuf_pool,
18007b295dceSLavanya Govindarajan 				ol_flags, 512, 0) < 0)
18017b295dceSLavanya Govindarajan 		GOTO_FAIL("%s failed: TSO req not met.\n", __func__);
18027b295dceSLavanya Govindarajan 
18037b295dceSLavanya Govindarajan 	ol_flags = 0;
18047b295dceSLavanya Govindarajan 	/* test if outer IP checksum set for non outer IPv4 packet */
1805daa02b5cSOlivier Matz 	ol_flags |= RTE_MBUF_F_TX_IPV6;
1806daa02b5cSOlivier Matz 	ol_flags |= RTE_MBUF_F_TX_OUTER_IP_CKSUM;
18077b295dceSLavanya Govindarajan 	if (test_mbuf_validate_tx_offload("MBUF_TEST_OUTER_IPV4_NOT_SET",
18087b295dceSLavanya Govindarajan 				pktmbuf_pool,
18097b295dceSLavanya Govindarajan 				ol_flags, 512, -EINVAL) < 0)
18107b295dceSLavanya Govindarajan 		GOTO_FAIL("%s failed: Outer IP cksum set.\n", __func__);
18117b295dceSLavanya Govindarajan 
18127b295dceSLavanya Govindarajan 	ol_flags = 0;
18137b295dceSLavanya Govindarajan 	/* test to confirm outer IP checksum is set for outer IPV4 packet */
1814daa02b5cSOlivier Matz 	ol_flags |= RTE_MBUF_F_TX_OUTER_IP_CKSUM;
1815daa02b5cSOlivier Matz 	ol_flags |= RTE_MBUF_F_TX_OUTER_IPV4;
18167b295dceSLavanya Govindarajan 	if (test_mbuf_validate_tx_offload("MBUF_TEST_OUTER_IPV4_SET",
18177b295dceSLavanya Govindarajan 				pktmbuf_pool,
18187b295dceSLavanya Govindarajan 				ol_flags, 512, 0) < 0)
18197b295dceSLavanya Govindarajan 		GOTO_FAIL("%s failed: tx offload flag error.\n", __func__);
18207b295dceSLavanya Govindarajan 
18217b295dceSLavanya Govindarajan 	ol_flags = 0;
18227b295dceSLavanya Govindarajan 	/* test to confirm if packets with no TX_OFFLOAD_MASK are skipped */
18237b295dceSLavanya Govindarajan 	if (test_mbuf_validate_tx_offload("MBUF_TEST_OL_MASK_NOT_SET",
18247b295dceSLavanya Govindarajan 				pktmbuf_pool,
18257b295dceSLavanya Govindarajan 				ol_flags, 512, 0) < 0)
18267b295dceSLavanya Govindarajan 		GOTO_FAIL("%s failed: tx offload flag error.\n", __func__);
18277b295dceSLavanya Govindarajan 	return 0;
18287b295dceSLavanya Govindarajan fail:
18297b295dceSLavanya Govindarajan 	return -1;
18307b295dceSLavanya Govindarajan }
18317b295dceSLavanya Govindarajan 
18327b295dceSLavanya Govindarajan /*
18337b295dceSLavanya Govindarajan  * Test for allocating a bulk of mbufs
18347b295dceSLavanya Govindarajan  * define an array with positive sizes for mbufs allocations.
18357b295dceSLavanya Govindarajan  */
18367b295dceSLavanya Govindarajan static int
test_pktmbuf_alloc_bulk(struct rte_mempool * pktmbuf_pool)18377b295dceSLavanya Govindarajan test_pktmbuf_alloc_bulk(struct rte_mempool *pktmbuf_pool)
18387b295dceSLavanya Govindarajan {
18397b295dceSLavanya Govindarajan 	int ret = 0;
18407b295dceSLavanya Govindarajan 	unsigned int idx, loop;
18417b295dceSLavanya Govindarajan 	unsigned int alloc_counts[] = {
18427b295dceSLavanya Govindarajan 		0,
18437b295dceSLavanya Govindarajan 		MEMPOOL_CACHE_SIZE - 1,
18447b295dceSLavanya Govindarajan 		MEMPOOL_CACHE_SIZE + 1,
18457b295dceSLavanya Govindarajan 		MEMPOOL_CACHE_SIZE * 1.5,
18467b295dceSLavanya Govindarajan 		MEMPOOL_CACHE_SIZE * 2,
18477b295dceSLavanya Govindarajan 		MEMPOOL_CACHE_SIZE * 2 - 1,
18487b295dceSLavanya Govindarajan 		MEMPOOL_CACHE_SIZE * 2 + 1,
18497b295dceSLavanya Govindarajan 		MEMPOOL_CACHE_SIZE,
18507b295dceSLavanya Govindarajan 	};
18517b295dceSLavanya Govindarajan 
18527b295dceSLavanya Govindarajan 	/* allocate a large array of mbuf pointers */
18537b295dceSLavanya Govindarajan 	struct rte_mbuf *mbufs[NB_MBUF] = { 0 };
18547b295dceSLavanya Govindarajan 	for (idx = 0; idx < RTE_DIM(alloc_counts); idx++) {
18557b295dceSLavanya Govindarajan 		ret = rte_pktmbuf_alloc_bulk(pktmbuf_pool, mbufs,
18567b295dceSLavanya Govindarajan 				alloc_counts[idx]);
18577b295dceSLavanya Govindarajan 		if (ret == 0) {
18587b295dceSLavanya Govindarajan 			for (loop = 0; loop < alloc_counts[idx] &&
18597b295dceSLavanya Govindarajan 					mbufs[loop] != NULL; loop++)
18607b295dceSLavanya Govindarajan 				rte_pktmbuf_free(mbufs[loop]);
18617b295dceSLavanya Govindarajan 		} else if (ret != 0) {
18627b295dceSLavanya Govindarajan 			printf("%s: Bulk alloc failed count(%u); ret val(%d)\n",
18637b295dceSLavanya Govindarajan 					__func__, alloc_counts[idx], ret);
18647b295dceSLavanya Govindarajan 			return -1;
18657b295dceSLavanya Govindarajan 		}
18667b295dceSLavanya Govindarajan 	}
18677b295dceSLavanya Govindarajan 	return 0;
18687b295dceSLavanya Govindarajan }
18697b295dceSLavanya Govindarajan 
18707b295dceSLavanya Govindarajan /*
18717b295dceSLavanya Govindarajan  * Negative testing for allocating a bulk of mbufs
18727b295dceSLavanya Govindarajan  */
18737b295dceSLavanya Govindarajan static int
test_neg_pktmbuf_alloc_bulk(struct rte_mempool * pktmbuf_pool)18747b295dceSLavanya Govindarajan test_neg_pktmbuf_alloc_bulk(struct rte_mempool *pktmbuf_pool)
18757b295dceSLavanya Govindarajan {
18767b295dceSLavanya Govindarajan 	int ret = 0;
18777b295dceSLavanya Govindarajan 	unsigned int idx, loop;
18787b295dceSLavanya Govindarajan 	unsigned int neg_alloc_counts[] = {
18797b295dceSLavanya Govindarajan 		MEMPOOL_CACHE_SIZE - NB_MBUF,
18807b295dceSLavanya Govindarajan 		NB_MBUF + 1,
18817b295dceSLavanya Govindarajan 		NB_MBUF * 8,
18827b295dceSLavanya Govindarajan 		UINT_MAX
18837b295dceSLavanya Govindarajan 	};
18847b295dceSLavanya Govindarajan 	struct rte_mbuf *mbufs[NB_MBUF * 8] = { 0 };
18857b295dceSLavanya Govindarajan 
18867b295dceSLavanya Govindarajan 	for (idx = 0; idx < RTE_DIM(neg_alloc_counts); idx++) {
18877b295dceSLavanya Govindarajan 		ret = rte_pktmbuf_alloc_bulk(pktmbuf_pool, mbufs,
18887b295dceSLavanya Govindarajan 				neg_alloc_counts[idx]);
18897b295dceSLavanya Govindarajan 		if (ret == 0) {
18907b295dceSLavanya Govindarajan 			printf("%s: Bulk alloc must fail! count(%u); ret(%d)\n",
18917b295dceSLavanya Govindarajan 					__func__, neg_alloc_counts[idx], ret);
18927b295dceSLavanya Govindarajan 			for (loop = 0; loop < neg_alloc_counts[idx] &&
18937b295dceSLavanya Govindarajan 					mbufs[loop] != NULL; loop++)
18947b295dceSLavanya Govindarajan 				rte_pktmbuf_free(mbufs[loop]);
18957b295dceSLavanya Govindarajan 			return -1;
18967b295dceSLavanya Govindarajan 		}
18977b295dceSLavanya Govindarajan 	}
18987b295dceSLavanya Govindarajan 	return 0;
18997b295dceSLavanya Govindarajan }
19007b295dceSLavanya Govindarajan 
19017b295dceSLavanya Govindarajan /*
19027b295dceSLavanya Govindarajan  * Test to read mbuf packet using rte_pktmbuf_read
19037b295dceSLavanya Govindarajan  */
19047b295dceSLavanya Govindarajan static int
test_pktmbuf_read(struct rte_mempool * pktmbuf_pool)19057b295dceSLavanya Govindarajan test_pktmbuf_read(struct rte_mempool *pktmbuf_pool)
19067b295dceSLavanya Govindarajan {
19077b295dceSLavanya Govindarajan 	struct rte_mbuf *m = NULL;
19087b295dceSLavanya Govindarajan 	char *data = NULL;
19097b295dceSLavanya Govindarajan 	const char *data_copy = NULL;
19107b295dceSLavanya Govindarajan 	int off;
19117b295dceSLavanya Govindarajan 
19127b295dceSLavanya Govindarajan 	/* alloc a mbuf */
19137b295dceSLavanya Govindarajan 	m = rte_pktmbuf_alloc(pktmbuf_pool);
19147b295dceSLavanya Govindarajan 	if (m == NULL)
19157b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: mbuf allocation failed!\n", __func__);
19167b295dceSLavanya Govindarajan 	if (rte_pktmbuf_pkt_len(m) != 0)
19177b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Bad packet length\n", __func__);
19187b295dceSLavanya Govindarajan 	rte_mbuf_sanity_check(m, 0);
19197b295dceSLavanya Govindarajan 
19207b295dceSLavanya Govindarajan 	data = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN2);
19217b295dceSLavanya Govindarajan 	if (data == NULL)
19227b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Cannot append data\n", __func__);
19237b295dceSLavanya Govindarajan 	if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN2)
19247b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Bad packet length\n", __func__);
19257b295dceSLavanya Govindarajan 	memset(data, 0xfe, MBUF_TEST_DATA_LEN2);
19267b295dceSLavanya Govindarajan 
19277b295dceSLavanya Govindarajan 	/* read the data from mbuf */
19287b295dceSLavanya Govindarajan 	data_copy = rte_pktmbuf_read(m, 0, MBUF_TEST_DATA_LEN2, NULL);
19297b295dceSLavanya Govindarajan 	if (data_copy == NULL)
19307b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Error in reading data!\n", __func__);
19317b295dceSLavanya Govindarajan 	for (off = 0; off < MBUF_TEST_DATA_LEN2; off++) {
19327b295dceSLavanya Govindarajan 		if (data_copy[off] != (char)0xfe)
19337b295dceSLavanya Govindarajan 			GOTO_FAIL("Data corrupted at offset %u", off);
19347b295dceSLavanya Govindarajan 	}
19357b295dceSLavanya Govindarajan 	rte_pktmbuf_free(m);
19367b295dceSLavanya Govindarajan 	m = NULL;
19377b295dceSLavanya Govindarajan 
19387b295dceSLavanya Govindarajan 	return 0;
19397b295dceSLavanya Govindarajan fail:
19407b295dceSLavanya Govindarajan 	if (m) {
19417b295dceSLavanya Govindarajan 		rte_pktmbuf_free(m);
19427b295dceSLavanya Govindarajan 		m = NULL;
19437b295dceSLavanya Govindarajan 	}
19447b295dceSLavanya Govindarajan 	return -1;
19457b295dceSLavanya Govindarajan }
19467b295dceSLavanya Govindarajan 
19477b295dceSLavanya Govindarajan /*
19487b295dceSLavanya Govindarajan  * Test to read mbuf packet data from offset
19497b295dceSLavanya Govindarajan  */
19507b295dceSLavanya Govindarajan static int
test_pktmbuf_read_from_offset(struct rte_mempool * pktmbuf_pool)19517b295dceSLavanya Govindarajan test_pktmbuf_read_from_offset(struct rte_mempool *pktmbuf_pool)
19527b295dceSLavanya Govindarajan {
19537b295dceSLavanya Govindarajan 	struct rte_mbuf *m = NULL;
19547b295dceSLavanya Govindarajan 	struct ether_hdr *hdr = NULL;
19557b295dceSLavanya Govindarajan 	char *data = NULL;
19567b295dceSLavanya Govindarajan 	const char *data_copy = NULL;
19577b295dceSLavanya Govindarajan 	unsigned int off;
19587b295dceSLavanya Govindarajan 	unsigned int hdr_len = sizeof(struct rte_ether_hdr);
19597b295dceSLavanya Govindarajan 
19607b295dceSLavanya Govindarajan 	/* alloc a mbuf */
19617b295dceSLavanya Govindarajan 	m = rte_pktmbuf_alloc(pktmbuf_pool);
19627b295dceSLavanya Govindarajan 	if (m == NULL)
19637b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: mbuf allocation failed!\n", __func__);
19647b295dceSLavanya Govindarajan 
19657b295dceSLavanya Govindarajan 	if (rte_pktmbuf_pkt_len(m) != 0)
19667b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Bad packet length\n", __func__);
19677b295dceSLavanya Govindarajan 	rte_mbuf_sanity_check(m, 0);
19687b295dceSLavanya Govindarajan 
19697b295dceSLavanya Govindarajan 	/* prepend an ethernet header */
19707b295dceSLavanya Govindarajan 	hdr = (struct ether_hdr *)rte_pktmbuf_prepend(m, hdr_len);
19717b295dceSLavanya Govindarajan 	if (hdr == NULL)
19727b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Cannot prepend header\n", __func__);
19737b295dceSLavanya Govindarajan 	if (rte_pktmbuf_pkt_len(m) != hdr_len)
19747b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Bad pkt length", __func__);
19757b295dceSLavanya Govindarajan 	if (rte_pktmbuf_data_len(m) != hdr_len)
19767b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Bad data length", __func__);
19777b295dceSLavanya Govindarajan 	memset(hdr, 0xde, hdr_len);
19787b295dceSLavanya Govindarajan 
19797b295dceSLavanya Govindarajan 	/* read mbuf header info from 0 offset */
19807b295dceSLavanya Govindarajan 	data_copy = rte_pktmbuf_read(m, 0, hdr_len, NULL);
19817b295dceSLavanya Govindarajan 	if (data_copy == NULL)
19827b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Error in reading header!\n", __func__);
19837b295dceSLavanya Govindarajan 	for (off = 0; off < hdr_len; off++) {
19847b295dceSLavanya Govindarajan 		if (data_copy[off] != (char)0xde)
19857b295dceSLavanya Govindarajan 			GOTO_FAIL("Header info corrupted at offset %u", off);
19867b295dceSLavanya Govindarajan 	}
19877b295dceSLavanya Govindarajan 
19887b295dceSLavanya Govindarajan 	/* append sample data after ethernet header */
19897b295dceSLavanya Govindarajan 	data = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN2);
19907b295dceSLavanya Govindarajan 	if (data == NULL)
19917b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Cannot append data\n", __func__);
19927b295dceSLavanya Govindarajan 	if (rte_pktmbuf_pkt_len(m) != hdr_len + MBUF_TEST_DATA_LEN2)
19937b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Bad packet length\n", __func__);
19947b295dceSLavanya Govindarajan 	if (rte_pktmbuf_data_len(m) != hdr_len + MBUF_TEST_DATA_LEN2)
19957b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Bad data length\n", __func__);
19967b295dceSLavanya Govindarajan 	memset(data, 0xcc, MBUF_TEST_DATA_LEN2);
19977b295dceSLavanya Govindarajan 
19987b295dceSLavanya Govindarajan 	/* read mbuf data after header info */
19997b295dceSLavanya Govindarajan 	data_copy = rte_pktmbuf_read(m, hdr_len, MBUF_TEST_DATA_LEN2, NULL);
20007b295dceSLavanya Govindarajan 	if (data_copy == NULL)
20017b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Error in reading header data!\n", __func__);
20027b295dceSLavanya Govindarajan 	for (off = 0; off < MBUF_TEST_DATA_LEN2; off++) {
20037b295dceSLavanya Govindarajan 		if (data_copy[off] != (char)0xcc)
20047b295dceSLavanya Govindarajan 			GOTO_FAIL("Data corrupted at offset %u", off);
20057b295dceSLavanya Govindarajan 	}
20067b295dceSLavanya Govindarajan 
20077b295dceSLavanya Govindarajan 	/* partial reading of mbuf data */
20087b295dceSLavanya Govindarajan 	data_copy = rte_pktmbuf_read(m, hdr_len + 5, MBUF_TEST_DATA_LEN2 - 5,
20097b295dceSLavanya Govindarajan 			NULL);
20107b295dceSLavanya Govindarajan 	if (data_copy == NULL)
20117b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Error in reading packet data!\n", __func__);
20127b295dceSLavanya Govindarajan 	for (off = 0; off < MBUF_TEST_DATA_LEN2 - 5; off++) {
20137b295dceSLavanya Govindarajan 		if (data_copy[off] != (char)0xcc)
20147b295dceSLavanya Govindarajan 			GOTO_FAIL("Data corrupted at offset %u", off);
20157b295dceSLavanya Govindarajan 	}
20167b295dceSLavanya Govindarajan 
20177b295dceSLavanya Govindarajan 	/* read length greater than mbuf data_len */
20187b295dceSLavanya Govindarajan 	if (rte_pktmbuf_read(m, hdr_len, rte_pktmbuf_data_len(m) + 1,
20197b295dceSLavanya Govindarajan 				NULL) != NULL)
20207b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Requested len is larger than mbuf data len!\n",
20217b295dceSLavanya Govindarajan 				__func__);
20227b295dceSLavanya Govindarajan 
20237b295dceSLavanya Govindarajan 	/* read length greater than mbuf pkt_len */
20247b295dceSLavanya Govindarajan 	if (rte_pktmbuf_read(m, hdr_len, rte_pktmbuf_pkt_len(m) + 1,
20257b295dceSLavanya Govindarajan 				NULL) != NULL)
20267b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Requested len is larger than mbuf pkt len!\n",
20277b295dceSLavanya Govindarajan 				__func__);
20287b295dceSLavanya Govindarajan 
20297b295dceSLavanya Govindarajan 	/* read data of zero len from valid offset */
20307b295dceSLavanya Govindarajan 	data_copy = rte_pktmbuf_read(m, hdr_len, 0, NULL);
20317b295dceSLavanya Govindarajan 	if (data_copy == NULL)
20327b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Error in reading packet data!\n", __func__);
20337b295dceSLavanya Govindarajan 	for (off = 0; off < MBUF_TEST_DATA_LEN2; off++) {
20347b295dceSLavanya Govindarajan 		if (data_copy[off] != (char)0xcc)
20357b295dceSLavanya Govindarajan 			GOTO_FAIL("Data corrupted at offset %u", off);
20367b295dceSLavanya Govindarajan 	}
20377b295dceSLavanya Govindarajan 
20387b295dceSLavanya Govindarajan 	/* read data of zero length from zero offset */
20397b295dceSLavanya Govindarajan 	data_copy = rte_pktmbuf_read(m, 0, 0, NULL);
20407b295dceSLavanya Govindarajan 	if (data_copy == NULL)
20417b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Error in reading packet data!\n", __func__);
20427b295dceSLavanya Govindarajan 	/* check if the received address is the beginning of header info */
20437b295dceSLavanya Govindarajan 	if (hdr != (const struct ether_hdr *)data_copy)
20447b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Corrupted data address!\n", __func__);
20457b295dceSLavanya Govindarajan 
20467b295dceSLavanya Govindarajan 	/* read data of max length from valid offset */
20477b295dceSLavanya Govindarajan 	data_copy = rte_pktmbuf_read(m, hdr_len, UINT_MAX, NULL);
20487b295dceSLavanya Govindarajan 	if (data_copy == NULL)
20497b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Error in reading packet data!\n", __func__);
20507b295dceSLavanya Govindarajan 	/* check if the received address is the beginning of data segment */
20517b295dceSLavanya Govindarajan 	if (data_copy != data)
20527b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Corrupted data address!\n", __func__);
20537b295dceSLavanya Govindarajan 
20547b295dceSLavanya Govindarajan 	/* try to read from mbuf with max size offset */
20557b295dceSLavanya Govindarajan 	data_copy = rte_pktmbuf_read(m, UINT_MAX, 0, NULL);
20567b295dceSLavanya Govindarajan 	if (data_copy != NULL)
20577b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Error in reading packet data!\n", __func__);
20587b295dceSLavanya Govindarajan 
20597b295dceSLavanya Govindarajan 	/* try to read from mbuf with max size offset and len */
20607b295dceSLavanya Govindarajan 	data_copy = rte_pktmbuf_read(m, UINT_MAX, UINT_MAX, NULL);
20617b295dceSLavanya Govindarajan 	if (data_copy != NULL)
20627b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Error in reading packet data!\n", __func__);
20637b295dceSLavanya Govindarajan 
20647b295dceSLavanya Govindarajan 	rte_pktmbuf_dump(stdout, m, rte_pktmbuf_pkt_len(m));
20657b295dceSLavanya Govindarajan 
20667b295dceSLavanya Govindarajan 	rte_pktmbuf_free(m);
20677b295dceSLavanya Govindarajan 	m = NULL;
20687b295dceSLavanya Govindarajan 
20697b295dceSLavanya Govindarajan 	return 0;
20707b295dceSLavanya Govindarajan fail:
20717b295dceSLavanya Govindarajan 	if (m) {
20727b295dceSLavanya Govindarajan 		rte_pktmbuf_free(m);
20737b295dceSLavanya Govindarajan 		m = NULL;
20747b295dceSLavanya Govindarajan 	}
20757b295dceSLavanya Govindarajan 	return -1;
20767b295dceSLavanya Govindarajan }
20777b295dceSLavanya Govindarajan 
20787b295dceSLavanya Govindarajan struct test_case {
20797b295dceSLavanya Govindarajan 	unsigned int seg_count;
20807b295dceSLavanya Govindarajan 	unsigned int flags;
20817b295dceSLavanya Govindarajan 	uint32_t read_off;
20827b295dceSLavanya Govindarajan 	uint32_t read_len;
20837b295dceSLavanya Govindarajan 	unsigned int seg_lengths[MBUF_MAX_SEG];
20847b295dceSLavanya Govindarajan };
20857b295dceSLavanya Govindarajan 
20867b295dceSLavanya Govindarajan /* create a mbuf with different sized segments
20877b295dceSLavanya Govindarajan  *  and fill with data [0x00 0x01 0x02 ...]
20887b295dceSLavanya Govindarajan  */
20897b295dceSLavanya Govindarajan static struct rte_mbuf *
create_packet(struct rte_mempool * pktmbuf_pool,struct test_case * test_data)20907b295dceSLavanya Govindarajan create_packet(struct rte_mempool *pktmbuf_pool,
20917b295dceSLavanya Govindarajan 		struct test_case *test_data)
20927b295dceSLavanya Govindarajan {
20937b295dceSLavanya Govindarajan 	uint16_t i, ret, seg, seg_len = 0;
20947b295dceSLavanya Govindarajan 	uint32_t last_index = 0;
20957b295dceSLavanya Govindarajan 	unsigned int seg_lengths[MBUF_MAX_SEG];
20967b295dceSLavanya Govindarajan 	unsigned int hdr_len;
20977b295dceSLavanya Govindarajan 	struct rte_mbuf *pkt = NULL;
20987b295dceSLavanya Govindarajan 	struct rte_mbuf	*pkt_seg = NULL;
20997b295dceSLavanya Govindarajan 	char *hdr = NULL;
21007b295dceSLavanya Govindarajan 	char *data = NULL;
21017b295dceSLavanya Govindarajan 
21027b295dceSLavanya Govindarajan 	memcpy(seg_lengths, test_data->seg_lengths,
21037b295dceSLavanya Govindarajan 			sizeof(unsigned int)*test_data->seg_count);
21047b295dceSLavanya Govindarajan 	for (seg = 0; seg < test_data->seg_count; seg++) {
21057b295dceSLavanya Govindarajan 		hdr_len = 0;
21067b295dceSLavanya Govindarajan 		seg_len =  seg_lengths[seg];
21077b295dceSLavanya Govindarajan 		pkt_seg = rte_pktmbuf_alloc(pktmbuf_pool);
21087b295dceSLavanya Govindarajan 		if (pkt_seg == NULL)
21097b295dceSLavanya Govindarajan 			GOTO_FAIL("%s: mbuf allocation failed!\n", __func__);
21107b295dceSLavanya Govindarajan 		if (rte_pktmbuf_pkt_len(pkt_seg) != 0)
21117b295dceSLavanya Govindarajan 			GOTO_FAIL("%s: Bad packet length\n", __func__);
21127b295dceSLavanya Govindarajan 		rte_mbuf_sanity_check(pkt_seg, 0);
21137b295dceSLavanya Govindarajan 		/* Add header only for the first segment */
21147b295dceSLavanya Govindarajan 		if (test_data->flags == MBUF_HEADER && seg == 0) {
21157b295dceSLavanya Govindarajan 			hdr_len = sizeof(struct rte_ether_hdr);
21167b295dceSLavanya Govindarajan 			/* prepend a header and fill with dummy data */
21177b295dceSLavanya Govindarajan 			hdr = (char *)rte_pktmbuf_prepend(pkt_seg, hdr_len);
21187b295dceSLavanya Govindarajan 			if (hdr == NULL)
21197b295dceSLavanya Govindarajan 				GOTO_FAIL("%s: Cannot prepend header\n",
21207b295dceSLavanya Govindarajan 						__func__);
21217b295dceSLavanya Govindarajan 			if (rte_pktmbuf_pkt_len(pkt_seg) != hdr_len)
21227b295dceSLavanya Govindarajan 				GOTO_FAIL("%s: Bad pkt length", __func__);
21237b295dceSLavanya Govindarajan 			if (rte_pktmbuf_data_len(pkt_seg) != hdr_len)
21247b295dceSLavanya Govindarajan 				GOTO_FAIL("%s: Bad data length", __func__);
21257b295dceSLavanya Govindarajan 			for (i = 0; i < hdr_len; i++)
21267b295dceSLavanya Govindarajan 				hdr[i] = (last_index + i) % 0xffff;
21277b295dceSLavanya Govindarajan 			last_index += hdr_len;
21287b295dceSLavanya Govindarajan 		}
21297b295dceSLavanya Govindarajan 		/* skip appending segment with 0 length */
21307b295dceSLavanya Govindarajan 		if (seg_len == 0)
21317b295dceSLavanya Govindarajan 			continue;
21327b295dceSLavanya Govindarajan 		data = rte_pktmbuf_append(pkt_seg, seg_len);
21337b295dceSLavanya Govindarajan 		if (data == NULL)
21347b295dceSLavanya Govindarajan 			GOTO_FAIL("%s: Cannot append data segment\n", __func__);
21357b295dceSLavanya Govindarajan 		if (rte_pktmbuf_pkt_len(pkt_seg) != hdr_len + seg_len)
21367b295dceSLavanya Govindarajan 			GOTO_FAIL("%s: Bad packet segment length: %d\n",
21377b295dceSLavanya Govindarajan 					__func__, rte_pktmbuf_pkt_len(pkt_seg));
21387b295dceSLavanya Govindarajan 		if (rte_pktmbuf_data_len(pkt_seg) != hdr_len + seg_len)
21397b295dceSLavanya Govindarajan 			GOTO_FAIL("%s: Bad data length\n", __func__);
21407b295dceSLavanya Govindarajan 		for (i = 0; i < seg_len; i++)
21417b295dceSLavanya Govindarajan 			data[i] = (last_index + i) % 0xffff;
21427b295dceSLavanya Govindarajan 		/* to fill continuous data from one seg to another */
21437b295dceSLavanya Govindarajan 		last_index += i;
21447b295dceSLavanya Govindarajan 		/* create chained mbufs */
21457b295dceSLavanya Govindarajan 		if (seg == 0)
21467b295dceSLavanya Govindarajan 			pkt = pkt_seg;
21477b295dceSLavanya Govindarajan 		else {
21487b295dceSLavanya Govindarajan 			ret = rte_pktmbuf_chain(pkt, pkt_seg);
21497b295dceSLavanya Govindarajan 			if (ret != 0)
21507b295dceSLavanya Govindarajan 				GOTO_FAIL("%s:FAIL: Chained mbuf creation %d\n",
21517b295dceSLavanya Govindarajan 						__func__, ret);
21527b295dceSLavanya Govindarajan 		}
21537b295dceSLavanya Govindarajan 
21547b295dceSLavanya Govindarajan 		pkt_seg = pkt_seg->next;
21557b295dceSLavanya Govindarajan 	}
21567b295dceSLavanya Govindarajan 	return pkt;
21577b295dceSLavanya Govindarajan fail:
21587b295dceSLavanya Govindarajan 	if (pkt != NULL) {
21597b295dceSLavanya Govindarajan 		rte_pktmbuf_free(pkt);
21607b295dceSLavanya Govindarajan 		pkt = NULL;
21617b295dceSLavanya Govindarajan 	}
21627b295dceSLavanya Govindarajan 	if (pkt_seg != NULL) {
21637b295dceSLavanya Govindarajan 		rte_pktmbuf_free(pkt_seg);
21647b295dceSLavanya Govindarajan 		pkt_seg = NULL;
21657b295dceSLavanya Govindarajan 	}
21667b295dceSLavanya Govindarajan 	return NULL;
21677b295dceSLavanya Govindarajan }
21687b295dceSLavanya Govindarajan 
21697b295dceSLavanya Govindarajan static int
test_pktmbuf_read_from_chain(struct rte_mempool * pktmbuf_pool)21707b295dceSLavanya Govindarajan test_pktmbuf_read_from_chain(struct rte_mempool *pktmbuf_pool)
21717b295dceSLavanya Govindarajan {
21727b295dceSLavanya Govindarajan 	struct rte_mbuf *m;
21737b295dceSLavanya Govindarajan 	struct test_case test_cases[] = {
21747b295dceSLavanya Govindarajan 		{
21757b295dceSLavanya Govindarajan 			.seg_lengths = { 100, 100, 100 },
21767b295dceSLavanya Govindarajan 			.seg_count = 3,
21777b295dceSLavanya Govindarajan 			.flags = MBUF_NO_HEADER,
21787b295dceSLavanya Govindarajan 			.read_off = 0,
21797b295dceSLavanya Govindarajan 			.read_len = 300
21807b295dceSLavanya Govindarajan 		},
21817b295dceSLavanya Govindarajan 		{
21827b295dceSLavanya Govindarajan 			.seg_lengths = { 100, 125, 150 },
21837b295dceSLavanya Govindarajan 			.seg_count = 3,
21847b295dceSLavanya Govindarajan 			.flags = MBUF_NO_HEADER,
21857b295dceSLavanya Govindarajan 			.read_off = 99,
21867b295dceSLavanya Govindarajan 			.read_len = 201
21877b295dceSLavanya Govindarajan 		},
21887b295dceSLavanya Govindarajan 		{
21897b295dceSLavanya Govindarajan 			.seg_lengths = { 100, 100 },
21907b295dceSLavanya Govindarajan 			.seg_count = 2,
21917b295dceSLavanya Govindarajan 			.flags = MBUF_NO_HEADER,
21927b295dceSLavanya Govindarajan 			.read_off = 0,
21937b295dceSLavanya Govindarajan 			.read_len = 100
21947b295dceSLavanya Govindarajan 		},
21957b295dceSLavanya Govindarajan 		{
21967b295dceSLavanya Govindarajan 			.seg_lengths = { 100, 200 },
21977b295dceSLavanya Govindarajan 			.seg_count = 2,
21987b295dceSLavanya Govindarajan 			.flags = MBUF_HEADER,
21997b295dceSLavanya Govindarajan 			.read_off = sizeof(struct rte_ether_hdr),
22007b295dceSLavanya Govindarajan 			.read_len = 150
22017b295dceSLavanya Govindarajan 		},
22027b295dceSLavanya Govindarajan 		{
22037b295dceSLavanya Govindarajan 			.seg_lengths = { 1000, 100 },
22047b295dceSLavanya Govindarajan 			.seg_count = 2,
22057b295dceSLavanya Govindarajan 			.flags = MBUF_NO_HEADER,
22067b295dceSLavanya Govindarajan 			.read_off = 0,
22077b295dceSLavanya Govindarajan 			.read_len = 1000
22087b295dceSLavanya Govindarajan 		},
22097b295dceSLavanya Govindarajan 		{
22107b295dceSLavanya Govindarajan 			.seg_lengths = { 1024, 0, 100 },
22117b295dceSLavanya Govindarajan 			.seg_count = 3,
22127b295dceSLavanya Govindarajan 			.flags = MBUF_NO_HEADER,
22137b295dceSLavanya Govindarajan 			.read_off = 100,
22147b295dceSLavanya Govindarajan 			.read_len = 1001
22157b295dceSLavanya Govindarajan 		},
22167b295dceSLavanya Govindarajan 		{
22177b295dceSLavanya Govindarajan 			.seg_lengths = { 1000, 1, 1000 },
22187b295dceSLavanya Govindarajan 			.seg_count = 3,
22197b295dceSLavanya Govindarajan 			.flags = MBUF_NO_HEADER,
22207b295dceSLavanya Govindarajan 			.read_off = 1000,
22217b295dceSLavanya Govindarajan 			.read_len = 2
22227b295dceSLavanya Govindarajan 		},
22237b295dceSLavanya Govindarajan 		{
22247b295dceSLavanya Govindarajan 			.seg_lengths = { MBUF_TEST_DATA_LEN,
22257b295dceSLavanya Govindarajan 					MBUF_TEST_DATA_LEN2,
22267b295dceSLavanya Govindarajan 					MBUF_TEST_DATA_LEN3, 800, 10 },
22277b295dceSLavanya Govindarajan 			.seg_count = 5,
22287b295dceSLavanya Govindarajan 			.flags = MBUF_NEG_TEST_READ,
22297b295dceSLavanya Govindarajan 			.read_off = 1000,
22307b295dceSLavanya Govindarajan 			.read_len = MBUF_DATA_SIZE
22317b295dceSLavanya Govindarajan 		},
22327b295dceSLavanya Govindarajan 	};
22337b295dceSLavanya Govindarajan 
22347b295dceSLavanya Govindarajan 	uint32_t i, pos;
22357b295dceSLavanya Govindarajan 	const char *data_copy = NULL;
22367b295dceSLavanya Govindarajan 	char data_buf[MBUF_DATA_SIZE];
22377b295dceSLavanya Govindarajan 
22387b295dceSLavanya Govindarajan 	memset(data_buf, 0, MBUF_DATA_SIZE);
22397b295dceSLavanya Govindarajan 
22407b295dceSLavanya Govindarajan 	for (i = 0; i < RTE_DIM(test_cases); i++) {
22417b295dceSLavanya Govindarajan 		m = create_packet(pktmbuf_pool, &test_cases[i]);
22427b295dceSLavanya Govindarajan 		if (m == NULL)
22437b295dceSLavanya Govindarajan 			GOTO_FAIL("%s: mbuf allocation failed!\n", __func__);
22447b295dceSLavanya Govindarajan 
22457b295dceSLavanya Govindarajan 		data_copy = rte_pktmbuf_read(m, test_cases[i].read_off,
22467b295dceSLavanya Govindarajan 				test_cases[i].read_len, data_buf);
22477b295dceSLavanya Govindarajan 		if (test_cases[i].flags == MBUF_NEG_TEST_READ) {
22487b295dceSLavanya Govindarajan 			if (data_copy != NULL)
22497b295dceSLavanya Govindarajan 				GOTO_FAIL("%s: mbuf data read should fail!\n",
22507b295dceSLavanya Govindarajan 						__func__);
22517b295dceSLavanya Govindarajan 			else {
22527b295dceSLavanya Govindarajan 				rte_pktmbuf_free(m);
22537b295dceSLavanya Govindarajan 				m = NULL;
22547b295dceSLavanya Govindarajan 				continue;
22557b295dceSLavanya Govindarajan 			}
22567b295dceSLavanya Govindarajan 		}
22577b295dceSLavanya Govindarajan 		if (data_copy == NULL)
22587b295dceSLavanya Govindarajan 			GOTO_FAIL("%s: Error in reading packet data!\n",
22597b295dceSLavanya Govindarajan 					__func__);
22607b295dceSLavanya Govindarajan 		for (pos = 0; pos < test_cases[i].read_len; pos++) {
22617b295dceSLavanya Govindarajan 			if (data_copy[pos] !=
22627b295dceSLavanya Govindarajan 					(char)((test_cases[i].read_off + pos)
22637b295dceSLavanya Govindarajan 						% 0xffff))
22647b295dceSLavanya Govindarajan 				GOTO_FAIL("Data corrupted at offset %u is %2X",
22657b295dceSLavanya Govindarajan 						pos, data_copy[pos]);
22667b295dceSLavanya Govindarajan 		}
22677b295dceSLavanya Govindarajan 		rte_pktmbuf_dump(stdout, m, rte_pktmbuf_pkt_len(m));
22687b295dceSLavanya Govindarajan 		rte_pktmbuf_free(m);
22697b295dceSLavanya Govindarajan 		m = NULL;
22707b295dceSLavanya Govindarajan 	}
22717b295dceSLavanya Govindarajan 	return 0;
22727b295dceSLavanya Govindarajan 
22737b295dceSLavanya Govindarajan fail:
22747b295dceSLavanya Govindarajan 	if (m != NULL) {
22757b295dceSLavanya Govindarajan 		rte_pktmbuf_free(m);
22767b295dceSLavanya Govindarajan 		m = NULL;
22777b295dceSLavanya Govindarajan 	}
22787b295dceSLavanya Govindarajan 	return -1;
22797b295dceSLavanya Govindarajan }
22807b295dceSLavanya Govindarajan 
22817b295dceSLavanya Govindarajan /* Define a free call back function to be used for external buffer */
22827b295dceSLavanya Govindarajan static void
ext_buf_free_callback_fn(void * addr,void * opaque)22837dc62742SOlivier Matz ext_buf_free_callback_fn(void *addr, void *opaque)
22847b295dceSLavanya Govindarajan {
22857dc62742SOlivier Matz 	bool *freed = opaque;
22867b295dceSLavanya Govindarajan 
22877dc62742SOlivier Matz 	if (addr == NULL) {
22887b295dceSLavanya Govindarajan 		printf("External buffer address is invalid\n");
22897b295dceSLavanya Govindarajan 		return;
22907b295dceSLavanya Govindarajan 	}
22917dc62742SOlivier Matz 	rte_free(addr);
22927dc62742SOlivier Matz 	*freed = true;
22937b295dceSLavanya Govindarajan 	printf("External buffer freed via callback\n");
22947b295dceSLavanya Govindarajan }
22957b295dceSLavanya Govindarajan 
22967b295dceSLavanya Govindarajan /*
22977b295dceSLavanya Govindarajan  * Test to initialize shared data in external buffer before attaching to mbuf
22987b295dceSLavanya Govindarajan  *  - Allocate mbuf with no data.
22997b295dceSLavanya Govindarajan  *  - Allocate external buffer with size should be large enough to accommodate
23007b295dceSLavanya Govindarajan  *     rte_mbuf_ext_shared_info.
23017b295dceSLavanya Govindarajan  *  - Invoke pktmbuf_ext_shinfo_init_helper to initialize shared data.
23027b295dceSLavanya Govindarajan  *  - Invoke rte_pktmbuf_attach_extbuf to attach external buffer to the mbuf.
23037b295dceSLavanya Govindarajan  *  - Clone another mbuf and attach the same external buffer to it.
23047b295dceSLavanya Govindarajan  *  - Invoke rte_pktmbuf_detach_extbuf to detach the external buffer from mbuf.
23057b295dceSLavanya Govindarajan  */
23067b295dceSLavanya Govindarajan static int
test_pktmbuf_ext_shinfo_init_helper(struct rte_mempool * pktmbuf_pool)23077b295dceSLavanya Govindarajan test_pktmbuf_ext_shinfo_init_helper(struct rte_mempool *pktmbuf_pool)
23087b295dceSLavanya Govindarajan {
23097b295dceSLavanya Govindarajan 	struct rte_mbuf *m = NULL;
23107b295dceSLavanya Govindarajan 	struct rte_mbuf *clone = NULL;
23117b295dceSLavanya Govindarajan 	struct rte_mbuf_ext_shared_info *ret_shinfo = NULL;
23127b295dceSLavanya Govindarajan 	rte_iova_t buf_iova;
23137b295dceSLavanya Govindarajan 	void *ext_buf_addr = NULL;
23147b295dceSLavanya Govindarajan 	uint16_t buf_len = EXT_BUF_TEST_DATA_LEN +
23157b295dceSLavanya Govindarajan 				sizeof(struct rte_mbuf_ext_shared_info);
23167dc62742SOlivier Matz 	bool freed = false;
23177b295dceSLavanya Govindarajan 
23187b295dceSLavanya Govindarajan 	/* alloc a mbuf */
23197b295dceSLavanya Govindarajan 	m = rte_pktmbuf_alloc(pktmbuf_pool);
23207b295dceSLavanya Govindarajan 	if (m == NULL)
23217b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: mbuf allocation failed!\n", __func__);
23227b295dceSLavanya Govindarajan 	if (rte_pktmbuf_pkt_len(m) != 0)
23237b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Bad packet length\n", __func__);
23247b295dceSLavanya Govindarajan 	rte_mbuf_sanity_check(m, 0);
23257b295dceSLavanya Govindarajan 
23267b295dceSLavanya Govindarajan 	ext_buf_addr = rte_malloc("External buffer", buf_len,
23277b295dceSLavanya Govindarajan 			RTE_CACHE_LINE_SIZE);
23287b295dceSLavanya Govindarajan 	if (ext_buf_addr == NULL)
23297b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: External buffer allocation failed\n", __func__);
23307b295dceSLavanya Govindarajan 
23317b295dceSLavanya Govindarajan 	ret_shinfo = rte_pktmbuf_ext_shinfo_init_helper(ext_buf_addr, &buf_len,
23327dc62742SOlivier Matz 		ext_buf_free_callback_fn, &freed);
23337b295dceSLavanya Govindarajan 	if (ret_shinfo == NULL)
23347b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Shared info initialization failed!\n", __func__);
23357b295dceSLavanya Govindarajan 
23367b295dceSLavanya Govindarajan 	if (rte_mbuf_ext_refcnt_read(ret_shinfo) != 1)
23377b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: External refcount is not 1\n", __func__);
23387b295dceSLavanya Govindarajan 
23397b295dceSLavanya Govindarajan 	if (rte_mbuf_refcnt_read(m) != 1)
23407b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Invalid refcnt in mbuf\n", __func__);
23417b295dceSLavanya Govindarajan 
2342eb3fea3cSOlivier Matz 	buf_iova = rte_mem_virt2iova(ext_buf_addr);
23437b295dceSLavanya Govindarajan 	rte_pktmbuf_attach_extbuf(m, ext_buf_addr, buf_iova, buf_len,
23447b295dceSLavanya Govindarajan 		ret_shinfo);
2345daa02b5cSOlivier Matz 	if (m->ol_flags != RTE_MBUF_F_EXTERNAL)
23467b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: External buffer is not attached to mbuf\n",
23477b295dceSLavanya Govindarajan 				__func__);
23487b295dceSLavanya Govindarajan 
2349*6dbaa4eeSRakesh Kudurumalla 	/* allocate one more mbuf, it is attached to the same external buffer */
23507b295dceSLavanya Govindarajan 	clone = rte_pktmbuf_clone(m, pktmbuf_pool);
23517b295dceSLavanya Govindarajan 	if (clone == NULL)
23527b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: mbuf clone allocation failed!\n", __func__);
23537b295dceSLavanya Govindarajan 	if (rte_pktmbuf_pkt_len(clone) != 0)
23547b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Bad packet length\n", __func__);
23557b295dceSLavanya Govindarajan 
2356daa02b5cSOlivier Matz 	if (clone->ol_flags != RTE_MBUF_F_EXTERNAL)
23577b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: External buffer is not attached to mbuf\n",
23587b295dceSLavanya Govindarajan 				__func__);
23597b295dceSLavanya Govindarajan 
23607b295dceSLavanya Govindarajan 	if (rte_mbuf_ext_refcnt_read(ret_shinfo) != 2)
23617b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Invalid ext_buf ref_cnt\n", __func__);
23627dc62742SOlivier Matz 	if (freed)
23637dc62742SOlivier Matz 		GOTO_FAIL("%s: extbuf should not be freed\n", __func__);
23647b295dceSLavanya Govindarajan 
23657b295dceSLavanya Govindarajan 	/* test to manually update ext_buf_ref_cnt from 2 to 3*/
23667b295dceSLavanya Govindarajan 	rte_mbuf_ext_refcnt_update(ret_shinfo, 1);
23677b295dceSLavanya Govindarajan 	if (rte_mbuf_ext_refcnt_read(ret_shinfo) != 3)
23687b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Update ext_buf ref_cnt failed\n", __func__);
23697dc62742SOlivier Matz 	if (freed)
23707dc62742SOlivier Matz 		GOTO_FAIL("%s: extbuf should not be freed\n", __func__);
23717b295dceSLavanya Govindarajan 
23727b295dceSLavanya Govindarajan 	/* reset the ext_refcnt before freeing the external buffer */
23737b295dceSLavanya Govindarajan 	rte_mbuf_ext_refcnt_set(ret_shinfo, 2);
23747b295dceSLavanya Govindarajan 	if (rte_mbuf_ext_refcnt_read(ret_shinfo) != 2)
23757b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: set ext_buf ref_cnt failed\n", __func__);
23767dc62742SOlivier Matz 	if (freed)
23777dc62742SOlivier Matz 		GOTO_FAIL("%s: extbuf should not be freed\n", __func__);
23787b295dceSLavanya Govindarajan 
23797b295dceSLavanya Govindarajan 	/* detach the external buffer from mbufs */
23807b295dceSLavanya Govindarajan 	rte_pktmbuf_detach_extbuf(m);
23817b295dceSLavanya Govindarajan 	/* check if ref cnt is decremented */
23827b295dceSLavanya Govindarajan 	if (rte_mbuf_ext_refcnt_read(ret_shinfo) != 1)
23837b295dceSLavanya Govindarajan 		GOTO_FAIL("%s: Invalid ext_buf ref_cnt\n", __func__);
23847dc62742SOlivier Matz 	if (freed)
23857dc62742SOlivier Matz 		GOTO_FAIL("%s: extbuf should not be freed\n", __func__);
23867b295dceSLavanya Govindarajan 
23877b295dceSLavanya Govindarajan 	rte_pktmbuf_detach_extbuf(clone);
23887dc62742SOlivier Matz 	if (!freed)
23897dc62742SOlivier Matz 		GOTO_FAIL("%s: extbuf should be freed\n", __func__);
23907dc62742SOlivier Matz 	freed = false;
23917b295dceSLavanya Govindarajan 
23927b295dceSLavanya Govindarajan 	rte_pktmbuf_free(m);
23937b295dceSLavanya Govindarajan 	m = NULL;
23947b295dceSLavanya Govindarajan 	rte_pktmbuf_free(clone);
23957b295dceSLavanya Govindarajan 	clone = NULL;
23967b295dceSLavanya Govindarajan 
23977b295dceSLavanya Govindarajan 	return 0;
23987b295dceSLavanya Govindarajan 
23997b295dceSLavanya Govindarajan fail:
24007b295dceSLavanya Govindarajan 	if (m) {
24017b295dceSLavanya Govindarajan 		rte_pktmbuf_free(m);
24027b295dceSLavanya Govindarajan 		m = NULL;
24037b295dceSLavanya Govindarajan 	}
24047b295dceSLavanya Govindarajan 	if (clone) {
24057b295dceSLavanya Govindarajan 		rte_pktmbuf_free(clone);
24067b295dceSLavanya Govindarajan 		clone = NULL;
24077b295dceSLavanya Govindarajan 	}
24087b295dceSLavanya Govindarajan 	if (ext_buf_addr != NULL) {
24097b295dceSLavanya Govindarajan 		rte_free(ext_buf_addr);
24107b295dceSLavanya Govindarajan 		ext_buf_addr = NULL;
24117b295dceSLavanya Govindarajan 	}
24127b295dceSLavanya Govindarajan 	return -1;
24137b295dceSLavanya Govindarajan }
24147b295dceSLavanya Govindarajan 
24155d3e7176SViacheslav Ovsiienko /*
24165d3e7176SViacheslav Ovsiienko  * Test the mbuf pool with pinned external data buffers
24175d3e7176SViacheslav Ovsiienko  *  - Allocate memory zone for external buffer
24185d3e7176SViacheslav Ovsiienko  *  - Create the mbuf pool with pinned external buffer
24195d3e7176SViacheslav Ovsiienko  *  - Check the created pool with relevant mbuf pool unit tests
24205d3e7176SViacheslav Ovsiienko  */
24215d3e7176SViacheslav Ovsiienko static int
test_pktmbuf_ext_pinned_buffer(struct rte_mempool * std_pool)24225d3e7176SViacheslav Ovsiienko test_pktmbuf_ext_pinned_buffer(struct rte_mempool *std_pool)
24235d3e7176SViacheslav Ovsiienko {
24245d3e7176SViacheslav Ovsiienko 
24255d3e7176SViacheslav Ovsiienko 	struct rte_pktmbuf_extmem ext_mem;
24265d3e7176SViacheslav Ovsiienko 	struct rte_mempool *pinned_pool = NULL;
24275d3e7176SViacheslav Ovsiienko 	const struct rte_memzone *mz = NULL;
24285d3e7176SViacheslav Ovsiienko 
24295d3e7176SViacheslav Ovsiienko 	printf("Test mbuf pool with external pinned data buffers\n");
24305d3e7176SViacheslav Ovsiienko 
24315d3e7176SViacheslav Ovsiienko 	/* Allocate memzone for the external data buffer */
24325d3e7176SViacheslav Ovsiienko 	mz = rte_memzone_reserve("pinned_pool",
24335d3e7176SViacheslav Ovsiienko 				 NB_MBUF * MBUF_DATA_SIZE,
24345d3e7176SViacheslav Ovsiienko 				 SOCKET_ID_ANY,
24355d3e7176SViacheslav Ovsiienko 				 RTE_MEMZONE_2MB | RTE_MEMZONE_SIZE_HINT_ONLY);
24365d3e7176SViacheslav Ovsiienko 	if (mz == NULL)
24375d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: Memzone allocation failed\n", __func__);
24385d3e7176SViacheslav Ovsiienko 
24395d3e7176SViacheslav Ovsiienko 	/* Create the mbuf pool with pinned external data buffer */
24405d3e7176SViacheslav Ovsiienko 	ext_mem.buf_ptr = mz->addr;
24415d3e7176SViacheslav Ovsiienko 	ext_mem.buf_iova = mz->iova;
24425d3e7176SViacheslav Ovsiienko 	ext_mem.buf_len = mz->len;
24435d3e7176SViacheslav Ovsiienko 	ext_mem.elt_size = MBUF_DATA_SIZE;
24445d3e7176SViacheslav Ovsiienko 
24455d3e7176SViacheslav Ovsiienko 	pinned_pool = rte_pktmbuf_pool_create_extbuf("test_pinned_pool",
24465d3e7176SViacheslav Ovsiienko 				NB_MBUF, MEMPOOL_CACHE_SIZE, 0,
24475d3e7176SViacheslav Ovsiienko 				MBUF_DATA_SIZE,	SOCKET_ID_ANY,
24485d3e7176SViacheslav Ovsiienko 				&ext_mem, 1);
24495d3e7176SViacheslav Ovsiienko 	if (pinned_pool == NULL)
24505d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: Mbuf pool with pinned external"
24515d3e7176SViacheslav Ovsiienko 			  " buffer creation failed\n", __func__);
24525d3e7176SViacheslav Ovsiienko 	/* test multiple mbuf alloc */
24535d3e7176SViacheslav Ovsiienko 	if (test_pktmbuf_pool(pinned_pool) < 0)
24545d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: test_mbuf_pool(pinned) failed\n",
24555d3e7176SViacheslav Ovsiienko 			  __func__);
24565d3e7176SViacheslav Ovsiienko 
24575d3e7176SViacheslav Ovsiienko 	/* do it another time to check that all mbufs were freed */
24585d3e7176SViacheslav Ovsiienko 	if (test_pktmbuf_pool(pinned_pool) < 0)
24595d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: test_mbuf_pool(pinned) failed (2)\n",
24605d3e7176SViacheslav Ovsiienko 			  __func__);
24615d3e7176SViacheslav Ovsiienko 
24625d3e7176SViacheslav Ovsiienko 	/* test that the data pointer on a packet mbuf is set properly */
24635d3e7176SViacheslav Ovsiienko 	if (test_pktmbuf_pool_ptr(pinned_pool) < 0)
24645d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: test_pktmbuf_pool_ptr(pinned) failed\n",
24655d3e7176SViacheslav Ovsiienko 			  __func__);
24665d3e7176SViacheslav Ovsiienko 
24675d3e7176SViacheslav Ovsiienko 	/* test data manipulation in mbuf with non-ascii data */
24685d3e7176SViacheslav Ovsiienko 	if (test_pktmbuf_with_non_ascii_data(pinned_pool) < 0)
24695d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: test_pktmbuf_with_non_ascii_data(pinned)"
24705d3e7176SViacheslav Ovsiienko 			  " failed\n", __func__);
24715d3e7176SViacheslav Ovsiienko 
24725d3e7176SViacheslav Ovsiienko 	/* test free pktmbuf segment one by one */
24735d3e7176SViacheslav Ovsiienko 	if (test_pktmbuf_free_segment(pinned_pool) < 0)
24745d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: test_pktmbuf_free_segment(pinned) failed\n",
24755d3e7176SViacheslav Ovsiienko 			  __func__);
24765d3e7176SViacheslav Ovsiienko 
24775d3e7176SViacheslav Ovsiienko 	if (testclone_testupdate_testdetach(pinned_pool, std_pool) < 0)
24785d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: testclone_and_testupdate(pinned) failed\n",
24795d3e7176SViacheslav Ovsiienko 			  __func__);
24805d3e7176SViacheslav Ovsiienko 
24815d3e7176SViacheslav Ovsiienko 	if (test_pktmbuf_copy(pinned_pool, std_pool) < 0)
24825d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: test_pktmbuf_copy(pinned) failed\n",
24835d3e7176SViacheslav Ovsiienko 			  __func__);
24845d3e7176SViacheslav Ovsiienko 
24855d3e7176SViacheslav Ovsiienko 	if (test_failing_mbuf_sanity_check(pinned_pool) < 0)
24865d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: test_failing_mbuf_sanity_check(pinned)"
24875d3e7176SViacheslav Ovsiienko 			  " failed\n", __func__);
24885d3e7176SViacheslav Ovsiienko 
24895d3e7176SViacheslav Ovsiienko 	if (test_mbuf_linearize_check(pinned_pool) < 0)
24905d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: test_mbuf_linearize_check(pinned) failed\n",
24915d3e7176SViacheslav Ovsiienko 			  __func__);
24925d3e7176SViacheslav Ovsiienko 
24935d3e7176SViacheslav Ovsiienko 	/* test for allocating a bulk of mbufs with various sizes */
24945d3e7176SViacheslav Ovsiienko 	if (test_pktmbuf_alloc_bulk(pinned_pool) < 0)
24955d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: test_rte_pktmbuf_alloc_bulk(pinned) failed\n",
24965d3e7176SViacheslav Ovsiienko 			  __func__);
24975d3e7176SViacheslav Ovsiienko 
24985d3e7176SViacheslav Ovsiienko 	/* test for allocating a bulk of mbufs with various sizes */
24995d3e7176SViacheslav Ovsiienko 	if (test_neg_pktmbuf_alloc_bulk(pinned_pool) < 0)
25005d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: test_neg_rte_pktmbuf_alloc_bulk(pinned)"
25015d3e7176SViacheslav Ovsiienko 			  " failed\n", __func__);
25025d3e7176SViacheslav Ovsiienko 
25035d3e7176SViacheslav Ovsiienko 	/* test to read mbuf packet */
25045d3e7176SViacheslav Ovsiienko 	if (test_pktmbuf_read(pinned_pool) < 0)
25055d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: test_rte_pktmbuf_read(pinned) failed\n",
25065d3e7176SViacheslav Ovsiienko 			  __func__);
25075d3e7176SViacheslav Ovsiienko 
25085d3e7176SViacheslav Ovsiienko 	/* test to read mbuf packet from offset */
25095d3e7176SViacheslav Ovsiienko 	if (test_pktmbuf_read_from_offset(pinned_pool) < 0)
25105d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: test_rte_pktmbuf_read_from_offset(pinned)"
25115d3e7176SViacheslav Ovsiienko 			  " failed\n", __func__);
25125d3e7176SViacheslav Ovsiienko 
25135d3e7176SViacheslav Ovsiienko 	/* test to read data from chain of mbufs with data segments */
25145d3e7176SViacheslav Ovsiienko 	if (test_pktmbuf_read_from_chain(pinned_pool) < 0)
25155d3e7176SViacheslav Ovsiienko 		GOTO_FAIL("%s: test_rte_pktmbuf_read_from_chain(pinned)"
25165d3e7176SViacheslav Ovsiienko 			  " failed\n", __func__);
25175d3e7176SViacheslav Ovsiienko 
25185d3e7176SViacheslav Ovsiienko 	RTE_SET_USED(std_pool);
25195d3e7176SViacheslav Ovsiienko 	rte_mempool_free(pinned_pool);
25205d3e7176SViacheslav Ovsiienko 	rte_memzone_free(mz);
25215d3e7176SViacheslav Ovsiienko 	return 0;
25225d3e7176SViacheslav Ovsiienko 
25235d3e7176SViacheslav Ovsiienko fail:
25245d3e7176SViacheslav Ovsiienko 	rte_mempool_free(pinned_pool);
25255d3e7176SViacheslav Ovsiienko 	rte_memzone_free(mz);
25265d3e7176SViacheslav Ovsiienko 	return -1;
25275d3e7176SViacheslav Ovsiienko }
25285d3e7176SViacheslav Ovsiienko 
25297b295dceSLavanya Govindarajan static int
test_mbuf_dyn(struct rte_mempool * pktmbuf_pool)25304958ca3aSOlivier Matz test_mbuf_dyn(struct rte_mempool *pktmbuf_pool)
25314958ca3aSOlivier Matz {
25324958ca3aSOlivier Matz 	const struct rte_mbuf_dynfield dynfield = {
25334958ca3aSOlivier Matz 		.name = "test-dynfield",
25344958ca3aSOlivier Matz 		.size = sizeof(uint8_t),
253508966fe7STyler Retzlaff 		.align = alignof(uint8_t),
25364958ca3aSOlivier Matz 		.flags = 0,
25374958ca3aSOlivier Matz 	};
25384958ca3aSOlivier Matz 	const struct rte_mbuf_dynfield dynfield2 = {
25394958ca3aSOlivier Matz 		.name = "test-dynfield2",
25404958ca3aSOlivier Matz 		.size = sizeof(uint16_t),
254108966fe7STyler Retzlaff 		.align = alignof(uint16_t),
25424958ca3aSOlivier Matz 		.flags = 0,
25434958ca3aSOlivier Matz 	};
25444958ca3aSOlivier Matz 	const struct rte_mbuf_dynfield dynfield3 = {
25454958ca3aSOlivier Matz 		.name = "test-dynfield3",
25464958ca3aSOlivier Matz 		.size = sizeof(uint8_t),
254708966fe7STyler Retzlaff 		.align = alignof(uint8_t),
25484958ca3aSOlivier Matz 		.flags = 0,
25494958ca3aSOlivier Matz 	};
25504958ca3aSOlivier Matz 	const struct rte_mbuf_dynfield dynfield_fail_big = {
25514958ca3aSOlivier Matz 		.name = "test-dynfield-fail-big",
25524958ca3aSOlivier Matz 		.size = 256,
25534958ca3aSOlivier Matz 		.align = 1,
25544958ca3aSOlivier Matz 		.flags = 0,
25554958ca3aSOlivier Matz 	};
25564958ca3aSOlivier Matz 	const struct rte_mbuf_dynfield dynfield_fail_align = {
25574958ca3aSOlivier Matz 		.name = "test-dynfield-fail-align",
25584958ca3aSOlivier Matz 		.size = 1,
25594958ca3aSOlivier Matz 		.align = 3,
25604958ca3aSOlivier Matz 		.flags = 0,
25614958ca3aSOlivier Matz 	};
2562e9123c46SDavid Marchand 	const struct rte_mbuf_dynfield dynfield_fail_flag = {
2563e9123c46SDavid Marchand 		.name = "test-dynfield",
2564e9123c46SDavid Marchand 		.size = sizeof(uint8_t),
256508966fe7STyler Retzlaff 		.align = alignof(uint8_t),
2566e9123c46SDavid Marchand 		.flags = 1,
2567e9123c46SDavid Marchand 	};
2568e9123c46SDavid Marchand 	const struct rte_mbuf_dynflag dynflag_fail_flag = {
2569e9123c46SDavid Marchand 		.name = "test-dynflag",
2570e9123c46SDavid Marchand 		.flags = 1,
2571e9123c46SDavid Marchand 	};
25724958ca3aSOlivier Matz 	const struct rte_mbuf_dynflag dynflag = {
25734958ca3aSOlivier Matz 		.name = "test-dynflag",
25744958ca3aSOlivier Matz 		.flags = 0,
25754958ca3aSOlivier Matz 	};
25764958ca3aSOlivier Matz 	const struct rte_mbuf_dynflag dynflag2 = {
25774958ca3aSOlivier Matz 		.name = "test-dynflag2",
25784958ca3aSOlivier Matz 		.flags = 0,
25794958ca3aSOlivier Matz 	};
25804958ca3aSOlivier Matz 	const struct rte_mbuf_dynflag dynflag3 = {
25814958ca3aSOlivier Matz 		.name = "test-dynflag3",
25824958ca3aSOlivier Matz 		.flags = 0,
25834958ca3aSOlivier Matz 	};
25844958ca3aSOlivier Matz 	struct rte_mbuf *m = NULL;
25854958ca3aSOlivier Matz 	int offset, offset2, offset3;
25864958ca3aSOlivier Matz 	int flag, flag2, flag3;
25874958ca3aSOlivier Matz 	int ret;
25884958ca3aSOlivier Matz 
25894958ca3aSOlivier Matz 	printf("Test mbuf dynamic fields and flags\n");
25904958ca3aSOlivier Matz 	rte_mbuf_dyn_dump(stdout);
25914958ca3aSOlivier Matz 
25924958ca3aSOlivier Matz 	offset = rte_mbuf_dynfield_register(&dynfield);
25934958ca3aSOlivier Matz 	if (offset == -1)
25944958ca3aSOlivier Matz 		GOTO_FAIL("failed to register dynamic field, offset=%d: %s",
25954958ca3aSOlivier Matz 			offset, strerror(errno));
25964958ca3aSOlivier Matz 
25974958ca3aSOlivier Matz 	ret = rte_mbuf_dynfield_register(&dynfield);
25984958ca3aSOlivier Matz 	if (ret != offset)
25994958ca3aSOlivier Matz 		GOTO_FAIL("failed to lookup dynamic field, ret=%d: %s",
26004958ca3aSOlivier Matz 			ret, strerror(errno));
26014958ca3aSOlivier Matz 
26024958ca3aSOlivier Matz 	offset2 = rte_mbuf_dynfield_register(&dynfield2);
26034958ca3aSOlivier Matz 	if (offset2 == -1 || offset2 == offset || (offset2 & 1))
26044958ca3aSOlivier Matz 		GOTO_FAIL("failed to register dynamic field 2, offset2=%d: %s",
26054958ca3aSOlivier Matz 			offset2, strerror(errno));
26064958ca3aSOlivier Matz 
26074958ca3aSOlivier Matz 	offset3 = rte_mbuf_dynfield_register_offset(&dynfield3,
26084958ca3aSOlivier Matz 				offsetof(struct rte_mbuf, dynfield1[1]));
2609530de86aSThomas Monjalon 	if (offset3 != offsetof(struct rte_mbuf, dynfield1[1])) {
2610530de86aSThomas Monjalon 		if (rte_errno == EBUSY)
2611530de86aSThomas Monjalon 			printf("mbuf test error skipped: dynfield is busy\n");
2612530de86aSThomas Monjalon 		else
2613530de86aSThomas Monjalon 			GOTO_FAIL("failed to register dynamic field 3, offset="
2614530de86aSThomas Monjalon 				"%d: %s", offset3, strerror(errno));
2615530de86aSThomas Monjalon 	}
26164958ca3aSOlivier Matz 
26174958ca3aSOlivier Matz 	printf("dynfield: offset=%d, offset2=%d, offset3=%d\n",
26184958ca3aSOlivier Matz 		offset, offset2, offset3);
26194958ca3aSOlivier Matz 
26204958ca3aSOlivier Matz 	ret = rte_mbuf_dynfield_register(&dynfield_fail_big);
26214958ca3aSOlivier Matz 	if (ret != -1)
26224958ca3aSOlivier Matz 		GOTO_FAIL("dynamic field creation should fail (too big)");
26234958ca3aSOlivier Matz 
26244958ca3aSOlivier Matz 	ret = rte_mbuf_dynfield_register(&dynfield_fail_align);
26254958ca3aSOlivier Matz 	if (ret != -1)
26264958ca3aSOlivier Matz 		GOTO_FAIL("dynamic field creation should fail (bad alignment)");
26274958ca3aSOlivier Matz 
26284958ca3aSOlivier Matz 	ret = rte_mbuf_dynfield_register_offset(&dynfield_fail_align,
26294958ca3aSOlivier Matz 				offsetof(struct rte_mbuf, ol_flags));
26304958ca3aSOlivier Matz 	if (ret != -1)
26314958ca3aSOlivier Matz 		GOTO_FAIL("dynamic field creation should fail (not avail)");
26324958ca3aSOlivier Matz 
2633e9123c46SDavid Marchand 	ret = rte_mbuf_dynfield_register(&dynfield_fail_flag);
2634e9123c46SDavid Marchand 	if (ret != -1)
2635e9123c46SDavid Marchand 		GOTO_FAIL("dynamic field creation should fail (invalid flag)");
2636e9123c46SDavid Marchand 
2637e9123c46SDavid Marchand 	ret = rte_mbuf_dynflag_register(&dynflag_fail_flag);
2638e9123c46SDavid Marchand 	if (ret != -1)
2639e9123c46SDavid Marchand 		GOTO_FAIL("dynamic flag creation should fail (invalid flag)");
2640e9123c46SDavid Marchand 
26414958ca3aSOlivier Matz 	flag = rte_mbuf_dynflag_register(&dynflag);
26424958ca3aSOlivier Matz 	if (flag == -1)
26434958ca3aSOlivier Matz 		GOTO_FAIL("failed to register dynamic flag, flag=%d: %s",
26444958ca3aSOlivier Matz 			flag, strerror(errno));
26454958ca3aSOlivier Matz 
26464958ca3aSOlivier Matz 	ret = rte_mbuf_dynflag_register(&dynflag);
26474958ca3aSOlivier Matz 	if (ret != flag)
26484958ca3aSOlivier Matz 		GOTO_FAIL("failed to lookup dynamic flag, ret=%d: %s",
26494958ca3aSOlivier Matz 			ret, strerror(errno));
26504958ca3aSOlivier Matz 
26514958ca3aSOlivier Matz 	flag2 = rte_mbuf_dynflag_register(&dynflag2);
26524958ca3aSOlivier Matz 	if (flag2 == -1 || flag2 == flag)
26534958ca3aSOlivier Matz 		GOTO_FAIL("failed to register dynamic flag 2, flag2=%d: %s",
26544958ca3aSOlivier Matz 			flag2, strerror(errno));
26554958ca3aSOlivier Matz 
26564958ca3aSOlivier Matz 	flag3 = rte_mbuf_dynflag_register_bitnum(&dynflag3,
2657daa02b5cSOlivier Matz 						rte_bsf64(RTE_MBUF_F_LAST_FREE));
26584b81c145STyler Retzlaff 	if ((uint32_t)flag3 != rte_bsf64(RTE_MBUF_F_LAST_FREE))
265972ea8d40SXiaolong Ye 		GOTO_FAIL("failed to register dynamic flag 3, flag3=%d: %s",
26604958ca3aSOlivier Matz 			flag3, strerror(errno));
26614958ca3aSOlivier Matz 
26624958ca3aSOlivier Matz 	printf("dynflag: flag=%d, flag2=%d, flag3=%d\n", flag, flag2, flag3);
26634958ca3aSOlivier Matz 
26644958ca3aSOlivier Matz 	/* set, get dynamic field */
26654958ca3aSOlivier Matz 	m = rte_pktmbuf_alloc(pktmbuf_pool);
26664958ca3aSOlivier Matz 	if (m == NULL)
26674958ca3aSOlivier Matz 		GOTO_FAIL("Cannot allocate mbuf");
26684958ca3aSOlivier Matz 
26694958ca3aSOlivier Matz 	*RTE_MBUF_DYNFIELD(m, offset, uint8_t *) = 1;
26704958ca3aSOlivier Matz 	if (*RTE_MBUF_DYNFIELD(m, offset, uint8_t *) != 1)
26714958ca3aSOlivier Matz 		GOTO_FAIL("failed to read dynamic field");
26724958ca3aSOlivier Matz 	*RTE_MBUF_DYNFIELD(m, offset2, uint16_t *) = 1000;
26734958ca3aSOlivier Matz 	if (*RTE_MBUF_DYNFIELD(m, offset2, uint16_t *) != 1000)
26744958ca3aSOlivier Matz 		GOTO_FAIL("failed to read dynamic field");
26754958ca3aSOlivier Matz 
26764958ca3aSOlivier Matz 	/* set a dynamic flag */
26774958ca3aSOlivier Matz 	m->ol_flags |= (1ULL << flag);
26784958ca3aSOlivier Matz 
26794958ca3aSOlivier Matz 	rte_mbuf_dyn_dump(stdout);
26804958ca3aSOlivier Matz 	rte_pktmbuf_free(m);
26814958ca3aSOlivier Matz 	return 0;
26824958ca3aSOlivier Matz fail:
26834958ca3aSOlivier Matz 	rte_pktmbuf_free(m);
26844958ca3aSOlivier Matz 	return -1;
26854958ca3aSOlivier Matz }
26864958ca3aSOlivier Matz 
2687efc6f910SOlivier Matz /* check that m->nb_segs and m->next are reset on mbuf free */
2688efc6f910SOlivier Matz static int
test_nb_segs_and_next_reset(void)2689efc6f910SOlivier Matz test_nb_segs_and_next_reset(void)
2690efc6f910SOlivier Matz {
2691efc6f910SOlivier Matz 	struct rte_mbuf *m0 = NULL, *m1 = NULL, *m2 = NULL;
2692efc6f910SOlivier Matz 	struct rte_mempool *pool = NULL;
2693efc6f910SOlivier Matz 
2694efc6f910SOlivier Matz 	pool = rte_pktmbuf_pool_create("test_mbuf_reset",
2695efc6f910SOlivier Matz 			3, 0, 0, MBUF_DATA_SIZE, SOCKET_ID_ANY);
2696efc6f910SOlivier Matz 	if (pool == NULL)
2697efc6f910SOlivier Matz 		GOTO_FAIL("Failed to create mbuf pool");
2698efc6f910SOlivier Matz 
2699efc6f910SOlivier Matz 	/* alloc mbufs */
2700efc6f910SOlivier Matz 	m0 = rte_pktmbuf_alloc(pool);
2701efc6f910SOlivier Matz 	m1 = rte_pktmbuf_alloc(pool);
2702efc6f910SOlivier Matz 	m2 = rte_pktmbuf_alloc(pool);
2703efc6f910SOlivier Matz 	if (m0 == NULL || m1 == NULL || m2 == NULL)
2704efc6f910SOlivier Matz 		GOTO_FAIL("Failed to allocate mbuf");
2705efc6f910SOlivier Matz 
2706efc6f910SOlivier Matz 	/* append data in all of them */
2707efc6f910SOlivier Matz 	if (rte_pktmbuf_append(m0, 500) == NULL ||
2708efc6f910SOlivier Matz 			rte_pktmbuf_append(m1, 500) == NULL ||
2709efc6f910SOlivier Matz 			rte_pktmbuf_append(m2, 500) == NULL)
2710efc6f910SOlivier Matz 		GOTO_FAIL("Failed to append data in mbuf");
2711efc6f910SOlivier Matz 
2712efc6f910SOlivier Matz 	/* chain them in one mbuf m0 */
2713efc6f910SOlivier Matz 	rte_pktmbuf_chain(m1, m2);
2714efc6f910SOlivier Matz 	rte_pktmbuf_chain(m0, m1);
2715efc6f910SOlivier Matz 	if (m0->nb_segs != 3 || m0->next != m1 || m1->next != m2 ||
2716efc6f910SOlivier Matz 			m2->next != NULL) {
2717efc6f910SOlivier Matz 		m1 = m2 = NULL;
2718efc6f910SOlivier Matz 		GOTO_FAIL("Failed to chain mbufs");
2719efc6f910SOlivier Matz 	}
2720efc6f910SOlivier Matz 
2721efc6f910SOlivier Matz 	/* split m0 chain in two, between m1 and m2 */
2722efc6f910SOlivier Matz 	m0->nb_segs = 2;
2723ce5440e0SPavel Ivashchenko 	m0->pkt_len -= m2->data_len;
2724efc6f910SOlivier Matz 	m1->next = NULL;
2725efc6f910SOlivier Matz 	m2->nb_segs = 1;
2726efc6f910SOlivier Matz 
2727efc6f910SOlivier Matz 	/* free the 2 mbuf chains m0 and m2  */
2728efc6f910SOlivier Matz 	rte_pktmbuf_free(m0);
2729efc6f910SOlivier Matz 	rte_pktmbuf_free(m2);
2730efc6f910SOlivier Matz 
2731efc6f910SOlivier Matz 	/* realloc the 3 mbufs */
2732efc6f910SOlivier Matz 	m0 = rte_mbuf_raw_alloc(pool);
2733efc6f910SOlivier Matz 	m1 = rte_mbuf_raw_alloc(pool);
2734efc6f910SOlivier Matz 	m2 = rte_mbuf_raw_alloc(pool);
2735efc6f910SOlivier Matz 	if (m0 == NULL || m1 == NULL || m2 == NULL)
2736efc6f910SOlivier Matz 		GOTO_FAIL("Failed to reallocate mbuf");
2737efc6f910SOlivier Matz 
2738efc6f910SOlivier Matz 	/* ensure that m->next and m->nb_segs are reset allocated mbufs */
2739efc6f910SOlivier Matz 	if (m0->nb_segs != 1 || m0->next != NULL ||
2740efc6f910SOlivier Matz 			m1->nb_segs != 1 || m1->next != NULL ||
2741efc6f910SOlivier Matz 			m2->nb_segs != 1 || m2->next != NULL)
2742efc6f910SOlivier Matz 		GOTO_FAIL("nb_segs or next was not reset properly");
2743efc6f910SOlivier Matz 
2744bf47fb83SJie Hai 	rte_mempool_free(pool);
2745efc6f910SOlivier Matz 	return 0;
2746efc6f910SOlivier Matz 
2747efc6f910SOlivier Matz fail:
2748efc6f910SOlivier Matz 	rte_mempool_free(pool);
2749efc6f910SOlivier Matz 	return -1;
2750efc6f910SOlivier Matz }
2751efc6f910SOlivier Matz 
27524958ca3aSOlivier Matz static int
test_mbuf(void)2753a9de470cSBruce Richardson test_mbuf(void)
2754a9de470cSBruce Richardson {
2755a9de470cSBruce Richardson 	int ret = -1;
2756a9de470cSBruce Richardson 	struct rte_mempool *pktmbuf_pool = NULL;
2757a9de470cSBruce Richardson 	struct rte_mempool *pktmbuf_pool2 = NULL;
2758a9de470cSBruce Richardson 
2759a9de470cSBruce Richardson 
2760a9de470cSBruce Richardson 	RTE_BUILD_BUG_ON(sizeof(struct rte_mbuf) != RTE_CACHE_LINE_MIN_SIZE * 2);
2761a9de470cSBruce Richardson 
2762a9de470cSBruce Richardson 	/* create pktmbuf pool if it does not exist */
2763a9de470cSBruce Richardson 	pktmbuf_pool = rte_pktmbuf_pool_create("test_pktmbuf_pool",
27647b295dceSLavanya Govindarajan 			NB_MBUF, MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
27657b295dceSLavanya Govindarajan 			SOCKET_ID_ANY);
2766a9de470cSBruce Richardson 
2767a9de470cSBruce Richardson 	if (pktmbuf_pool == NULL) {
2768a9de470cSBruce Richardson 		printf("cannot allocate mbuf pool\n");
2769a9de470cSBruce Richardson 		goto err;
2770a9de470cSBruce Richardson 	}
2771a9de470cSBruce Richardson 
27724958ca3aSOlivier Matz 	/* test registration of dynamic fields and flags */
27734958ca3aSOlivier Matz 	if (test_mbuf_dyn(pktmbuf_pool) < 0) {
27744958ca3aSOlivier Matz 		printf("mbuf dynflag test failed\n");
27754958ca3aSOlivier Matz 		goto err;
27764958ca3aSOlivier Matz 	}
27774958ca3aSOlivier Matz 
2778a9de470cSBruce Richardson 	/* create a specific pktmbuf pool with a priv_size != 0 and no data
2779a9de470cSBruce Richardson 	 * room size */
2780a9de470cSBruce Richardson 	pktmbuf_pool2 = rte_pktmbuf_pool_create("test_pktmbuf_pool2",
27817b295dceSLavanya Govindarajan 			NB_MBUF, MEMPOOL_CACHE_SIZE, MBUF2_PRIV_SIZE, 0,
27827b295dceSLavanya Govindarajan 			SOCKET_ID_ANY);
2783a9de470cSBruce Richardson 
2784a9de470cSBruce Richardson 	if (pktmbuf_pool2 == NULL) {
2785a9de470cSBruce Richardson 		printf("cannot allocate mbuf pool\n");
2786a9de470cSBruce Richardson 		goto err;
2787a9de470cSBruce Richardson 	}
2788a9de470cSBruce Richardson 
2789a9de470cSBruce Richardson 	/* test multiple mbuf alloc */
2790a9de470cSBruce Richardson 	if (test_pktmbuf_pool(pktmbuf_pool) < 0) {
2791a9de470cSBruce Richardson 		printf("test_mbuf_pool() failed\n");
2792a9de470cSBruce Richardson 		goto err;
2793a9de470cSBruce Richardson 	}
2794a9de470cSBruce Richardson 
2795a9de470cSBruce Richardson 	/* do it another time to check that all mbufs were freed */
2796a9de470cSBruce Richardson 	if (test_pktmbuf_pool(pktmbuf_pool) < 0) {
2797a9de470cSBruce Richardson 		printf("test_mbuf_pool() failed (2)\n");
2798a9de470cSBruce Richardson 		goto err;
2799a9de470cSBruce Richardson 	}
2800a9de470cSBruce Richardson 
2801824b67c2SMorten Brørup 	/* test bulk mbuf alloc and free */
2802824b67c2SMorten Brørup 	if (test_pktmbuf_pool_bulk() < 0) {
2803824b67c2SMorten Brørup 		printf("test_pktmbuf_pool_bulk() failed\n");
2804824b67c2SMorten Brørup 		goto err;
2805824b67c2SMorten Brørup 	}
2806824b67c2SMorten Brørup 
2807a9de470cSBruce Richardson 	/* test that the pointer to the data on a packet mbuf is set properly */
2808a9de470cSBruce Richardson 	if (test_pktmbuf_pool_ptr(pktmbuf_pool) < 0) {
2809a9de470cSBruce Richardson 		printf("test_pktmbuf_pool_ptr() failed\n");
2810a9de470cSBruce Richardson 		goto err;
2811a9de470cSBruce Richardson 	}
2812a9de470cSBruce Richardson 
2813a9de470cSBruce Richardson 	/* test data manipulation in mbuf */
2814a9de470cSBruce Richardson 	if (test_one_pktmbuf(pktmbuf_pool) < 0) {
2815a9de470cSBruce Richardson 		printf("test_one_mbuf() failed\n");
2816a9de470cSBruce Richardson 		goto err;
2817a9de470cSBruce Richardson 	}
2818a9de470cSBruce Richardson 
2819a9de470cSBruce Richardson 
2820a9de470cSBruce Richardson 	/*
2821a9de470cSBruce Richardson 	 * do it another time, to check that allocation reinitialize
2822a9de470cSBruce Richardson 	 * the mbuf correctly
2823a9de470cSBruce Richardson 	 */
2824a9de470cSBruce Richardson 	if (test_one_pktmbuf(pktmbuf_pool) < 0) {
2825a9de470cSBruce Richardson 		printf("test_one_mbuf() failed (2)\n");
2826a9de470cSBruce Richardson 		goto err;
2827a9de470cSBruce Richardson 	}
2828a9de470cSBruce Richardson 
2829a9de470cSBruce Richardson 	if (test_pktmbuf_with_non_ascii_data(pktmbuf_pool) < 0) {
2830a9de470cSBruce Richardson 		printf("test_pktmbuf_with_non_ascii_data() failed\n");
2831a9de470cSBruce Richardson 		goto err;
2832a9de470cSBruce Richardson 	}
2833a9de470cSBruce Richardson 
2834a9de470cSBruce Richardson 	/* test free pktmbuf segment one by one */
2835a9de470cSBruce Richardson 	if (test_pktmbuf_free_segment(pktmbuf_pool) < 0) {
2836a9de470cSBruce Richardson 		printf("test_pktmbuf_free_segment() failed.\n");
2837a9de470cSBruce Richardson 		goto err;
2838a9de470cSBruce Richardson 	}
2839a9de470cSBruce Richardson 
28405d3e7176SViacheslav Ovsiienko 	if (testclone_testupdate_testdetach(pktmbuf_pool, pktmbuf_pool) < 0) {
2841a9de470cSBruce Richardson 		printf("testclone_and_testupdate() failed \n");
2842a9de470cSBruce Richardson 		goto err;
2843a9de470cSBruce Richardson 	}
2844a9de470cSBruce Richardson 
28455d3e7176SViacheslav Ovsiienko 	if (test_pktmbuf_copy(pktmbuf_pool, pktmbuf_pool) < 0) {
2846c3a90c38SStephen Hemminger 		printf("test_pktmbuf_copy() failed\n");
2847c3a90c38SStephen Hemminger 		goto err;
2848c3a90c38SStephen Hemminger 	}
2849c3a90c38SStephen Hemminger 
2850a9de470cSBruce Richardson 	if (test_attach_from_different_pool(pktmbuf_pool, pktmbuf_pool2) < 0) {
2851a9de470cSBruce Richardson 		printf("test_attach_from_different_pool() failed\n");
2852a9de470cSBruce Richardson 		goto err;
2853a9de470cSBruce Richardson 	}
2854a9de470cSBruce Richardson 
2855a9de470cSBruce Richardson 	if (test_refcnt_mbuf() < 0) {
2856a9de470cSBruce Richardson 		printf("test_refcnt_mbuf() failed \n");
2857a9de470cSBruce Richardson 		goto err;
2858a9de470cSBruce Richardson 	}
2859a9de470cSBruce Richardson 
2860a9de470cSBruce Richardson 	if (test_failing_mbuf_sanity_check(pktmbuf_pool) < 0) {
2861a9de470cSBruce Richardson 		printf("test_failing_mbuf_sanity_check() failed\n");
2862a9de470cSBruce Richardson 		goto err;
2863a9de470cSBruce Richardson 	}
2864a9de470cSBruce Richardson 
2865a9de470cSBruce Richardson 	if (test_mbuf_linearize_check(pktmbuf_pool) < 0) {
2866a9de470cSBruce Richardson 		printf("test_mbuf_linearize_check() failed\n");
2867a9de470cSBruce Richardson 		goto err;
2868a9de470cSBruce Richardson 	}
2869a9de470cSBruce Richardson 
28708d9c2c3aSKonstantin Ananyev 	if (test_tx_offload() < 0) {
28718d9c2c3aSKonstantin Ananyev 		printf("test_tx_offload() failed\n");
28728d9c2c3aSKonstantin Ananyev 		goto err;
28738d9c2c3aSKonstantin Ananyev 	}
28748d9c2c3aSKonstantin Ananyev 
2875b364bc9eSPallantla Poornima 	if (test_get_rx_ol_flag_list() < 0) {
2876b364bc9eSPallantla Poornima 		printf("test_rte_get_rx_ol_flag_list() failed\n");
2877b364bc9eSPallantla Poornima 		goto err;
2878b364bc9eSPallantla Poornima 	}
2879b364bc9eSPallantla Poornima 
2880b364bc9eSPallantla Poornima 	if (test_get_tx_ol_flag_list() < 0) {
2881b364bc9eSPallantla Poornima 		printf("test_rte_get_tx_ol_flag_list() failed\n");
2882b364bc9eSPallantla Poornima 		goto err;
2883b364bc9eSPallantla Poornima 	}
2884b364bc9eSPallantla Poornima 
2885b364bc9eSPallantla Poornima 	if (test_get_rx_ol_flag_name() < 0) {
2886b364bc9eSPallantla Poornima 		printf("test_rte_get_rx_ol_flag_name() failed\n");
2887b364bc9eSPallantla Poornima 		goto err;
2888b364bc9eSPallantla Poornima 	}
2889b364bc9eSPallantla Poornima 
2890b364bc9eSPallantla Poornima 	if (test_get_tx_ol_flag_name() < 0) {
2891b364bc9eSPallantla Poornima 		printf("test_rte_get_tx_ol_flag_name() failed\n");
2892b364bc9eSPallantla Poornima 		goto err;
2893b364bc9eSPallantla Poornima 	}
2894b364bc9eSPallantla Poornima 
28957b295dceSLavanya Govindarajan 	if (test_mbuf_validate_tx_offload_one(pktmbuf_pool) < 0) {
28967b295dceSLavanya Govindarajan 		printf("test_mbuf_validate_tx_offload_one() failed\n");
28977b295dceSLavanya Govindarajan 		goto err;
28987b295dceSLavanya Govindarajan 	}
28997b295dceSLavanya Govindarajan 
29007b295dceSLavanya Govindarajan 	/* test for allocating a bulk of mbufs with various sizes */
29017b295dceSLavanya Govindarajan 	if (test_pktmbuf_alloc_bulk(pktmbuf_pool) < 0) {
29027b295dceSLavanya Govindarajan 		printf("test_rte_pktmbuf_alloc_bulk() failed\n");
29037b295dceSLavanya Govindarajan 		goto err;
29047b295dceSLavanya Govindarajan 	}
29057b295dceSLavanya Govindarajan 
29067b295dceSLavanya Govindarajan 	/* test for allocating a bulk of mbufs with various sizes */
29077b295dceSLavanya Govindarajan 	if (test_neg_pktmbuf_alloc_bulk(pktmbuf_pool) < 0) {
29087b295dceSLavanya Govindarajan 		printf("test_neg_rte_pktmbuf_alloc_bulk() failed\n");
29097b295dceSLavanya Govindarajan 		goto err;
29107b295dceSLavanya Govindarajan 	}
29117b295dceSLavanya Govindarajan 
29127b295dceSLavanya Govindarajan 	/* test to read mbuf packet */
29137b295dceSLavanya Govindarajan 	if (test_pktmbuf_read(pktmbuf_pool) < 0) {
29147b295dceSLavanya Govindarajan 		printf("test_rte_pktmbuf_read() failed\n");
29157b295dceSLavanya Govindarajan 		goto err;
29167b295dceSLavanya Govindarajan 	}
29177b295dceSLavanya Govindarajan 
29187b295dceSLavanya Govindarajan 	/* test to read mbuf packet from offset */
29197b295dceSLavanya Govindarajan 	if (test_pktmbuf_read_from_offset(pktmbuf_pool) < 0) {
29207b295dceSLavanya Govindarajan 		printf("test_rte_pktmbuf_read_from_offset() failed\n");
29217b295dceSLavanya Govindarajan 		goto err;
29227b295dceSLavanya Govindarajan 	}
29237b295dceSLavanya Govindarajan 
29247b295dceSLavanya Govindarajan 	/* test to read data from chain of mbufs with data segments */
29257b295dceSLavanya Govindarajan 	if (test_pktmbuf_read_from_chain(pktmbuf_pool) < 0) {
29267b295dceSLavanya Govindarajan 		printf("test_rte_pktmbuf_read_from_chain() failed\n");
29277b295dceSLavanya Govindarajan 		goto err;
29287b295dceSLavanya Govindarajan 	}
29297b295dceSLavanya Govindarajan 
29307b295dceSLavanya Govindarajan 	/* test to initialize shared info. at the end of external buffer */
29317b295dceSLavanya Govindarajan 	if (test_pktmbuf_ext_shinfo_init_helper(pktmbuf_pool) < 0) {
29327b295dceSLavanya Govindarajan 		printf("test_pktmbuf_ext_shinfo_init_helper() failed\n");
29337b295dceSLavanya Govindarajan 		goto err;
29347b295dceSLavanya Govindarajan 	}
29357b295dceSLavanya Govindarajan 
29365d3e7176SViacheslav Ovsiienko 	/* test the mbuf pool with pinned external data buffers */
29375d3e7176SViacheslav Ovsiienko 	if (test_pktmbuf_ext_pinned_buffer(pktmbuf_pool) < 0) {
29385d3e7176SViacheslav Ovsiienko 		printf("test_pktmbuf_ext_pinned_buffer() failed\n");
29395d3e7176SViacheslav Ovsiienko 		goto err;
29405d3e7176SViacheslav Ovsiienko 	}
29415d3e7176SViacheslav Ovsiienko 
2942efc6f910SOlivier Matz 	/* test reset of m->nb_segs and m->next on mbuf free */
2943efc6f910SOlivier Matz 	if (test_nb_segs_and_next_reset() < 0) {
2944efc6f910SOlivier Matz 		printf("test_nb_segs_and_next_reset() failed\n");
2945efc6f910SOlivier Matz 		goto err;
2946efc6f910SOlivier Matz 	}
29475d3e7176SViacheslav Ovsiienko 
29488d9c2c3aSKonstantin Ananyev 	ret = 0;
2949a9de470cSBruce Richardson err:
2950a9de470cSBruce Richardson 	rte_mempool_free(pktmbuf_pool);
2951a9de470cSBruce Richardson 	rte_mempool_free(pktmbuf_pool2);
2952a9de470cSBruce Richardson 	return ret;
2953a9de470cSBruce Richardson }
29547b295dceSLavanya Govindarajan #undef GOTO_FAIL
2955a9de470cSBruce Richardson 
2956e0a8442cSBruce Richardson REGISTER_FAST_TEST(mbuf_autotest, false, true, test_mbuf);
2957