xref: /dpdk/drivers/gpu/cuda/gdrcopy.c (revision cda3d17609c2cb81af67d5babbd0c1702b503fca)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2022 NVIDIA Corporation & Affiliates
3  */
4 
5 #include "common.h"
6 
7 #ifdef DRIVERS_GPU_CUDA_GDRCOPY_H
8 
9 #include <stdlib.h>
10 
11 static void *gdrclib;
12 static gdr_t (*sym_gdr_open)(void);
13 static int (*sym_gdr_pin_buffer)(gdr_t g, unsigned long addr, size_t size,
14 		uint64_t p2p_token, uint32_t va_space, gdr_mh_t *handle);
15 static int (*sym_gdr_unpin_buffer)(gdr_t g, gdr_mh_t handle);
16 static int (*sym_gdr_map)(gdr_t g, gdr_mh_t handle, void **va, size_t size);
17 static int (*sym_gdr_unmap)(gdr_t g, gdr_mh_t handle, void *va, size_t size);
18 
19 static int
gdrcopy_loader(void)20 gdrcopy_loader(void)
21 {
22 	char gdrcopy_path[1024];
23 
24 	if (getenv("GDRCOPY_PATH_L") == NULL)
25 		snprintf(gdrcopy_path, 1024, "%s", "libgdrapi.so");
26 	else
27 		snprintf(gdrcopy_path, 1024, "%s/%s", getenv("GDRCOPY_PATH_L"), "libgdrapi.so");
28 
29 	gdrclib = dlopen(gdrcopy_path, RTLD_LAZY);
30 	if (gdrclib == NULL) {
31 		rte_cuda_log(ERR, "Failed to find GDRCopy library %s (GDRCOPY_PATH_L=%s)\n",
32 				gdrcopy_path, getenv("GDRCOPY_PATH_L"));
33 		return -1;
34 	}
35 
36 	sym_gdr_open = dlsym(gdrclib, "gdr_open");
37 	if (sym_gdr_open == NULL) {
38 		rte_cuda_log(ERR, "Failed to load GDRCopy symbols\n");
39 		return -1;
40 	}
41 
42 	sym_gdr_pin_buffer = dlsym(gdrclib, "gdr_pin_buffer");
43 	if (sym_gdr_pin_buffer == NULL) {
44 		rte_cuda_log(ERR, "Failed to load GDRCopy symbols\n");
45 		return -1;
46 	}
47 
48 	sym_gdr_unpin_buffer = dlsym(gdrclib, "gdr_unpin_buffer");
49 	if (sym_gdr_unpin_buffer == NULL) {
50 		rte_cuda_log(ERR, "Failed to load GDRCopy symbols\n");
51 		return -1;
52 	}
53 
54 	sym_gdr_map = dlsym(gdrclib, "gdr_map");
55 	if (sym_gdr_map == NULL) {
56 		rte_cuda_log(ERR, "Failed to load GDRCopy symbols\n");
57 		return -1;
58 	}
59 
60 	sym_gdr_unmap = dlsym(gdrclib, "gdr_unmap");
61 	if (sym_gdr_unmap == NULL) {
62 		rte_cuda_log(ERR, "Failed to load GDRCopy symbols\n");
63 		return -1;
64 	}
65 
66 	return 0;
67 }
68 
69 static int
gdrcopy_open(gdr_t * g)70 gdrcopy_open(gdr_t *g)
71 {
72 	gdr_t g_;
73 
74 	g_ = sym_gdr_open();
75 	if (!g_)
76 		return -1;
77 	*g = g_;
78 
79 	return 0;
80 }
81 
82 #endif
83 
84 int
gdrcopy_pin(__rte_unused gdr_t * gdrc_h,__rte_unused gdr_mh_t * mh,__rte_unused uint64_t d_addr,__rte_unused size_t size,__rte_unused void ** h_addr)85 gdrcopy_pin(__rte_unused gdr_t *gdrc_h, __rte_unused gdr_mh_t *mh,
86 		__rte_unused uint64_t d_addr, __rte_unused size_t size,
87 		__rte_unused void **h_addr)
88 {
89 #ifdef DRIVERS_GPU_CUDA_GDRCOPY_H
90 	if (*gdrc_h == NULL) {
91 		if (gdrcopy_loader())
92 			return -ENOTSUP;
93 
94 		if (gdrcopy_open(gdrc_h)) {
95 			rte_cuda_log(ERR,
96 					"GDRCopy gdrdrv kernel module not found. Can't CPU map GPU memory.");
97 			return -EPERM;
98 		}
99 	}
100 
101 	/* Pin the device buffer */
102 	if (sym_gdr_pin_buffer(*gdrc_h, d_addr, size, 0, 0, mh) != 0) {
103 		rte_cuda_log(ERR, "GDRCopy pin buffer error.");
104 		return -1;
105 	}
106 
107 	/* Map the buffer to user space */
108 	if (sym_gdr_map(*gdrc_h, *mh, h_addr, size) != 0) {
109 		rte_cuda_log(ERR, "GDRCopy map buffer error.");
110 		sym_gdr_unpin_buffer(*gdrc_h, *mh);
111 		return -1;
112 	}
113 
114 	return 0;
115 #else
116 	rte_cuda_log(ERR,
117 			"GDRCopy headers not provided at DPDK building time. Can't CPU map GPU memory.");
118 	return -ENOTSUP;
119 #endif
120 }
121 
122 int
gdrcopy_unpin(gdr_t gdrc_h,__rte_unused gdr_mh_t mh,__rte_unused void * d_addr,__rte_unused size_t size)123 gdrcopy_unpin(gdr_t gdrc_h, __rte_unused gdr_mh_t mh,
124 		__rte_unused void *d_addr, __rte_unused size_t size)
125 {
126 	if (gdrc_h == NULL)
127 		return -EINVAL;
128 
129 #ifdef DRIVERS_GPU_CUDA_GDRCOPY_H
130 	/* Unmap the buffer from user space */
131 	if (sym_gdr_unmap(gdrc_h, mh, d_addr, size) != 0) {
132 		rte_cuda_log(ERR, "GDRCopy unmap buffer error.");
133 		return -1;
134 	}
135 	/* Unpin the device buffer */
136 	if (sym_gdr_unpin_buffer(gdrc_h, mh) != 0) {
137 		rte_cuda_log(ERR, "GDRCopy unpin buffer error.");
138 		return -1;
139 	}
140 #endif
141 
142 	return 0;
143 }
144