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