DPDK patches and discussions
 help / color / mirror / Atom feed
From: <eagostini@nvidia.com>
To: <dev@dpdk.org>
Cc: Elena Agostini <eagostini@nvidia.com>,
	Thomas Monjalon <thomas@monjalon.net>
Subject: [dpdk-dev] [PATCH v5 1/9] gpudev: introduce GPU device class library
Date: Mon, 8 Nov 2021 18:57:57 +0000	[thread overview]
Message-ID: <20211108185805.3887-2-eagostini@nvidia.com> (raw)
In-Reply-To: <20211108185805.3887-1-eagostini@nvidia.com>

From: Elena Agostini <eagostini@nvidia.com>

In heterogeneous computing system, processing is not only in the CPU.
Some tasks can be delegated to devices working in parallel.

The new library gpudev is for dealing with GPGPU computing devices
from a DPDK application running on the CPU.

The infrastructure is prepared to welcome drivers in drivers/gpu/.

Signed-off-by: Elena Agostini <eagostini@nvidia.com>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 .gitignore                             |   1 +
 MAINTAINERS                            |   6 +
 app/meson.build                        |   1 +
 app/test-gpudev/main.c                 | 107 +++++++++++
 app/test-gpudev/meson.build            |   5 +
 doc/api/doxy-api.conf.in               |   1 +
 doc/guides/conf.py                     |   8 +
 doc/guides/gpus/features/default.ini   |  10 +
 doc/guides/gpus/index.rst              |  11 ++
 doc/guides/gpus/overview.rst           |  10 +
 doc/guides/index.rst                   |   1 +
 doc/guides/prog_guide/gpudev.rst       |  36 ++++
 doc/guides/prog_guide/index.rst        |   1 +
 doc/guides/rel_notes/release_21_11.rst |   4 +
 drivers/gpu/meson.build                |   4 +
 drivers/meson.build                    |   1 +
 lib/gpudev/gpudev.c                    | 249 +++++++++++++++++++++++++
 lib/gpudev/gpudev_driver.h             |  67 +++++++
 lib/gpudev/meson.build                 |  10 +
 lib/gpudev/rte_gpudev.h                | 168 +++++++++++++++++
 lib/gpudev/version.map                 |  20 ++
 lib/meson.build                        |   1 +
 22 files changed, 722 insertions(+)
 create mode 100644 app/test-gpudev/main.c
 create mode 100644 app/test-gpudev/meson.build
 create mode 100644 doc/guides/gpus/features/default.ini
 create mode 100644 doc/guides/gpus/index.rst
 create mode 100644 doc/guides/gpus/overview.rst
 create mode 100644 doc/guides/prog_guide/gpudev.rst
 create mode 100644 drivers/gpu/meson.build
 create mode 100644 lib/gpudev/gpudev.c
 create mode 100644 lib/gpudev/gpudev_driver.h
 create mode 100644 lib/gpudev/meson.build
 create mode 100644 lib/gpudev/rte_gpudev.h
 create mode 100644 lib/gpudev/version.map

diff --git a/.gitignore b/.gitignore
index 7ec8688342..b98a43a601 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@ doc/guides/compressdevs/overview_feature_table.txt
 doc/guides/regexdevs/overview_feature_table.txt
 doc/guides/vdpadevs/overview_feature_table.txt
 doc/guides/bbdevs/overview_feature_table.txt
+doc/guides/gpus/overview_feature_table.txt
 
 # ignore generated ctags/cscope files
 cscope.out.po
diff --git a/MAINTAINERS b/MAINTAINERS
index 3459187e26..a2e67fb1e6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -467,6 +467,12 @@ M: Bruce Richardson <bruce.richardson@intel.com>
 F: examples/dma/
 F: doc/guides/sample_app_ug/dma.rst
 
+General-Purpose Graphics Processing Unit (GPU) API - EXPERIMENTAL
+M: Elena Agostini <eagostini@nvidia.com>
+F: lib/gpudev/
+F: doc/guides/prog_guide/gpudev.rst
+F: doc/guides/gpus/features/default.ini
+
 Eventdev API
 M: Jerin Jacob <jerinj@marvell.com>
 T: git://dpdk.org/next/dpdk-next-eventdev
