1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2021 NVIDIA Corporation & Affiliates
6 #include <rte_string_fns.h>
10 #include "rte_gpudev.h"
11 #include "gpudev_driver.h"
14 RTE_LOG_REGISTER_DEFAULT(gpu_logtype, NOTICE);
15 #define GPU_LOG(level, ...) \
16 rte_log(RTE_LOG_ ## level, gpu_logtype, RTE_FMT("gpu: " \
17 RTE_FMT_HEAD(__VA_ARGS__, ) "\n", RTE_FMT_TAIL(__VA_ARGS__, )))
19 /* Set any driver error as EPERM */
20 #define GPU_DRV_RET(function) \
21 ((function != 0) ? -(rte_errno = EPERM) : (rte_errno = 0))
23 /* Array of devices */
24 static struct rte_gpu *gpus;
25 /* Number of currently valid devices */
26 static int16_t gpu_max;
27 /* Number of currently valid devices */
28 static int16_t gpu_count;
31 rte_gpu_init(size_t dev_max)
33 if (dev_max == 0 || dev_max > INT16_MAX) {
34 GPU_LOG(ERR, "invalid array size");
39 /* No lock, it must be called before or during first probing. */
41 GPU_LOG(ERR, "already initialized");
46 gpus = calloc(dev_max, sizeof(struct rte_gpu));
48 GPU_LOG(ERR, "cannot initialize library");
58 rte_gpu_count_avail(void)
64 rte_gpu_is_valid(int16_t dev_id)
66 if (dev_id >= 0 && dev_id < gpu_max &&
67 gpus[dev_id].state == RTE_GPU_STATE_INITIALIZED)
73 rte_gpu_find_next(int16_t dev_id)
77 while (dev_id < gpu_max &&
78 gpus[dev_id].state == RTE_GPU_STATE_UNUSED)
81 if (dev_id >= gpu_max)
82 return RTE_GPU_ID_NONE;
87 gpu_find_free_id(void)
91 for (dev_id = 0; dev_id < gpu_max; dev_id++) {
92 if (gpus[dev_id].state == RTE_GPU_STATE_UNUSED)
95 return RTE_GPU_ID_NONE;
98 static struct rte_gpu *
99 gpu_get_by_id(int16_t dev_id)
101 if (!rte_gpu_is_valid(dev_id))
103 return &gpus[dev_id];
107 rte_gpu_get_by_name(const char *name)
117 RTE_GPU_FOREACH(dev_id) {
119 if (strncmp(name, dev->name, RTE_DEV_NAME_MAX_LEN) == 0)
126 rte_gpu_allocate(const char *name)
131 if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
132 GPU_LOG(ERR, "only primary process can allocate device");
137 GPU_LOG(ERR, "allocate device without a name");
142 /* implicit initialization of library before adding first device */
143 if (gpus == NULL && rte_gpu_init(RTE_GPU_DEFAULT_MAX) < 0)
146 if (rte_gpu_get_by_name(name) != NULL) {
147 GPU_LOG(ERR, "device with name %s already exists", name);
151 dev_id = gpu_find_free_id();
152 if (dev_id == RTE_GPU_ID_NONE) {
153 GPU_LOG(ERR, "reached maximum number of devices");
159 memset(dev, 0, sizeof(*dev));
161 if (rte_strscpy(dev->name, name, RTE_DEV_NAME_MAX_LEN) < 0) {
162 GPU_LOG(ERR, "device name too long: %s", name);
163 rte_errno = ENAMETOOLONG;
166 dev->info.name = dev->name;
167 dev->info.dev_id = dev_id;
168 dev->info.numa_node = -1;
171 GPU_LOG(DEBUG, "new device %s (id %d) of total %d",
172 name, dev_id, gpu_count);
177 rte_gpu_complete_new(struct rte_gpu *dev)
182 dev->state = RTE_GPU_STATE_INITIALIZED;
186 rte_gpu_release(struct rte_gpu *dev)
193 GPU_LOG(DEBUG, "free device %s (id %d)",
194 dev->info.name, dev->info.dev_id);
195 dev->state = RTE_GPU_STATE_UNUSED;
202 rte_gpu_close(int16_t dev_id)
204 int firsterr, binerr;
205 int *lasterr = &firsterr;
208 dev = gpu_get_by_id(dev_id);
210 GPU_LOG(ERR, "close invalid device ID %d", dev_id);
215 if (dev->ops.dev_close != NULL) {
216 *lasterr = GPU_DRV_RET(dev->ops.dev_close(dev));
221 *lasterr = rte_gpu_release(dev);
223 rte_errno = -firsterr;
228 rte_gpu_info_get(int16_t dev_id, struct rte_gpu_info *info)
232 dev = gpu_get_by_id(dev_id);
234 GPU_LOG(ERR, "query invalid device ID %d", dev_id);
239 GPU_LOG(ERR, "query without storage");
244 if (dev->ops.dev_info_get == NULL) {
248 return GPU_DRV_RET(dev->ops.dev_info_get(dev, info));