124c77594SElena Agostini /* SPDX-License-Identifier: BSD-3-Clause
224c77594SElena Agostini * Copyright (c) 2022 NVIDIA Corporation & Affiliates
324c77594SElena Agostini */
424c77594SElena Agostini
524c77594SElena Agostini #include "common.h"
624c77594SElena Agostini
724c77594SElena Agostini #ifdef DRIVERS_GPU_CUDA_GDRCOPY_H
824c77594SElena Agostini
9*cda3d176SLevend Sayar #include <stdlib.h>
10*cda3d176SLevend Sayar
1124c77594SElena Agostini static void *gdrclib;
1224c77594SElena Agostini static gdr_t (*sym_gdr_open)(void);
1324c77594SElena Agostini static int (*sym_gdr_pin_buffer)(gdr_t g, unsigned long addr, size_t size,
1424c77594SElena Agostini uint64_t p2p_token, uint32_t va_space, gdr_mh_t *handle);
1524c77594SElena Agostini static int (*sym_gdr_unpin_buffer)(gdr_t g, gdr_mh_t handle);
1624c77594SElena Agostini static int (*sym_gdr_map)(gdr_t g, gdr_mh_t handle, void **va, size_t size);
1724c77594SElena Agostini static int (*sym_gdr_unmap)(gdr_t g, gdr_mh_t handle, void *va, size_t size);
1824c77594SElena Agostini
1924c77594SElena Agostini static int
gdrcopy_loader(void)2024c77594SElena Agostini gdrcopy_loader(void)
2124c77594SElena Agostini {
2224c77594SElena Agostini char gdrcopy_path[1024];
2324c77594SElena Agostini
2424c77594SElena Agostini if (getenv("GDRCOPY_PATH_L") == NULL)
2524c77594SElena Agostini snprintf(gdrcopy_path, 1024, "%s", "libgdrapi.so");
2624c77594SElena Agostini else
2724c77594SElena Agostini snprintf(gdrcopy_path, 1024, "%s/%s", getenv("GDRCOPY_PATH_L"), "libgdrapi.so");
2824c77594SElena Agostini
2924c77594SElena Agostini gdrclib = dlopen(gdrcopy_path, RTLD_LAZY);
3024c77594SElena Agostini if (gdrclib == NULL) {
3124c77594SElena Agostini rte_cuda_log(ERR, "Failed to find GDRCopy library %s (GDRCOPY_PATH_L=%s)\n",
3224c77594SElena Agostini gdrcopy_path, getenv("GDRCOPY_PATH_L"));
3324c77594SElena Agostini return -1;
3424c77594SElena Agostini }
3524c77594SElena Agostini
3624c77594SElena Agostini sym_gdr_open = dlsym(gdrclib, "gdr_open");
3724c77594SElena Agostini if (sym_gdr_open == NULL) {
3824c77594SElena Agostini rte_cuda_log(ERR, "Failed to load GDRCopy symbols\n");
3924c77594SElena Agostini return -1;
4024c77594SElena Agostini }
4124c77594SElena Agostini
4224c77594SElena Agostini sym_gdr_pin_buffer = dlsym(gdrclib, "gdr_pin_buffer");
4324c77594SElena Agostini if (sym_gdr_pin_buffer == NULL) {
4424c77594SElena Agostini rte_cuda_log(ERR, "Failed to load GDRCopy symbols\n");
4524c77594SElena Agostini return -1;
4624c77594SElena Agostini }
4724c77594SElena Agostini
4824c77594SElena Agostini sym_gdr_unpin_buffer = dlsym(gdrclib, "gdr_unpin_buffer");
4924c77594SElena Agostini if (sym_gdr_unpin_buffer == NULL) {
5024c77594SElena Agostini rte_cuda_log(ERR, "Failed to load GDRCopy symbols\n");
5124c77594SElena Agostini return -1;
5224c77594SElena Agostini }
5324c77594SElena Agostini
5424c77594SElena Agostini sym_gdr_map = dlsym(gdrclib, "gdr_map");
5524c77594SElena Agostini if (sym_gdr_map == NULL) {
5624c77594SElena Agostini rte_cuda_log(ERR, "Failed to load GDRCopy symbols\n");
5724c77594SElena Agostini return -1;
5824c77594SElena Agostini }
5924c77594SElena Agostini
6024c77594SElena Agostini sym_gdr_unmap = dlsym(gdrclib, "gdr_unmap");
6124c77594SElena Agostini if (sym_gdr_unmap == NULL) {
6224c77594SElena Agostini rte_cuda_log(ERR, "Failed to load GDRCopy symbols\n");
6324c77594SElena Agostini return -1;
6424c77594SElena Agostini }
6524c77594SElena Agostini
6624c77594SElena Agostini return 0;
6724c77594SElena Agostini }
6824c77594SElena Agostini
6924c77594SElena Agostini static int
gdrcopy_open(gdr_t * g)7024c77594SElena Agostini gdrcopy_open(gdr_t *g)
7124c77594SElena Agostini {
7224c77594SElena Agostini gdr_t g_;
7324c77594SElena Agostini
7424c77594SElena Agostini g_ = sym_gdr_open();
7524c77594SElena Agostini if (!g_)
7624c77594SElena Agostini return -1;
7724c77594SElena Agostini *g = g_;
7824c77594SElena Agostini
7924c77594SElena Agostini return 0;
8024c77594SElena Agostini }
8124c77594SElena Agostini
8224c77594SElena Agostini #endif
8324c77594SElena Agostini
8424c77594SElena Agostini 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)85ca12f5e8SElena Agostini gdrcopy_pin(__rte_unused gdr_t *gdrc_h, __rte_unused gdr_mh_t *mh,
86ca12f5e8SElena Agostini __rte_unused uint64_t d_addr, __rte_unused size_t size,
87ca12f5e8SElena Agostini __rte_unused void **h_addr)
8824c77594SElena Agostini {
8924c77594SElena Agostini #ifdef DRIVERS_GPU_CUDA_GDRCOPY_H
9024c77594SElena Agostini if (*gdrc_h == NULL) {
9124c77594SElena Agostini if (gdrcopy_loader())
9224c77594SElena Agostini return -ENOTSUP;
9324c77594SElena Agostini
9424c77594SElena Agostini if (gdrcopy_open(gdrc_h)) {
9524c77594SElena Agostini rte_cuda_log(ERR,
9624c77594SElena Agostini "GDRCopy gdrdrv kernel module not found. Can't CPU map GPU memory.");
9724c77594SElena Agostini return -EPERM;
9824c77594SElena Agostini }
9924c77594SElena Agostini }
10024c77594SElena Agostini
10124c77594SElena Agostini /* Pin the device buffer */
10224c77594SElena Agostini if (sym_gdr_pin_buffer(*gdrc_h, d_addr, size, 0, 0, mh) != 0) {
10324c77594SElena Agostini rte_cuda_log(ERR, "GDRCopy pin buffer error.");
10424c77594SElena Agostini return -1;
10524c77594SElena Agostini }
10624c77594SElena Agostini
10724c77594SElena Agostini /* Map the buffer to user space */
10824c77594SElena Agostini if (sym_gdr_map(*gdrc_h, *mh, h_addr, size) != 0) {
10924c77594SElena Agostini rte_cuda_log(ERR, "GDRCopy map buffer error.");
11024c77594SElena Agostini sym_gdr_unpin_buffer(*gdrc_h, *mh);
11124c77594SElena Agostini return -1;
11224c77594SElena Agostini }
11324c77594SElena Agostini
11424c77594SElena Agostini return 0;
11524c77594SElena Agostini #else
11624c77594SElena Agostini rte_cuda_log(ERR,
11724c77594SElena Agostini "GDRCopy headers not provided at DPDK building time. Can't CPU map GPU memory.");
11824c77594SElena Agostini return -ENOTSUP;
11924c77594SElena Agostini #endif
12024c77594SElena Agostini }
12124c77594SElena Agostini
12224c77594SElena Agostini int
gdrcopy_unpin(gdr_t gdrc_h,__rte_unused gdr_mh_t mh,__rte_unused void * d_addr,__rte_unused size_t size)123ca12f5e8SElena Agostini gdrcopy_unpin(gdr_t gdrc_h, __rte_unused gdr_mh_t mh,
124ca12f5e8SElena Agostini __rte_unused void *d_addr, __rte_unused size_t size)
12524c77594SElena Agostini {
12624c77594SElena Agostini if (gdrc_h == NULL)
12724c77594SElena Agostini return -EINVAL;
12824c77594SElena Agostini
12924c77594SElena Agostini #ifdef DRIVERS_GPU_CUDA_GDRCOPY_H
13024c77594SElena Agostini /* Unmap the buffer from user space */
13124c77594SElena Agostini if (sym_gdr_unmap(gdrc_h, mh, d_addr, size) != 0) {
13224c77594SElena Agostini rte_cuda_log(ERR, "GDRCopy unmap buffer error.");
13324c77594SElena Agostini return -1;
13424c77594SElena Agostini }
13524c77594SElena Agostini /* Unpin the device buffer */
13624c77594SElena Agostini if (sym_gdr_unpin_buffer(gdrc_h, mh) != 0) {
13724c77594SElena Agostini rte_cuda_log(ERR, "GDRCopy unpin buffer error.");
13824c77594SElena Agostini return -1;
13924c77594SElena Agostini }
14024c77594SElena Agostini #endif
14124c77594SElena Agostini
14224c77594SElena Agostini return 0;
14324c77594SElena Agostini }
144