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