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 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 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 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 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