xref: /dpdk/app/test-gpudev/main.c (revision 9b8cae4d991ee4fb0faf92d8994879d6776df181)
18b8036a6SElena Agostini /* SPDX-License-Identifier: BSD-3-Clause
28b8036a6SElena Agostini  * Copyright (c) 2021 NVIDIA Corporation & Affiliates
38b8036a6SElena Agostini  */
48b8036a6SElena Agostini 
58b8036a6SElena Agostini #include <stdio.h>
68b8036a6SElena Agostini #include <stdlib.h>
78b8036a6SElena Agostini #include <string.h>
88b8036a6SElena Agostini #include <stdint.h>
98b8036a6SElena Agostini #include <inttypes.h>
108b8036a6SElena Agostini #include <stdarg.h>
118b8036a6SElena Agostini #include <errno.h>
128b8036a6SElena Agostini #include <getopt.h>
138b8036a6SElena Agostini 
148b8036a6SElena Agostini #include <rte_common.h>
158b8036a6SElena Agostini #include <rte_malloc.h>
168b8036a6SElena Agostini #include <rte_memory.h>
178b8036a6SElena Agostini #include <rte_eal.h>
188b8036a6SElena Agostini #include <rte_ether.h>
198b8036a6SElena Agostini #include <rte_ethdev.h>
208b8036a6SElena Agostini #include <rte_mempool.h>
218b8036a6SElena Agostini #include <rte_mbuf.h>
228b8036a6SElena Agostini 
238b8036a6SElena Agostini #include <rte_gpudev.h>
248b8036a6SElena Agostini 
258b8036a6SElena Agostini enum app_args {
268b8036a6SElena Agostini 	ARG_HELP,
278b8036a6SElena Agostini 	ARG_MEMPOOL
288b8036a6SElena Agostini };
298b8036a6SElena Agostini 
308b8036a6SElena Agostini static void
usage(const char * prog_name)318b8036a6SElena Agostini usage(const char *prog_name)
328b8036a6SElena Agostini {
338b8036a6SElena Agostini 	printf("%s [EAL options] --\n",
348b8036a6SElena Agostini 		prog_name);
358b8036a6SElena Agostini }
368b8036a6SElena Agostini 
378b8036a6SElena Agostini static void
args_parse(int argc,char ** argv)388b8036a6SElena Agostini args_parse(int argc, char **argv)
398b8036a6SElena Agostini {
408b8036a6SElena Agostini 	char **argvopt;
418b8036a6SElena Agostini 	int opt;
428b8036a6SElena Agostini 	int opt_idx;
438b8036a6SElena Agostini 
448b8036a6SElena Agostini 	static struct option lgopts[] = {
458b8036a6SElena Agostini 		{ "help", 0, 0, ARG_HELP},
468b8036a6SElena Agostini 		/* End of options */
478b8036a6SElena Agostini 		{ 0, 0, 0, 0 }
488b8036a6SElena Agostini 	};
498b8036a6SElena Agostini 
508b8036a6SElena Agostini 	argvopt = argv;
518b8036a6SElena Agostini 	while ((opt = getopt_long(argc, argvopt, "",
528b8036a6SElena Agostini 				lgopts, &opt_idx)) != EOF) {
538b8036a6SElena Agostini 		switch (opt) {
548b8036a6SElena Agostini 		case ARG_HELP:
558b8036a6SElena Agostini 			usage(argv[0]);
568b8036a6SElena Agostini 			break;
578b8036a6SElena Agostini 		default:
588b8036a6SElena Agostini 			usage(argv[0]);
598b8036a6SElena Agostini 			rte_exit(EXIT_FAILURE, "Invalid option: %s\n", argv[optind]);
608b8036a6SElena Agostini 			break;
618b8036a6SElena Agostini 		}
628b8036a6SElena Agostini 	}
638b8036a6SElena Agostini }
648b8036a6SElena Agostini 
65e818c4e2SElena Agostini static int
alloc_gpu_memory(uint16_t gpu_id)66e818c4e2SElena Agostini alloc_gpu_memory(uint16_t gpu_id)
67e818c4e2SElena Agostini {
68e818c4e2SElena Agostini 	void *ptr_1 = NULL;
69e818c4e2SElena Agostini 	void *ptr_2 = NULL;
70e818c4e2SElena Agostini 	size_t buf_bytes = 1024;
71c8557ed4SElena Agostini 	unsigned int align = 4096;
72e818c4e2SElena Agostini 	int ret;
73e818c4e2SElena Agostini 
74329f73ebSElena Agostini 	printf("\n=======> TEST: Allocate GPU memory\n\n");
75e818c4e2SElena Agostini 
76c8557ed4SElena Agostini 	/* Alloc memory on GPU 0 without any specific alignment */
77c8557ed4SElena Agostini 	ptr_1 = rte_gpu_mem_alloc(gpu_id, buf_bytes, 0);
78e818c4e2SElena Agostini 	if (ptr_1 == NULL) {
79e818c4e2SElena Agostini 		fprintf(stderr, "rte_gpu_mem_alloc GPU memory returned error\n");
80329f73ebSElena Agostini 		goto error;
81e818c4e2SElena Agostini 	}
82329f73ebSElena Agostini 	printf("GPU memory allocated at 0x%p size is %zd bytes\n",
83329f73ebSElena Agostini 			ptr_1, buf_bytes);
84e818c4e2SElena Agostini 
85c8557ed4SElena Agostini 	/* Alloc memory on GPU 0 with 4kB alignment */
86c8557ed4SElena Agostini 	ptr_2 = rte_gpu_mem_alloc(gpu_id, buf_bytes, align);
87e818c4e2SElena Agostini 	if (ptr_2 == NULL) {
88e818c4e2SElena Agostini 		fprintf(stderr, "rte_gpu_mem_alloc GPU memory returned error\n");
89329f73ebSElena Agostini 		goto error;
90e818c4e2SElena Agostini 	}
91329f73ebSElena Agostini 	printf("GPU memory allocated at 0x%p size is %zd bytes\n",
92329f73ebSElena Agostini 			ptr_2, buf_bytes);
93e818c4e2SElena Agostini 
94c8557ed4SElena Agostini 	if (((uintptr_t)ptr_2) % align) {
95c8557ed4SElena Agostini 		fprintf(stderr, "Memory address 0x%p is not aligned to %u\n", ptr_2, align);
96c8557ed4SElena Agostini 		goto error;
97c8557ed4SElena Agostini 	}
98c8557ed4SElena Agostini 
99e818c4e2SElena Agostini 	ret = rte_gpu_mem_free(gpu_id, (uint8_t *)(ptr_1)+0x700);
100e818c4e2SElena Agostini 	if (ret < 0) {
101329f73ebSElena Agostini 		printf("GPU memory 0x%p NOT freed: GPU driver didn't find this memory address internally.\n",
102329f73ebSElena Agostini 				(uint8_t *)(ptr_1)+0x700);
103e818c4e2SElena Agostini 	} else {
104329f73ebSElena Agostini 		fprintf(stderr, "ERROR: rte_gpu_mem_free freed GPU memory 0x%p\n",
105329f73ebSElena Agostini 				(uint8_t *)(ptr_1)+0x700);
106329f73ebSElena Agostini 		goto error;
107e818c4e2SElena Agostini 	}
108e818c4e2SElena Agostini 
109e818c4e2SElena Agostini 	ret = rte_gpu_mem_free(gpu_id, ptr_2);
110e818c4e2SElena Agostini 	if (ret < 0) {
111e818c4e2SElena Agostini 		fprintf(stderr, "rte_gpu_mem_free returned error %d\n", ret);
112329f73ebSElena Agostini 		goto error;
113e818c4e2SElena Agostini 	}
114e818c4e2SElena Agostini 	printf("GPU memory 0x%p freed\n", ptr_2);
115e818c4e2SElena Agostini 
116e818c4e2SElena Agostini 	ret = rte_gpu_mem_free(gpu_id, ptr_1);
117e818c4e2SElena Agostini 	if (ret < 0) {
118e818c4e2SElena Agostini 		fprintf(stderr, "rte_gpu_mem_free returned error %d\n", ret);
119329f73ebSElena Agostini 		goto error;
120e818c4e2SElena Agostini 	}
121e818c4e2SElena Agostini 	printf("GPU memory 0x%p freed\n", ptr_1);
122e818c4e2SElena Agostini 
123329f73ebSElena Agostini 	printf("\n=======> TEST: PASSED\n");
124e818c4e2SElena Agostini 	return 0;
125329f73ebSElena Agostini 
126329f73ebSElena Agostini error:
1276399acadSElena Agostini 
1286399acadSElena Agostini 	rte_gpu_mem_free(gpu_id, ptr_1);
1296399acadSElena Agostini 	rte_gpu_mem_free(gpu_id, ptr_2);
1306399acadSElena Agostini 
131329f73ebSElena Agostini 	printf("\n=======> TEST: FAILED\n");
132329f73ebSElena Agostini 	return -1;
133e818c4e2SElena Agostini }
134e818c4e2SElena Agostini 
135e818c4e2SElena Agostini static int
register_cpu_memory(uint16_t gpu_id)136e818c4e2SElena Agostini register_cpu_memory(uint16_t gpu_id)
137e818c4e2SElena Agostini {
138e818c4e2SElena Agostini 	void *ptr = NULL;
139e818c4e2SElena Agostini 	size_t buf_bytes = 1024;
140e818c4e2SElena Agostini 	int ret;
141e818c4e2SElena Agostini 
142329f73ebSElena Agostini 	printf("\n=======> TEST: Register CPU memory\n\n");
143e818c4e2SElena Agostini 
144e818c4e2SElena Agostini 	/* Alloc memory on CPU visible from GPU 0 */
145e818c4e2SElena Agostini 	ptr = rte_zmalloc(NULL, buf_bytes, 0);
146e818c4e2SElena Agostini 	if (ptr == NULL) {
147e818c4e2SElena Agostini 		fprintf(stderr, "Failed to allocate CPU memory.\n");
148329f73ebSElena Agostini 		goto error;
149e818c4e2SElena Agostini 	}
150e818c4e2SElena Agostini 
151e818c4e2SElena Agostini 	ret = rte_gpu_mem_register(gpu_id, buf_bytes, ptr);
152e818c4e2SElena Agostini 	if (ret < 0) {
153e818c4e2SElena Agostini 		fprintf(stderr, "rte_gpu_mem_register CPU memory returned error %d\n", ret);
154329f73ebSElena Agostini 		goto error;
155e818c4e2SElena Agostini 	}
156e818c4e2SElena Agostini 	printf("CPU memory registered at 0x%p %zdB\n", ptr, buf_bytes);
157e818c4e2SElena Agostini 
158e818c4e2SElena Agostini 	ret = rte_gpu_mem_unregister(gpu_id, (uint8_t *)(ptr)+0x700);
159e818c4e2SElena Agostini 	if (ret < 0) {
160329f73ebSElena Agostini 		printf("CPU memory 0x%p NOT unregistered: GPU driver didn't find this memory address internally\n",
161329f73ebSElena Agostini 				(uint8_t *)(ptr)+0x700);
162e818c4e2SElena Agostini 	} else {
163329f73ebSElena Agostini 		fprintf(stderr, "ERROR: rte_gpu_mem_unregister unregistered GPU memory 0x%p\n",
164329f73ebSElena Agostini 				(uint8_t *)(ptr)+0x700);
165329f73ebSElena Agostini 		goto error;
166e818c4e2SElena Agostini 	}
167e818c4e2SElena Agostini 
168e818c4e2SElena Agostini 	ret = rte_gpu_mem_unregister(gpu_id, ptr);
169e818c4e2SElena Agostini 	if (ret < 0) {
170e818c4e2SElena Agostini 		fprintf(stderr, "rte_gpu_mem_unregister returned error %d\n", ret);
171329f73ebSElena Agostini 		goto error;
172e818c4e2SElena Agostini 	}
173e818c4e2SElena Agostini 	printf("CPU memory 0x%p unregistered\n", ptr);
174e818c4e2SElena Agostini 
1756399acadSElena Agostini 	rte_free(ptr);
1766399acadSElena Agostini 
177329f73ebSElena Agostini 	printf("\n=======> TEST: PASSED\n");
178e818c4e2SElena Agostini 	return 0;
179329f73ebSElena Agostini 
180329f73ebSElena Agostini error:
1816399acadSElena Agostini 
1826399acadSElena Agostini 	rte_gpu_mem_unregister(gpu_id, ptr);
1836399acadSElena Agostini 	rte_free(ptr);
184329f73ebSElena Agostini 	printf("\n=======> TEST: FAILED\n");
185329f73ebSElena Agostini 	return -1;
186e818c4e2SElena Agostini }
187e818c4e2SElena Agostini 
188f56160a2SElena Agostini static int
gpu_mem_cpu_map(uint16_t gpu_id)189d69bb47dSElena Agostini gpu_mem_cpu_map(uint16_t gpu_id)
190d69bb47dSElena Agostini {
191d69bb47dSElena Agostini 	void *ptr_gpu = NULL;
192d69bb47dSElena Agostini 	void *ptr_cpu = NULL;
193d69bb47dSElena Agostini 	size_t buf_bytes = 1024;
194d69bb47dSElena Agostini 	unsigned int align = 4096;
195d69bb47dSElena Agostini 	int ret;
196d69bb47dSElena Agostini 
197d69bb47dSElena Agostini 	printf("\n=======> TEST: Map GPU memory for CPU visibility\n\n");
198d69bb47dSElena Agostini 
199d69bb47dSElena Agostini 	/* Alloc memory on GPU 0 with 4kB alignment */
200d69bb47dSElena Agostini 	ptr_gpu = rte_gpu_mem_alloc(gpu_id, buf_bytes, align);
201d69bb47dSElena Agostini 	if (ptr_gpu == NULL) {
202d69bb47dSElena Agostini 		fprintf(stderr, "rte_gpu_mem_alloc GPU memory returned error\n");
203d69bb47dSElena Agostini 		goto error;
204d69bb47dSElena Agostini 	}
205d69bb47dSElena Agostini 	printf("GPU memory allocated at 0x%p size is %zd bytes\n",
206d69bb47dSElena Agostini 			ptr_gpu, buf_bytes);
207d69bb47dSElena Agostini 
208d69bb47dSElena Agostini 	ptr_cpu = rte_gpu_mem_cpu_map(gpu_id, buf_bytes, ptr_gpu);
209d69bb47dSElena Agostini 	if (ptr_cpu == NULL) {
210d69bb47dSElena Agostini 		fprintf(stderr, "rte_gpu_mem_cpu_map returned error\n");
211d69bb47dSElena Agostini 		goto error;
212d69bb47dSElena Agostini 	}
21377f40e04SElena Agostini 	printf("GPU memory CPU mapped at 0x%p\n", ptr_cpu);
214d69bb47dSElena Agostini 
215d69bb47dSElena Agostini 	((uint8_t *)ptr_cpu)[0] = 0x4;
216d69bb47dSElena Agostini 	((uint8_t *)ptr_cpu)[1] = 0x5;
217d69bb47dSElena Agostini 	((uint8_t *)ptr_cpu)[2] = 0x6;
218d69bb47dSElena Agostini 
219d69bb47dSElena Agostini 	printf("GPU memory first 3 bytes set from CPU: %x %x %x\n",
220d69bb47dSElena Agostini 			((uint8_t *)ptr_cpu)[0],
221d69bb47dSElena Agostini 			((uint8_t *)ptr_cpu)[1],
222d69bb47dSElena Agostini 			((uint8_t *)ptr_cpu)[2]);
223d69bb47dSElena Agostini 
22477f40e04SElena Agostini 	ret = rte_gpu_mem_cpu_unmap(gpu_id, ptr_gpu);
225d69bb47dSElena Agostini 	if (ret < 0) {
226d69bb47dSElena Agostini 		fprintf(stderr, "rte_gpu_mem_cpu_unmap returned error %d\n", ret);
227d69bb47dSElena Agostini 		goto error;
228d69bb47dSElena Agostini 	}
22977f40e04SElena Agostini 	printf("GPU memory CPU unmapped, 0x%p not valid anymore\n", ptr_cpu);
230d69bb47dSElena Agostini 
231d69bb47dSElena Agostini 	ret = rte_gpu_mem_free(gpu_id, ptr_gpu);
232d69bb47dSElena Agostini 	if (ret < 0) {
233d69bb47dSElena Agostini 		fprintf(stderr, "rte_gpu_mem_free returned error %d\n", ret);
234d69bb47dSElena Agostini 		goto error;
235d69bb47dSElena Agostini 	}
236d69bb47dSElena Agostini 	printf("GPU memory 0x%p freed\n", ptr_gpu);
237d69bb47dSElena Agostini 
238d69bb47dSElena Agostini 	printf("\n=======> TEST: PASSED\n");
239d69bb47dSElena Agostini 	return 0;
240d69bb47dSElena Agostini 
241d69bb47dSElena Agostini error:
242d69bb47dSElena Agostini 
24377f40e04SElena Agostini 	rte_gpu_mem_cpu_unmap(gpu_id, ptr_gpu);
244d69bb47dSElena Agostini 	rte_gpu_mem_free(gpu_id, ptr_gpu);
245d69bb47dSElena Agostini 
246d69bb47dSElena Agostini 	printf("\n=======> TEST: FAILED\n");
247d69bb47dSElena Agostini 	return -1;
248d69bb47dSElena Agostini }
249d69bb47dSElena Agostini 
250d69bb47dSElena Agostini static int
create_update_comm_flag(uint16_t gpu_id)251f56160a2SElena Agostini create_update_comm_flag(uint16_t gpu_id)
252f56160a2SElena Agostini {
253f56160a2SElena Agostini 	struct rte_gpu_comm_flag devflag;
254f56160a2SElena Agostini 	int ret = 0;
255f56160a2SElena Agostini 	uint32_t set_val;
256f56160a2SElena Agostini 	uint32_t get_val;
257f56160a2SElena Agostini 
258329f73ebSElena Agostini 	printf("\n=======> TEST: Communication flag\n\n");
259f56160a2SElena Agostini 
260f56160a2SElena Agostini 	ret = rte_gpu_comm_create_flag(gpu_id, &devflag, RTE_GPU_COMM_FLAG_CPU);
261f56160a2SElena Agostini 	if (ret < 0) {
262f56160a2SElena Agostini 		fprintf(stderr, "rte_gpu_comm_create_flag returned error %d\n", ret);
263329f73ebSElena Agostini 		goto error;
264f56160a2SElena Agostini 	}
265f56160a2SElena Agostini 
266f56160a2SElena Agostini 	set_val = 25;
267f56160a2SElena Agostini 	ret = rte_gpu_comm_set_flag(&devflag, set_val);
268f56160a2SElena Agostini 	if (ret < 0) {
269f56160a2SElena Agostini 		fprintf(stderr, "rte_gpu_comm_set_flag returned error %d\n", ret);
270329f73ebSElena Agostini 		goto error;
271f56160a2SElena Agostini 	}
272f56160a2SElena Agostini 
273f56160a2SElena Agostini 	ret = rte_gpu_comm_get_flag_value(&devflag, &get_val);
274f56160a2SElena Agostini 	if (ret < 0) {
275f56160a2SElena Agostini 		fprintf(stderr, "rte_gpu_comm_get_flag_value returned error %d\n", ret);
276329f73ebSElena Agostini 		goto error;
277f56160a2SElena Agostini 	}
278f56160a2SElena Agostini 
279329f73ebSElena Agostini 	printf("Communication flag value at 0x%p was set to %d and current value is %d\n",
280329f73ebSElena Agostini 			devflag.ptr, set_val, get_val);
281f56160a2SElena Agostini 
282f56160a2SElena Agostini 	set_val = 38;
283f56160a2SElena Agostini 	ret = rte_gpu_comm_set_flag(&devflag, set_val);
284f56160a2SElena Agostini 	if (ret < 0) {
285f56160a2SElena Agostini 		fprintf(stderr, "rte_gpu_comm_set_flag returned error %d\n", ret);
286329f73ebSElena Agostini 		goto error;
287f56160a2SElena Agostini 	}
288f56160a2SElena Agostini 
289f56160a2SElena Agostini 	ret = rte_gpu_comm_get_flag_value(&devflag, &get_val);
290f56160a2SElena Agostini 	if (ret < 0) {
291f56160a2SElena Agostini 		fprintf(stderr, "rte_gpu_comm_get_flag_value returned error %d\n", ret);
292329f73ebSElena Agostini 		goto error;
293f56160a2SElena Agostini 	}
294f56160a2SElena Agostini 
295329f73ebSElena Agostini 	printf("Communication flag value at 0x%p was set to %d and current value is %d\n",
296329f73ebSElena Agostini 			devflag.ptr, set_val, get_val);
297f56160a2SElena Agostini 
298f56160a2SElena Agostini 	ret = rte_gpu_comm_destroy_flag(&devflag);
299f56160a2SElena Agostini 	if (ret < 0) {
300f56160a2SElena Agostini 		fprintf(stderr, "rte_gpu_comm_destroy_flags returned error %d\n", ret);
301329f73ebSElena Agostini 		goto error;
302f56160a2SElena Agostini 	}
303f56160a2SElena Agostini 
304329f73ebSElena Agostini 	printf("\n=======> TEST: PASSED\n");
305f56160a2SElena Agostini 	return 0;
306329f73ebSElena Agostini 
307329f73ebSElena Agostini error:
3086399acadSElena Agostini 
3096399acadSElena Agostini 	rte_gpu_comm_destroy_flag(&devflag);
310329f73ebSElena Agostini 	printf("\n=======> TEST: FAILED\n");
311329f73ebSElena Agostini 	return -1;
312f56160a2SElena Agostini }
313f56160a2SElena Agostini 
314c7ebd65cSElena Agostini static int
simulate_gpu_task(struct rte_gpu_comm_list * comm_list_item,int num_pkts)315c7ebd65cSElena Agostini simulate_gpu_task(struct rte_gpu_comm_list *comm_list_item, int num_pkts)
316c7ebd65cSElena Agostini {
317c7ebd65cSElena Agostini 	int idx;
318c7ebd65cSElena Agostini 
319c7ebd65cSElena Agostini 	if (comm_list_item == NULL)
320c7ebd65cSElena Agostini 		return -1;
321c7ebd65cSElena Agostini 
322c7ebd65cSElena Agostini 	for (idx = 0; idx < num_pkts; idx++) {
323c7ebd65cSElena Agostini 		/**
324c7ebd65cSElena Agostini 		 * consume(comm_list_item->pkt_list[idx].addr);
325c7ebd65cSElena Agostini 		 */
326c7ebd65cSElena Agostini 	}
327*9b8cae4dSElena Agostini 	/*
328*9b8cae4dSElena Agostini 	 * A real GPU workload function can't directly call rte_gpu_comm_set_status
329*9b8cae4dSElena Agostini 	 * because it's a CPU-only function.
330*9b8cae4dSElena Agostini 	 * A real GPU workload should implement the content
331*9b8cae4dSElena Agostini 	 * of rte_gpu_comm_set_status() in GPU specific code.
332*9b8cae4dSElena Agostini 	 */
333*9b8cae4dSElena Agostini 	rte_gpu_comm_set_status(comm_list_item, RTE_GPU_COMM_LIST_DONE);
334c7ebd65cSElena Agostini 
335c7ebd65cSElena Agostini 	return 0;
336c7ebd65cSElena Agostini }
337c7ebd65cSElena Agostini 
338c7ebd65cSElena Agostini static int
create_update_comm_list(uint16_t gpu_id)339c7ebd65cSElena Agostini create_update_comm_list(uint16_t gpu_id)
340c7ebd65cSElena Agostini {
341c7ebd65cSElena Agostini 	int ret = 0;
342c7ebd65cSElena Agostini 	int i = 0;
3436399acadSElena Agostini 	struct rte_gpu_comm_list *comm_list = NULL;
344c7ebd65cSElena Agostini 	uint32_t num_comm_items = 1024;
345c7ebd65cSElena Agostini 	struct rte_mbuf *mbufs[10];
346c7ebd65cSElena Agostini 
347329f73ebSElena Agostini 	printf("\n=======> TEST: Communication list\n\n");
348c7ebd65cSElena Agostini 
349c7ebd65cSElena Agostini 	comm_list = rte_gpu_comm_create_list(gpu_id, num_comm_items);
350c7ebd65cSElena Agostini 	if (comm_list == NULL) {
351c7ebd65cSElena Agostini 		fprintf(stderr, "rte_gpu_comm_create_list returned error %d\n", ret);
352329f73ebSElena Agostini 		goto error;
353c7ebd65cSElena Agostini 	}
354c7ebd65cSElena Agostini 
355c7ebd65cSElena Agostini 	/**
356c7ebd65cSElena Agostini 	 * Simulate DPDK receive functions like rte_eth_rx_burst()
357c7ebd65cSElena Agostini 	 */
358c7ebd65cSElena Agostini 	for (i = 0; i < 10; i++) {
359c7ebd65cSElena Agostini 		mbufs[i] = rte_zmalloc(NULL, sizeof(struct rte_mbuf), 0);
360c7ebd65cSElena Agostini 		if (mbufs[i] == NULL) {
361c7ebd65cSElena Agostini 			fprintf(stderr, "Failed to allocate fake mbufs in CPU memory.\n");
362329f73ebSElena Agostini 			goto error;
363c7ebd65cSElena Agostini 		}
364c7ebd65cSElena Agostini 
365c7ebd65cSElena Agostini 		memset(mbufs[i], 0, sizeof(struct rte_mbuf));
366c7ebd65cSElena Agostini 	}
367c7ebd65cSElena Agostini 
368c7ebd65cSElena Agostini 	/**
369c7ebd65cSElena Agostini 	 * Populate just the first item of  the list
370c7ebd65cSElena Agostini 	 */
371c7ebd65cSElena Agostini 	ret = rte_gpu_comm_populate_list_pkts(&(comm_list[0]), mbufs, 10);
372c7ebd65cSElena Agostini 	if (ret < 0) {
373c7ebd65cSElena Agostini 		fprintf(stderr, "rte_gpu_comm_populate_list_pkts returned error %d\n", ret);
374329f73ebSElena Agostini 		goto error;
375c7ebd65cSElena Agostini 	}
376c7ebd65cSElena Agostini 
377c7ebd65cSElena Agostini 	ret = rte_gpu_comm_cleanup_list(&(comm_list[0]));
378c7ebd65cSElena Agostini 	if (ret == 0) {
379c7ebd65cSElena Agostini 		fprintf(stderr, "rte_gpu_comm_cleanup_list erroneously cleaned the list even if packets have not been consumed yet\n");
380329f73ebSElena Agostini 		goto error;
381c7ebd65cSElena Agostini 	}
382329f73ebSElena Agostini 	printf("Communication list not cleaned because packets have not been consumed yet.\n");
383c7ebd65cSElena Agostini 
384c7ebd65cSElena Agostini 	/**
385c7ebd65cSElena Agostini 	 * Simulate a GPU tasks going through the packet list to consume
386c7ebd65cSElena Agostini 	 * mbufs packets and release them
387c7ebd65cSElena Agostini 	 */
388329f73ebSElena Agostini 	printf("Consuming packets...\n");
389c7ebd65cSElena Agostini 	simulate_gpu_task(&(comm_list[0]), 10);
390c7ebd65cSElena Agostini 
391c7ebd65cSElena Agostini 	/**
392c7ebd65cSElena Agostini 	 * Packets have been consumed, now the communication item
393c7ebd65cSElena Agostini 	 * and the related mbufs can be all released
394c7ebd65cSElena Agostini 	 */
395c7ebd65cSElena Agostini 	ret = rte_gpu_comm_cleanup_list(&(comm_list[0]));
396c7ebd65cSElena Agostini 	if (ret < 0) {
397c7ebd65cSElena Agostini 		fprintf(stderr, "rte_gpu_comm_cleanup_list returned error %d\n", ret);
398329f73ebSElena Agostini 		goto error;
399c7ebd65cSElena Agostini 	}
400c7ebd65cSElena Agostini 
401329f73ebSElena Agostini 	printf("Communication list cleaned because packets have been consumed now.\n");
402329f73ebSElena Agostini 
403c7ebd65cSElena Agostini 	ret = rte_gpu_comm_destroy_list(comm_list, num_comm_items);
404c7ebd65cSElena Agostini 	if (ret < 0) {
405c7ebd65cSElena Agostini 		fprintf(stderr, "rte_gpu_comm_destroy_list returned error %d\n", ret);
406329f73ebSElena Agostini 		goto error;
407c7ebd65cSElena Agostini 	}
408c7ebd65cSElena Agostini 
409c7ebd65cSElena Agostini 	for (i = 0; i < 10; i++)
410c7ebd65cSElena Agostini 		rte_free(mbufs[i]);
411c7ebd65cSElena Agostini 
412329f73ebSElena Agostini 	printf("\n=======> TEST: PASSED\n");
413c7ebd65cSElena Agostini 	return 0;
414329f73ebSElena Agostini 
415329f73ebSElena Agostini error:
4166399acadSElena Agostini 
4176399acadSElena Agostini 	rte_gpu_comm_destroy_list(comm_list, num_comm_items);
4186399acadSElena Agostini 	for (i = 0; i < 10; i++)
4196399acadSElena Agostini 		rte_free(mbufs[i]);
420329f73ebSElena Agostini 	printf("\n=======> TEST: FAILED\n");
421329f73ebSElena Agostini 	return -1;
422c7ebd65cSElena Agostini }
423c7ebd65cSElena Agostini 
4248b8036a6SElena Agostini int
main(int argc,char ** argv)4258b8036a6SElena Agostini main(int argc, char **argv)
4268b8036a6SElena Agostini {
4278b8036a6SElena Agostini 	int ret;
4288b8036a6SElena Agostini 	int nb_gpus = 0;
4298b8036a6SElena Agostini 	int16_t gpu_id = 0;
4308b8036a6SElena Agostini 	struct rte_gpu_info ginfo;
4318b8036a6SElena Agostini 
4328b8036a6SElena Agostini 	/* Init EAL. */
4338b8036a6SElena Agostini 	ret = rte_eal_init(argc, argv);
4348b8036a6SElena Agostini 	if (ret < 0)
4358b8036a6SElena Agostini 		rte_exit(EXIT_FAILURE, "EAL init failed\n");
4368b8036a6SElena Agostini 	argc -= ret;
4378b8036a6SElena Agostini 	argv += ret;
4388b8036a6SElena Agostini 	if (argc > 1)
4398b8036a6SElena Agostini 		args_parse(argc, argv);
4408b8036a6SElena Agostini 	argc -= ret;
4418b8036a6SElena Agostini 	argv += ret;
4428b8036a6SElena Agostini 
4438b8036a6SElena Agostini 	nb_gpus = rte_gpu_count_avail();
4448b8036a6SElena Agostini 	printf("\n\nDPDK found %d GPUs:\n", nb_gpus);
4458b8036a6SElena Agostini 	RTE_GPU_FOREACH(gpu_id)
4468b8036a6SElena Agostini 	{
4478b8036a6SElena Agostini 		if (rte_gpu_info_get(gpu_id, &ginfo))
4488b8036a6SElena Agostini 			rte_exit(EXIT_FAILURE, "rte_gpu_info_get error - bye\n");
4498b8036a6SElena Agostini 
45082e5f6b6SThomas Monjalon 		printf("\tGPU ID %d\n\t\tparent ID %d GPU Bus ID %s NUMA node %d Tot memory %.02f MB, Tot processors %d\n",
4518b8036a6SElena Agostini 				ginfo.dev_id,
45282e5f6b6SThomas Monjalon 				ginfo.parent,
4538b8036a6SElena Agostini 				ginfo.name,
4548b8036a6SElena Agostini 				ginfo.numa_node,
4558b8036a6SElena Agostini 				(((float)ginfo.total_memory)/(float)1024)/(float)1024,
4568b8036a6SElena Agostini 				ginfo.processor_count
4578b8036a6SElena Agostini 			);
4588b8036a6SElena Agostini 	}
4598b8036a6SElena Agostini 	printf("\n\n");
4608b8036a6SElena Agostini 
461e818c4e2SElena Agostini 	if (nb_gpus == 0) {
462e818c4e2SElena Agostini 		fprintf(stderr, "Need at least one GPU on the system to run the example\n");
463e818c4e2SElena Agostini 		return EXIT_FAILURE;
464e818c4e2SElena Agostini 	}
465e818c4e2SElena Agostini 
466e818c4e2SElena Agostini 	gpu_id = 0;
467e818c4e2SElena Agostini 
468e818c4e2SElena Agostini 	/**
469e818c4e2SElena Agostini 	 * Memory tests
470e818c4e2SElena Agostini 	 */
471e818c4e2SElena Agostini 	alloc_gpu_memory(gpu_id);
472e818c4e2SElena Agostini 	register_cpu_memory(gpu_id);
473d69bb47dSElena Agostini 	gpu_mem_cpu_map(gpu_id);
474e818c4e2SElena Agostini 
475f56160a2SElena Agostini 	/**
476f56160a2SElena Agostini 	 * Communication items test
477f56160a2SElena Agostini 	 */
478f56160a2SElena Agostini 	create_update_comm_flag(gpu_id);
479c7ebd65cSElena Agostini 	create_update_comm_list(gpu_id);
480f56160a2SElena Agostini 
4818b8036a6SElena Agostini 	/* clean up the EAL */
4828b8036a6SElena Agostini 	rte_eal_cleanup();
4838b8036a6SElena Agostini 
4848b8036a6SElena Agostini 	return EXIT_SUCCESS;
4858b8036a6SElena Agostini }
486