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(__rte_unused gdr_t *gdrc_h, __rte_unused gdr_mh_t *mh, 84 __rte_unused uint64_t d_addr, __rte_unused size_t size, 85 __rte_unused void **h_addr) 86 { 87 #ifdef DRIVERS_GPU_CUDA_GDRCOPY_H 88 if (*gdrc_h == NULL) { 89 if (gdrcopy_loader()) 90 return -ENOTSUP; 91 92 if (gdrcopy_open(gdrc_h)) { 93 rte_cuda_log(ERR, 94 "GDRCopy gdrdrv kernel module not found. Can't CPU map GPU memory."); 95 return -EPERM; 96 } 97 } 98 99 /* Pin the device buffer */ 100 if (sym_gdr_pin_buffer(*gdrc_h, d_addr, size, 0, 0, mh) != 0) { 101 rte_cuda_log(ERR, "GDRCopy pin buffer error."); 102 return -1; 103 } 104 105 /* Map the buffer to user space */ 106 if (sym_gdr_map(*gdrc_h, *mh, h_addr, size) != 0) { 107 rte_cuda_log(ERR, "GDRCopy map buffer error."); 108 sym_gdr_unpin_buffer(*gdrc_h, *mh); 109 return -1; 110 } 111 112 return 0; 113 #else 114 rte_cuda_log(ERR, 115 "GDRCopy headers not provided at DPDK building time. Can't CPU map GPU memory."); 116 return -ENOTSUP; 117 #endif 118 } 119 120 int 121 gdrcopy_unpin(gdr_t gdrc_h, __rte_unused gdr_mh_t mh, 122 __rte_unused void *d_addr, __rte_unused size_t size) 123 { 124 if (gdrc_h == NULL) 125 return -EINVAL; 126 127 #ifdef DRIVERS_GPU_CUDA_GDRCOPY_H 128 /* Unmap the buffer from user space */ 129 if (sym_gdr_unmap(gdrc_h, mh, d_addr, size) != 0) { 130 rte_cuda_log(ERR, "GDRCopy unmap buffer error."); 131 return -1; 132 } 133 /* Unpin the device buffer */ 134 if (sym_gdr_unpin_buffer(gdrc_h, mh) != 0) { 135 rte_cuda_log(ERR, "GDRCopy unpin buffer error."); 136 return -1; 137 } 138 #endif 139 140 return 0; 141 } 142