diff --git a/app/meson.build b/app/meson.build
index 986c1a4ad4..310e83076f 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -13,6 +13,7 @@ apps = [
         'test-eventdev',
         'test-fib',
         'test-flow-perf',
+        'test-gpudev',
         'test-pipeline',
         'test-pmd',
         'test-regex',
diff --git a/app/test-gpudev/main.c b/app/test-gpudev/main.c
new file mode 100644
index 0000000000..438cfdac54
--- /dev/null
+++ b/app/test-gpudev/main.c
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2021 NVIDIA Corporation & Affiliates
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <getopt.h>
+
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_memory.h>
+#include <rte_eal.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+
+#include <rte_gpudev.h>
+
+enum app_args {
+	ARG_HELP,
+	ARG_MEMPOOL
+};
+
+static void
+usage(const char *prog_name)
+{
+	printf("%s [EAL options] --\n",
+		prog_name);
+}
+
+static void
+args_parse(int argc, char **argv)
+{
+	char **argvopt;
+	int opt;
+	int opt_idx;
+
+	static struct option lgopts[] = {
+		{ "help", 0, 0, ARG_HELP},
+		/* End of options */
+		{ 0, 0, 0, 0 }
+	};
+
+	argvopt = argv;
+	while ((opt = getopt_long(argc, argvopt, "",
+				lgopts, &opt_idx)) != EOF) {
+		switch (opt) {
+		case ARG_HELP:
+			usage(argv[0]);
+			break;
+		default:
+			usage(argv[0]);
+			rte_exit(EXIT_FAILURE, "Invalid option: %s\n", argv[optind]);
+			break;
+		}
+	}
+}
+
+int
+main(int argc, char **argv)
+{
+	int ret;
+	int nb_gpus = 0;
+	int16_t gpu_id = 0;
+	struct rte_gpu_info ginfo;
+
+	/* Init EAL. */
+	ret = rte_eal_init(argc, argv);
+	if (ret < 0)
+		rte_exit(EXIT_FAILURE, "EAL init failed\n");
+	argc -= ret;
+	argv += ret;
+	if (argc > 1)
+		args_parse(argc, argv);
+	argc -= ret;
+	argv += ret;
+
+	nb_gpus = rte_gpu_count_avail();
+	printf("\n\nDPDK found %d GPUs:\n", nb_gpus);
+	RTE_GPU_FOREACH(gpu_id)
+	{
+		if (rte_gpu_info_get(gpu_id, &ginfo))
+			rte_exit(EXIT_FAILURE, "rte_gpu_info_get error - bye\n");
+
+		printf("\tGPU ID %d\n\t\tparent ID %d GPU Bus ID %s NUMA node %d Tot memory %.02f MB, Tot processors %d\n",
+				ginfo.dev_id,
+				ginfo.parent,
+				ginfo.name,
+				ginfo.numa_node,
+				(((float)ginfo.total_memory)/(float)1024)/(float)1024,
+				ginfo.processor_count
+			);
+	}
+	printf("\n\n");
+
+	/* clean up the EAL */
+	rte_eal_cleanup();
+	printf("Bye...\n");
+
+	return EXIT_SUCCESS;
+}
diff --git a/app/test-gpudev/meson.build b/app/test-gpudev/meson.build
new file mode 100644
index 0000000000..17bdef3646
--- /dev/null
+++ b/app/test-gpudev/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright (c) 2021 NVIDIA Corporation & Affiliates
+
+sources = files('main.c')
+deps = ['gpudev', 'ethdev']
diff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in
index 096ebbaf0d..db2ca9b6ed 100644
--- a/doc/api/doxy-api.conf.in
+++ b/doc/api/doxy-api.conf.in
@@ -41,6 +41,7 @@ INPUT                   = @TOPDIR@/doc/api/doxy-api-index.md \
                           @TOPDIR@/lib/eventdev \
                           @TOPDIR@/lib/fib \
                           @TOPDIR@/lib/flow_classify \
+                          @TOPDIR@/lib/gpudev \
                           @TOPDIR@/lib/graph \
                           @TOPDIR@/lib/gro \
                           @TOPDIR@/lib/gso \
diff --git a/doc/guides/conf.py b/doc/guides/conf.py
index 0494b0efe7..e6ce929bc8 100644
--- a/doc/guides/conf.py
+++ b/doc/guides/conf.py
@@ -152,6 +152,9 @@ def generate_overview_table(output_filename, table_id, section, table_name, titl
         name = ini_filename[:-4]
         name = name.replace('_vf', 'vf')
         pmd_names.append(name)
+    if not pmd_names:
+        # Add an empty column if table is empty (required by RST syntax)
+        pmd_names.append(' ')
 
     # Pad the table header names.
     max_header_len = len(max(pmd_names, key=len))
@@ -393,6 +396,11 @@ def setup(app):
                             'Features',
                             'Features availability in bbdev drivers',
                             'Feature')
+    table_file = dirname(__file__) + '/gpus/overview_feature_table.txt'
+    generate_overview_table(table_file, 1,
+                            'Features',
+                            'Features availability in GPU drivers',
+                            'Feature')
 
     if LooseVersion(sphinx_version) < LooseVersion('1.3.1'):
         print('Upgrade sphinx to version >= 1.3.1 for '
diff --git a/doc/guides/gpus/features/default.ini b/doc/guides/gpus/features/default.ini
new file mode 100644
index 0000000000..ec7a545eb7
--- /dev/null
+++ b/doc/guides/gpus/features/default.ini
@@ -0,0 +1,10 @@
+;
+; Features of GPU drivers.
+;
+; This file defines the features that are valid for inclusion in
+; the other driver files and also the order that they appear in
+; the features table in the documentation. The feature description
+; string should not exceed feature_str_len defined in conf.py.
+;
+[Features]
+Get device info                =
diff --git a/doc/guides/gpus/index.rst b/doc/guides/gpus/index.rst
new file mode 100644
index 0000000000..1878423239
--- /dev/null
+++ b/doc/guides/gpus/index.rst
@@ -0,0 +1,11 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+   Copyright (c) 2021 NVIDIA Corporation & Affiliates
+
+General-Purpose Graphics Processing Unit Drivers
+================================================
+
+.. toctree::
+   :maxdepth: 2
+   :numbered:
+
+   overview
diff --git a/doc/guides/gpus/overview.rst b/doc/guides/gpus/overview.rst
new file mode 100644
index 0000000000..4830348818
--- /dev/null
+++ b/doc/guides/gpus/overview.rst
@@ -0,0 +1,10 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+   Copyright (c) 2021 NVIDIA Corporation & Affiliates
+
+Overview of GPU Drivers
+=======================
+
+General-Purpose computing on Graphics Processing Unit (GPGPU)
+is the use of GPU to perform parallel computation.
+
+.. include:: overview_feature_table.txt
diff --git a/doc/guides/index.rst b/doc/guides/index.rst
index 919825992e..5eb5bd9c9a 100644
--- a/doc/guides/index.rst
+++ b/doc/guides/index.rst
@@ -22,6 +22,7 @@ DPDK documentation
    vdpadevs/index
    regexdevs/index
    dmadevs/index
+   gpus/index
    eventdevs/index
    rawdevs/index
    mempool/index
diff --git a/doc/guides/prog_guide/gpudev.rst b/doc/guides/prog_guide/gpudev.rst
new file mode 100644
index 0000000000..6ea7239159
--- /dev/null
+++ b/doc/guides/prog_guide/gpudev.rst
@@ -0,0 +1,36 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+   Copyright (c) 2021 NVIDIA Corporation & Affiliates
+
+General-Purpose Graphics Processing Unit Library
+================================================
+
+When mixing networking activity with task processing on a GPU device,
+there may be the need to put in communication the CPU with the device
+in order to manage the memory, synchronize operations, exchange info, etc..
+
+By means of the generic GPU interface provided by this library,
+it is possible to allocate a chunk of GPU memory and use it
+to create a DPDK mempool with external mbufs having the payload
+on the GPU memory, enabling any network interface card
+(which support this feature like Mellanox NIC)
+to directly transmit and receive packets using GPU memory.
+
+Additionally, this library provides a number of functions
+to enhance the dialog between CPU and GPU.
+
+Out of scope of this library is to provide a wrapper for GPU specific libraries
+(e.g. CUDA Toolkit or OpenCL), thus it is not possible to launch workload
+on the device or create GPU specific objects
+(e.g. CUDA Driver context or CUDA Streams in case of NVIDIA GPUs).
+
+
+Features
+--------
+
+This library provides a number of features:
+
+- Interoperability with device-specific library through generic handlers.
+
+
+API Overview
+------------
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index 20e5155cf4..7090b5589a 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -28,6 +28,7 @@ Programmer's Guide
     compressdev
     regexdev
     dmadev
+    gpudev
     rte_security
     rawdev
     link_bonding_poll_mode_drv_lib
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 8da19c613a..9cf59e73bb 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -101,6 +101,10 @@ New Features
   Added ``rte_eth_macaddrs_get`` to allow user to retrieve all Ethernet
   addresses assigned to given ethernet port.
 
+* **Introduced GPU device class with first features:**
+
+  * Device information
+
 * **Added new RSS offload types for IPv4/L4 checksum in RSS flow.**
 
   Added macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now IPv4 and
diff --git a/drivers/gpu/meson.build b/drivers/gpu/meson.build
new file mode 100644
index 0000000000..e51ad3381b
--- /dev/null
+++ b/drivers/gpu/meson.build
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright (c) 2021 NVIDIA Corporation & Affiliates
+
+drivers = []
diff --git a/drivers/meson.build b/drivers/meson.build
index 34c0276487..d5f4e1c1f2 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -19,6 +19,7 @@ subdirs = [
         'vdpa',           # depends on common, bus and mempool.
         'event',          # depends on common, bus, mempool and net.
         'baseband',       # depends on common and bus.
+        'gpu',            # depends on common and bus.
 ]
 
 if meson.is_cross_build()
diff --git a/lib/gpudev/gpudev.c b/lib/gpudev/gpudev.c
new file mode 100644
index 0000000000..aeb021f2cc
--- /dev/null
+++ b/lib/gpudev/gpudev.c
@@ -0,0 +1,249 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2021 NVIDIA Corporation & Affiliates
+ */
+
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_errno.h>
+#include <rte_log.h>
+
+#include "rte_gpudev.h"
+#include "gpudev_driver.h"
+
+/* Logging */
+RTE_LOG_REGISTER_DEFAULT(gpu_logtype, NOTICE);
+#define GPU_LOG(level, ...) \
+	rte_log(RTE_LOG_ ## level, gpu_logtype, RTE_FMT("gpu: " \
+		RTE_FMT_HEAD(__VA_ARGS__, ) "\n", RTE_FMT_TAIL(__VA_ARGS__, )))
+
+/* Set any driver error as EPERM */
+#define GPU_DRV_RET(function) \
+	((function != 0) ? -(rte_errno = EPERM) : (rte_errno = 0))
+
+/* Array of devices */
+static struct rte_gpu *gpus;
+/* Number of currently valid devices */
+static int16_t gpu_max;
+/* Number of currently valid devices */
+static int16_t gpu_count;
+
+int
+rte_gpu_init(size_t dev_max)
+{
+	if (dev_max == 0 || dev_max > INT16_MAX) {
+		GPU_LOG(ERR, "invalid array size");
+		rte_errno = EINVAL;
+		return -rte_errno;
+	}
+
+	/* No lock, it must be called before or during first probing. */
+	if (gpus != NULL) {
+		GPU_LOG(ERR, "already initialized");
+		rte_errno = EBUSY;
+		return -rte_errno;
+	}
+
+	gpus = calloc(dev_max, sizeof(struct rte_gpu));
+	if (gpus == NULL) {
+		GPU_LOG(ERR, "cannot initialize library");
+		rte_errno = ENOMEM;
+		return -rte_errno;
+	}
+
+	gpu_max = dev_max;
+	return 0;
+}
+
+uint16_t
+rte_gpu_count_avail(void)
+{
+	return gpu_count;
+}
+
+bool
+rte_gpu_is_valid(int16_t dev_id)
+{
+	if (dev_id >= 0 && dev_id < gpu_max &&
+		gpus[dev_id].state == RTE_GPU_STATE_INITIALIZED)
+		return true;
+	return false;
+}
+
+int16_t
+rte_gpu_find_next(int16_t dev_id)
+{
+	if (dev_id < 0)
+		dev_id = 0;
+	while (dev_id < gpu_max &&
+			gpus[dev_id].state == RTE_GPU_STATE_UNUSED)
+		dev_id++;
+
+	if (dev_id >= gpu_max)
+		return RTE_GPU_ID_NONE;
+	return dev_id;
+}
+
+static int16_t
+gpu_find_free_id(void)
+{
+	int16_t dev_id;
+
+	for (dev_id = 0; dev_id < gpu_max; dev_id++) {
+		if (gpus[dev_id].state == RTE_GPU_STATE_UNUSED)
+			return dev_id;
+	}
+	return RTE_GPU_ID_NONE;
+}
+
+static struct rte_gpu *
+gpu_get_by_id(int16_t dev_id)
+{
+	if (!rte_gpu_is_valid(dev_id))
+		return NULL;
+	return &gpus[dev_id];
+}
+
+struct rte_gpu *
+rte_gpu_get_by_name(const char *name)
+{
+	int16_t dev_id;
+	struct rte_gpu *dev;
+
+	if (name == NULL) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	RTE_GPU_FOREACH(dev_id) {
+		dev = &gpus[dev_id];
+		if (strncmp(name, dev->name, RTE_DEV_NAME_MAX_LEN) == 0)
+			return dev;
+	}
+	return NULL;
+}
+
+struct rte_gpu *
+rte_gpu_allocate(const char *name)
+{
+	int16_t dev_id;
+	struct rte_gpu *dev;
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+		GPU_LOG(ERR, "only primary process can allocate device");
+		rte_errno = EPERM;
+		return NULL;
+	}
+	if (name == NULL) {
+		GPU_LOG(ERR, "allocate device without a name");
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	/* implicit initialization of library before adding first device */
+	if (gpus == NULL && rte_gpu_init(RTE_GPU_DEFAULT_MAX) < 0)
+		return NULL;
+
+	if (rte_gpu_get_by_name(name) != NULL) {
+		GPU_LOG(ERR, "device with name %s already exists", name);
+		rte_errno = EEXIST;
+		return NULL;
+	}
+	dev_id = gpu_find_free_id();
+	if (dev_id == RTE_GPU_ID_NONE) {
+		GPU_LOG(ERR, "reached maximum number of devices");
+		rte_errno = ENOENT;
+		return NULL;
+	}
+
+	dev = &gpus[dev_id];
+	memset(dev, 0, sizeof(*dev));
+
+	if (rte_strscpy(dev->name, name, RTE_DEV_NAME_MAX_LEN) < 0) {
+		GPU_LOG(ERR, "device name too long: %s", name);
+		rte_errno = ENAMETOOLONG;
+		return NULL;
+	}
+	dev->info.name = dev->name;
+	dev->info.dev_id = dev_id;
+	dev->info.numa_node = -1;
+
+	gpu_count++;
+	GPU_LOG(DEBUG, "new device %s (id %d) of total %d",
+			name, dev_id, gpu_count);
+	return dev;
+}
+
+void
+rte_gpu_complete_new(struct rte_gpu *dev)
+{
+	if (dev == NULL)
+		return;
+
+	dev->state = RTE_GPU_STATE_INITIALIZED;
+}
+
+int
+rte_gpu_release(struct rte_gpu *dev)
+{
+	if (dev == NULL) {
+		rte_errno = ENODEV;
+		return -rte_errno;
+	}
+
+	GPU_LOG(DEBUG, "free device %s (id %d)",
+			dev->info.name, dev->info.dev_id);
+	dev->state = RTE_GPU_STATE_UNUSED;
+	gpu_count--;
+
+	return 0;
+}
+
+int
+rte_gpu_close(int16_t dev_id)
+{
+	int firsterr, binerr;
+	int *lasterr = &firsterr;
+	struct rte_gpu *dev;
+
+	dev = gpu_get_by_id(dev_id);
+	if (dev == NULL) {
+		GPU_LOG(ERR, "close invalid device ID %d", dev_id);
+		rte_errno = ENODEV;
+		return -rte_errno;
+	}
+
+	if (dev->ops.dev_close != NULL) {
+		*lasterr = GPU_DRV_RET(dev->ops.dev_close(dev));
+		if (*lasterr != 0)
+			lasterr = &binerr;
+	}
+
+	*lasterr = rte_gpu_release(dev);
+
+	rte_errno = -firsterr;
+	return firsterr;
+}
+
+int
+rte_gpu_info_get(int16_t dev_id, struct rte_gpu_info *info)
+{
+	struct rte_gpu *dev;
+
+	dev = gpu_get_by_id(dev_id);
+	if (dev == NULL) {
+		GPU_LOG(ERR, "query invalid device ID %d", dev_id);
+		rte_errno = ENODEV;
+		return -rte_errno;
+	}
+	if (info == NULL) {
+		GPU_LOG(ERR, "query without storage");
+		rte_errno = EINVAL;
+		return -rte_errno;
+	}
+
+	if (dev->ops.dev_info_get == NULL) {
+		*info = dev->info;
+		return 0;
+	}
+	return GPU_DRV_RET(dev->ops.dev_info_get(dev, info));
+}
diff --git a/lib/gpudev/gpudev_driver.h b/lib/gpudev/gpudev_driver.h
new file mode 100644
index 0000000000..9e096e3b64
--- /dev/null
+++ b/lib/gpudev/gpudev_driver.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2021 NVIDIA Corporation & Affiliates
+ */
+
+/*
+ * This header file must be included only by drivers.
+ * It is considered internal, i.e. hidden for the application.
+ * The prefix rte_ is used to avoid namespace clash in drivers.
+ */
+
+#ifndef RTE_GPUDEV_DRIVER_H
+#define RTE_GPUDEV_DRIVER_H
+
+#include <stdint.h>
+
+#include <rte_dev.h>
+
+#include "rte_gpudev.h"
+
+/* Flags indicate current state of device. */
+enum rte_gpu_state {
+	RTE_GPU_STATE_UNUSED,        /* not initialized */
+	RTE_GPU_STATE_INITIALIZED,   /* initialized */
+};
+
+struct rte_gpu;
+typedef int (rte_gpu_close_t)(struct rte_gpu *dev);
+typedef int (rte_gpu_info_get_t)(struct rte_gpu *dev, struct rte_gpu_info *info);
+
+struct rte_gpu_ops {
+	/* Get device info. If NULL, info is just copied. */
+	rte_gpu_info_get_t *dev_info_get;
+	/* Close device. */
+	rte_gpu_close_t *dev_close;
+};
+
+struct rte_gpu {
+	/* Backing device. */
+	struct rte_device *device;
+	/* Unique identifier name. */
+	char name[RTE_DEV_NAME_MAX_LEN]; /* Updated by this library. */
+	/* Device info structure. */
+	struct rte_gpu_info info;
+	/* Driver functions. */
+	struct rte_gpu_ops ops;
+	/* Current state (used or not) in the running process. */
+	enum rte_gpu_state state; /* Updated by this library. */
+	/* Driver-specific private data for the running process. */
+	void *process_private;
+} __rte_cache_aligned;
+
+__rte_internal
+struct rte_gpu *rte_gpu_get_by_name(const char *name);
+
+/* First step of initialization */
+__rte_internal
+struct rte_gpu *rte_gpu_allocate(const char *name);
+
+/* Last step of initialization. */
+__rte_internal
+void rte_gpu_complete_new(struct rte_gpu *dev);
+
+/* Last step of removal. */
+__rte_internal
+int rte_gpu_release(struct rte_gpu *dev);
+
+#endif /* RTE_GPUDEV_DRIVER_H */
diff --git a/lib/gpudev/meson.build b/lib/gpudev/meson.build
new file mode 100644
index 0000000000..608154817b
--- /dev/null
+++ b/lib/gpudev/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright (c) 2021 NVIDIA Corporation & Affiliates
+
+headers = files(
+        'rte_gpudev.h',
+)
+
+sources = files(
+        'gpudev.c',
+)
diff --git a/lib/gpudev/rte_gpudev.h b/lib/gpudev/rte_gpudev.h
new file mode 100644
index 0000000000..eb7cfa8c59
--- /dev/null
+++ b/lib/gpudev/rte_gpudev.h
@@ -0,0 +1,168 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2021 NVIDIA Corporation & Affiliates
+ */
+
+#ifndef RTE_GPUDEV_H
+#define RTE_GPUDEV_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <rte_compat.h>
+
+/**
+ * @file
+ * Generic library to interact with GPU computing device.
+ *
+ * The API is not thread-safe.
+ * Device management must be done by a single thread.
+ *
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Maximum number of devices if rte_gpu_init() is not called. */
+#define RTE_GPU_DEFAULT_MAX 32
+
+/** Empty device ID. */
+#define RTE_GPU_ID_NONE -1
+
+/** Store device info. */
+struct rte_gpu_info {
+	/** Unique identifier name. */
+	const char *name;
+	/** Device ID. */
+	int16_t dev_id;
+	/** Total processors available on device. */
+	uint32_t processor_count;
+	/** Total memory available on device. */
+	size_t total_memory;
+	/* Local NUMA memory ID. -1 if unknown. */
+	int16_t numa_node;
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Initialize the device array before probing devices.
+ * If not called, the maximum of probed devices is RTE_GPU_DEFAULT_MAX.
+ *
+ * @param dev_max
+ *   Maximum number of devices.
+ *
+ * @return
+ *   0 on success, -rte_errno otherwise:
+ *   - ENOMEM if out of memory
+ *   - EINVAL if 0 size
+ *   - EBUSY if already initialized
+ */
+__rte_experimental
+int rte_gpu_init(size_t dev_max);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Return the number of GPU detected and associated to DPDK.
+ *
+ * @return
+ *   The number of available computing devices.
+ */
+__rte_experimental
+uint16_t rte_gpu_count_avail(void);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Check if the device is valid and initialized in DPDK.
+ *
+ * @param dev_id
+ *   The input device ID.
+ *
+ * @return
+ *   - True if dev_id is a valid and initialized computing device.
+ *   - False otherwise.
+ */
+__rte_experimental
+bool rte_gpu_is_valid(int16_t dev_id);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Get the ID of the next valid GPU initialized in DPDK.
+ *
+ * @param dev_id
+ *   The initial device ID to start the research.
+ *
+ * @return
+ *   Next device ID corresponding to a valid and initialized computing device,
+ *   RTE_GPU_ID_NONE if there is none.
+ */
+__rte_experimental
+int16_t rte_gpu_find_next(int16_t dev_id);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Macro to iterate over all valid GPU devices.
+ *
+ * @param dev_id
+ *   The ID of the next possible valid device, usually 0 to iterate all.
+ */
+#define RTE_GPU_FOREACH(dev_id) \
+	for (dev_id = rte_gpu_find_next(0); \
+	     dev_id > 0; \
+	     dev_id = rte_gpu_find_next(dev_id + 1))
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Close device.
+ * All resources are released.
+ *
+ * @param dev_id
+ *   Device ID to close.
+ *
+ * @return
+ *   0 on success, -rte_errno otherwise:
+ *   - ENODEV if invalid dev_id
+ *   - EPERM if driver error
+ */
+__rte_experimental
+int rte_gpu_close(int16_t dev_id);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Return device specific info.
+ *
+ * @param dev_id
+ *   Device ID to get info.
+ * @param info
+ *   Memory structure to fill with the info.
+ *
+ * @return
+ *   0 on success, -rte_errno otherwise:
+ *   - ENODEV if invalid dev_id
+ *   - EINVAL if NULL info
+ *   - EPERM if driver error
+ */
+__rte_experimental
+int rte_gpu_info_get(int16_t dev_id, struct rte_gpu_info *info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RTE_GPUDEV_H */
diff --git a/lib/gpudev/version.map b/lib/gpudev/version.map
new file mode 100644
index 0000000000..6ac6b327e2
--- /dev/null
+++ b/lib/gpudev/version.map
@@ -0,0 +1,20 @@
+EXPERIMENTAL {
+	global:
+
+	# added in 21.11
+	rte_gpu_close;
+	rte_gpu_count_avail;
+	rte_gpu_find_next;
+	rte_gpu_info_get;
+	rte_gpu_init;
+	rte_gpu_is_valid;
+};
+
+INTERNAL {
+	global:
+
+	rte_gpu_allocate;
+	rte_gpu_complete_new;
+	rte_gpu_get_by_name;
+	rte_gpu_release;
+};
diff --git a/lib/meson.build b/lib/meson.build
index 499d26060f..8537a5ab80 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -34,6 +34,7 @@ libraries = [
         'distributor',
         'efd',
         'eventdev',
+        'gpudev',
         'gro',
         'gso',
         'ip_frag',
-- 
2.17.1


  parent reply	other threads:[~2021-11-08 10:47 UTC|newest]

Thread overview: 128+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-02 20:35 [dpdk-dev] [PATCH] gpudev: introduce memory API Thomas Monjalon
2021-06-02 20:46 ` Stephen Hemminger
2021-06-02 20:48   ` Thomas Monjalon
2021-06-03  7:06 ` Andrew Rybchenko
2021-06-03  7:26   ` Thomas Monjalon
2021-06-03  7:49     ` Andrew Rybchenko
2021-06-03  8:26       ` Thomas Monjalon
2021-06-03  8:57         ` Andrew Rybchenko
2021-06-03  7:18 ` David Marchand
2021-06-03  7:30   ` Thomas Monjalon
2021-06-03  7:47 ` Jerin Jacob
2021-06-03  8:28   ` Thomas Monjalon
2021-06-03  8:41     ` Jerin Jacob
2021-06-03  8:43       ` Thomas Monjalon
2021-06-03  8:47         ` Jerin Jacob
2021-06-03  8:53           ` Thomas Monjalon
2021-06-03  9:20             ` Jerin Jacob
2021-06-03  9:36               ` Thomas Monjalon
2021-06-03 10:04                 ` Jerin Jacob
2021-06-03 10:30                   ` Thomas Monjalon
2021-06-03 11:38                     ` Jerin Jacob
2021-06-04 12:55                       ` Thomas Monjalon
2021-06-04 15:05                         ` Jerin Jacob
2021-06-03  9:33   ` Ferruh Yigit
2021-06-04 10:28     ` Thomas Monjalon
2021-06-04 11:09       ` Jerin Jacob
2021-06-04 12:46         ` Thomas Monjalon
2021-06-04 13:05           ` Andrew Rybchenko
2021-06-04 13:18             ` Thomas Monjalon
2021-06-04 13:59               ` Andrew Rybchenko
2021-06-04 14:09                 ` Thomas Monjalon
2021-06-04 15:20                   ` Jerin Jacob
2021-06-04 15:51                     ` Thomas Monjalon
2021-06-04 18:20                       ` Wang, Haiyue
2021-06-05  5:09                         ` Jerin Jacob
2021-06-06  1:13                           ` Honnappa Nagarahalli
2021-06-06  5:28                             ` Jerin Jacob
2021-06-07 10:29                               ` Thomas Monjalon
2021-06-07  7:20                             ` Wang, Haiyue
2021-06-07 10:43                               ` Thomas Monjalon
2021-06-07 13:54                                 ` Jerin Jacob
2021-06-07 16:47                                   ` Thomas Monjalon
2021-06-08  4:10                                     ` Jerin Jacob
2021-06-08  6:34                                       ` Thomas Monjalon
2021-06-08  7:09                                         ` Jerin Jacob
2021-06-08  7:32                                           ` Thomas Monjalon
2021-06-15 18:24                                         ` Ferruh Yigit
2021-06-15 18:54                                           ` Thomas Monjalon
2021-06-07 23:31                                   ` Honnappa Nagarahalli
2021-06-04  5:51 ` Wang, Haiyue
2021-06-04  8:15   ` Thomas Monjalon
2021-06-04 11:07 ` Wang, Haiyue
2021-06-04 12:43   ` Thomas Monjalon
2021-06-04 13:25     ` Wang, Haiyue
2021-06-04 14:06       ` Thomas Monjalon
2021-06-04 18:04         ` Wang, Haiyue
2021-06-05  7:49           ` Thomas Monjalon
2021-06-05 11:09             ` Wang, Haiyue
2021-06-06  1:10 ` Honnappa Nagarahalli
2021-06-07 10:50   ` Thomas Monjalon
2021-07-30 13:55 ` [dpdk-dev] [RFC PATCH v2 0/7] heterogeneous computing library Thomas Monjalon
2021-07-30 13:55   ` [dpdk-dev] [RFC PATCH v2 1/7] hcdev: introduce heterogeneous computing device library Thomas Monjalon
2021-07-30 13:55   ` [dpdk-dev] [RFC PATCH v2 2/7] hcdev: add event notification Thomas Monjalon
2021-07-30 13:55   ` [dpdk-dev] [RFC PATCH v2 3/7] hcdev: add child device representing a device context Thomas Monjalon
2021-07-30 13:55   ` [dpdk-dev] [RFC PATCH v2 4/7] hcdev: support multi-process Thomas Monjalon
2021-07-30 13:55   ` [dpdk-dev] [RFC PATCH v2 5/7] hcdev: add memory API Thomas Monjalon
2021-07-30 13:55   ` [dpdk-dev] [RFC PATCH v2 6/7] hcdev: add communication flag Thomas Monjalon
2021-07-30 13:55   ` [dpdk-dev] [RFC PATCH v2 7/7] hcdev: add communication list Thomas Monjalon
2021-07-31  7:06   ` [dpdk-dev] [RFC PATCH v2 0/7] heterogeneous computing library Jerin Jacob
2021-07-31  8:21     ` Thomas Monjalon
2021-07-31 13:42       ` Jerin Jacob
2021-08-27  9:44         ` Thomas Monjalon
2021-08-27 12:19           ` Jerin Jacob
2021-08-29  5:32             ` Wang, Haiyue
2021-09-01 15:35               ` Elena Agostini
2021-09-02 13:12                 ` Jerin Jacob
2021-09-06 16:11                   ` Elena Agostini
2021-09-06 17:15                     ` Wang, Haiyue
2021-09-06 17:22                       ` Elena Agostini
2021-09-07  0:55                         ` Wang, Haiyue
2021-10-09  1:53 ` [dpdk-dev] [PATCH v3 0/9] GPU library eagostini
2021-10-09  1:53   ` [dpdk-dev] [PATCH v3 1/9] gpudev: introduce GPU device class library eagostini
2021-10-09  1:53   ` [dpdk-dev] [PATCH v3 2/9] gpudev: add event notification eagostini
2021-10-09  1:53   ` [dpdk-dev] [PATCH v3 3/9] gpudev: add child device representing a device context eagostini
2021-10-09  1:53   ` [dpdk-dev] [PATCH v3 4/9] gpudev: support multi-process eagostini
2021-10-09  1:53   ` [dpdk-dev] [PATCH v3 5/9] gpudev: add memory API eagostini
2021-10-08 20:18     ` Thomas Monjalon
2021-10-29 19:38     ` Mattias Rönnblom
2021-11-08 15:16       ` Elena Agostini
2021-10-09  1:53   ` [dpdk-dev] [PATCH v3 6/9] gpudev: add memory barrier eagostini
2021-10-08 20:16     ` Thomas Monjalon
2021-10-09  1:53   ` [dpdk-dev] [PATCH v3 7/9] gpudev: add communication flag eagostini
2021-10-09  1:53   ` [dpdk-dev] [PATCH v3 8/9] gpudev: add communication list eagostini
2021-10-09  1:53   ` [dpdk-dev] [PATCH v3 9/9] doc: add CUDA example in GPU guide eagostini
2021-10-10 10:16   ` [dpdk-dev] [PATCH v3 0/9] GPU library Jerin Jacob
2021-10-11  8:18     ` Thomas Monjalon
2021-10-11  8:43       ` Jerin Jacob
2021-10-11  9:12         ` Thomas Monjalon
2021-10-11  9:29           ` Jerin Jacob
2021-10-11 10:27             ` Thomas Monjalon
2021-10-11 11:41               ` Jerin Jacob
2021-10-11 12:44                 ` Thomas Monjalon
2021-10-11 13:30                   ` Jerin Jacob
2021-10-19 10:00                     ` Elena Agostini
2021-10-19 18:47                       ` Jerin Jacob
2021-10-19 19:11                         ` Thomas Monjalon
2021-10-19 19:56                           ` [dpdk-dev] [EXT] " Jerin Jacob Kollanukkaran
2021-11-03 19:15 ` [dpdk-dev] [PATCH v4 " eagostini
2021-11-03 19:15   ` [dpdk-dev] [PATCH v4 1/9] gpudev: introduce GPU device class library eagostini
2021-11-03 19:15   ` [dpdk-dev] [PATCH v4 2/9] gpudev: add event notification eagostini
2021-11-03 19:15   ` [dpdk-dev] [PATCH v4 3/9] gpudev: add child device representing a device context eagostini
2021-11-03 19:15   ` [dpdk-dev] [PATCH v4 4/9] gpudev: support multi-process eagostini
2021-11-03 19:15   ` [dpdk-dev] [PATCH v4 5/9] gpudev: add memory API eagostini
2021-11-03 19:15   ` [dpdk-dev] [PATCH v4 6/9] gpudev: add memory barrier eagostini
2021-11-03 19:15   ` [dpdk-dev] [PATCH v4 7/9] gpudev: add communication flag eagostini
2021-11-03 19:15   ` [dpdk-dev] [PATCH v4 8/9] gpudev: add communication list eagostini
2021-11-03 19:15   ` [dpdk-dev] [PATCH v4 9/9] doc: add CUDA example in GPU guide eagostini
2021-11-08 18:57 ` [dpdk-dev] [PATCH v5 0/9] GPU library eagostini
2021-11-08 16:25   ` Thomas Monjalon
2021-11-08 18:57   ` eagostini [this message]
2021-11-08 18:57   ` [dpdk-dev] [PATCH v5 2/9] gpudev: add event notification eagostini
2021-11-08 18:57   ` [dpdk-dev] [PATCH v5 3/9] gpudev: add child device representing a device context eagostini
2021-11-08 18:58   ` [dpdk-dev] [PATCH v5 4/9] gpudev: support multi-process eagostini
2021-11-08 18:58   ` [dpdk-dev] [PATCH v5 5/9] gpudev: add memory API eagostini
2021-11-08 18:58   ` [dpdk-dev] [PATCH v5 6/9] gpudev: add memory barrier eagostini
2021-11-08 18:58   ` [dpdk-dev] [PATCH v5 7/9] gpudev: add communication flag eagostini
2021-11-08 18:58   ` [dpdk-dev] [PATCH v5 8/9] gpudev: add communication list eagostini
2021-11-08 18:58   ` [dpdk-dev] [PATCH v5 9/9] doc: add CUDA example in GPU guide eagostini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211108185805.3887-2-eagostini@nvidia.com \
    --to=eagostini@nvidia.com \
    --cc=dev@dpdk.org \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).