Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018 Intel Corporation
3 : : */
4 : :
5 : : #include "test.h"
6 : :
7 : : #include <errno.h>
8 : : #include <stdio.h>
9 : : #include <stdlib.h>
10 : : #include <string.h>
11 : : #include <fcntl.h>
12 : :
13 : : #ifdef RTE_EXEC_ENV_WINDOWS
14 : : static int
15 : : test_external_mem(void)
16 : : {
17 : : printf("external_mem not supported on Windows, skipping test\n");
18 : : return TEST_SKIPPED;
19 : : }
20 : :
21 : : #else
22 : :
23 : : #include <sys/mman.h>
24 : : #include <sys/wait.h>
25 : :
26 : : #include <rte_common.h>
27 : : #include <rte_debug.h>
28 : : #include <rte_eal.h>
29 : : #include <rte_eal_paging.h>
30 : : #include <rte_errno.h>
31 : : #include <rte_malloc.h>
32 : : #include <rte_ring.h>
33 : : #include <rte_string_fns.h>
34 : :
35 : : #define EXTERNAL_MEM_SZ (RTE_PGSIZE_4K << 10) /* 4M of data */
36 : :
37 : : static int
38 : 0 : check_mem(void *addr, rte_iova_t *iova, size_t pgsz, int n_pages)
39 : : {
40 : : int i;
41 : :
42 : : /* check that we can get this memory from EAL now */
43 [ # # ]: 0 : for (i = 0; i < n_pages; i++) {
44 : : const struct rte_memseg_list *msl;
45 : : const struct rte_memseg *ms;
46 : 0 : void *cur = RTE_PTR_ADD(addr, pgsz * i);
47 : : rte_iova_t expected_iova;
48 : :
49 : 0 : msl = rte_mem_virt2memseg_list(cur);
50 [ # # ]: 0 : if (!msl->external) {
51 : : printf("%s():%i: Memseg list is not marked as external\n",
52 : : __func__, __LINE__);
53 : 0 : return -1;
54 : : }
55 : :
56 : 0 : ms = rte_mem_virt2memseg(cur, msl);
57 [ # # ]: 0 : if (ms == NULL) {
58 : : printf("%s():%i: Failed to retrieve memseg for external mem\n",
59 : : __func__, __LINE__);
60 : 0 : return -1;
61 : : }
62 [ # # ]: 0 : if (ms->addr != cur) {
63 : : printf("%s():%i: VA mismatch\n", __func__, __LINE__);
64 : 0 : return -1;
65 : : }
66 [ # # ]: 0 : expected_iova = (iova == NULL) ? RTE_BAD_IOVA : iova[i];
67 [ # # ]: 0 : if (ms->iova != expected_iova) {
68 : : printf("%s():%i: IOVA mismatch\n", __func__, __LINE__);
69 : 0 : return -1;
70 : : }
71 : : }
72 : : return 0;
73 : : }
74 : :
75 : : static int
76 : 0 : test_malloc_invalid_param(void *addr, size_t len, size_t pgsz, rte_iova_t *iova,
77 : : int n_pages)
78 : : {
79 : : static const char * const names[] = {
80 : : NULL, /* NULL name */
81 : : "", /* empty name */
82 : : "this heap name is definitely way too long to be valid"
83 : : };
84 : : const char *valid_name = "valid heap name";
85 : : unsigned int i;
86 : :
87 : : /* check invalid name handling */
88 [ # # ]: 0 : for (i = 0; i < RTE_DIM(names); i++) {
89 : 0 : const char *name = names[i];
90 : :
91 : : /* these calls may fail for other reasons, so check errno */
92 [ # # # # ]: 0 : if (rte_malloc_heap_create(name) >= 0 || rte_errno != EINVAL) {
93 : : printf("%s():%i: Created heap with invalid name\n",
94 : : __func__, __LINE__);
95 : 0 : goto fail;
96 : : }
97 : :
98 [ # # # # ]: 0 : if (rte_malloc_heap_destroy(name) >= 0 || rte_errno != EINVAL) {
99 : : printf("%s():%i: Destroyed heap with invalid name\n",
100 : : __func__, __LINE__);
101 : 0 : goto fail;
102 : : }
103 : :
104 [ # # ]: 0 : if (rte_malloc_heap_get_socket(name) >= 0 ||
105 [ # # ]: 0 : rte_errno != EINVAL) {
106 : : printf("%s():%i: Found socket for heap with invalid name\n",
107 : : __func__, __LINE__);
108 : 0 : goto fail;
109 : : }
110 : :
111 [ # # ]: 0 : if (rte_malloc_heap_memory_add(name, addr, len,
112 [ # # ]: 0 : NULL, 0, pgsz) >= 0 || rte_errno != EINVAL) {
113 : : printf("%s():%i: Added memory to heap with invalid name\n",
114 : : __func__, __LINE__);
115 : 0 : goto fail;
116 : : }
117 [ # # ]: 0 : if (rte_malloc_heap_memory_remove(name, addr, len) >= 0 ||
118 [ # # ]: 0 : rte_errno != EINVAL) {
119 : : printf("%s():%i: Removed memory from heap with invalid name\n",
120 : : __func__, __LINE__);
121 : 0 : goto fail;
122 : : }
123 : :
124 [ # # ]: 0 : if (rte_malloc_heap_memory_attach(name, addr, len) >= 0 ||
125 [ # # ]: 0 : rte_errno != EINVAL) {
126 : : printf("%s():%i: Attached memory to heap with invalid name\n",
127 : : __func__, __LINE__);
128 : 0 : goto fail;
129 : : }
130 [ # # ]: 0 : if (rte_malloc_heap_memory_detach(name, addr, len) >= 0 ||
131 [ # # ]: 0 : rte_errno != EINVAL) {
132 : : printf("%s():%i: Detached memory from heap with invalid name\n",
133 : : __func__, __LINE__);
134 : 0 : goto fail;
135 : : }
136 : : }
137 : :
138 : : /* do same as above, but with a valid heap name */
139 : :
140 : : /* skip create call */
141 [ # # # # ]: 0 : if (rte_malloc_heap_destroy(valid_name) >= 0 || rte_errno != ENOENT) {
142 : : printf("%s():%i: Destroyed heap with invalid name\n",
143 : : __func__, __LINE__);
144 : 0 : goto fail;
145 : : }
146 [ # # ]: 0 : if (rte_malloc_heap_get_socket(valid_name) >= 0 ||
147 [ # # ]: 0 : rte_errno != ENOENT) {
148 : : printf("%s():%i: Found socket for heap with invalid name\n",
149 : : __func__, __LINE__);
150 : 0 : goto fail;
151 : : }
152 : :
153 : : /* these calls may fail for other reasons, so check errno */
154 [ # # ]: 0 : if (rte_malloc_heap_memory_add(valid_name, addr, len,
155 [ # # ]: 0 : NULL, 0, pgsz) >= 0 || rte_errno != ENOENT) {
156 : : printf("%s():%i: Added memory to non-existent heap\n",
157 : : __func__, __LINE__);
158 : 0 : goto fail;
159 : : }
160 [ # # ]: 0 : if (rte_malloc_heap_memory_remove(valid_name, addr, len) >= 0 ||
161 [ # # ]: 0 : rte_errno != ENOENT) {
162 : : printf("%s():%i: Removed memory from non-existent heap\n",
163 : : __func__, __LINE__);
164 : 0 : goto fail;
165 : : }
166 : :
167 [ # # ]: 0 : if (rte_malloc_heap_memory_attach(valid_name, addr, len) >= 0 ||
168 [ # # ]: 0 : rte_errno != ENOENT) {
169 : : printf("%s():%i: Attached memory to non-existent heap\n",
170 : : __func__, __LINE__);
171 : 0 : goto fail;
172 : : }
173 [ # # ]: 0 : if (rte_malloc_heap_memory_detach(valid_name, addr, len) >= 0 ||
174 [ # # ]: 0 : rte_errno != ENOENT) {
175 : : printf("%s():%i: Detached memory from non-existent heap\n",
176 : : __func__, __LINE__);
177 : 0 : goto fail;
178 : : }
179 : :
180 : : /* create a valid heap but test other invalid parameters */
181 [ # # ]: 0 : if (rte_malloc_heap_create(valid_name) != 0) {
182 : : printf("%s():%i: Failed to create valid heap\n",
183 : : __func__, __LINE__);
184 : 0 : goto fail;
185 : : }
186 : :
187 : : /* zero length */
188 [ # # ]: 0 : if (rte_malloc_heap_memory_add(valid_name, addr, 0,
189 [ # # ]: 0 : NULL, 0, pgsz) >= 0 || rte_errno != EINVAL) {
190 : : printf("%s():%i: Added memory with invalid parameters\n",
191 : : __func__, __LINE__);
192 : 0 : goto fail;
193 : : }
194 : :
195 [ # # ]: 0 : if (rte_malloc_heap_memory_remove(valid_name, addr, 0) >= 0 ||
196 [ # # ]: 0 : rte_errno != EINVAL) {
197 : : printf("%s():%i: Removed memory with invalid parameters\n",
198 : : __func__, __LINE__);
199 : 0 : goto fail;
200 : : }
201 : :
202 [ # # ]: 0 : if (rte_malloc_heap_memory_attach(valid_name, addr, 0) >= 0 ||
203 [ # # ]: 0 : rte_errno != EINVAL) {
204 : : printf("%s():%i: Attached memory with invalid parameters\n",
205 : : __func__, __LINE__);
206 : 0 : goto fail;
207 : : }
208 [ # # ]: 0 : if (rte_malloc_heap_memory_detach(valid_name, addr, 0) >= 0 ||
209 [ # # ]: 0 : rte_errno != EINVAL) {
210 : : printf("%s():%i: Detached memory with invalid parameters\n",
211 : : __func__, __LINE__);
212 : 0 : goto fail;
213 : : }
214 : :
215 : : /* zero address */
216 [ # # ]: 0 : if (rte_malloc_heap_memory_add(valid_name, NULL, len,
217 [ # # ]: 0 : NULL, 0, pgsz) >= 0 || rte_errno != EINVAL) {
218 : : printf("%s():%i: Added memory with invalid parameters\n",
219 : : __func__, __LINE__);
220 : 0 : goto fail;
221 : : }
222 : :
223 [ # # ]: 0 : if (rte_malloc_heap_memory_remove(valid_name, NULL, len) >= 0 ||
224 [ # # ]: 0 : rte_errno != EINVAL) {
225 : : printf("%s():%i: Removed memory with invalid parameters\n",
226 : : __func__, __LINE__);
227 : 0 : goto fail;
228 : : }
229 : :
230 [ # # ]: 0 : if (rte_malloc_heap_memory_attach(valid_name, NULL, len) >= 0 ||
231 [ # # ]: 0 : rte_errno != EINVAL) {
232 : : printf("%s():%i: Attached memory with invalid parameters\n",
233 : : __func__, __LINE__);
234 : 0 : goto fail;
235 : : }
236 [ # # ]: 0 : if (rte_malloc_heap_memory_detach(valid_name, NULL, len) >= 0 ||
237 [ # # ]: 0 : rte_errno != EINVAL) {
238 : : printf("%s():%i: Detached memory with invalid parameters\n",
239 : : __func__, __LINE__);
240 : 0 : goto fail;
241 : : }
242 : :
243 : : /* the following tests are only valid if IOVA table is not NULL */
244 [ # # ]: 0 : if (iova != NULL) {
245 : : /* wrong page count */
246 [ # # ]: 0 : if (rte_malloc_heap_memory_add(valid_name, addr, len,
247 [ # # ]: 0 : iova, 0, pgsz) >= 0 || rte_errno != EINVAL) {
248 : : printf("%s():%i: Added memory with invalid parameters\n",
249 : : __func__, __LINE__);
250 : 0 : goto fail;
251 : : }
252 [ # # ]: 0 : if (rte_malloc_heap_memory_add(valid_name, addr, len,
253 : 0 : iova, n_pages - 1, pgsz) >= 0 ||
254 [ # # ]: 0 : rte_errno != EINVAL) {
255 : : printf("%s():%i: Added memory with invalid parameters\n",
256 : : __func__, __LINE__);
257 : 0 : goto fail;
258 : : }
259 [ # # ]: 0 : if (rte_malloc_heap_memory_add(valid_name, addr, len,
260 : 0 : iova, n_pages + 1, pgsz) >= 0 ||
261 [ # # ]: 0 : rte_errno != EINVAL) {
262 : : printf("%s():%i: Added memory with invalid parameters\n",
263 : : __func__, __LINE__);
264 : 0 : goto fail;
265 : : }
266 : : }
267 : :
268 : : /* tests passed, destroy heap */
269 [ # # ]: 0 : if (rte_malloc_heap_destroy(valid_name) != 0) {
270 : : printf("%s():%i: Failed to destroy valid heap\n",
271 : : __func__, __LINE__);
272 : 0 : goto fail;
273 : : }
274 : : return 0;
275 : 0 : fail:
276 : 0 : rte_malloc_heap_destroy(valid_name);
277 : 0 : return -1;
278 : : }
279 : :
280 : : static int
281 : 0 : test_malloc_basic(void *addr, size_t len, size_t pgsz, rte_iova_t *iova,
282 : : int n_pages)
283 : : {
284 : : const char *heap_name = "heap";
285 : : void *ptr = NULL;
286 : : int socket_id;
287 : : const struct rte_memzone *mz = NULL, *contig_mz = NULL;
288 : :
289 : : /* create heap */
290 [ # # ]: 0 : if (rte_malloc_heap_create(heap_name) != 0) {
291 : : printf("%s():%i: Failed to create malloc heap\n",
292 : : __func__, __LINE__);
293 : 0 : goto fail;
294 : : }
295 : :
296 : : /* get socket ID corresponding to this heap */
297 : 0 : socket_id = rte_malloc_heap_get_socket(heap_name);
298 [ # # ]: 0 : if (socket_id < 0) {
299 : : printf("%s():%i: cannot find socket for external heap\n",
300 : : __func__, __LINE__);
301 : 0 : goto fail;
302 : : }
303 : :
304 : : /* heap is empty, so any allocation should fail */
305 : 0 : ptr = rte_malloc_socket("EXTMEM", 64, 0, socket_id);
306 [ # # ]: 0 : if (ptr != NULL) {
307 : : printf("%s():%i: Allocated from empty heap\n", __func__,
308 : : __LINE__);
309 : 0 : goto fail;
310 : : }
311 : :
312 : : /* add memory to heap */
313 [ # # ]: 0 : if (rte_malloc_heap_memory_add(heap_name, addr, len,
314 : : iova, n_pages, pgsz) != 0) {
315 : : printf("%s():%i: Failed to add memory to heap\n",
316 : : __func__, __LINE__);
317 : 0 : goto fail;
318 : : }
319 : :
320 : : /* check if memory is accessible from EAL */
321 [ # # ]: 0 : if (check_mem(addr, iova, pgsz, n_pages) < 0)
322 : 0 : goto fail;
323 : :
324 : : /* allocate - this now should succeed */
325 : 0 : ptr = rte_malloc_socket("EXTMEM", 64, 0, socket_id);
326 [ # # ]: 0 : if (ptr == NULL) {
327 : : printf("%s():%i: Failed to allocate from external heap\n",
328 : : __func__, __LINE__);
329 : 0 : goto fail;
330 : : }
331 : :
332 : : /* check if address is in expected range */
333 [ # # # # ]: 0 : if (ptr < addr || ptr >= RTE_PTR_ADD(addr, len)) {
334 : : printf("%s():%i: Allocated from unexpected address space\n",
335 : : __func__, __LINE__);
336 : 0 : goto fail;
337 : : }
338 : :
339 : : /* we've allocated something - removing memory should fail */
340 [ # # ]: 0 : if (rte_malloc_heap_memory_remove(heap_name, addr, len) >= 0 ||
341 [ # # ]: 0 : rte_errno != EBUSY) {
342 : : printf("%s():%i: Removing memory succeeded when memory is not free\n",
343 : : __func__, __LINE__);
344 : 0 : goto fail;
345 : : }
346 [ # # # # ]: 0 : if (rte_malloc_heap_destroy(heap_name) >= 0 || rte_errno != EBUSY) {
347 : : printf("%s():%i: Destroying heap succeeded when memory is not free\n",
348 : : __func__, __LINE__);
349 : 0 : goto fail;
350 : : }
351 : :
352 : : /* try allocating a memzone */
353 : 0 : mz = rte_memzone_reserve("heap_test", pgsz * 2, socket_id, 0);
354 [ # # ]: 0 : if (mz == NULL) {
355 : : printf("%s():%i: Failed to reserve memzone\n",
356 : : __func__, __LINE__);
357 : 0 : goto fail;
358 : : }
359 : : /* try allocating an IOVA-contiguous memzone - this should succeed
360 : : * if we've set up a contiguous IOVA table, and fail if we haven't.
361 : : */
362 : 0 : contig_mz = rte_memzone_reserve("heap_test_contig", pgsz * 2, socket_id,
363 : : RTE_MEMZONE_IOVA_CONTIG);
364 [ # # ]: 0 : if ((iova == NULL) != (contig_mz == NULL)) {
365 : : printf("%s():%i: Failed to reserve memzone\n",
366 : : __func__, __LINE__);
367 : 0 : goto fail;
368 : : }
369 : :
370 : 0 : rte_malloc_dump_stats(stdout, NULL);
371 : 0 : rte_malloc_dump_heaps(stdout);
372 : :
373 : : /* free memory - removing it should now succeed */
374 : 0 : rte_free(ptr);
375 : : ptr = NULL;
376 : :
377 : 0 : rte_memzone_free(mz);
378 : : mz = NULL;
379 : 0 : rte_memzone_free(contig_mz);
380 : : contig_mz = NULL;
381 : :
382 [ # # ]: 0 : if (rte_malloc_heap_memory_remove(heap_name, addr, len) != 0) {
383 : : printf("%s():%i: Removing memory from heap failed\n",
384 : : __func__, __LINE__);
385 : 0 : goto fail;
386 : : }
387 [ # # ]: 0 : if (rte_malloc_heap_destroy(heap_name) != 0) {
388 : : printf("%s():%i: Destroying heap failed\n",
389 : : __func__, __LINE__);
390 : 0 : goto fail;
391 : : }
392 : :
393 : : return 0;
394 : 0 : fail:
395 : 0 : rte_memzone_free(contig_mz);
396 : 0 : rte_memzone_free(mz);
397 : 0 : rte_free(ptr);
398 : : /* even if something failed, attempt to clean up */
399 : 0 : rte_malloc_heap_memory_remove(heap_name, addr, len);
400 : 0 : rte_malloc_heap_destroy(heap_name);
401 : :
402 : 0 : return -1;
403 : : }
404 : :
405 : : static int
406 : 0 : test_extmem_invalid_param(void *addr, size_t len, size_t pgsz, rte_iova_t *iova,
407 : : int n_pages)
408 : : {
409 : : /* these calls may fail for other reasons, so check errno */
410 [ # # ]: 0 : if (rte_extmem_unregister(addr, len) >= 0 ||
411 [ # # ]: 0 : rte_errno != ENOENT) {
412 : : printf("%s():%i: Unregistered non-existent memory\n",
413 : : __func__, __LINE__);
414 : 0 : return -1;
415 : : }
416 : :
417 [ # # ]: 0 : if (rte_extmem_attach(addr, len) >= 0 ||
418 [ # # ]: 0 : rte_errno != ENOENT) {
419 : : printf("%s():%i: Attached to non-existent memory\n",
420 : : __func__, __LINE__);
421 : 0 : return -1;
422 : : }
423 [ # # ]: 0 : if (rte_extmem_attach(addr, len) >= 0 ||
424 [ # # ]: 0 : rte_errno != ENOENT) {
425 : : printf("%s():%i: Detached from non-existent memory\n",
426 : : __func__, __LINE__);
427 : 0 : return -1;
428 : : }
429 : :
430 : : /* zero length */
431 [ # # ]: 0 : if (rte_extmem_register(addr, 0, NULL, 0, pgsz) >= 0 ||
432 [ # # ]: 0 : rte_errno != EINVAL) {
433 : : printf("%s():%i: Registered memory with invalid parameters\n",
434 : : __func__, __LINE__);
435 : 0 : return -1;
436 : : }
437 : :
438 [ # # ]: 0 : if (rte_extmem_unregister(addr, 0) >= 0 ||
439 [ # # ]: 0 : rte_errno != EINVAL) {
440 : : printf("%s():%i: Unregistered memory with invalid parameters\n",
441 : : __func__, __LINE__);
442 : 0 : return -1;
443 : : }
444 : :
445 [ # # ]: 0 : if (rte_extmem_attach(addr, 0) >= 0 ||
446 [ # # ]: 0 : rte_errno != EINVAL) {
447 : : printf("%s():%i: Attached memory with invalid parameters\n",
448 : : __func__, __LINE__);
449 : 0 : return -1;
450 : : }
451 [ # # ]: 0 : if (rte_extmem_attach(addr, 0) >= 0 ||
452 [ # # ]: 0 : rte_errno != EINVAL) {
453 : : printf("%s():%i: Detached memory with invalid parameters\n",
454 : : __func__, __LINE__);
455 : 0 : return -1;
456 : : }
457 : :
458 : : /* zero address */
459 [ # # ]: 0 : if (rte_extmem_register(NULL, len, NULL, 0, pgsz) >= 0 ||
460 [ # # ]: 0 : rte_errno != EINVAL) {
461 : : printf("%s():%i: Registered memory with invalid parameters\n",
462 : : __func__, __LINE__);
463 : 0 : return -1;
464 : : }
465 : :
466 [ # # ]: 0 : if (rte_extmem_unregister(NULL, len) >= 0 ||
467 [ # # ]: 0 : rte_errno != EINVAL) {
468 : : printf("%s():%i: Unregistered memory with invalid parameters\n",
469 : : __func__, __LINE__);
470 : 0 : return -1;
471 : : }
472 : :
473 [ # # ]: 0 : if (rte_extmem_attach(NULL, len) >= 0 ||
474 [ # # ]: 0 : rte_errno != EINVAL) {
475 : : printf("%s():%i: Attached memory with invalid parameters\n",
476 : : __func__, __LINE__);
477 : 0 : return -1;
478 : : }
479 [ # # ]: 0 : if (rte_extmem_attach(NULL, len) >= 0 ||
480 [ # # ]: 0 : rte_errno != EINVAL) {
481 : : printf("%s():%i: Detached memory with invalid parameters\n",
482 : : __func__, __LINE__);
483 : 0 : return -1;
484 : : }
485 : :
486 : : /* the following tests are only valid if IOVA table is not NULL */
487 [ # # ]: 0 : if (iova != NULL) {
488 : : /* wrong page count */
489 [ # # ]: 0 : if (rte_extmem_register(addr, len,
490 [ # # ]: 0 : iova, 0, pgsz) >= 0 || rte_errno != EINVAL) {
491 : : printf("%s():%i: Registered memory with invalid parameters\n",
492 : : __func__, __LINE__);
493 : 0 : return -1;
494 : : }
495 [ # # ]: 0 : if (rte_extmem_register(addr, len,
496 : 0 : iova, n_pages - 1, pgsz) >= 0 ||
497 [ # # ]: 0 : rte_errno != EINVAL) {
498 : : printf("%s():%i: Registered memory with invalid parameters\n",
499 : : __func__, __LINE__);
500 : 0 : return -1;
501 : : }
502 [ # # ]: 0 : if (rte_extmem_register(addr, len,
503 : 0 : iova, n_pages + 1, pgsz) >= 0 ||
504 [ # # ]: 0 : rte_errno != EINVAL) {
505 : : printf("%s():%i: Registered memory with invalid parameters\n",
506 : : __func__, __LINE__);
507 : 0 : return -1;
508 : : }
509 : : }
510 : :
511 : : return 0;
512 : : }
513 : :
514 : : static int
515 : 0 : test_extmem_basic(void *addr, size_t len, size_t pgsz, rte_iova_t *iova,
516 : : int n_pages)
517 : : {
518 : : /* register memory */
519 [ # # ]: 0 : if (rte_extmem_register(addr, len, iova, n_pages, pgsz) != 0) {
520 : : printf("%s():%i: Failed to register memory\n",
521 : : __func__, __LINE__);
522 : 0 : goto fail;
523 : : }
524 : :
525 : : /* check if memory is accessible from EAL */
526 [ # # ]: 0 : if (check_mem(addr, iova, pgsz, n_pages) < 0)
527 : 0 : goto fail;
528 : :
529 [ # # ]: 0 : if (rte_extmem_unregister(addr, len) != 0) {
530 : : printf("%s():%i: Removing memory from heap failed\n",
531 : : __func__, __LINE__);
532 : 0 : goto fail;
533 : : }
534 : :
535 : : return 0;
536 : 0 : fail:
537 : : /* even if something failed, attempt to clean up */
538 : 0 : rte_extmem_unregister(addr, len);
539 : :
540 : 0 : return -1;
541 : : }
542 : :
543 : : /* we need to test attach/detach in secondary processes. */
544 : : static int
545 : 0 : test_external_mem(void)
546 : 0 : {
547 : 0 : size_t pgsz = rte_mem_page_size();
548 : : size_t len = EXTERNAL_MEM_SZ;
549 : 0 : rte_iova_t iova[len / pgsz];
550 : : void *addr;
551 : : int ret, n_pages;
552 : : int i;
553 : :
554 : : /* create external memory area */
555 : 0 : n_pages = RTE_DIM(iova);
556 : 0 : addr = mmap(NULL, len, PROT_WRITE | PROT_READ,
557 : : MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
558 [ # # ]: 0 : if (addr == MAP_FAILED) {
559 : : printf("%s():%i: Failed to create dummy memory area\n",
560 : : __func__, __LINE__);
561 : 0 : return -1;
562 : : }
563 [ # # ]: 0 : for (i = 0; i < n_pages; i++) {
564 : : /* arbitrary IOVA */
565 : 0 : rte_iova_t tmp = 0x100000000 + i * pgsz;
566 : 0 : iova[i] = tmp;
567 : : }
568 : :
569 : : /* test external heap memory */
570 : 0 : ret = test_malloc_invalid_param(addr, len, pgsz, iova, n_pages);
571 : 0 : ret |= test_malloc_basic(addr, len, pgsz, iova, n_pages);
572 : : /* when iova table is NULL, everything should still work */
573 : 0 : ret |= test_malloc_invalid_param(addr, len, pgsz, NULL, n_pages);
574 : 0 : ret |= test_malloc_basic(addr, len, pgsz, NULL, n_pages);
575 : :
576 : : /* test non-heap memory */
577 : 0 : ret |= test_extmem_invalid_param(addr, len, pgsz, iova, n_pages);
578 : 0 : ret |= test_extmem_basic(addr, len, pgsz, iova, n_pages);
579 : : /* when iova table is NULL, everything should still work */
580 : 0 : ret |= test_extmem_invalid_param(addr, len, pgsz, NULL, n_pages);
581 : 0 : ret |= test_extmem_basic(addr, len, pgsz, NULL, n_pages);
582 : :
583 : 0 : munmap(addr, len);
584 : :
585 : 0 : return ret;
586 : : }
587 : :
588 : : #endif /* !RTE_EXEC_ENV_WINDOWS */
589 : :
590 : 252 : REGISTER_TEST_COMMAND(external_mem_autotest, test_external_mem);
|