From patchwork Sat Oct 9 01:53:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elena Agostini X-Patchwork-Id: 100830 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 401F3A0C43; Fri, 8 Oct 2021 19:43:41 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 66A644068E; Fri, 8 Oct 2021 19:43:39 +0200 (CEST) Received: from NAM11-BN8-obe.outbound.protection.outlook.com (mail-bn8nam11on2044.outbound.protection.outlook.com [40.107.236.44]) by mails.dpdk.org (Postfix) with ESMTP id AA76D40688 for ; Fri, 8 Oct 2021 19:43:38 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=dUGihQhJ0aTg917YtyYPHM7HrzHXdzOWXuOkmjrRWtZGID2js6eB08JgPetgfV0KHrnpP/jvSEQo7ATdUlmR9psXkQ+1b2EDvWQ6OA4yaD/m09GMTTB3xK3DrPZXX6eKbFFFU3I3qaeG8Hy380a6utEjxozWRW1kJMnUgitanXgsjQdzDJpi7fiCA7TJnPolVhfJaIUOU7AqucuNgNHJVo+6HFa6AXf9TU6XaNYOfgdhgvW9XHnl+wJd1bJFwg0JV1Xp/hdVX74BaVZZzfvIhINuFMWuwacJ63U3AfPToqO9vpBDMZ4KGI/mrnkHViMNt99po0ohNNYA4kCibShzag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=LAOG65KpiXFHo3MVhIuify1dngONuJ/YFXEGKqz5zaw=; b=fWzKwwu+wdSFgP8UhqBazwlP0Xl/9o6RFrQ7gw6R5SArg9qp4+Mjlz8G2IOqPy9MSadoM6Uj+KhbUvE6En+/+N6XyIKHwh2oKIRkLd8GzSaBAWJETQdgQ1odIkAnnXqy0RvmhgZhD0E6nrw8098CuTcYp5Q/32JzylHad9ofNjhZTgIabYfUDbUMTrymd4cBqiZb7ziQUE1b0nqVj1Z95hQ4VjnszKtmLKP4B4GP2ZIM+Bo0xZ0VxQdhihlKCSCwehdTpbORi/PP7FQ7IzkXza0nQ8yhxXOBWtcOqIKZ9tqHQ0Xy3I1WvDEwsNGI9o+2EbahMS1ACVaKQcUTiPxLTg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=monjalon.net smtp.mailfrom=nvidia.com; dmarc=pass (p=quarantine sp=none pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=LAOG65KpiXFHo3MVhIuify1dngONuJ/YFXEGKqz5zaw=; b=GrLAO90KFcX3OXqYddPnb9j42yhPIj0ppv8dEnoWeHyLqmX1ffxGE3BBp2tLRpgFnHJoXsQiFInJNDJb7mTbKul4Zl9PJ5PjylKnOpkA9945aTbbH2FaVKyPGUkeZ6V+pSNVn1dPFNPYfs6Hz0v+6+g/IY4j6/qeJs8TqkFhcrTdsHbWIu8BUqnBt//cbNC71DJp3drckh4GxMzVcuXdTR0p6RI0V2tEmG3iWVfICH9YAhK11e9V1/TlhelIMVWLXf5vMeVRYqroVhbmErRrNPvZfYfh5FvQjZQntIIU766VZU2sFLo/gqEOeX4l/1FHDUS14zT/RJVyEaMVb9HP3Q== Received: from MW4PR03CA0142.namprd03.prod.outlook.com (2603:10b6:303:8c::27) by MWHPR12MB1214.namprd12.prod.outlook.com (2603:10b6:300:e::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.22; Fri, 8 Oct 2021 17:43:36 +0000 Received: from CO1NAM11FT047.eop-nam11.prod.protection.outlook.com (2603:10b6:303:8c:cafe::26) by MW4PR03CA0142.outlook.office365.com (2603:10b6:303:8c::27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:36 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; monjalon.net; dkim=none (message not signed) header.d=none;monjalon.net; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by CO1NAM11FT047.mail.protection.outlook.com (10.13.174.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:35 +0000 Received: from nvidia.com (172.20.187.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Fri, 8 Oct 2021 17:43:30 +0000 From: To: CC: Elena Agostini , Thomas Monjalon Date: Sat, 9 Oct 2021 01:53:41 +0000 Message-ID: <20211009015349.9694-2-eagostini@nvidia.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211009015349.9694-1-eagostini@nvidia.com> References: <20210602203531.2288645-1-thomas@monjalon.net> <20211009015349.9694-1-eagostini@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [172.20.187.6] X-ClientProxiedBy: HQMAIL111.nvidia.com (172.20.187.18) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 19d9c58d-270b-4991-9e53-08d98a8327b3 X-MS-TrafficTypeDiagnostic: MWHPR12MB1214: X-LD-Processed: 43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:1824; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Yt93708i3Gv1tlLE/h9h5V0rBa7yaQAtxomtTvfehgrd+8Z05h5DRWOJVjUjzJDf7+W76jLgL5mqsRxa5U4GWEg9nyn1aEpirezmT5nbuOTAZ4YZQ4Ip4G31rLsI+1of/kcj+GNaAi93MPAs9+2fgjQGaA2/Ihpom8AcVwRhj4gnzylgjbkRVMb6INoROALCDu6w56bBquLq/Pl+2oEKyD8FYhQoYus3VHL8Pxv2KPysqfyx7zB6mgT67uasCL6m8q/nytJnHGxaurfygD+I6RKX9Qfyy2fK2p3fto6StnWHh38TN8V3eLFzMug/py2XdLPB8Abf9cW1JIsnKvihT9+FSo++kdJqseD5f3yl8Z5wE77udnqzxxUrWAF/k4rmnM24EkG2v+pMiKvfoXsx8gSmajel8RAVbJ0+Otm+1/QJqS6wqUvFNNea0B0q9zfevnZZsASicJI6eBuA5nBE10LseP7e0dioDWHV3Ma4R4suOGMuMfHjdxDlP7pNfhjIgRf5YDWv9ZcI7L0DdndBPIg6sQ63QtlzBWPKdCoYl6toGUIjJDf+MTRkNO/nye9rT8MnPKtOOgiGZl0IyfkzT2N0/ilPD8pCH7EjME3hRSnnGwHnhqZTj96jkNCmEAMojENGqyLGwJLnDfiaguQzDXVIIZxVgg+4YYkzP77ErJ/mIsOOfvE2HnHtrEjGo6yUrv5a27tAUe0WbwNrNdiqMg== X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(36840700001)(46966006)(36756003)(86362001)(83380400001)(6286002)(47076005)(82310400003)(55016002)(336012)(36860700001)(356005)(54906003)(1076003)(7636003)(426003)(2906002)(7696005)(316002)(2876002)(4326008)(5660300002)(6666004)(26005)(508600001)(70206006)(70586007)(6916009)(186003)(8936002)(16526019)(8676002)(30864003)(2616005); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Oct 2021 17:43:35.9718 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 19d9c58d-270b-4991-9e53-08d98a8327b3 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: CO1NAM11FT047.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR12MB1214 Subject: [dpdk-dev] [PATCH v3 1/9] gpudev: introduce GPU device class library X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Elena Agostini 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 Signed-off-by: Thomas Monjalon --- .gitignore | 1 + MAINTAINERS | 6 + app/meson.build | 1 + app/test-gpudev/main.c | 107 +++++++++++ app/test-gpudev/meson.build | 5 + doc/api/doxy-api-index.md | 1 + 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 + 23 files changed, 723 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 b19c0717e6..49494e0c6c 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,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 278e5b3226..b61ad61ee2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -454,6 +454,12 @@ F: app/test-regex/ F: doc/guides/prog_guide/regexdev.rst F: doc/guides/regexdevs/features/default.ini +General-Purpose Graphics Processing Unit (GPU) API - EXPERIMENTAL +M: Elena Agostini +F: lib/gpudev/ +F: doc/guides/prog_guide/gpudev.rst +F: doc/guides/gpus/features/default.ini + Eventdev API M: Jerin Jacob T: git://dpdk.org/next/dpdk-next-eventdev diff --git a/app/meson.build b/app/meson.build index 4c6049807c..42bca044e0 100644 --- a/app/meson.build +++ b/app/meson.build @@ -12,6 +12,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..6a73a54e84 --- /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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +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-index.md b/doc/api/doxy-api-index.md index 1992107a03..bd10342ca2 100644 --- a/doc/api/doxy-api-index.md +++ b/doc/api/doxy-api-index.md @@ -21,6 +21,7 @@ The public API headers are grouped by topics: [compressdev] (@ref rte_compressdev.h), [compress] (@ref rte_comp.h), [regexdev] (@ref rte_regexdev.h), + [gpudev] (@ref rte_gpudev.h), [eventdev] (@ref rte_eventdev.h), [event_eth_rx_adapter] (@ref rte_event_eth_rx_adapter.h), [event_eth_tx_adapter] (@ref rte_event_eth_tx_adapter.h), diff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in index 325a0195c6..831b9a6b33 100644 --- a/doc/api/doxy-api.conf.in +++ b/doc/api/doxy-api.conf.in @@ -40,6 +40,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 67d2dd62c7..7930da9ceb 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)) @@ -388,6 +391,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 857f0363d3..ee4d79a4eb 100644 --- a/doc/guides/index.rst +++ b/doc/guides/index.rst @@ -21,6 +21,7 @@ DPDK documentation compressdevs/index vdpadevs/index regexdevs/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 2dce507f46..e49a09a07a 100644 --- a/doc/guides/prog_guide/index.rst +++ b/doc/guides/prog_guide/index.rst @@ -27,6 +27,7 @@ Programmer's Guide cryptodev_lib compressdev regexdev + 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 c0a7f75518..4986a35b50 100644 --- a/doc/guides/rel_notes/release_21_11.rst +++ b/doc/guides/rel_notes/release_21_11.rst @@ -62,6 +62,10 @@ New Features * Added bus-level parsing of the devargs syntax. * Kept compatibility with the legacy syntax as parsing fallback. +* **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 3d08540581..be2d78ffd5 100644 --- a/drivers/meson.build +++ b/drivers/meson.build @@ -18,6 +18,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..c839c530c8 --- /dev/null +++ b/lib/gpudev/gpudev.c @@ -0,0 +1,249 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 NVIDIA Corporation & Affiliates + */ + +#include +#include +#include +#include + +#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 + +#include + +#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 +#include +#include + +#include + +/** + * @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 b2ba7258d8..029298842a 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -33,6 +33,7 @@ libraries = [ 'distributor', 'efd', 'eventdev', + 'gpudev', 'gro', 'gso', 'ip_frag', From patchwork Sat Oct 9 01:53:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elena Agostini X-Patchwork-Id: 100834 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 86B8AA0C43; Fri, 8 Oct 2021 19:44:13 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2E7CF41121; Fri, 8 Oct 2021 19:43:46 +0200 (CEST) Received: from NAM12-BN8-obe.outbound.protection.outlook.com (mail-bn8nam12on2054.outbound.protection.outlook.com [40.107.237.54]) by mails.dpdk.org (Postfix) with ESMTP id 4FD42407FF for ; Fri, 8 Oct 2021 19:43:43 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Sln2hejquHLCf4AG1kzj+sqYgMOzmqMJDrw8zE24e82+qJq6KVBOSOg1nciJj5OGSy1vZOZ2EfxOiTzPtJ7H66n/TlDqyR/lV3fmAF2Y2f2m3waoeegguw9uDRyuRpSz2nY6sBa7Yrn3+jZop9AuxWOV/hInv7gW0GyQcsSCyLM0cE4glfjyRJ4PpUgi4AvTBb5oKKSA2Q1tudupJfBMxP8QM/JA073JlOS0IRzKD/ojMNh24uXbO5zhQEwkaQUySauEiiEXECa0ZOowEMvZzN60WAFSKzi7uruzxtKgQOmNUyfNQHIF9Oq2p7wxURxDIF0cNq5lFgL5fubCv+Unfw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=2TJJfWuag8aNaZVVL61bL7JJLJN39ujkKZD8whqRu/U=; b=EF4OZ0t9lJkNVVpRv3bS4EvkXKNOniIGgSUexlHV+icd0fhFEyUzQ0layBmRXICFdCz8YqRsh5hmWQ6EkZJk7U5YArwNiFlx8Xj9AwviPQNWCzV2wekfO+7PjSfqSX5QvfX3NYkpL5YfJ1pvQeMlto6xc87/6IKpXXL+r4eKQ644mkS+YEU9eKp/sbaOwC8lBciAsXEo0/JqtyrznYq198txaEhk6D8b7c6q+BVCV2WLflGtJFX9qmjiT3L+HeHMCklxnd+5HlUgrMEVUEG/pTWCC2li0o6KFKcnkrJkw5UxpPjqiWakZziiwJcyFQx+8FyIjN8cJ/VobOEvnhK00g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=monjalon.net smtp.mailfrom=nvidia.com; dmarc=pass (p=quarantine sp=none pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=2TJJfWuag8aNaZVVL61bL7JJLJN39ujkKZD8whqRu/U=; b=X2XLty+PQe1/BQDZDKnYjnNOK0nD2xXhYDRDkqjr0Qrnl4lOUQZnpAZ5h9LS3Os6vjhxZePKY139DGxJhd9iJKUUHBvLz6YBcIKMMlc4ffsLu0hdY9jLNsXrbbnunLs8siMrkfv9yYhpfUkJMdeM1dSr0/ETs0pRoWRJdp+bA9HoKbBg6HZqUAextIFsqQ2sLaFpV9xjDmqzqpoPKmwqMWfD7qWLQ+d5K8vB6gPLW0v+iuT82UJKVsjLKdcuDaW0AWvXcarvxGO1/TNjTsxNOO/BzFpjvN51IaYhfw4uHVW2UOGz0egxYb6A+KVzxq2OBVDIQPgq7QZr7Vr9ngjpbg== Received: from MW4PR03CA0126.namprd03.prod.outlook.com (2603:10b6:303:8c::11) by SN1PR12MB2399.namprd12.prod.outlook.com (2603:10b6:802:2b::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.22; Fri, 8 Oct 2021 17:43:37 +0000 Received: from CO1NAM11FT047.eop-nam11.prod.protection.outlook.com (2603:10b6:303:8c:cafe::21) by MW4PR03CA0126.outlook.office365.com (2603:10b6:303:8c::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4566.19 via Frontend Transport; Fri, 8 Oct 2021 17:43:37 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; monjalon.net; dkim=none (message not signed) header.d=none;monjalon.net; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by CO1NAM11FT047.mail.protection.outlook.com (10.13.174.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:37 +0000 Received: from nvidia.com (172.20.187.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Fri, 8 Oct 2021 17:43:32 +0000 From: To: CC: Thomas Monjalon Date: Sat, 9 Oct 2021 01:53:42 +0000 Message-ID: <20211009015349.9694-3-eagostini@nvidia.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211009015349.9694-1-eagostini@nvidia.com> References: <20210602203531.2288645-1-thomas@monjalon.net> <20211009015349.9694-1-eagostini@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [172.20.187.6] X-ClientProxiedBy: HQMAIL111.nvidia.com (172.20.187.18) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 25ee5b00-58f6-4689-2a63-08d98a832873 X-MS-TrafficTypeDiagnostic: SN1PR12MB2399: X-LD-Processed: 43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:8273; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: p0JBoTP2vJ9LjLHM8gHqoQ02ryEeoI5ffFf+3NN5wu1Yy67rnPzm0y+pkO9T9FF3I0wCTdhmWk9shtAe0RxEhwQASED7obuevSPkS/MqA1NcsJ6Ck3cjNxxzMvd3L7asLycl9A0XhMs/lRvbArO5TjxVkC/8ft7CgnJJ356QvbJUSFtJW59KyCyZRwIV5gbwBf9aedWxi0qiIp/BYDDiuvKIHZNO6H6VIBDJOMCYH63UwcMpiqvsTwxGrBPRWW8qtzpEz+idMB9raPxNFv+0dBg/tMlwvdcUo/Ga7mAh5fjk8yYGTuCk3g9t08QJkgShsR8o9V9GsRORG5ATPqCNlui7Y+2zNJefSlqIvEl2wIQhjsCkdbZoW/BtE1wJZ5aipALHsUIGSVcJhiPsuUxffZkNtgMdehQVFJ1/lgpimXYeq15EW3erBnnnH+npLRZVGV49V+yGakWc5YD8ukUrhUSlf2ejeCQEkVZLu2mZ2eSACv8Y5yu8jJNe5HBkdKilwXTKy+RD5pcAxpIAQF+RAhK6OuVQZk1VkNhnbKyYIvTRqJUzCAIeAzcU0wWpC2UXdFF0SSdOsaTlY1KEcu+Ny1U1150/pxyUw8LMSDLOgEXRmEKEzfS7HnBtKbMzL0LP0fJ2iDzuuc2qZe/n36oFnv0Sf0kmVqrt24hjn8mFH1zu+thNE6qu7ppucekOOBnZz/Y0ZpPK76kc+KnoyHEXqg== X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(36840700001)(46966006)(16526019)(26005)(83380400001)(8676002)(4326008)(7636003)(186003)(55016002)(70206006)(70586007)(508600001)(6286002)(356005)(47076005)(2616005)(2876002)(1076003)(86362001)(7696005)(336012)(82310400003)(8936002)(36860700001)(36756003)(316002)(5660300002)(6666004)(426003)(15650500001)(2906002)(6916009); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Oct 2021 17:43:37.2461 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 25ee5b00-58f6-4689-2a63-08d98a832873 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: CO1NAM11FT047.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR12MB2399 Subject: [dpdk-dev] [PATCH v3 2/9] gpudev: add event notification X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Thomas Monjalon Callback functions may be registered for a device event. Callback management is per-process and not thread-safe. The events RTE_GPU_EVENT_NEW and RTE_GPU_EVENT_DEL are notified respectively after creation and before removal of a device, as part of the library functions. Some future events may be emitted from drivers. Signed-off-by: Thomas Monjalon --- lib/gpudev/gpudev.c | 148 +++++++++++++++++++++++++++++++++++++ lib/gpudev/gpudev_driver.h | 7 ++ lib/gpudev/rte_gpudev.h | 70 ++++++++++++++++++ lib/gpudev/version.map | 3 + 4 files changed, 228 insertions(+) diff --git a/lib/gpudev/gpudev.c b/lib/gpudev/gpudev.c index c839c530c8..d57e23df7c 100644 --- a/lib/gpudev/gpudev.c +++ b/lib/gpudev/gpudev.c @@ -3,6 +3,7 @@ */ #include +#include #include #include #include @@ -27,6 +28,16 @@ static int16_t gpu_max; /* Number of currently valid devices */ static int16_t gpu_count; +/* Event callback object */ +struct rte_gpu_callback { + TAILQ_ENTRY(rte_gpu_callback) next; + rte_gpu_callback_t *function; + void *user_data; + enum rte_gpu_event event; +}; +static rte_rwlock_t gpu_callback_lock = RTE_RWLOCK_INITIALIZER; +static void gpu_free_callbacks(struct rte_gpu *dev); + int rte_gpu_init(size_t dev_max) { @@ -166,6 +177,7 @@ rte_gpu_allocate(const char *name) dev->info.name = dev->name; dev->info.dev_id = dev_id; dev->info.numa_node = -1; + TAILQ_INIT(&dev->callbacks); gpu_count++; GPU_LOG(DEBUG, "new device %s (id %d) of total %d", @@ -180,6 +192,8 @@ rte_gpu_complete_new(struct rte_gpu *dev) return; dev->state = RTE_GPU_STATE_INITIALIZED; + dev->state = RTE_GPU_STATE_INITIALIZED; + rte_gpu_notify(dev, RTE_GPU_EVENT_NEW); } int @@ -192,6 +206,9 @@ rte_gpu_release(struct rte_gpu *dev) GPU_LOG(DEBUG, "free device %s (id %d)", dev->info.name, dev->info.dev_id); + rte_gpu_notify(dev, RTE_GPU_EVENT_DEL); + + gpu_free_callbacks(dev); dev->state = RTE_GPU_STATE_UNUSED; gpu_count--; @@ -224,6 +241,137 @@ rte_gpu_close(int16_t dev_id) return firsterr; } +int +rte_gpu_callback_register(int16_t dev_id, enum rte_gpu_event event, + rte_gpu_callback_t *function, void *user_data) +{ + int16_t next_dev, last_dev; + struct rte_gpu_callback_list *callbacks; + struct rte_gpu_callback *callback; + + if (!rte_gpu_is_valid(dev_id) && dev_id != RTE_GPU_ID_ANY) { + GPU_LOG(ERR, "register callback of invalid ID %d", dev_id); + rte_errno = ENODEV; + return -rte_errno; + } + if (function == NULL) { + GPU_LOG(ERR, "cannot register callback without function"); + rte_errno = EINVAL; + return -rte_errno; + } + + if (dev_id == RTE_GPU_ID_ANY) { + next_dev = 0; + last_dev = gpu_max - 1; + } else { + next_dev = last_dev = dev_id; + } + + rte_rwlock_write_lock(&gpu_callback_lock); + do { + callbacks = &gpus[next_dev].callbacks; + + /* check if not already registered */ + TAILQ_FOREACH(callback, callbacks, next) { + if (callback->event == event && + callback->function == function && + callback->user_data == user_data) { + GPU_LOG(INFO, "callback already registered"); + return 0; + } + } + + callback = malloc(sizeof(*callback)); + if (callback == NULL) { + GPU_LOG(ERR, "cannot allocate callback"); + return -ENOMEM; + } + callback->function = function; + callback->user_data = user_data; + callback->event = event; + TAILQ_INSERT_TAIL(callbacks, callback, next); + + } while (++next_dev <= last_dev); + rte_rwlock_write_unlock(&gpu_callback_lock); + + return 0; +} + +int +rte_gpu_callback_unregister(int16_t dev_id, enum rte_gpu_event event, + rte_gpu_callback_t *function, void *user_data) +{ + int16_t next_dev, last_dev; + struct rte_gpu_callback_list *callbacks; + struct rte_gpu_callback *callback, *nextcb; + + if (!rte_gpu_is_valid(dev_id) && dev_id != RTE_GPU_ID_ANY) { + GPU_LOG(ERR, "unregister callback of invalid ID %d", dev_id); + rte_errno = ENODEV; + return -rte_errno; + } + if (function == NULL) { + GPU_LOG(ERR, "cannot unregister callback without function"); + rte_errno = EINVAL; + return -rte_errno; + } + + if (dev_id == RTE_GPU_ID_ANY) { + next_dev = 0; + last_dev = gpu_max - 1; + } else { + next_dev = last_dev = dev_id; + } + + rte_rwlock_write_lock(&gpu_callback_lock); + do { + callbacks = &gpus[next_dev].callbacks; + RTE_TAILQ_FOREACH_SAFE(callback, callbacks, next, nextcb) { + if (callback->event != event || + callback->function != function || + (callback->user_data != user_data && + user_data != (void *)-1)) + continue; + TAILQ_REMOVE(callbacks, callback, next); + free(callback); + } + } while (++next_dev <= last_dev); + rte_rwlock_write_unlock(&gpu_callback_lock); + + return 0; +} + +static void +gpu_free_callbacks(struct rte_gpu *dev) +{ + struct rte_gpu_callback_list *callbacks; + struct rte_gpu_callback *callback, *nextcb; + + callbacks = &dev->callbacks; + rte_rwlock_write_lock(&gpu_callback_lock); + RTE_TAILQ_FOREACH_SAFE(callback, callbacks, next, nextcb) { + TAILQ_REMOVE(callbacks, callback, next); + free(callback); + } + rte_rwlock_write_unlock(&gpu_callback_lock); +} + +void +rte_gpu_notify(struct rte_gpu *dev, enum rte_gpu_event event) +{ + int16_t dev_id; + struct rte_gpu_callback *callback; + + dev_id = dev->info.dev_id; + rte_rwlock_read_lock(&gpu_callback_lock); + TAILQ_FOREACH(callback, &dev->callbacks, next) { + if (callback->event != event || callback->function == NULL) + continue; + callback->function(dev_id, event, callback->user_data); + } + rte_rwlock_read_unlock(&gpu_callback_lock); +} + int rte_gpu_info_get(int16_t dev_id, struct rte_gpu_info *info) { diff --git a/lib/gpudev/gpudev_driver.h b/lib/gpudev/gpudev_driver.h index 9e096e3b64..2a7089aa52 100644 --- a/lib/gpudev/gpudev_driver.h +++ b/lib/gpudev/gpudev_driver.h @@ -12,6 +12,7 @@ #define RTE_GPUDEV_DRIVER_H #include +#include #include @@ -43,6 +44,8 @@ struct rte_gpu { struct rte_gpu_info info; /* Driver functions. */ struct rte_gpu_ops ops; + /* Event callback list. */ + TAILQ_HEAD(rte_gpu_callback_list, rte_gpu_callback) callbacks; /* 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. */ @@ -64,4 +67,8 @@ void rte_gpu_complete_new(struct rte_gpu *dev); __rte_internal int rte_gpu_release(struct rte_gpu *dev); +/* Call registered callbacks. No multi-process event. */ +__rte_internal +void rte_gpu_notify(struct rte_gpu *dev, enum rte_gpu_event); + #endif /* RTE_GPUDEV_DRIVER_H */ diff --git a/lib/gpudev/rte_gpudev.h b/lib/gpudev/rte_gpudev.h index eb7cfa8c59..e1702fbfe4 100644 --- a/lib/gpudev/rte_gpudev.h +++ b/lib/gpudev/rte_gpudev.h @@ -31,6 +31,11 @@ extern "C" { /** Empty device ID. */ #define RTE_GPU_ID_NONE -1 +/** Catch-all device ID. */ +#define RTE_GPU_ID_ANY INT16_MIN + +/** Catch-all callback data. */ +#define RTE_GPU_CALLBACK_ANY_DATA ((void *)-1) /** Store device info. */ struct rte_gpu_info { @@ -46,6 +51,18 @@ struct rte_gpu_info { int16_t numa_node; }; +/** Flags passed in notification callback. */ +enum rte_gpu_event { + /** Device is just initialized. */ + RTE_GPU_EVENT_NEW, + /** Device is going to be released. */ + RTE_GPU_EVENT_DEL, +}; + +/** Prototype of event callback function. */ +typedef void (rte_gpu_callback_t)(int16_t dev_id, + enum rte_gpu_event event, void *user_data); + /** * @warning * @b EXPERIMENTAL: this API may change without prior notice. @@ -141,6 +158,59 @@ int16_t rte_gpu_find_next(int16_t dev_id); __rte_experimental int rte_gpu_close(int16_t dev_id); +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Register a function as event callback. + * A function may be registered multiple times for different events. + * + * @param dev_id + * Device ID to get notified about. + * RTE_GPU_ID_ANY means all devices. + * @param event + * Device event to be registered for. + * @param function + * Callback function to be called on event. + * @param user_data + * Optional parameter passed in the callback. + * + * @return + * 0 on success, -rte_errno otherwise: + * - ENODEV if invalid dev_id + * - EINVAL if NULL function + * - ENOMEM if out of memory + */ +__rte_experimental +int rte_gpu_callback_register(int16_t dev_id, enum rte_gpu_event event, + rte_gpu_callback_t *function, void *user_data); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Unregister for an event. + * + * @param dev_id + * Device ID to be silenced. + * RTE_GPU_ID_ANY means all devices. + * @param event + * Registered event. + * @param function + * Registered function. + * @param user_data + * Optional parameter as registered. + * RTE_GPU_CALLBACK_ANY_DATA is a catch-all. + * + * @return + * 0 on success, -rte_errno otherwise: + * - ENODEV if invalid dev_id + * - EINVAL if NULL function + */ +__rte_experimental +int rte_gpu_callback_unregister(int16_t dev_id, enum rte_gpu_event event, + rte_gpu_callback_t *function, void *user_data); + /** * @warning * @b EXPERIMENTAL: this API may change without prior notice. diff --git a/lib/gpudev/version.map b/lib/gpudev/version.map index 6ac6b327e2..b3b6b76c1c 100644 --- a/lib/gpudev/version.map +++ b/lib/gpudev/version.map @@ -2,6 +2,8 @@ EXPERIMENTAL { global: # added in 21.11 + rte_gpu_callback_register; + rte_gpu_callback_unregister; rte_gpu_close; rte_gpu_count_avail; rte_gpu_find_next; @@ -16,5 +18,6 @@ INTERNAL { rte_gpu_allocate; rte_gpu_complete_new; rte_gpu_get_by_name; + rte_gpu_notify; rte_gpu_release; }; From patchwork Sat Oct 9 01:53:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elena Agostini X-Patchwork-Id: 100831 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 10358A0C43; Fri, 8 Oct 2021 19:43:50 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C9180410EA; Fri, 8 Oct 2021 19:43:41 +0200 (CEST) Received: from NAM12-BN8-obe.outbound.protection.outlook.com (mail-bn8nam12on2041.outbound.protection.outlook.com [40.107.237.41]) by mails.dpdk.org (Postfix) with ESMTP id 79FFF410DB for ; Fri, 8 Oct 2021 19:43:40 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Mlu3zD0Ka33eielUZsyJsdwtzPAapmx1dhTTwpAo2ThubjBuBli2H/jy58wACrz1NZUWFeAOdE27hc3lA2U1SwAGxsSqCCC+TFRP5ku6rT5v9ODXxe4JhqlQ6fFpiI6tUJe3UZLNGJvuvwe2R46H3jU48i1hFvJhvIwAmbA0KPep0GzpXrLX5KONlqOKIB2RTSz1SNPX1RhQHlVfDeZBReVGLkQfAvivHK+TL09oyztgblgbCJ3Ngtpv0Gu/ahRnanN+nt77WshMbUEEEquyTsuli84cyrjIjhWifjK3P3o9NBTD3W969WrhPytx1UYYYeA3RGsQl88NjZQs0SxItg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=jU6qN/2cZBay1ysZuzS9t+JNTNnvUCIuXrt06SvDRt4=; b=Ko1XKyvHU7/R/kDxPAz2YKUgoO+HXI+orwV93/BRxKWfjlDnjk/VVq03yApHnlb27yO9IdCB+OkK1NIfOkDgZJVPjfAv3BsGYdkg0j1zk5p2Jar/C5IGFyyIycCZY5uOxFVdFLbpTACrgHDwuUcU95n1Pz00CvYbC3u7AW3CAkOSR0BxdTxqEGQEJeNbnnT81kPhDfnBqv519EN2KKPy99JGw7ydq5B9nnj4P2wf0YupwuyTi8DdO17KershUPZ3ye5mA8najAYN1mM00tiEyJkiiWSwyANATKCJCXo3Hld79zet27sgdKLWFOvmA/zNvV5RAk8BUmn90bTVNQC1PQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=monjalon.net smtp.mailfrom=nvidia.com; dmarc=pass (p=quarantine sp=none pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=jU6qN/2cZBay1ysZuzS9t+JNTNnvUCIuXrt06SvDRt4=; b=iziVPftoJ8CqWnNaDIKoYv6OqExRPgnojdSQcXQYNqkpr5tk5eXa8yziUG9Bnd6nKzt8NivFpi0HFczpdjtcJBb3nigiYdKRkzW7RqG3JBhybw70iy4zqn73TXcdgU8atnQYnSQ+Mx6WcJ60Mcy53jCPz9+zDOJIH9rwQXr2wO3P0rU0+FVFzrrtKTui/x7iIhADbFJGR5Ac7DNzl2fCPT9r4X1/1Ju2uBsbOp9qIvMSPCMnPvtuktKAE7GR/PyFY1cAQdr+FsaJAYdp4WJjVo7exXDlRHmwOouxKcqBgUHB4UBLqju2klICrhiDqqDZeC0652nhsS4OlOLeHwvZ0Q== Received: from MW4PR03CA0131.namprd03.prod.outlook.com (2603:10b6:303:8c::16) by DM4PR12MB5182.namprd12.prod.outlook.com (2603:10b6:5:395::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.18; Fri, 8 Oct 2021 17:43:39 +0000 Received: from CO1NAM11FT047.eop-nam11.prod.protection.outlook.com (2603:10b6:303:8c:cafe::fc) by MW4PR03CA0131.outlook.office365.com (2603:10b6:303:8c::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:39 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; monjalon.net; dkim=none (message not signed) header.d=none;monjalon.net; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by CO1NAM11FT047.mail.protection.outlook.com (10.13.174.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:38 +0000 Received: from nvidia.com (172.20.187.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Fri, 8 Oct 2021 17:43:34 +0000 From: To: CC: Thomas Monjalon Date: Sat, 9 Oct 2021 01:53:43 +0000 Message-ID: <20211009015349.9694-4-eagostini@nvidia.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211009015349.9694-1-eagostini@nvidia.com> References: <20210602203531.2288645-1-thomas@monjalon.net> <20211009015349.9694-1-eagostini@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [172.20.187.6] X-ClientProxiedBy: HQMAIL111.nvidia.com (172.20.187.18) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 9cfdf352-57f4-489c-cde3-08d98a83295c X-MS-TrafficTypeDiagnostic: DM4PR12MB5182: X-LD-Processed: 43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:6790; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 6FJa0P/CqhJMV+68EX22Z4zx6UkhywFpIBEvTTk69HiTQ7MZ0QM8+j40Dl+eJ/6ta9qWF0OYb2t7fn3bTdDA9dKYi2bjBBYoXEFZsdVIwfnB91GQ2N9n1n4WeXmWjb7WirgkjXPwwytXmzSCROPbfDxjomSv5P4njmxcPaayHAPIOqnPfkEVi16IPZp780bZKggdbWliNc5loBs/mdaYKQbSnUgnehMN0HPW2kxtBpnnYzccJbXT1wuok8sxOVtyfKJaSQANZHaWkbnHDiJCyYgNa/aPTG2b+8C2EGdJYxwKJvgdpRe4K93jQm+fAiF7OF1BLAB6ptdz6uWZxiv9bw10u2vV4YVnBcjxyEMoXfM3SCyYU1ofwGaO3Z9MaiAhfZZTDHY3tg/urnO8grVrqYXsaTQQk5Aoiat+ijBkKwCpWzyvJyquZ839Jq3cSo63/Fj2c0YFwKW7ZMeTc7gKs1fxLFPtFhbBSP/GE2IC/cliEVZwrp7hgeP5dpaIcc82UjUS7GvwGfyxXOFPGanIY7PGGIli4O/tOL25qacnbDGW1jhA6vb1YT2kBKxhXN4S6JgmwGWXJZlA436CXbFUxLHbAG22iQhmPilKCAEQoeicKPTBJB5nzfDpkX5QQZZN2C8x8qMzHnxg/8e58oC8Y0ytdtKw/pKndeINCGZvCWaKlN6I/kj9XdtkhrLz2AmCj29dgTyUgncpn39Cx+CmYQ== X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(46966006)(36840700001)(6916009)(1076003)(2616005)(4326008)(5660300002)(70586007)(70206006)(316002)(356005)(7696005)(6286002)(8936002)(8676002)(86362001)(426003)(186003)(16526019)(6666004)(36756003)(7636003)(508600001)(55016002)(26005)(2876002)(36860700001)(83380400001)(2906002)(336012)(82310400003)(47076005); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Oct 2021 17:43:38.7853 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 9cfdf352-57f4-489c-cde3-08d98a83295c X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: CO1NAM11FT047.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB5182 Subject: [dpdk-dev] [PATCH v3 3/9] gpudev: add child device representing a device context X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Thomas Monjalon The computing device may operate in some isolated contexts. Memory and processing are isolated in a silo represented by a child device. The context is provided as an opaque by the caller of rte_gpu_add_child(). Signed-off-by: Thomas Monjalon --- doc/guides/prog_guide/gpudev.rst | 12 ++++++ lib/gpudev/gpudev.c | 45 +++++++++++++++++++- lib/gpudev/gpudev_driver.h | 2 +- lib/gpudev/rte_gpudev.h | 71 +++++++++++++++++++++++++++++--- lib/gpudev/version.map | 1 + 5 files changed, 123 insertions(+), 8 deletions(-) diff --git a/doc/guides/prog_guide/gpudev.rst b/doc/guides/prog_guide/gpudev.rst index 6ea7239159..7694639489 100644 --- a/doc/guides/prog_guide/gpudev.rst +++ b/doc/guides/prog_guide/gpudev.rst @@ -34,3 +34,15 @@ This library provides a number of features: API Overview ------------ + +Child Device +~~~~~~~~~~~~ + +By default, DPDK PCIe module detects and registers physical GPU devices +in the system. +With the gpudev library is also possible to add additional non-physical devices +through an ``uint64_t`` generic handler (e.g. CUDA Driver context) +that will be registered internally by the driver as an additional device (child) +connected to a physical device (parent). +Each device (parent or child) is represented through a ID +required to indicate which device a given operation should be executed on. diff --git a/lib/gpudev/gpudev.c b/lib/gpudev/gpudev.c index d57e23df7c..74cdd7f20b 100644 --- a/lib/gpudev/gpudev.c +++ b/lib/gpudev/gpudev.c @@ -80,13 +80,22 @@ rte_gpu_is_valid(int16_t dev_id) return false; } +static bool +gpu_match_parent(int16_t dev_id, int16_t parent) +{ + if (parent == RTE_GPU_ID_ANY) + return true; + return gpus[dev_id].info.parent == parent; +} + int16_t -rte_gpu_find_next(int16_t dev_id) +rte_gpu_find_next(int16_t dev_id, int16_t parent) { if (dev_id < 0) dev_id = 0; while (dev_id < gpu_max && - gpus[dev_id].state == RTE_GPU_STATE_UNUSED) + (gpus[dev_id].state == RTE_GPU_STATE_UNUSED || + !gpu_match_parent(dev_id, parent))) dev_id++; if (dev_id >= gpu_max) @@ -177,6 +186,7 @@ rte_gpu_allocate(const char *name) dev->info.name = dev->name; dev->info.dev_id = dev_id; dev->info.numa_node = -1; + dev->info.parent = RTE_GPU_ID_NONE; TAILQ_INIT(&dev->callbacks); gpu_count++; @@ -185,6 +195,28 @@ rte_gpu_allocate(const char *name) return dev; } +int16_t +rte_gpu_add_child(const char *name, int16_t parent, uint64_t child_context) +{ + struct rte_gpu *dev; + + if (!rte_gpu_is_valid(parent)) { + GPU_LOG(ERR, "add child to invalid parent ID %d", parent); + rte_errno = ENODEV; + return -rte_errno; + } + + dev = rte_gpu_allocate(name); + if (dev == NULL) + return -rte_errno; + + dev->info.parent = parent; + dev->info.context = child_context; + + rte_gpu_complete_new(dev); + return dev->info.dev_id; +} + void rte_gpu_complete_new(struct rte_gpu *dev) { @@ -199,10 +231,19 @@ rte_gpu_complete_new(struct rte_gpu *dev) int rte_gpu_release(struct rte_gpu *dev) { + int16_t dev_id, child; + if (dev == NULL) { rte_errno = ENODEV; return -rte_errno; } + dev_id = dev->info.dev_id; + RTE_GPU_FOREACH_CHILD(child, dev_id) { + GPU_LOG(ERR, "cannot release device %d with child %d", + dev_id, child); + rte_errno = EBUSY; + return -rte_errno; + } GPU_LOG(DEBUG, "free device %s (id %d)", dev->info.name, dev->info.dev_id); diff --git a/lib/gpudev/gpudev_driver.h b/lib/gpudev/gpudev_driver.h index 2a7089aa52..4d0077161c 100644 --- a/lib/gpudev/gpudev_driver.h +++ b/lib/gpudev/gpudev_driver.h @@ -31,7 +31,7 @@ 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. */ + /* Close device or child context. */ rte_gpu_close_t *dev_close; }; diff --git a/lib/gpudev/rte_gpudev.h b/lib/gpudev/rte_gpudev.h index e1702fbfe4..df75dbdbab 100644 --- a/lib/gpudev/rte_gpudev.h +++ b/lib/gpudev/rte_gpudev.h @@ -41,8 +41,12 @@ extern "C" { struct rte_gpu_info { /** Unique identifier name. */ const char *name; + /** Opaque handler of the device context. */ + uint64_t context; /** Device ID. */ int16_t dev_id; + /** ID of the parent device, RTE_GPU_ID_NONE if no parent */ + int16_t parent; /** Total processors available on device. */ uint32_t processor_count; /** Total memory available on device. */ @@ -110,6 +114,33 @@ uint16_t rte_gpu_count_avail(void); __rte_experimental bool rte_gpu_is_valid(int16_t dev_id); +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Create a virtual device representing a context in the parent device. + * + * @param name + * Unique string to identify the device. + * @param parent + * Device ID of the parent. + * @param child_context + * Opaque context handler. + * + * @return + * Device ID of the new created child, -rte_errno otherwise: + * - EINVAL if empty name + * - ENAMETOOLONG if long name + * - EEXIST if existing device name + * - ENODEV if invalid parent + * - EPERM if secondary process + * - ENOENT if too many devices + * - ENOMEM if out of space + */ +__rte_experimental +int16_t rte_gpu_add_child(const char *name, + int16_t parent, uint64_t child_context); + /** * @warning * @b EXPERIMENTAL: this API may change without prior notice. @@ -118,13 +149,17 @@ bool rte_gpu_is_valid(int16_t dev_id); * * @param dev_id * The initial device ID to start the research. + * @param parent + * The device ID of the parent. + * RTE_GPU_ID_NONE means no parent. + * RTE_GPU_ID_ANY means no or any parent. * * @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); +int16_t rte_gpu_find_next(int16_t dev_id, int16_t parent); /** * @warning @@ -136,15 +171,41 @@ int16_t rte_gpu_find_next(int16_t 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)) + RTE_GPU_FOREACH_CHILD(dev_id, RTE_GPU_ID_ANY) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Macro to iterate over all valid computing devices having no parent. + * + * @param dev_id + * The ID of the next possible valid device, usually 0 to iterate all. + */ +#define RTE_GPU_FOREACH_PARENT(dev_id) \ + RTE_GPU_FOREACH_CHILD(dev_id, RTE_GPU_ID_NONE) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Macro to iterate over all valid children of a computing device parent. + * + * @param dev_id + * The ID of the next possible valid device, usually 0 to iterate all. + * @param parent + * The device ID of the parent. + */ +#define RTE_GPU_FOREACH_CHILD(dev_id, parent) \ + for (dev_id = rte_gpu_find_next(0, parent); \ + dev_id >= 0; \ + dev_id = rte_gpu_find_next(dev_id + 1, parent)) /** * @warning * @b EXPERIMENTAL: this API may change without prior notice. * - * Close device. + * Close device or child context. * All resources are released. * * @param dev_id diff --git a/lib/gpudev/version.map b/lib/gpudev/version.map index b3b6b76c1c..4a934ed933 100644 --- a/lib/gpudev/version.map +++ b/lib/gpudev/version.map @@ -2,6 +2,7 @@ EXPERIMENTAL { global: # added in 21.11 + rte_gpu_add_child; rte_gpu_callback_register; rte_gpu_callback_unregister; rte_gpu_close; From patchwork Sat Oct 9 01:53:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elena Agostini X-Patchwork-Id: 100833 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4E8E1A0C43; Fri, 8 Oct 2021 19:44:04 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D3BEC41102; Fri, 8 Oct 2021 19:43:44 +0200 (CEST) Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11on2082.outbound.protection.outlook.com [40.107.223.82]) by mails.dpdk.org (Postfix) with ESMTP id B4A15410E0 for ; Fri, 8 Oct 2021 19:43:42 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=eeEIItU2Kiivi43mI8WTZ4Se6iB2Ii60ZPYr4YM0O1zJ/OzhoX34gEC2/ufoyWtCAZqMiPtzPz9FL4+yyxObS6Yi7B5+WDi7dHlfo4C51uEGnVj6LSjF9Nvk7+ydGhVIQTD5gnfkbAncKaZG7uFa9WiGb2Y0cB7eG3h7pXAxcvMcYY6NDjDldyNXsNkJqSOO/yPE7P/BBDJh2G2/6ZC+2g8sdK6el0v5dKVAJZ8kAmGIZPgg+DA4NK7NEWXUn6ICMnQ9XzV8MTcx0Kw8GEPWUc8D5tbO2DFQRFlv8a9k1BKgEojr8gtx222aBM7AOhvnn8GW9VnPL1H4pTBale7Rlw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=EyTGReqUbUqXTf8a4NDk7zJE5RD2+qYqn96/Ab8N6GQ=; b=Cc/epkp14pKcrxla33sGYyRUdpll72Bm/GaBOLTt/G9qLhqyoQchDRbpHeB2MEr9c+33qMrGkeWiuUQ7vt/EUctl3miYsQrmiAas9hvVP+1grr88zgriPsWaqg5PTn/YqbHlO83h+r+s8MRK2Q7kMTup/AYyW8X1xqvW+Frlf2qUjiD9lA6EqSq6d/VxIdulhzPYwH0bK8IImG2QxAvJL3pG7yt1ssrhIJ72jiR2tScIvzDit+bSCoBos4EnwM9fgzDNVxAbra2JmVWs9GCXARpvLu8qYE8nnerqR2Sj3ed7RnvjPYJarKgvwNXEJkwBc0ERGyvqGRYIFnUaeTkd3Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=monjalon.net smtp.mailfrom=nvidia.com; dmarc=pass (p=quarantine sp=none pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=EyTGReqUbUqXTf8a4NDk7zJE5RD2+qYqn96/Ab8N6GQ=; b=tB+xOgLoSqVubDC33RnuYilDpwN9fCc8qQOFqCx9m3ogMV3tJ5rzqP5JNF1g3otULnCTskEsNmO2lBkt94wJD5IcFMkWskDmiZSs2OVNabbSIFPqz877lypGe+zd/usFmjK4ndZuAHzW6Mx5xm1NGGMmurcMfLYn8wDDaxJ/Mh3+AYCzVbPnTM+P+MKN0jooQX6D+Pn8SlhtiXCvb2GomaQRjFATfxLqHRlXqJeMrepuL6yIl3K2IErGTlWod8DgXzyBT+qmTQGFFxsK54Em72/iMg8YZB0YFsq2pfxBXOkvQwNvY+Ba19cYUf+3aghX7XCV+ZCWRqj4s0gAm3+pqg== Received: from MW4PR03CA0131.namprd03.prod.outlook.com (2603:10b6:303:8c::16) by DM6PR12MB5533.namprd12.prod.outlook.com (2603:10b6:5:1bc::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.22; Fri, 8 Oct 2021 17:43:40 +0000 Received: from CO1NAM11FT047.eop-nam11.prod.protection.outlook.com (2603:10b6:303:8c:cafe::79) by MW4PR03CA0131.outlook.office365.com (2603:10b6:303:8c::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:40 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; monjalon.net; dkim=none (message not signed) header.d=none;monjalon.net; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by CO1NAM11FT047.mail.protection.outlook.com (10.13.174.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:39 +0000 Received: from nvidia.com (172.20.187.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Fri, 8 Oct 2021 17:43:35 +0000 From: To: CC: Thomas Monjalon Date: Sat, 9 Oct 2021 01:53:44 +0000 Message-ID: <20211009015349.9694-5-eagostini@nvidia.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211009015349.9694-1-eagostini@nvidia.com> References: <20210602203531.2288645-1-thomas@monjalon.net> <20211009015349.9694-1-eagostini@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [172.20.187.6] X-ClientProxiedBy: HQMAIL111.nvidia.com (172.20.187.18) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: eb44b491-dead-4d00-0f3a-08d98a8329e6 X-MS-TrafficTypeDiagnostic: DM6PR12MB5533: X-LD-Processed: 43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:2043; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: bMeto1TjgdMUyCtlx7zSn3Bjjkn69OZaWxB9TIfm95fjHQzpnkrKQYIp7ZdWlwNhAOZ6h5eUnrazgQJlysYL9rzWCDHXxWJDJqKfG7pevIhU4QndWe5q4FRaBfZGWn0K7YStd9LZPP7Mp+uAvEFdKooZkm1ppS+IH2ijyDRC8MOv9h7InwrZ2CfT+ezqTYjwsQu65V9dBvruL/ENOkiJREMyJcLpk+TtFavlxSzIFiDI/ENLbO8Ac3GuO5QxDnETCvG46fkW2Udv+f3H3rLwPA3qPJIdr20RvJzcfxTDaW8Mtj9HmaIrwdNV093IZ1uY8q+x7M1PIm3aGnZo07wTHgksFuJ0jfOVBI7EKbvDKTGr7yZgYH4pYG5e0laqwpE16GAI8ymvqot0a6s8anvTsuQgTN+CysBrpDvZ1DZ1U/YLMQiBkw+QQGedjtaucFRRlQYQg4VxTiAl577nJu3mxai28Ax/Otm1olX+INgc3LX0RplELE3QMlVaLzYs/ivzQirJSn/V4okEVrLUvOiomkCSqnS8OtYn9WIpZRk459ttrpf7HMk0xwbR0Z/cty8CaTomadKjRmNBi9IFtuRw/G9RIbg+/fQ+KmtqtoNH1WogvyBHtNfVN5N/MkTrKRTpdHJY3e9ofH3bL6XqktuPgrLjV+o55ydOgJ/B4AePnsuA/WO50I0BYhW1Mpsy2LBgEO/Q2lBruSOFp0h9jY9nhw== X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(36840700001)(46966006)(83380400001)(82310400003)(86362001)(47076005)(2616005)(36756003)(36860700001)(8676002)(2906002)(356005)(30864003)(55016002)(336012)(316002)(6286002)(426003)(70586007)(7636003)(1076003)(5660300002)(2876002)(6666004)(186003)(7696005)(26005)(8936002)(16526019)(4326008)(508600001)(6916009)(70206006); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Oct 2021 17:43:39.5598 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: eb44b491-dead-4d00-0f3a-08d98a8329e6 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: CO1NAM11FT047.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB5533 Subject: [dpdk-dev] [PATCH v3 4/9] gpudev: support multi-process X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Thomas Monjalon The device data shared between processes are moved in a struct allocated in a shared memory (a new memzone for all GPUs). The main struct rte_gpu references the shared memory via the pointer mpshared. The API function rte_gpu_attach() is added to attach a device from the secondary process. The function rte_gpu_allocate() can be used only by primary process. Signed-off-by: Thomas Monjalon --- lib/gpudev/gpudev.c | 127 +++++++++++++++++++++++++++++++------ lib/gpudev/gpudev_driver.h | 25 ++++++-- lib/gpudev/version.map | 1 + 3 files changed, 127 insertions(+), 26 deletions(-) diff --git a/lib/gpudev/gpudev.c b/lib/gpudev/gpudev.c index 74cdd7f20b..f0690cf730 100644 --- a/lib/gpudev/gpudev.c +++ b/lib/gpudev/gpudev.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -28,6 +29,12 @@ static int16_t gpu_max; /* Number of currently valid devices */ static int16_t gpu_count; +/* Shared memory between processes. */ +static const char *GPU_MEMZONE = "rte_gpu_shared"; +static struct { + __extension__ struct rte_gpu_mpshared gpus[0]; +} *gpu_shared_mem; + /* Event callback object */ struct rte_gpu_callback { TAILQ_ENTRY(rte_gpu_callback) next; @@ -75,7 +82,7 @@ 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) + gpus[dev_id].process_state == RTE_GPU_STATE_INITIALIZED) return true; return false; } @@ -85,7 +92,7 @@ gpu_match_parent(int16_t dev_id, int16_t parent) { if (parent == RTE_GPU_ID_ANY) return true; - return gpus[dev_id].info.parent == parent; + return gpus[dev_id].mpshared->info.parent == parent; } int16_t @@ -94,7 +101,7 @@ rte_gpu_find_next(int16_t dev_id, int16_t parent) if (dev_id < 0) dev_id = 0; while (dev_id < gpu_max && - (gpus[dev_id].state == RTE_GPU_STATE_UNUSED || + (gpus[dev_id].process_state == RTE_GPU_STATE_UNUSED || !gpu_match_parent(dev_id, parent))) dev_id++; @@ -109,7 +116,7 @@ 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) + if (gpus[dev_id].process_state == RTE_GPU_STATE_UNUSED) return dev_id; } return RTE_GPU_ID_NONE; @@ -136,12 +143,35 @@ rte_gpu_get_by_name(const char *name) RTE_GPU_FOREACH(dev_id) { dev = &gpus[dev_id]; - if (strncmp(name, dev->name, RTE_DEV_NAME_MAX_LEN) == 0) + if (strncmp(name, dev->mpshared->name, RTE_DEV_NAME_MAX_LEN) == 0) return dev; } return NULL; } +static int +gpu_shared_mem_init(void) +{ + const struct rte_memzone *memzone; + + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + memzone = rte_memzone_reserve(GPU_MEMZONE, + sizeof(*gpu_shared_mem) + + sizeof(*gpu_shared_mem->gpus) * gpu_max, + SOCKET_ID_ANY, 0); + } else { + memzone = rte_memzone_lookup(GPU_MEMZONE); + } + if (memzone == NULL) { + GPU_LOG(ERR, "cannot initialize shared memory"); + rte_errno = ENOMEM; + return -rte_errno; + } + + gpu_shared_mem = memzone->addr; + return 0; +} + struct rte_gpu * rte_gpu_allocate(const char *name) { @@ -163,6 +193,10 @@ rte_gpu_allocate(const char *name) if (gpus == NULL && rte_gpu_init(RTE_GPU_DEFAULT_MAX) < 0) return NULL; + /* initialize shared memory before adding first device */ + if (gpu_shared_mem == NULL && gpu_shared_mem_init() < 0) + return NULL; + if (rte_gpu_get_by_name(name) != NULL) { GPU_LOG(ERR, "device with name %s already exists", name); rte_errno = EEXIST; @@ -178,16 +212,20 @@ rte_gpu_allocate(const char *name) dev = &gpus[dev_id]; memset(dev, 0, sizeof(*dev)); - if (rte_strscpy(dev->name, name, RTE_DEV_NAME_MAX_LEN) < 0) { + dev->mpshared = &gpu_shared_mem->gpus[dev_id]; + memset(dev->mpshared, 0, sizeof(*dev->mpshared)); + + if (rte_strscpy(dev->mpshared->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; - dev->info.parent = RTE_GPU_ID_NONE; + dev->mpshared->info.name = dev->mpshared->name; + dev->mpshared->info.dev_id = dev_id; + dev->mpshared->info.numa_node = -1; + dev->mpshared->info.parent = RTE_GPU_ID_NONE; TAILQ_INIT(&dev->callbacks); + __atomic_fetch_add(&dev->mpshared->process_refcnt, 1, __ATOMIC_RELAXED); gpu_count++; GPU_LOG(DEBUG, "new device %s (id %d) of total %d", @@ -195,6 +233,55 @@ rte_gpu_allocate(const char *name) return dev; } +struct rte_gpu * +rte_gpu_attach(const char *name) +{ + int16_t dev_id; + struct rte_gpu *dev; + struct rte_gpu_mpshared *shared_dev; + + if (rte_eal_process_type() != RTE_PROC_SECONDARY) { + GPU_LOG(ERR, "only secondary process can attach device"); + rte_errno = EPERM; + return NULL; + } + if (name == NULL) { + GPU_LOG(ERR, "attach 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; + + /* initialize shared memory before adding first device */ + if (gpu_shared_mem == NULL && gpu_shared_mem_init() < 0) + return NULL; + + for (dev_id = 0; dev_id < gpu_max; dev_id++) { + shared_dev = &gpu_shared_mem->gpus[dev_id]; + if (strncmp(name, shared_dev->name, RTE_DEV_NAME_MAX_LEN) == 0) + break; + } + if (dev_id >= gpu_max) { + GPU_LOG(ERR, "device with name %s not found", name); + rte_errno = ENOENT; + return NULL; + } + dev = &gpus[dev_id]; + memset(dev, 0, sizeof(*dev)); + + TAILQ_INIT(&dev->callbacks); + dev->mpshared = shared_dev; + __atomic_fetch_add(&dev->mpshared->process_refcnt, 1, __ATOMIC_RELAXED); + + gpu_count++; + GPU_LOG(DEBUG, "attached device %s (id %d) of total %d", + name, dev_id, gpu_count); + return dev; +} + int16_t rte_gpu_add_child(const char *name, int16_t parent, uint64_t child_context) { @@ -210,11 +297,11 @@ rte_gpu_add_child(const char *name, int16_t parent, uint64_t child_context) if (dev == NULL) return -rte_errno; - dev->info.parent = parent; - dev->info.context = child_context; + dev->mpshared->info.parent = parent; + dev->mpshared->info.context = child_context; rte_gpu_complete_new(dev); - return dev->info.dev_id; + return dev->mpshared->info.dev_id; } void @@ -223,8 +310,7 @@ rte_gpu_complete_new(struct rte_gpu *dev) if (dev == NULL) return; - dev->state = RTE_GPU_STATE_INITIALIZED; - dev->state = RTE_GPU_STATE_INITIALIZED; + dev->process_state = RTE_GPU_STATE_INITIALIZED; rte_gpu_notify(dev, RTE_GPU_EVENT_NEW); } @@ -237,7 +323,7 @@ rte_gpu_release(struct rte_gpu *dev) rte_errno = ENODEV; return -rte_errno; } - dev_id = dev->info.dev_id; + dev_id = dev->mpshared->info.dev_id; RTE_GPU_FOREACH_CHILD(child, dev_id) { GPU_LOG(ERR, "cannot release device %d with child %d", dev_id, child); @@ -246,11 +332,12 @@ rte_gpu_release(struct rte_gpu *dev) } GPU_LOG(DEBUG, "free device %s (id %d)", - dev->info.name, dev->info.dev_id); + dev->mpshared->info.name, dev->mpshared->info.dev_id); rte_gpu_notify(dev, RTE_GPU_EVENT_DEL); gpu_free_callbacks(dev); - dev->state = RTE_GPU_STATE_UNUSED; + dev->process_state = RTE_GPU_STATE_UNUSED; + __atomic_fetch_sub(&dev->mpshared->process_refcnt, 1, __ATOMIC_RELAXED); gpu_count--; return 0; @@ -403,7 +490,7 @@ rte_gpu_notify(struct rte_gpu *dev, enum rte_gpu_event event) int16_t dev_id; struct rte_gpu_callback *callback; - dev_id = dev->info.dev_id; + dev_id = dev->mpshared->info.dev_id; rte_rwlock_read_lock(&gpu_callback_lock); TAILQ_FOREACH(callback, &dev->callbacks, next) { if (callback->event != event || callback->function == NULL) @@ -431,7 +518,7 @@ rte_gpu_info_get(int16_t dev_id, struct rte_gpu_info *info) } if (dev->ops.dev_info_get == NULL) { - *info = dev->info; + *info = dev->mpshared->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 index 4d0077161c..9459c7e30f 100644 --- a/lib/gpudev/gpudev_driver.h +++ b/lib/gpudev/gpudev_driver.h @@ -35,19 +35,28 @@ struct rte_gpu_ops { rte_gpu_close_t *dev_close; }; -struct rte_gpu { - /* Backing device. */ - struct rte_device *device; +struct rte_gpu_mpshared { /* Unique identifier name. */ char name[RTE_DEV_NAME_MAX_LEN]; /* Updated by this library. */ + /* Driver-specific private data shared in multi-process. */ + void *dev_private; /* Device info structure. */ struct rte_gpu_info info; + /* Counter of processes using the device. */ + uint16_t process_refcnt; /* Updated by this library. */ +}; + +struct rte_gpu { + /* Backing device. */ + struct rte_device *device; + /* Data shared between processes. */ + struct rte_gpu_mpshared *mpshared; /* Driver functions. */ struct rte_gpu_ops ops; /* Event callback list. */ TAILQ_HEAD(rte_gpu_callback_list, rte_gpu_callback) callbacks; /* Current state (used or not) in the running process. */ - enum rte_gpu_state state; /* Updated by this library. */ + enum rte_gpu_state process_state; /* Updated by this library. */ /* Driver-specific private data for the running process. */ void *process_private; } __rte_cache_aligned; @@ -55,15 +64,19 @@ struct rte_gpu { __rte_internal struct rte_gpu *rte_gpu_get_by_name(const char *name); -/* First step of initialization */ +/* First step of initialization in primary process. */ __rte_internal struct rte_gpu *rte_gpu_allocate(const char *name); +/* First step of initialization in secondary process. */ +__rte_internal +struct rte_gpu *rte_gpu_attach(const char *name); + /* Last step of initialization. */ __rte_internal void rte_gpu_complete_new(struct rte_gpu *dev); -/* Last step of removal. */ +/* Last step of removal (primary or secondary process). */ __rte_internal int rte_gpu_release(struct rte_gpu *dev); diff --git a/lib/gpudev/version.map b/lib/gpudev/version.map index 4a934ed933..58dc632393 100644 --- a/lib/gpudev/version.map +++ b/lib/gpudev/version.map @@ -17,6 +17,7 @@ INTERNAL { global: rte_gpu_allocate; + rte_gpu_attach; rte_gpu_complete_new; rte_gpu_get_by_name; rte_gpu_notify; From patchwork Sat Oct 9 01:53:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elena Agostini X-Patchwork-Id: 100832 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1EE06A0C43; Fri, 8 Oct 2021 19:43:57 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CFFA7410E0; Fri, 8 Oct 2021 19:43:43 +0200 (CEST) Received: from NAM02-BN1-obe.outbound.protection.outlook.com (mail-bn1nam07on2054.outbound.protection.outlook.com [40.107.212.54]) by mails.dpdk.org (Postfix) with ESMTP id A8526407FF for ; Fri, 8 Oct 2021 19:43:42 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=YIeJ9pN7RUjOfC+sC5lP+EC673nsEtw0Vu137klCGXMJolk2ufUga5ENKLqNscv64//qDPesENvjWOBwi8tmOWVHtIiNIQst2wIWJfz/BPNlzVmSBtTKaLwPDoLctTazTkoRKcSbUwsA1VzbupWDZ6wNw+EhMSHeTk1Vc9+oQpn6bI8tZxvzBJSaMVWo6gyrQ8+B2ZuiH321qID46L6gUiuJjN8hRVg7WGeiVwbFDuZ3fr7CC/H6PKdg6JtHjbuXw07gEVsvC+LRrIeFCSSutDngmljc+lUGcr0sIAVH4FBlPpARrNPLvfFQ0+EJIlwLMTHrxtCx8SjMwBwNxVc8+w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=xg1RFO3F5iRpuP/zcXWZ9wyWBhooDDzU6WPni/HqNbw=; b=lXmqh0j47wCYmWf9iketg4j38Gv5w+jyZGpjgt366kv4rM4MCtQ36LuhjYu7sO8Q9QEBasKKaxroF/7DLdFfkA/U2VW9eJlIgoa5X+5Xd+VULuABWQDB7Eoy6QthYlVLoUPTcrNEJYkKE3DHav7jsZs23+N6fmhZ8trSjN/o43KqQgwVjp66Mo1P1mKoBOPsA1sp/KJGcteJM5ucD5mpibCpZZihvOghNi42c+KhO+QvzDiMcGc+PcZ/iqhuuIkXt7FTYyvRnNEq2GqePjOKz3RNeMCKEsUaWXMbYljWQbA5wGMY/+r3/S/+KtySZ85dzKtumSrHJnwVA+dKJEhtdA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=monjalon.net smtp.mailfrom=nvidia.com; dmarc=pass (p=quarantine sp=none pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=xg1RFO3F5iRpuP/zcXWZ9wyWBhooDDzU6WPni/HqNbw=; b=IY+MfP3peISMOsRqJXhW21Sced/PzD+YCIeV5Ub8oJz2Bxmi5nazpszQEBPHtZQu1lDs57uhrrgKS2DVkdHmx6Jr9poTH+6qbiUcwH3kJBznHlftdn2CB2VkOtbKxFqOEsY9TYPD9TSHNs3FxsK96vOIo7s7sPPWmzxHHjWW1v8xAyxV7CBsJBxHoXGXhcBt2jd9eoJ050OELjohbImGTKKznuicg2y2eFHtt48mce1aQkUJ037HzEgOJwh/S8Edzt2fa7BykUBq6NTUaAIhc2uZdo8jDirxhIrLMkQz+TIvj8HONa8rBLs2EhoNd5RYpAeXQeE1JnFydrpcwEDBvA== Received: from MW4PR03CA0143.namprd03.prod.outlook.com (2603:10b6:303:8c::28) by BN7PR12MB2756.namprd12.prod.outlook.com (2603:10b6:408:29::32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.18; Fri, 8 Oct 2021 17:43:41 +0000 Received: from CO1NAM11FT047.eop-nam11.prod.protection.outlook.com (2603:10b6:303:8c:cafe::59) by MW4PR03CA0143.outlook.office365.com (2603:10b6:303:8c::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:40 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; monjalon.net; dkim=none (message not signed) header.d=none;monjalon.net; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by CO1NAM11FT047.mail.protection.outlook.com (10.13.174.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:40 +0000 Received: from nvidia.com (172.20.187.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Fri, 8 Oct 2021 17:43:37 +0000 From: To: CC: Elena Agostini , Thomas Monjalon Date: Sat, 9 Oct 2021 01:53:45 +0000 Message-ID: <20211009015349.9694-6-eagostini@nvidia.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211009015349.9694-1-eagostini@nvidia.com> References: <20210602203531.2288645-1-thomas@monjalon.net> <20211009015349.9694-1-eagostini@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [172.20.187.6] X-ClientProxiedBy: HQMAIL111.nvidia.com (172.20.187.18) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 05c1a709-0ad7-46fd-18bb-08d98a832a65 X-MS-TrafficTypeDiagnostic: BN7PR12MB2756: X-LD-Processed: 43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:7691; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 2eGlZXuQFpB19BihnwXguEXK1xBIjgHFjFM11rcMIUqi+wae4wg8+btifJm4EuUBndALsSIyYSyK+oRHF/ukGCxSYI6vlLWxJZDq3SR9Z9Et9+WIZD39O2QX0Bpgv1vbPa8xEuLJalP3CzNxMmjn/ntOUDTjc3NcL91DJjHjxcOLjJpguvKCD1sBV4NprLSE44so8Q010rj/hLCEn9pUAzM6H8jOf3tzuTiTf+07XV/DuvnXLKFQ1K38q+HGdvhFfI2XJp9FVQ0b0CECMar/s6NEO862dBAIaH4TAtVsjRXLgWnenLqwPUJa7RprGHrO6MBOj4ZjZdUQ4IoS6/CGmTFYmLLBjKeGqWJMsExyW0loJqPykITkOngLvD25zO8FVFfPa9jnlEJRxPIcAenRX2MVn2xlc5Julz2dG4URm6n/NfgNkhqXOrvGcT3Tu8kjdxAiMjmlo4TX/WzzByYvBafM2pD0Vs11y43lOcOVvPFJAp1l+zQUflrPoP997Ng/rEN61arMlhT4gmVZUd9Kon7/5/hPwNZec20MbnTiRHGqDDBaxQgDLSrFBqaF1oagg1HPSZ+4G1GKP+ZZqlf+iKwKk/a5J2jfoL8yCciWDuIwE7hcSnI+oUnN66g4lYumo3bg3Hi5mCu9vvWFtg0LMQ7dPKVs0erYbxlML/3jcmOGEJLhBQhOO6t1mLFrLZSC X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(46966006)(36840700001)(2876002)(6286002)(26005)(316002)(2906002)(6916009)(86362001)(47076005)(5660300002)(36756003)(4326008)(36860700001)(30864003)(54906003)(82310400003)(8936002)(426003)(336012)(8676002)(508600001)(1076003)(83380400001)(2616005)(16526019)(6666004)(55016002)(186003)(7696005)(70586007)(356005)(7636003)(70206006); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Oct 2021 17:43:40.5103 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 05c1a709-0ad7-46fd-18bb-08d98a832a65 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: CO1NAM11FT047.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN7PR12MB2756 Subject: [dpdk-dev] [PATCH v3 5/9] gpudev: add memory API X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Elena Agostini In heterogeneous computing system, processing is not only in the CPU. Some tasks can be delegated to devices working in parallel. Such workload distribution can be achieved by sharing some memory. As a first step, the features are focused on memory management. A function allows to allocate memory inside the device, or in the main (CPU) memory while making it visible for the device. This memory may be used to save packets or for synchronization data. The next step should focus on GPU processing task control. Signed-off-by: Elena Agostini Signed-off-by: Thomas Monjalon --- app/test-gpudev/main.c | 118 +++++++++++++++++++++++++ doc/guides/gpus/features/default.ini | 3 + doc/guides/prog_guide/gpudev.rst | 19 ++++ doc/guides/rel_notes/release_21_11.rst | 1 + lib/gpudev/gpudev.c | 101 +++++++++++++++++++++ lib/gpudev/gpudev_driver.h | 12 +++ lib/gpudev/rte_gpudev.h | 95 ++++++++++++++++++++ lib/gpudev/version.map | 4 + 8 files changed, 353 insertions(+) diff --git a/app/test-gpudev/main.c b/app/test-gpudev/main.c index 6a73a54e84..98c02a3ee0 100644 --- a/app/test-gpudev/main.c +++ b/app/test-gpudev/main.c @@ -62,6 +62,110 @@ args_parse(int argc, char **argv) } } +static int +alloc_gpu_memory(uint16_t gpu_id) +{ + void * ptr_1 = NULL; + void * ptr_2 = NULL; + size_t buf_bytes = 1024; + int ret = 0; + + printf("\n=======> TEST: Allocate GPU memory\n"); + + /* Alloc memory on GPU 0 */ + ptr_1 = rte_gpu_malloc(gpu_id, buf_bytes); + if(ptr_1 == NULL) + { + fprintf(stderr, "rte_gpu_malloc GPU memory returned error\n"); + return -1; + } + printf("GPU memory allocated at 0x%p %zdB\n", ptr_1, buf_bytes); + + ptr_2 = rte_gpu_malloc(gpu_id, buf_bytes); + if(ptr_2 == NULL) + { + fprintf(stderr, "rte_gpu_malloc GPU memory returned error\n"); + return -1; + } + printf("GPU memory allocated at 0x%p %zdB\n", ptr_2, buf_bytes); + + ret = rte_gpu_free(gpu_id, (uint8_t*)(ptr_1)+0x700); + if(ret < 0) + { + printf("GPU memory 0x%p + 0x700 NOT freed because of memory address not recognized by driver\n", ptr_1); + } + else + { + fprintf(stderr, "rte_gpu_free erroneusly freed GPU memory 0x%p + 0x700\n", ptr_1); + return -1; + } + + ret = rte_gpu_free(gpu_id, ptr_2); + if(ret < 0) + { + fprintf(stderr, "rte_gpu_free returned error %d\n", ret); + return -1; + } + printf("GPU memory 0x%p freed\n", ptr_2); + + ret = rte_gpu_free(gpu_id, ptr_1); + if(ret < 0) + { + fprintf(stderr, "rte_gpu_free returned error %d\n", ret); + return -1; + } + printf("GPU memory 0x%p freed\n", ptr_1); + + return 0; +} + +static int +register_cpu_memory(uint16_t gpu_id) +{ + void * ptr = NULL; + size_t buf_bytes = 1024; + int ret = 0; + + printf("\n=======> TEST: Register CPU memory\n"); + + /* Alloc memory on CPU visible from GPU 0 */ + ptr = rte_zmalloc(NULL, buf_bytes, 0); + if (ptr == NULL) { + fprintf(stderr, "Failed to allocate CPU memory.\n"); + return -1; + } + + ret = rte_gpu_register(gpu_id, buf_bytes, ptr); + if(ret < 0) + { + fprintf(stderr, "rte_gpu_register CPU memory returned error %d\n", ret); + return -1; + } + printf("CPU memory registered at 0x%p %zdB\n", ptr, buf_bytes); + + ret = rte_gpu_unregister(gpu_id, (uint8_t*)(ptr)+0x700); + if(ret < 0) + { + printf("CPU memory 0x%p + 0x700 NOT unregistered because of memory address not recognized by driver\n", ptr); + } + else + { + fprintf(stderr, "rte_gpu_free erroneusly freed GPU memory 0x%p + 0x700\n", ptr); + return -1; + } + printf("CPU memory 0x%p unregistered\n", ptr); + + ret = rte_gpu_unregister(gpu_id, ptr); + if(ret < 0) + { + fprintf(stderr, "rte_gpu_unregister returned error %d\n", ret); + return -1; + } + printf("CPU memory 0x%p unregistered\n", ptr); + + return 0; +} + int main(int argc, char **argv) { @@ -99,6 +203,20 @@ main(int argc, char **argv) } printf("\n\n"); + if(nb_gpus == 0) + { + fprintf(stderr, "Need at least one GPU on the system to run the example\n"); + return EXIT_FAILURE; + } + + gpu_id = 0; + + /** + * Memory tests + */ + alloc_gpu_memory(gpu_id); + register_cpu_memory(gpu_id); + /* clean up the EAL */ rte_eal_cleanup(); printf("Bye...\n"); diff --git a/doc/guides/gpus/features/default.ini b/doc/guides/gpus/features/default.ini index ec7a545eb7..87e9966424 100644 --- a/doc/guides/gpus/features/default.ini +++ b/doc/guides/gpus/features/default.ini @@ -8,3 +8,6 @@ ; [Features] Get device info = +Share CPU memory with device = +Allocate device memory = +Free memory = diff --git a/doc/guides/prog_guide/gpudev.rst b/doc/guides/prog_guide/gpudev.rst index 7694639489..9aca69038c 100644 --- a/doc/guides/prog_guide/gpudev.rst +++ b/doc/guides/prog_guide/gpudev.rst @@ -30,6 +30,8 @@ Features This library provides a number of features: - Interoperability with device-specific library through generic handlers. +- Allocate and free memory on the device. +- Register CPU memory to make it visible from the device. API Overview @@ -46,3 +48,20 @@ that will be registered internally by the driver as an additional device (child) connected to a physical device (parent). Each device (parent or child) is represented through a ID required to indicate which device a given operation should be executed on. + +Memory Allocation +~~~~~~~~~~~~~~~~~ + +gpudev can allocate on an input given GPU device a memory area +returning the pointer to that memory. +Later, it's also possible to free that memory with gpudev. +GPU memory allocated outside of the gpudev library +(e.g. with GPU-specific library) cannot be freed by the gpudev library. + +Memory Registration +~~~~~~~~~~~~~~~~~~~ + +gpudev can register a CPU memory area to make it visible from a GPU device. +Later, it's also possible to unregister that memory with gpudev. +CPU memory registered outside of the gpudev library +(e.g. with GPU specific library) cannot be unregistered by the gpudev library. diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst index 4986a35b50..c4ac5e3053 100644 --- a/doc/guides/rel_notes/release_21_11.rst +++ b/doc/guides/rel_notes/release_21_11.rst @@ -65,6 +65,7 @@ New Features * **Introduced GPU device class with first features:** * Device information + * Memory management * **Added new RSS offload types for IPv4/L4 checksum in RSS flow.** diff --git a/lib/gpudev/gpudev.c b/lib/gpudev/gpudev.c index f0690cf730..1d8318f769 100644 --- a/lib/gpudev/gpudev.c +++ b/lib/gpudev/gpudev.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -523,3 +524,103 @@ rte_gpu_info_get(int16_t dev_id, struct rte_gpu_info *info) } return GPU_DRV_RET(dev->ops.dev_info_get(dev, info)); } + +void * +rte_gpu_malloc(int16_t dev_id, size_t size) +{ + struct rte_gpu *dev; + void *ptr; + int ret; + + dev = gpu_get_by_id(dev_id); + if (dev == NULL) { + GPU_LOG(ERR, "alloc mem for invalid device ID %d", dev_id); + rte_errno = ENODEV; + return NULL; + } + + if (dev->ops.mem_alloc == NULL) { + GPU_LOG(ERR, "mem allocation not supported"); + rte_errno = ENOTSUP; + return NULL; + } + + if (size == 0) /* dry-run */ + return NULL; + + ret = dev->ops.mem_alloc(dev, size, &ptr); + + switch (ret) { + case 0: + return ptr; + case -ENOMEM: + case -E2BIG: + rte_errno = -ret; + return NULL; + default: + rte_errno = -EPERM; + return NULL; + } +} + +int +rte_gpu_register(int16_t dev_id, size_t size, void * ptr) +{ + struct rte_gpu *dev; + + dev = gpu_get_by_id(dev_id); + if (dev == NULL) { + GPU_LOG(ERR, "alloc mem for invalid device ID %d", dev_id); + rte_errno = ENODEV; + return -rte_errno; + } + + if (dev->ops.mem_register == NULL) { + GPU_LOG(ERR, "mem registration not supported"); + rte_errno = ENOTSUP; + return -rte_errno; + } + + if (size == 0 || ptr == NULL) /* dry-run */ + return -EINVAL; + + return GPU_DRV_RET(dev->ops.mem_register(dev, size, ptr)); +} + +int +rte_gpu_unregister(int16_t dev_id, void * ptr) +{ + struct rte_gpu *dev; + + dev = gpu_get_by_id(dev_id); + if (dev == NULL) { + GPU_LOG(ERR, "unregister mem for invalid device ID %d", dev_id); + rte_errno = ENODEV; + return -rte_errno; + } + + if (dev->ops.mem_unregister == NULL) { + rte_errno = ENOTSUP; + return -rte_errno; + } + return GPU_DRV_RET(dev->ops.mem_unregister(dev, ptr)); +} + +int +rte_gpu_free(int16_t dev_id, void *ptr) +{ + struct rte_gpu *dev; + + dev = gpu_get_by_id(dev_id); + if (dev == NULL) { + GPU_LOG(ERR, "free mem for invalid device ID %d", dev_id); + rte_errno = ENODEV; + return -rte_errno; + } + + if (dev->ops.mem_free == NULL) { + rte_errno = ENOTSUP; + return -rte_errno; + } + return GPU_DRV_RET(dev->ops.mem_free(dev, ptr)); +} diff --git a/lib/gpudev/gpudev_driver.h b/lib/gpudev/gpudev_driver.h index 9459c7e30f..11015944a6 100644 --- a/lib/gpudev/gpudev_driver.h +++ b/lib/gpudev/gpudev_driver.h @@ -27,12 +27,24 @@ enum rte_gpu_state { 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); +typedef int (rte_gpu_mem_alloc_t)(struct rte_gpu *dev, size_t size, void **ptr); +typedef int (rte_gpu_free_t)(struct rte_gpu *dev, void *ptr); +typedef int (rte_gpu_mem_register_t)(struct rte_gpu *dev, size_t size, void *ptr); +typedef int (rte_gpu_mem_unregister_t)(struct rte_gpu *dev, void *ptr); struct rte_gpu_ops { /* Get device info. If NULL, info is just copied. */ rte_gpu_info_get_t *dev_info_get; /* Close device or child context. */ rte_gpu_close_t *dev_close; + /* Allocate memory in device. */ + rte_gpu_mem_alloc_t *mem_alloc; + /* Register CPU memory in device. */ + rte_gpu_mem_register_t *mem_register; + /* Free memory allocated or registered in device. */ + rte_gpu_free_t *mem_free; + /* Unregister CPU memory in device. */ + rte_gpu_mem_unregister_t *mem_unregister; }; struct rte_gpu_mpshared { diff --git a/lib/gpudev/rte_gpudev.h b/lib/gpudev/rte_gpudev.h index df75dbdbab..3c276581c0 100644 --- a/lib/gpudev/rte_gpudev.h +++ b/lib/gpudev/rte_gpudev.h @@ -9,6 +9,7 @@ #include #include +#include #include /** @@ -292,6 +293,100 @@ int rte_gpu_callback_unregister(int16_t dev_id, enum rte_gpu_event event, __rte_experimental int rte_gpu_info_get(int16_t dev_id, struct rte_gpu_info *info); +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Allocate a chunk of memory usable by the device. + * + * @param dev_id + * Device ID requiring allocated memory. + * @param size + * Number of bytes to allocate. + * Requesting 0 will do nothing. + * + * @return + * A pointer to the allocated memory, otherwise NULL and rte_errno is set: + * - ENODEV if invalid dev_id + * - EINVAL if reserved flags + * - ENOTSUP if operation not supported by the driver + * - E2BIG if size is higher than limit + * - ENOMEM if out of space + * - EPERM if driver error + */ +__rte_experimental +void *rte_gpu_malloc(int16_t dev_id, size_t size) +__rte_alloc_size(2); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Deallocate a chunk of memory allocated with rte_gpu_malloc(). + * + * @param dev_id + * Reference device ID. + * @param ptr + * Pointer to the memory area to be deallocated. + * NULL is a no-op accepted value. + * + * @return + * 0 on success, -rte_errno otherwise: + * - ENODEV if invalid dev_id + * - ENOTSUP if operation not supported by the driver + * - EPERM if driver error + */ +__rte_experimental +int rte_gpu_free(int16_t dev_id, void *ptr); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Register a chunk of memory on the CPU usable by the device. + * + * @param dev_id + * Device ID requiring allocated memory. + * @param size + * Number of bytes to allocate. + * Requesting 0 will do nothing. + * @param ptr + * Pointer to the memory area to be registered. + * NULL is a no-op accepted value. + + * @return + * A pointer to the allocated memory, otherwise NULL and rte_errno is set: + * - ENODEV if invalid dev_id + * - EINVAL if reserved flags + * - ENOTSUP if operation not supported by the driver + * - E2BIG if size is higher than limit + * - ENOMEM if out of space + * - EPERM if driver error + */ +__rte_experimental +int rte_gpu_register(int16_t dev_id, size_t size, void * ptr); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Deregister a chunk of memory previusly registered with rte_gpu_mem_register() + * + * @param dev_id + * Reference device ID. + * @param ptr + * Pointer to the memory area to be unregistered. + * NULL is a no-op accepted value. + * + * @return + * 0 on success, -rte_errno otherwise: + * - ENODEV if invalid dev_id + * - ENOTSUP if operation not supported by the driver + * - EPERM if driver error + */ +__rte_experimental +int rte_gpu_unregister(int16_t dev_id, void *ptr); + #ifdef __cplusplus } #endif diff --git a/lib/gpudev/version.map b/lib/gpudev/version.map index 58dc632393..d4a65ebd52 100644 --- a/lib/gpudev/version.map +++ b/lib/gpudev/version.map @@ -8,9 +8,13 @@ EXPERIMENTAL { rte_gpu_close; rte_gpu_count_avail; rte_gpu_find_next; + rte_gpu_free; rte_gpu_info_get; rte_gpu_init; rte_gpu_is_valid; + rte_gpu_malloc; + rte_gpu_register; + rte_gpu_unregister; }; INTERNAL { From patchwork Sat Oct 9 01:53:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elena Agostini X-Patchwork-Id: 100835 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 589E9A0C43; Fri, 8 Oct 2021 19:44:20 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 41E1D41125; Fri, 8 Oct 2021 19:43:47 +0200 (CEST) Received: from NAM10-BN7-obe.outbound.protection.outlook.com (mail-bn7nam10on2048.outbound.protection.outlook.com [40.107.92.48]) by mails.dpdk.org (Postfix) with ESMTP id 9DB42410FE for ; Fri, 8 Oct 2021 19:43:44 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Oi1JGdOQOSUCSxLNezDvGy4WDTxFTIDD+o51rIvauoVflxdpDkFPzVCNf+8gfaZwpVmSlGlmLjdJGOx8n2D+fh2I5NskjRZsn6TWHtFi5E7zH5e/fGvV3Xr3scHSlfJifBVPkeC1VK2o3UYTSgcOQaDcxSm5xooEpQB88LUVeXzosASWaHPRLizdZRnvaC12D0i7Og+VDo85sOgiGc+IZ0vDmNV0M5ndXB2KtF/w/MphxddjUFDrKGhglBrI4FzVWl41u/bNRDTKI1DORgokpFA1aNdWtLlW3GjRAAtH0XX2ihuICHw7GU9iYmDcN5cIk15/+fNKGT8yscEb5uMcIA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=RcJ8lKWpo6+elUvJVL104uFWcIiXQcFjM5BhbdJDUPo=; b=lxb1Q3l1T+tXTeMxC07OzLAq+RjBiAAYK18m17fLCXzlRu2TK8ZdXydGlalKYhnqATfiyRVxwOUnKAJKIM7p8FgrJZDSeIZaaPv3IZX+wsGd0l8rZOtE8QeCIilYNwctDG9UclBWy8JKWaSYc8n82uS44LtmEnAIXm9SoBk9JHctWd0+MoMuz5nCF6u3MebqXTeRA1IOL0o5ctHzXg/emzUJx5PAp+8cD7c76vFBBqSP2QRcOFHjYXwTsVe1QYkX9Hw9NUL5Gxd0gTrmP9WuiQXK60O2LOa1lyuKmHhCKz9X+SQGCr6+1q9dQ4kVEm1s+Df5MAprX9yoK/5a3cQYkw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=dpdk.org smtp.mailfrom=nvidia.com; dmarc=pass (p=quarantine sp=none pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=RcJ8lKWpo6+elUvJVL104uFWcIiXQcFjM5BhbdJDUPo=; b=shBhDy7OvpNwMF87ELMWZaB3ZjLz+IyLMAOP7u4jKSsYX0bhcmgmbJDBuwj+rUxVamfpzgcisMKy0P53WFrwlBkHRh0YMcvSyCIOgVLzUQ57e76zdYBwFB/rHik0Bk9Btu3JZY57SNxxFosMqM/+jTUxhgZ6qM2+Lp3RbSOnpIbzRp1/mUXfrUIllJqelrbHcO7lwQ2n2ljfk7NZ/GQsxkEtaLGIoGovt42fJgT7lTyXpnf+xtQJH/D1WuMUKGYlo599i06OEOaDaPzzcgrOyktZM59ZaLNCi6k7cm8L47o9QYODbpKw3HXLTi5UN2zLBCyBJXf1I/AfM/IQW480eg== Received: from MW4PR03CA0142.namprd03.prod.outlook.com (2603:10b6:303:8c::27) by DM5PR12MB2583.namprd12.prod.outlook.com (2603:10b6:4:b3::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4566.22; Fri, 8 Oct 2021 17:43:43 +0000 Received: from CO1NAM11FT047.eop-nam11.prod.protection.outlook.com (2603:10b6:303:8c:cafe::97) by MW4PR03CA0142.outlook.office365.com (2603:10b6:303:8c::27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:42 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; dpdk.org; dkim=none (message not signed) header.d=none;dpdk.org; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by CO1NAM11FT047.mail.protection.outlook.com (10.13.174.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:42 +0000 Received: from nvidia.com (172.20.187.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Fri, 8 Oct 2021 17:43:38 +0000 From: To: CC: Elena Agostini Date: Sat, 9 Oct 2021 01:53:46 +0000 Message-ID: <20211009015349.9694-7-eagostini@nvidia.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211009015349.9694-1-eagostini@nvidia.com> References: <20210602203531.2288645-1-thomas@monjalon.net> <20211009015349.9694-1-eagostini@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [172.20.187.6] X-ClientProxiedBy: HQMAIL111.nvidia.com (172.20.187.18) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 3a6d4725-0da9-4a19-4570-08d98a832b69 X-MS-TrafficTypeDiagnostic: DM5PR12MB2583: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:3968; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Weooi5ZcV3D7M2l6eZTc85WmR2hGMBKMjDL/hmefKeORF3W/IRmvlBiUeFUTrDSXg/c1VZd0yKCPHmCgKjgA7wBFJ9QV6stxqsIg9SSIB920d9RnEppB0XbGL6qouFuj11jwPP0ELRDEscFzeVrEf5BGpVY3n36H/E1DPWGAHYGvBYoN+qOa3QXMScTs8OjiSncFruRqddzw1lr7IJAPCYRZlwcFfGs6SsyW9oNDi3cawgkXg41k3JFs2XGSbk+MjOzDES8nE7fIXXGMAlJ/IZQj0oWuOnLaU5SqQUyanZ3KgYeLXUfWCmlQBkKnTmgOoztmB5Waeyr4VOM+kgHWzv7tHSaK/LByHGYoqiiCzp3+DM/Fyf/7HDw2HS2w6OPH35Ka5SKMiSoZLC7TJGKV6RtdPMN3HZwXejPVvv2M4pA4nP9SIhShOBKErvvVgcY4lmqexdeCaESLSF6RyutHXF6e5qyV2UspUl+KJZbGJhNQIyexVcSpfm9ktDrp6vtjpPM0/7LVKclgeNDqa9St5WZYfbTcY76JXYzzHWq+4REDt5zqk6VPzhCLQlvSHHto4eVp5tWfZxCo/akL4Y8/wBkg0L8bBFsDZdNEKvdoJaBzE/DFgd959cKCHf37Bm3u0B9xLkEvr/nv9waecvycl3bQ3jWYG1fm/PYbu//hLacL+APDolfzlq4wHBw/m9nzX9aFhZhbJ+8mcPAkJzgLbg== X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(36840700001)(46966006)(6916009)(55016002)(6666004)(508600001)(2616005)(5660300002)(2876002)(82310400003)(6286002)(316002)(426003)(8676002)(83380400001)(2906002)(336012)(16526019)(86362001)(36860700001)(1076003)(70206006)(26005)(47076005)(36756003)(186003)(107886003)(7696005)(7636003)(8936002)(70586007)(356005)(4326008); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Oct 2021 17:43:42.2314 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 3a6d4725-0da9-4a19-4570-08d98a832b69 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: CO1NAM11FT047.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR12MB2583 Subject: [dpdk-dev] [PATCH v3 6/9] gpudev: add memory barrier X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Elena Agostini Add a function for the application to ensure the coherency of the writes executed by another device into the GPU memory. Signed-off-by: Elena Agostini --- doc/guides/prog_guide/gpudev.rst | 8 ++++++++ lib/gpudev/gpudev.c | 19 +++++++++++++++++++ lib/gpudev/gpudev_driver.h | 3 +++ lib/gpudev/rte_gpudev.h | 18 ++++++++++++++++++ lib/gpudev/version.map | 1 + 5 files changed, 49 insertions(+) diff --git a/doc/guides/prog_guide/gpudev.rst b/doc/guides/prog_guide/gpudev.rst index 9aca69038c..eb5f0af817 100644 --- a/doc/guides/prog_guide/gpudev.rst +++ b/doc/guides/prog_guide/gpudev.rst @@ -65,3 +65,11 @@ gpudev can register a CPU memory area to make it visible from a GPU device. Later, it's also possible to unregister that memory with gpudev. CPU memory registered outside of the gpudev library (e.g. with GPU specific library) cannot be unregistered by the gpudev library. + +Memory Barrier +~~~~~~~~~~~~~~ + +Some GPU drivers may need, under certain conditions, +to enforce the coherency of external devices writes (e.g. NIC receiving packets) +into the GPU memory. +gpudev abstracts and exposes this capability. diff --git a/lib/gpudev/gpudev.c b/lib/gpudev/gpudev.c index 1d8318f769..cefefd737a 100644 --- a/lib/gpudev/gpudev.c +++ b/lib/gpudev/gpudev.c @@ -624,3 +624,22 @@ rte_gpu_free(int16_t dev_id, void *ptr) } return GPU_DRV_RET(dev->ops.mem_free(dev, ptr)); } + +int +rte_gpu_mbw(int16_t dev_id) +{ + struct rte_gpu *dev; + + dev = gpu_get_by_id(dev_id); + if (dev == NULL) { + GPU_LOG(ERR, "memory barrier for invalid device ID %d", dev_id); + rte_errno = ENODEV; + return -rte_errno; + } + + if (dev->ops.mbw == NULL) { + rte_errno = ENOTSUP; + return -rte_errno; + } + return GPU_DRV_RET(dev->ops.mbw(dev)); +} diff --git a/lib/gpudev/gpudev_driver.h b/lib/gpudev/gpudev_driver.h index 11015944a6..ab24de9e28 100644 --- a/lib/gpudev/gpudev_driver.h +++ b/lib/gpudev/gpudev_driver.h @@ -31,6 +31,7 @@ typedef int (rte_gpu_mem_alloc_t)(struct rte_gpu *dev, size_t size, void **ptr); typedef int (rte_gpu_free_t)(struct rte_gpu *dev, void *ptr); typedef int (rte_gpu_mem_register_t)(struct rte_gpu *dev, size_t size, void *ptr); typedef int (rte_gpu_mem_unregister_t)(struct rte_gpu *dev, void *ptr); +typedef int (rte_gpu_mbw_t)(struct rte_gpu *dev); struct rte_gpu_ops { /* Get device info. If NULL, info is just copied. */ @@ -45,6 +46,8 @@ struct rte_gpu_ops { rte_gpu_free_t *mem_free; /* Unregister CPU memory in device. */ rte_gpu_mem_unregister_t *mem_unregister; + /* Enforce GPU memory write barrier. */ + rte_gpu_mbw_t *mbw; }; struct rte_gpu_mpshared { diff --git a/lib/gpudev/rte_gpudev.h b/lib/gpudev/rte_gpudev.h index 3c276581c0..e790b3e2b7 100644 --- a/lib/gpudev/rte_gpudev.h +++ b/lib/gpudev/rte_gpudev.h @@ -387,6 +387,24 @@ int rte_gpu_register(int16_t dev_id, size_t size, void * ptr); __rte_experimental int rte_gpu_unregister(int16_t dev_id, void *ptr); +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Enforce a GPU memory write barrier. + * + * @param dev_id + * Reference device ID. + * + * @return + * 0 on success, -rte_errno otherwise: + * - ENODEV if invalid dev_id + * - ENOTSUP if operation not supported by the driver + * - EPERM if driver error + */ +__rte_experimental +int rte_gpu_mbw(int16_t dev_id); + #ifdef __cplusplus } #endif diff --git a/lib/gpudev/version.map b/lib/gpudev/version.map index d4a65ebd52..d72d470d8e 100644 --- a/lib/gpudev/version.map +++ b/lib/gpudev/version.map @@ -13,6 +13,7 @@ EXPERIMENTAL { rte_gpu_init; rte_gpu_is_valid; rte_gpu_malloc; + rte_gpu_mbw; rte_gpu_register; rte_gpu_unregister; }; From patchwork Sat Oct 9 01:53:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elena Agostini X-Patchwork-Id: 100836 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6D319A0C43; Fri, 8 Oct 2021 19:44:28 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A133A4113E; Fri, 8 Oct 2021 19:43:48 +0200 (CEST) Received: from NAM12-DM6-obe.outbound.protection.outlook.com (mail-dm6nam12on2065.outbound.protection.outlook.com [40.107.243.65]) by mails.dpdk.org (Postfix) with ESMTP id B170F41125 for ; Fri, 8 Oct 2021 19:43:46 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=eElQI83AZJO8hHwfRV3Yi+0S1lU86h/CMQCBJIF56zPfi8v4fBh4hcyLCZOWBZRB1c3+g6Eb26sVM2G2ac7IPCKhMgksbma/lHupMcTGn+zG4fSqRTSjKjxLVkIFjvtffbyRC1+m6xz0/JlSdgcBeAPWOYSAdAu5k9WII95V5Lb1BOkQ1WKA77fNfeEZVRLOYourElEA0ESAD0KHMTErliu0h2nSaChRqWF35HYsHGaDIk0GOTY1uj+eMLkwyqQKGZRCm7zvgm9g2ogdl1pJj4soYDFvBSH4qizqujuzoywAyPEv5ePT4SiN0RBFcI6odY9lgy+E7fosmf0oRm6ezA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=3n+jc1KWKUM8w+VbCHwgWOWoKG9DW3AuzWMyOxQ2nc8=; b=Y85ZvGpyq9sk+4kuaeEyh0mmsZ7oflDnAdwP3sVgy+V74/EGAxXji7ZF61osRbWU/C2vGpferG18qvl5uZt68ihRDTBqNALOjepO5SRoW/gfmqXEhGxikpOhxBNOjK/47aEbE6uV5XUP7Cy2uRodiKN7GShG21BRXmnmNIjF59oIaPMpiK6iAJMN7TIVFq+qtoEcYjAMU2MmzYZsQI7aeyuzAZuAOxQu8OEDwiByDhUahQAjKBaQPhpKZ85HK4vLk7D+l+z+9MCXH8VYOgSU+T/VMcbn/kG/chr1PA4NBJX02kUlfF9V6UXkThyOx0khbx1U/GEx4e7OiTM2DUP6Mw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=dpdk.org smtp.mailfrom=nvidia.com; dmarc=pass (p=quarantine sp=none pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=3n+jc1KWKUM8w+VbCHwgWOWoKG9DW3AuzWMyOxQ2nc8=; b=M7LkOivReFvQbFwUKYjKTnqaibj8D/hcNDlrZ9aA5Vv7H8fe24LbfX+2eur0YGor4yYMcrkTFYf+sgnqM4auno7beNQ5mRtDyyfL0eV+XOEn+Dxbw79aKHYj4Bz/1W9KjV4WXpfwoBCkcmmELIQiFevEWp5YpgdN2Lq4tB7hMTTuijMlA1npSoIfsMcT3U6kI50JNG6FtDqx3bCiWBT6ExHS319M0fAxHzgeBX3GrTKG0kJOYNyqskKjPHzKlUhFZpuCJfqeyuNH2IRGc8hwoRNay3Q6rVuFVAGXPHJny6sE7HQ5VjQgpQQDKx2T0OV+oIHiAzYre/cbnWhTG6ezag== Received: from MW4PR03CA0121.namprd03.prod.outlook.com (2603:10b6:303:8c::6) by MN2PR12MB3485.namprd12.prod.outlook.com (2603:10b6:208:c9::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.20; Fri, 8 Oct 2021 17:43:44 +0000 Received: from CO1NAM11FT047.eop-nam11.prod.protection.outlook.com (2603:10b6:303:8c:cafe::3d) by MW4PR03CA0121.outlook.office365.com (2603:10b6:303:8c::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:44 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; dpdk.org; dkim=none (message not signed) header.d=none;dpdk.org; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by CO1NAM11FT047.mail.protection.outlook.com (10.13.174.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:44 +0000 Received: from nvidia.com (172.20.187.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Fri, 8 Oct 2021 17:43:40 +0000 From: To: CC: Elena Agostini Date: Sat, 9 Oct 2021 01:53:47 +0000 Message-ID: <20211009015349.9694-8-eagostini@nvidia.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211009015349.9694-1-eagostini@nvidia.com> References: <20210602203531.2288645-1-thomas@monjalon.net> <20211009015349.9694-1-eagostini@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [172.20.187.6] X-ClientProxiedBy: HQMAIL111.nvidia.com (172.20.187.18) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 10d4b3d5-9b82-4ddf-a45a-08d98a832c8b X-MS-TrafficTypeDiagnostic: MN2PR12MB3485: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:117; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: +yJVX7k0wRXTRK/CfBePi5LhEQNRVNFdjXHat0xv0mIEfPSMUHaGmSUlmLsI7E/fdPGFX4bGDMocPL/ZWsu+Impj7G2+3iNtDimIJHl8RLay2pCZnNPuLBO0XdbGEJlG6ZiTWPCCY4BTafqDiu/t4gT5fNCNgl0iHzsZFrP5jZWPxJf6mkHanVnUf7F0eAPHTmRiMnn1HqoQK7WFmaiNi8yzG1j/Vlo9Dt6B0Z5kjuRz2vsp3cLRKPz+f25dExAm96ZjNPipLW4Sv/vHcVq5PewsLllNVEl7R6blYlXTqADrkEo+T8LPWT0c6gxI/MZDoP43vunbh/M1XQrKLVGaHWeKorvSJTGeLxpoDGI/Qrru01/vTOwuAfG3zAO/j8BjpBX9MgEXNKTvhv8TiKqA5TPnKfwx2/wqnG2ZwgihFUTziwE/G8uTdgBJbndsmVWz2FR5cOG8Vs20RKLhEQSYHPZPo8UY4KgEpC9oY+tB+zD9miiPXocKiMCXgba3sZphFX5KXsbEt+ci0g6IrRImxJR/PO/K6uwwejoVPNFUsXQI1W0M7ea1fIrVkIya5GusPHDfhLsBGigxyL1AggOwHyFqRqSbCjP5vMOgHtTBud2onau0mGJH1A7rznSPAJEdL2cOl2hXsUBMrqFef//TLhJkuaCTP0z9o0IIK7GHOK8wwlR6LnQ+1eLQJ2SO19vvlHRW2zlPPbtHiWCTdOOJEg== X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(46966006)(36840700001)(36860700001)(508600001)(86362001)(55016002)(7696005)(30864003)(316002)(8936002)(6286002)(70586007)(70206006)(107886003)(8676002)(426003)(83380400001)(336012)(36756003)(186003)(82310400003)(5660300002)(356005)(6916009)(7636003)(26005)(4326008)(16526019)(2616005)(47076005)(2876002)(2906002)(1076003); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Oct 2021 17:43:44.1244 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 10d4b3d5-9b82-4ddf-a45a-08d98a832c8b X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: CO1NAM11FT047.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB3485 Subject: [dpdk-dev] [PATCH v3 7/9] gpudev: add communication flag X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Elena Agostini In heterogeneous computing system, processing is not only in the CPU. Some tasks can be delegated to devices working in parallel. When mixing network activity with task processing there may be the need to put in communication the CPU with the device in order to synchronize operations. The purpose of this flag is to allow the CPU and the GPU to exchange ACKs. A possible use-case is described below. CPU: - Trigger some task on the GPU - Prepare some data - Signal to the GPU the data is ready updating the communication flag GPU: - Do some pre-processing - Wait for more data from the CPU polling on the communication flag - Consume the data prepared by the CPU Signed-off-by: Elena Agostini --- app/test-gpudev/main.c | 66 +++++++++++++++ doc/guides/prog_guide/gpudev.rst | 13 +++ doc/guides/rel_notes/release_21_11.rst | 1 + lib/gpudev/gpudev.c | 94 +++++++++++++++++++++ lib/gpudev/rte_gpudev.h | 108 +++++++++++++++++++++++++ lib/gpudev/version.map | 4 + 6 files changed, 286 insertions(+) diff --git a/app/test-gpudev/main.c b/app/test-gpudev/main.c index 98c02a3ee0..22f5c950b2 100644 --- a/app/test-gpudev/main.c +++ b/app/test-gpudev/main.c @@ -166,6 +166,67 @@ register_cpu_memory(uint16_t gpu_id) return 0; } +static int +create_update_comm_flag(uint16_t gpu_id) +{ + struct rte_gpu_comm_flag devflag; + int ret = 0; + uint32_t set_val; + uint32_t get_val; + + printf("\n=======> TEST: Communication flag\n"); + + ret = rte_gpu_comm_create_flag(gpu_id, &devflag, RTE_GPU_COMM_FLAG_CPU); + if(ret < 0) + { + fprintf(stderr, "rte_gpu_comm_create_flag returned error %d\n", ret); + return -1; + } + + set_val = 25; + ret = rte_gpu_comm_set_flag(&devflag, set_val); + if(ret < 0) + { + fprintf(stderr, "rte_gpu_comm_set_flag returned error %d\n", ret); + return -1; + } + + ret = rte_gpu_comm_get_flag_value(&devflag, &get_val); + if(ret < 0) + { + fprintf(stderr, "rte_gpu_comm_get_flag_value returned error %d\n", ret); + return -1; + } + + printf("Communication flag value at 0x%p was set to %d and current value is %d\n", devflag.ptr, set_val, get_val); + + set_val = 38; + ret = rte_gpu_comm_set_flag(&devflag, set_val); + if(ret < 0) + { + fprintf(stderr, "rte_gpu_comm_set_flag returned error %d\n", ret); + return -1; + } + + ret = rte_gpu_comm_get_flag_value(&devflag, &get_val); + if(ret < 0) + { + fprintf(stderr, "rte_gpu_comm_get_flag_value returned error %d\n", ret); + return -1; + } + + printf("Communication flag value at 0x%p was set to %d and current value is %d\n", devflag.ptr, set_val, get_val); + + ret = rte_gpu_comm_destroy_flag(&devflag); + if(ret < 0) + { + fprintf(stderr, "rte_gpu_comm_destroy_flags returned error %d\n", ret); + return -1; + } + + return 0; +} + int main(int argc, char **argv) { @@ -217,6 +278,11 @@ main(int argc, char **argv) alloc_gpu_memory(gpu_id); register_cpu_memory(gpu_id); + /** + * Communication items test + */ + create_update_comm_flag(gpu_id); + /* clean up the EAL */ rte_eal_cleanup(); printf("Bye...\n"); diff --git a/doc/guides/prog_guide/gpudev.rst b/doc/guides/prog_guide/gpudev.rst index eb5f0af817..e0db627aed 100644 --- a/doc/guides/prog_guide/gpudev.rst +++ b/doc/guides/prog_guide/gpudev.rst @@ -32,6 +32,10 @@ This library provides a number of features: - Interoperability with device-specific library through generic handlers. - Allocate and free memory on the device. - Register CPU memory to make it visible from the device. +- Communication between the CPU and the device. + +The whole CPU - GPU communication is implemented +using CPU memory visible from the GPU. API Overview @@ -73,3 +77,12 @@ Some GPU drivers may need, under certain conditions, to enforce the coherency of external devices writes (e.g. NIC receiving packets) into the GPU memory. gpudev abstracts and exposes this capability. + +Communication Flag +~~~~~~~~~~~~~~~~~~ + +Considering an application with some GPU task +that's waiting to receive a signal from the CPU +to move forward with the execution. +The communication flag allocates a CPU memory GPU-visible ``uint32_t`` flag +that can be used by the CPU to communicate with a GPU task. diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst index c4ac5e3053..59ab1a1920 100644 --- a/doc/guides/rel_notes/release_21_11.rst +++ b/doc/guides/rel_notes/release_21_11.rst @@ -66,6 +66,7 @@ New Features * Device information * Memory management + * Communication flag * **Added new RSS offload types for IPv4/L4 checksum in RSS flow.** diff --git a/lib/gpudev/gpudev.c b/lib/gpudev/gpudev.c index cefefd737a..827e29d8f6 100644 --- a/lib/gpudev/gpudev.c +++ b/lib/gpudev/gpudev.c @@ -643,3 +643,97 @@ rte_gpu_mbw(int16_t dev_id) } return GPU_DRV_RET(dev->ops.mbw(dev)); } + +int +rte_gpu_comm_create_flag(uint16_t dev_id, struct rte_gpu_comm_flag *devflag, + enum rte_gpu_comm_flag_type mtype) +{ + size_t flag_size; + int ret; + + if (devflag == NULL) { + rte_errno = EINVAL; + return -rte_errno; + } + if (mtype != RTE_GPU_COMM_FLAG_CPU) { + rte_errno = EINVAL; + return -rte_errno; + } + + flag_size = sizeof(uint32_t); + + devflag->ptr = rte_zmalloc(NULL, flag_size, 0); + if (devflag->ptr == NULL) { + rte_errno = ENOMEM; + return -rte_errno; + } + + ret = rte_gpu_register(dev_id, flag_size, devflag->ptr); + if(ret < 0) + { + rte_errno = ENOMEM; + return -rte_errno; + } + + devflag->mtype = mtype; + devflag->dev_id = dev_id; + + return 0; +} + +int +rte_gpu_comm_destroy_flag(struct rte_gpu_comm_flag *devflag) +{ + int ret; + + if (devflag == NULL) { + rte_errno = EINVAL; + return -rte_errno; + } + + ret = rte_gpu_unregister(devflag->dev_id, devflag->ptr); + if(ret < 0) + { + rte_errno = EINVAL; + return -1; + } + + rte_free(devflag->ptr); + + return 0; +} + +int +rte_gpu_comm_set_flag(struct rte_gpu_comm_flag *devflag, uint32_t val) +{ + if (devflag == NULL) { + rte_errno = EINVAL; + return -rte_errno; + } + + if (devflag->mtype != RTE_GPU_COMM_FLAG_CPU) { + rte_errno = EINVAL; + return -rte_errno; + } + + RTE_GPU_VOLATILE(*devflag->ptr) = val; + + return 0; +} + +int +rte_gpu_comm_get_flag_value(struct rte_gpu_comm_flag *devflag, uint32_t *val) +{ + if (devflag == NULL) { + rte_errno = EINVAL; + return -rte_errno; + } + if (devflag->mtype != RTE_GPU_COMM_FLAG_CPU) { + rte_errno = EINVAL; + return -rte_errno; + } + + *val = RTE_GPU_VOLATILE(*devflag->ptr); + + return 0; +} diff --git a/lib/gpudev/rte_gpudev.h b/lib/gpudev/rte_gpudev.h index e790b3e2b7..4a10a8bcf5 100644 --- a/lib/gpudev/rte_gpudev.h +++ b/lib/gpudev/rte_gpudev.h @@ -38,6 +38,9 @@ extern "C" { /** Catch-all callback data. */ #define RTE_GPU_CALLBACK_ANY_DATA ((void *)-1) +/** Access variable as volatile. */ +#define RTE_GPU_VOLATILE(x) (*(volatile typeof(x)*)&(x)) + /** Store device info. */ struct rte_gpu_info { /** Unique identifier name. */ @@ -68,6 +71,22 @@ enum rte_gpu_event { typedef void (rte_gpu_callback_t)(int16_t dev_id, enum rte_gpu_event event, void *user_data); +/** Memory where communication flag is allocated. */ +enum rte_gpu_comm_flag_type { + /** Allocate flag on CPU memory visible from device. */ + RTE_GPU_COMM_FLAG_CPU = 0, +}; + +/** Communication flag to coordinate CPU with the device. */ +struct rte_gpu_comm_flag { + /** Device that will use the device flag. */ + uint16_t dev_id; + /** Pointer to flag memory area. */ + uint32_t *ptr; + /** Type of memory used to allocate the flag. */ + enum rte_gpu_comm_flag_type mtype; +}; + /** * @warning * @b EXPERIMENTAL: this API may change without prior notice. @@ -405,6 +424,95 @@ int rte_gpu_unregister(int16_t dev_id, void *ptr); __rte_experimental int rte_gpu_mbw(int16_t dev_id); +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Create a communication flag that can be shared + * between CPU threads and device workload to exchange some status info + * (e.g. work is done, processing can start, etc..). + * + * @param dev_id + * Reference device ID. + * @param devflag + * Pointer to the memory area of the devflag structure. + * @param mtype + * Type of memory to allocate the communication flag. + * + * @return + * 0 on success, -rte_errno otherwise: + * - ENODEV if invalid dev_id + * - EINVAL if invalid inputs + * - ENOTSUP if operation not supported by the driver + * - ENOMEM if out of space + * - EPERM if driver error + */ +__rte_experimental +int rte_gpu_comm_create_flag(uint16_t dev_id, + struct rte_gpu_comm_flag *devflag, + enum rte_gpu_comm_flag_type mtype); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Deallocate a communication flag. + * + * @param devflag + * Pointer to the memory area of the devflag structure. + * + * @return + * 0 on success, -rte_errno otherwise: + * - ENODEV if invalid dev_id + * - EINVAL if NULL devflag + * - ENOTSUP if operation not supported by the driver + * - EPERM if driver error + */ +__rte_experimental +int rte_gpu_comm_destroy_flag(struct rte_gpu_comm_flag *devflag); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Set the value of a communication flag as the input value. + * Flag memory area is treated as volatile. + * The flag must have been allocated with RTE_GPU_COMM_FLAG_CPU. + * + * @param devflag + * Pointer to the memory area of the devflag structure. + * @param val + * Value to set in the flag. + * + * @return + * 0 on success, -rte_errno otherwise: + * - EINVAL if invalid input params + */ +__rte_experimental +int rte_gpu_comm_set_flag(struct rte_gpu_comm_flag *devflag, + uint32_t val); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Get the value of the communication flag. + * Flag memory area is treated as volatile. + * The flag must have been allocated with RTE_GPU_COMM_FLAG_CPU. + * + * @param devflag + * Pointer to the memory area of the devflag structure. + * @param val + * Flag output value. + * + * @return + * 0 on success, -rte_errno otherwise: + * - EINVAL if invalid input params + */ +__rte_experimental +int rte_gpu_comm_get_flag_value(struct rte_gpu_comm_flag *devflag, + uint32_t *val); + #ifdef __cplusplus } #endif diff --git a/lib/gpudev/version.map b/lib/gpudev/version.map index d72d470d8e..2fc039373a 100644 --- a/lib/gpudev/version.map +++ b/lib/gpudev/version.map @@ -6,6 +6,10 @@ EXPERIMENTAL { rte_gpu_callback_register; rte_gpu_callback_unregister; rte_gpu_close; + rte_gpu_comm_create_flag; + rte_gpu_comm_destroy_flag; + rte_gpu_comm_get_flag_value; + rte_gpu_comm_set_flag; rte_gpu_count_avail; rte_gpu_find_next; rte_gpu_free; From patchwork Sat Oct 9 01:53:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elena Agostini X-Patchwork-Id: 100837 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 77883A0C43; Fri, 8 Oct 2021 19:44:34 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9CA2741144; Fri, 8 Oct 2021 19:43:49 +0200 (CEST) Received: from NAM12-DM6-obe.outbound.protection.outlook.com (mail-dm6nam12on2053.outbound.protection.outlook.com [40.107.243.53]) by mails.dpdk.org (Postfix) with ESMTP id 4CF184111B for ; Fri, 8 Oct 2021 19:43:48 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Kj7+I5xxo5z5vF9nU27z3r0TzgRxFot5/DvLyoCNzAPNeACCTQl6VEKxNtcxfYmyPAes7S97f/NwZSRrSAg/6oPN/GuP47Z9hq2DELGDlbOKUCByKnIfLSbEhp961tP3XB3rYFHxbEYEfsrY4a0vrNkkYZ6Lq9JEFRfBCD2CTKX1oHyI8XM7xLMOAMh6WcPm3CXkvXJLH2h1wi8BMK8+RR4w/H1U3QoO0K39nLxpoag5BjBVNZ3dMClL6c/x+AuzqDH6vauMhXfrISoz/eFQ25bdPP2x3k+1F/RzUBN1X0uzLrzr+6uB6R+eiWbjVYpgpfFvLjaZF+dLmhXgtf4Z9g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=s/WBxikyjDTAI7mZnrXEdxFV5ugiZjp9vYBgnidbAAQ=; b=aLycI1AASeoKuB5A/HgifMcJBu0M4N9iGPaPxQxnHBAj39X++Ia1Z352IFdVjiPARuef1L5Vpjg3oF1C1yjeSfGi5vH8ITrcy+FGdooODwa0TpOdEc5x4r4kCQCU+LeGclMfURz+MnD2+TEq8dp6mrmJpTXeniBafwebCxf7o3eaqIm7sNzPwYW8tVGQ1BO5/n6q84gal1rRqYh42ZkYLgAjHVRklkGG/RNU4sy8JFx1UPmrmMCA2LzI8XT79ZQE0cM2RjTrZWHMxLrMGjULY2pnPW7w9EHAKXTQOoIBEEth3NDDYDWgl3rER8lR+Lhf7eGVcc4m2TIwsbz3c1OrqQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=dpdk.org smtp.mailfrom=nvidia.com; dmarc=pass (p=quarantine sp=none pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=s/WBxikyjDTAI7mZnrXEdxFV5ugiZjp9vYBgnidbAAQ=; b=G+rp4mS6eDVbcTu4qq39AASDfTUNztTxSOX6WfWT/usKhJcKw1EMtrIlSxf0THHNGNfzGQ0xrnFRo9zHCoM7XVoOZcUpFUXZT7I33wYYV6Ia/6tiCoqV8EyI5GqTUkuR6zR5OrDS7HRG2zfEO8eNtEZOCeDbuGNiwpZW+VYMrml7YUeuoxKoZ/kwb0cQbUWW5jRyt7ReNj8N6COhGXAqsGhEIRSToTUNvQH70qfQxa0lweg9iuUIDEXIagFT6zV9t7U7TYN6ckqSyi1I4AMRpq733SLMf0jbBs/+454mD8+kq1iJoaQCfEiCINf1hwLd1DJapKCxG/3sYpBM2CJWng== Received: from MW4PR03CA0121.namprd03.prod.outlook.com (2603:10b6:303:8c::6) by MN2PR12MB3485.namprd12.prod.outlook.com (2603:10b6:208:c9::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.20; Fri, 8 Oct 2021 17:43:46 +0000 Received: from CO1NAM11FT047.eop-nam11.prod.protection.outlook.com (2603:10b6:303:8c:cafe::3d) by MW4PR03CA0121.outlook.office365.com (2603:10b6:303:8c::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:46 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; dpdk.org; dkim=none (message not signed) header.d=none;dpdk.org; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by CO1NAM11FT047.mail.protection.outlook.com (10.13.174.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:46 +0000 Received: from nvidia.com (172.20.187.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Fri, 8 Oct 2021 17:43:41 +0000 From: To: CC: Elena Agostini Date: Sat, 9 Oct 2021 01:53:48 +0000 Message-ID: <20211009015349.9694-9-eagostini@nvidia.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211009015349.9694-1-eagostini@nvidia.com> References: <20210602203531.2288645-1-thomas@monjalon.net> <20211009015349.9694-1-eagostini@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [172.20.187.6] X-ClientProxiedBy: HQMAIL111.nvidia.com (172.20.187.18) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 296d36d5-e2f5-4430-6a74-08d98a832dbd X-MS-TrafficTypeDiagnostic: MN2PR12MB3485: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:962; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: BPx+UCI4Ug7vUdM8CRIdfoxwG/UMtY58XtwVDdWL9rT6ZQR0U4e2Qi9T6QVbakP48XlvLXxXX0YXvycDUyf8PlkkOOCOIJdCL7uA2piiVJveDiBwEYetWLjCtsvjSPulKaCRUe1thOmlymWWDgUIjt6uokTMau9o++ZwpJwEd0i6SuLuBpU1poZdAKLvrUl0yxd0DbhPDdbCG4KoUywVPGaJdALF5w88KI7VB7t2bU1FtO8WNzFBv6XnEW+AH2IxuCYS1VQ7EurT2F+6rYNWaAyAEADuaHTSSTtjydvaktrJYRDIxAxZuwjFsUO9q2WFm+CtoJQDkZ38DSGHVS0suyXVNnzfuQr31YMhudWwCC0SKGeW5E/I8N61qSsK1OD2WK+Ek+Ycd6waEQyMgbFLRhSe9e4V3KJFsFzS1npV8vw7xPmqjFAinmiw/p8HXQKTBX9ABCdpECwSlriGiuk6226NVvA1gGSTjIwDtsQycNrvzyPybAceiRYalhkt7QkA+lun6hyzIQGvkNLWw1rCRm1wN7xi7YLkq71pN27QAD9rkaU/JGhNCa25ebXggOwAP8HJGBb/UdOfQIQXwzGNn8sca0K2w8qM+mZpDPx41vVSng81/D2T1an1jJTnqfx1YJ7/JCJCIZA32QdMyC6bRylTksYyMNovTTbUWOyGrRhA7dOLLGjNnQvzqJV58c4DKoRrrl2AFiR6F3eesCHk3A== X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(46966006)(36840700001)(36860700001)(508600001)(86362001)(55016002)(7696005)(30864003)(316002)(8936002)(6286002)(70586007)(70206006)(107886003)(8676002)(426003)(83380400001)(336012)(36756003)(186003)(82310400003)(5660300002)(356005)(6916009)(7636003)(26005)(4326008)(16526019)(2616005)(47076005)(2876002)(2906002)(1076003); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Oct 2021 17:43:46.1323 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 296d36d5-e2f5-4430-6a74-08d98a832dbd X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: CO1NAM11FT047.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB3485 Subject: [dpdk-dev] [PATCH v3 8/9] gpudev: add communication list X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Elena Agostini In heterogeneous computing system, processing is not only in the CPU. Some tasks can be delegated to devices working in parallel. When mixing network activity with task processing there may be the need to put in communication the CPU with the device in order to synchronize operations. An example could be a receive-and-process application where CPU is responsible for receiving packets in multiple mbufs and the GPU is responsible for processing the content of those packets. The purpose of this list is to provide a buffer in CPU memory visible from the GPU that can be treated as a circular buffer to let the CPU provide fondamental info of received packets to the GPU. A possible use-case is described below. CPU: - Trigger some task on the GPU - in a loop: - receive a number of packets - provide packets info to the GPU GPU: - Do some pre-processing - Wait to receive a new set of packet to be processed Layout of a communication list would be: ------- | 0 | => pkt_list | status | | #pkts | ------- | 1 | => pkt_list | status | | #pkts | ------- | 2 | => pkt_list | status | | #pkts | ------- | .... | => pkt_list ------- Signed-off-by: Elena Agostini --- app/test-gpudev/main.c | 103 +++++++++++++++ doc/guides/prog_guide/gpudev.rst | 16 +++ doc/guides/rel_notes/release_21_11.rst | 2 +- lib/gpudev/gpudev.c | 165 +++++++++++++++++++++++++ lib/gpudev/meson.build | 2 + lib/gpudev/rte_gpudev.h | 129 +++++++++++++++++++ lib/gpudev/version.map | 4 + 7 files changed, 420 insertions(+), 1 deletion(-) diff --git a/app/test-gpudev/main.c b/app/test-gpudev/main.c index 22f5c950b2..8f7ffa4c63 100644 --- a/app/test-gpudev/main.c +++ b/app/test-gpudev/main.c @@ -227,6 +227,108 @@ create_update_comm_flag(uint16_t gpu_id) return 0; } +static int +simulate_gpu_task(struct rte_gpu_comm_list *comm_list_item, int num_pkts) +{ + int idx; + + if(comm_list_item == NULL) + return -1; + + for (idx = 0; idx < num_pkts; idx++) { + /** + * consume(comm_list_item->pkt_list[idx].addr); + */ + } + comm_list_item->status = RTE_GPU_COMM_LIST_DONE; + + return 0; +} + +static int +create_update_comm_list(uint16_t gpu_id) +{ + int ret = 0; + int i = 0; + struct rte_gpu_comm_list * comm_list; + uint32_t num_comm_items = 1024; + struct rte_mbuf * mbufs[10]; + + printf("\n=======> TEST: Communication list\n"); + + comm_list = rte_gpu_comm_create_list(gpu_id, num_comm_items); + if(comm_list == NULL) + { + fprintf(stderr, "rte_gpu_comm_create_list returned error %d\n", ret); + return -1; + } + + /** + * Simulate DPDK receive functions like rte_eth_rx_burst() + */ + for(i = 0; i < 10; i++) + { + mbufs[i] = rte_zmalloc(NULL, sizeof(struct rte_mbuf), 0); + if (mbufs[i] == NULL) { + fprintf(stderr, "Failed to allocate fake mbufs in CPU memory.\n"); + return -1; + } + + memset(mbufs[i], 0, sizeof(struct rte_mbuf)); + } + + /** + * Populate just the first item of the list + */ + ret = rte_gpu_comm_populate_list_pkts(&(comm_list[0]), mbufs, 10); + if(ret < 0) + { + fprintf(stderr, "rte_gpu_comm_populate_list_pkts returned error %d\n", ret); + return -1; + } + + ret = rte_gpu_comm_cleanup_list(&(comm_list[0])); + if(ret == 0) + { + fprintf(stderr, "rte_gpu_comm_cleanup_list erroneusly cleaned the list even if packets have not beeing consumed yet\n"); + return -1; + } + else + { + fprintf(stderr, "rte_gpu_comm_cleanup_list correctly didn't clean up the packets because they have not beeing consumed yet\n"); + } + + /** + * Simulate a GPU tasks going through the packet list to consume + * mbufs packets and release them + */ + simulate_gpu_task(&(comm_list[0]), 10); + + /** + * Packets have been consumed, now the communication item + * and the related mbufs can be all released + */ + ret = rte_gpu_comm_cleanup_list(&(comm_list[0])); + if(ret < 0) + { + fprintf(stderr, "rte_gpu_comm_cleanup_list returned error %d\n", ret); + return -1; + } + + ret = rte_gpu_comm_destroy_list(comm_list, num_comm_items); + if(ret < 0) + { + fprintf(stderr, "rte_gpu_comm_destroy_list returned error %d\n", ret); + return -1; + } + + for(i = 0; i < 10; i++) + rte_free(mbufs[i]); + + printf("\nCommunication list test passed!\n"); + return 0; +} + int main(int argc, char **argv) { @@ -282,6 +384,7 @@ main(int argc, char **argv) * Communication items test */ create_update_comm_flag(gpu_id); + create_update_comm_list(gpu_id); /* clean up the EAL */ rte_eal_cleanup(); diff --git a/doc/guides/prog_guide/gpudev.rst b/doc/guides/prog_guide/gpudev.rst index e0db627aed..cbaec5a1e4 100644 --- a/doc/guides/prog_guide/gpudev.rst +++ b/doc/guides/prog_guide/gpudev.rst @@ -86,3 +86,19 @@ that's waiting to receive a signal from the CPU to move forward with the execution. The communication flag allocates a CPU memory GPU-visible ``uint32_t`` flag that can be used by the CPU to communicate with a GPU task. + +Communication list +~~~~~~~~~~~~~~~~~~ + +By default, DPDK pulls free mbufs from a mempool to receive packets. +Best practice, expecially in a multithreaded application, +is to no make any assumption on which mbufs will be used +to receive the next bursts of packets. +Considering an application with a GPU memory mempool +attached to a receive queue having some task waiting on the GPU +to receive a new burst of packets to be processed, +there is the need to communicate from the CPU +the list of mbuf payload addresses where received packet have been stored. +The ``rte_gpu_comm_*()`` functions are responsible to create a list of packets +that can be populated with receive mbuf payload addresses +and communicated to the task running on the GPU. diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst index 59ab1a1920..0c6d92a269 100644 --- a/doc/guides/rel_notes/release_21_11.rst +++ b/doc/guides/rel_notes/release_21_11.rst @@ -66,7 +66,7 @@ New Features * Device information * Memory management - * Communication flag + * Communication flag & list * **Added new RSS offload types for IPv4/L4 checksum in RSS flow.** diff --git a/lib/gpudev/gpudev.c b/lib/gpudev/gpudev.c index 827e29d8f6..3cfde97e3c 100644 --- a/lib/gpudev/gpudev.c +++ b/lib/gpudev/gpudev.c @@ -737,3 +737,168 @@ rte_gpu_comm_get_flag_value(struct rte_gpu_comm_flag *devflag, uint32_t *val) return 0; } + +struct rte_gpu_comm_list * +rte_gpu_comm_create_list(uint16_t dev_id, + uint32_t num_comm_items) +{ + struct rte_gpu_comm_list *comm_list; + uint32_t idx_l; + int ret; + struct rte_gpu *dev; + + if (num_comm_items == 0) { + rte_errno = EINVAL; + return NULL; + } + + dev = gpu_get_by_id(dev_id); + if (dev == NULL) { + GPU_LOG(ERR, "memory barrier for invalid device ID %d", dev_id); + rte_errno = ENODEV; + return NULL; + } + + comm_list = rte_zmalloc(NULL, sizeof(struct rte_gpu_comm_list) * num_comm_items, 0); + if (comm_list == NULL) { + rte_errno = ENOMEM; + return NULL; + } + + ret = rte_gpu_register(dev_id, sizeof(struct rte_gpu_comm_list) * num_comm_items, comm_list); + if(ret < 0) + { + rte_errno = ENOMEM; + return NULL; + } + + for (idx_l = 0; idx_l < num_comm_items; idx_l++) { + comm_list[idx_l].pkt_list = rte_zmalloc(NULL, sizeof(struct rte_gpu_comm_pkt) * RTE_GPU_COMM_LIST_PKTS_MAX, 0); + if (comm_list[idx_l].pkt_list == NULL) { + rte_errno = ENOMEM; + return NULL; + } + + ret = rte_gpu_register(dev_id, sizeof(struct rte_gpu_comm_pkt) * RTE_GPU_COMM_LIST_PKTS_MAX, comm_list[idx_l].pkt_list); + if(ret < 0) + { + rte_errno = ENOMEM; + return NULL; + } + + RTE_GPU_VOLATILE(comm_list[idx_l].status) = RTE_GPU_COMM_LIST_FREE; + comm_list[idx_l].num_pkts = 0; + comm_list[idx_l].dev_id = dev_id; + } + + return comm_list; +} + +int +rte_gpu_comm_destroy_list(struct rte_gpu_comm_list *comm_list, + uint32_t num_comm_items) +{ + uint32_t idx_l; + int ret; + uint16_t dev_id; + + if (comm_list == NULL) { + rte_errno = EINVAL; + return -rte_errno; + } + + dev_id = comm_list[0].dev_id; + + for (idx_l = 0; idx_l < num_comm_items; idx_l++) + { + ret = rte_gpu_unregister(dev_id, comm_list[idx_l].pkt_list); + if(ret < 0) + { + rte_errno = EINVAL; + return -1; + } + + rte_free(comm_list[idx_l].pkt_list); + } + + ret = rte_gpu_unregister(dev_id, comm_list); + if(ret < 0) + { + rte_errno = EINVAL; + return -1; + } + + rte_free(comm_list); + + return 0; +} + +int +rte_gpu_comm_populate_list_pkts(struct rte_gpu_comm_list *comm_list_item, + struct rte_mbuf **mbufs, uint32_t num_mbufs) +{ + uint32_t idx; + + if (comm_list_item == NULL || comm_list_item->pkt_list == NULL || + mbufs == NULL || num_mbufs > RTE_GPU_COMM_LIST_PKTS_MAX) { + rte_errno = EINVAL; + return -rte_errno; + } + + for (idx = 0; idx < num_mbufs; idx++) { + /* support only unchained mbufs */ + if (unlikely((mbufs[idx]->nb_segs > 1) || + (mbufs[idx]->next != NULL) || + (mbufs[idx]->data_len != mbufs[idx]->pkt_len))) { + rte_errno = ENOTSUP; + return -rte_errno; + } + comm_list_item->pkt_list[idx].addr = + rte_pktmbuf_mtod_offset(mbufs[idx], uintptr_t, 0); + comm_list_item->pkt_list[idx].size = mbufs[idx]->pkt_len; + comm_list_item->pkt_list[idx].opaque = mbufs[idx]; + } + + RTE_GPU_VOLATILE(comm_list_item->num_pkts) = num_mbufs; + rte_gpu_mbw(comm_list_item->dev_id); + RTE_GPU_VOLATILE(comm_list_item->status) = RTE_GPU_COMM_LIST_READY; + rte_gpu_mbw(comm_list_item->dev_id); + + return 0; +} + +int +rte_gpu_comm_cleanup_list(struct rte_gpu_comm_list *comm_list_item) +{ + struct rte_mbuf *mbufs[RTE_GPU_COMM_LIST_PKTS_MAX]; + uint32_t idx = 0; + + if (comm_list_item == NULL) { + rte_errno = EINVAL; + return -rte_errno; + } + + if (RTE_GPU_VOLATILE(comm_list_item->status) == + RTE_GPU_COMM_LIST_READY) { + GPU_LOG(ERR, "packet list is still in progress"); + rte_errno = EINVAL; + return -rte_errno; + } + + for (idx = 0; idx < RTE_GPU_COMM_LIST_PKTS_MAX; idx++) { + if (comm_list_item->pkt_list[idx].addr == 0) + break; + + comm_list_item->pkt_list[idx].addr = 0; + comm_list_item->pkt_list[idx].size = 0; + mbufs[idx] = (struct rte_mbuf *) comm_list_item->pkt_list[idx].opaque; + } + + rte_pktmbuf_free_bulk(mbufs, idx); + + RTE_GPU_VOLATILE(comm_list_item->status) = RTE_GPU_COMM_LIST_FREE; + RTE_GPU_VOLATILE(comm_list_item->num_pkts) = 0; + rte_mb(); + + return 0; +} diff --git a/lib/gpudev/meson.build b/lib/gpudev/meson.build index 608154817b..89a118f357 100644 --- a/lib/gpudev/meson.build +++ b/lib/gpudev/meson.build @@ -8,3 +8,5 @@ headers = files( sources = files( 'gpudev.c', ) + +deps += ['mbuf'] diff --git a/lib/gpudev/rte_gpudev.h b/lib/gpudev/rte_gpudev.h index 4a10a8bcf5..a13a4fc2c8 100644 --- a/lib/gpudev/rte_gpudev.h +++ b/lib/gpudev/rte_gpudev.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -41,6 +42,9 @@ extern "C" { /** Access variable as volatile. */ #define RTE_GPU_VOLATILE(x) (*(volatile typeof(x)*)&(x)) +/** Max number of packets per communication list. */ +#define RTE_GPU_COMM_LIST_PKTS_MAX 1024 + /** Store device info. */ struct rte_gpu_info { /** Unique identifier name. */ @@ -87,6 +91,43 @@ struct rte_gpu_comm_flag { enum rte_gpu_comm_flag_type mtype; }; +/** List of packets shared among CPU and device. */ +struct rte_gpu_comm_pkt { + /** Address of the packet in memory (e.g. mbuf->buf_addr). */ + uintptr_t addr; + /** Size in byte of the packet. */ + size_t size; + /** Mbuf reference to release it in the rte_gpu_comm_cleanup_list(). */ + void *opaque; +}; + +/** Possible status for the list of packets shared among CPU and device. */ +enum rte_gpu_comm_list_status { + /** Packet list can be filled with new mbufs, no one is using it. */ + RTE_GPU_COMM_LIST_FREE = 0, + /** Packet list has been filled with new mbufs and it's ready to be used .*/ + RTE_GPU_COMM_LIST_READY, + /** Packet list has been processed, it's ready to be freed. */ + RTE_GPU_COMM_LIST_DONE, + /** Some error occurred during packet list processing. */ + RTE_GPU_COMM_LIST_ERROR, +}; + +/** + * Communication list holding a number of lists of packets + * each having a status flag. + */ +struct rte_gpu_comm_list { + /** Device that will use the communication list. */ + uint16_t dev_id; + /** List of packets populated by the CPU with a set of mbufs info. */ + struct rte_gpu_comm_pkt *pkt_list; + /** Number of packets in the list. */ + uint32_t num_pkts; + /** Status of the list. */ + enum rte_gpu_comm_list_status status; +}; + /** * @warning * @b EXPERIMENTAL: this API may change without prior notice. @@ -513,6 +554,94 @@ __rte_experimental int rte_gpu_comm_get_flag_value(struct rte_gpu_comm_flag *devflag, uint32_t *val); +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Create a communication list that can be used to share packets + * between CPU and device. + * Each element of the list contains: + * - a packet list of RTE_GPU_COMM_LIST_PKTS_MAX elements + * - number of packets in the list + * - a status flag to communicate if the packet list is FREE, + * READY to be processed, DONE with processing. + * + * The list is allocated in CPU-visible memory. + * At creation time, every list is in FREE state. + * + * @param dev_id + * Reference device ID. + * @param num_comm_items + * Number of items in the communication list. + * + * @return + * A pointer to the allocated list, otherwise NULL and rte_errno is set: + * - EINVAL if invalid input params + */ +__rte_experimental +struct rte_gpu_comm_list *rte_gpu_comm_create_list(uint16_t dev_id, + uint32_t num_comm_items); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Destroy a communication list. + * + * @param comm_list + * Communication list to be destroyed. + * @param num_comm_items + * Number of items in the communication list. + * + * @return + * 0 on success, -rte_errno otherwise: + * - EINVAL if invalid input params + */ +__rte_experimental +int rte_gpu_comm_destroy_list(struct rte_gpu_comm_list *comm_list, + uint32_t num_comm_items); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Populate the packets list of the communication item + * with info from a list of mbufs. + * Status flag of that packet list is set to READY. + * + * @param comm_list_item + * Communication list item to fill. + * @param mbufs + * List of mbufs. + * @param num_mbufs + * Number of mbufs. + * + * @return + * 0 on success, -rte_errno otherwise: + * - EINVAL if invalid input params + * - ENOTSUP if mbufs are chained (multiple segments) + */ +__rte_experimental +int rte_gpu_comm_populate_list_pkts(struct rte_gpu_comm_list *comm_list_item, + struct rte_mbuf **mbufs, uint32_t num_mbufs); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Reset a communication list item to the original state. + * The status flag set to FREE and mbufs are returned to the pool. + * + * @param comm_list_item + * Communication list item to reset. + * + * @return + * 0 on success, -rte_errno otherwise: + * - EINVAL if invalid input params + */ +__rte_experimental +int rte_gpu_comm_cleanup_list(struct rte_gpu_comm_list *comm_list_item); + #ifdef __cplusplus } #endif diff --git a/lib/gpudev/version.map b/lib/gpudev/version.map index 2fc039373a..45a35fa6e4 100644 --- a/lib/gpudev/version.map +++ b/lib/gpudev/version.map @@ -6,9 +6,13 @@ EXPERIMENTAL { rte_gpu_callback_register; rte_gpu_callback_unregister; rte_gpu_close; + rte_gpu_comm_cleanup_list; rte_gpu_comm_create_flag; + rte_gpu_comm_create_list; rte_gpu_comm_destroy_flag; + rte_gpu_comm_destroy_list; rte_gpu_comm_get_flag_value; + rte_gpu_comm_populate_list_pkts; rte_gpu_comm_set_flag; rte_gpu_count_avail; rte_gpu_find_next; From patchwork Sat Oct 9 01:53:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elena Agostini X-Patchwork-Id: 100838 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9ECD1A0C43; Fri, 8 Oct 2021 19:44:42 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id EDD974114E; Fri, 8 Oct 2021 19:43:52 +0200 (CEST) Received: from NAM11-BN8-obe.outbound.protection.outlook.com (mail-bn8nam11on2082.outbound.protection.outlook.com [40.107.236.82]) by mails.dpdk.org (Postfix) with ESMTP id 8847B41142 for ; Fri, 8 Oct 2021 19:43:49 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=nu3kfsr/+gxQGf9miZHy3y+YsRwJT7jaEW9BNIskEhaqixrxYwzUf881VUwpChVtPJvc1Ebf0R9FTlO20uoI7SYo6wEDyjU6hpzWrKnZg7/L02eA4Mc55C1awu94dcODsDjo8VJoBu+ZSZsm7P2xp/JiiJhNP7L4eVCgoKxBE2GFLqOdcPUfAa3HLGpLShNSJyVdGTxLw49YRrahynqOKju4lSUsyj4kyux0Oe2edYKYltrTQ+S1+XinXmwqutJdlDDFBgfy/Up70mNcF7JP/3GAydF6ynAESjdxi0sQitrPD6i6Z/kb3puf0zBcSeHQD3u6jp9O/pj80IySn5A/8A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=OxtiHhow+oMMccuwlq9p6l5sIJT9EIjR/wpVQcG82Kw=; b=TD1GLD5F6H4/WK8qkVLEpmgCVYyKRb5tfkacU/ucSGfsXQv6BHnClrAp3INR9I3Y4qOSMr6WeA3OUav/QjDzcpZXQYmXBUKb+TRV8S/49y9fAMlWNyhfc7bUUpCCXiGDanFt1nLwjikg9ni6LJxg1D5mp3AZeNPlIHOjnQ5MTX+Cgox76Y803u81fyIl036GZAkhg8iNQxCBwTIooWj+32UN/qmk2lr8zLthomYO9ejHbYK83E7LM9XPPNf9hqrmK3vdNW8SZWNOuPBsGvzvuoVGYOFu2ciosgnKV1jNuLIrf5LXlsGZI+sLZFDXzW0FbIilLJq/AiFwZn/Ezf/waw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=dpdk.org smtp.mailfrom=nvidia.com; dmarc=pass (p=quarantine sp=none pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=OxtiHhow+oMMccuwlq9p6l5sIJT9EIjR/wpVQcG82Kw=; b=KDM6lgQn5LoCtFvo+/bHBgXapfBuG479xHW14A+4+vgksFb2dtge6u7fewsAvlT/E2x+pf8UQBV9+vxwWUW0vgR8zoS/uyq0RjVjH5EycscdOiAnNW7/kQRd6PsrmpIdWC9dHSnWfB/v6hBixjW2TruUSwI7QldvZJ7nldBQ/iS9f7ugF9KSRZSdNoTq2z1MCitHQfpiGSJnB8zbJevp+9vhm5WvkvDn6mLx05XaP7I+QOpW/J3MvKCCVLRdGC1CBUO25jEakxQz+/QlVdTNSfRRe3qog0SoJ0KTGeaZrXnkvlpHwKeQJzdL7nQc9BGFLJERC3AXGX55MD474eG6Gw== Received: from MW4PR03CA0130.namprd03.prod.outlook.com (2603:10b6:303:8c::15) by CH0PR12MB5122.namprd12.prod.outlook.com (2603:10b6:610:bd::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.22; Fri, 8 Oct 2021 17:43:47 +0000 Received: from CO1NAM11FT047.eop-nam11.prod.protection.outlook.com (2603:10b6:303:8c:cafe::eb) by MW4PR03CA0130.outlook.office365.com (2603:10b6:303:8c::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:47 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; dpdk.org; dkim=none (message not signed) header.d=none;dpdk.org; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by CO1NAM11FT047.mail.protection.outlook.com (10.13.174.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4587.18 via Frontend Transport; Fri, 8 Oct 2021 17:43:47 +0000 Received: from nvidia.com (172.20.187.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Fri, 8 Oct 2021 17:43:43 +0000 From: To: CC: Elena Agostini Date: Sat, 9 Oct 2021 01:53:49 +0000 Message-ID: <20211009015349.9694-10-eagostini@nvidia.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211009015349.9694-1-eagostini@nvidia.com> References: <20210602203531.2288645-1-thomas@monjalon.net> <20211009015349.9694-1-eagostini@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [172.20.187.6] X-ClientProxiedBy: HQMAIL111.nvidia.com (172.20.187.18) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 9878705d-b820-4bd2-0a94-08d98a832e51 X-MS-TrafficTypeDiagnostic: CH0PR12MB5122: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:6430; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: vC5baE00yaFCYcQPz4GGTviXD4KHj6MKEcJpe0EkJBi32nsyg4ATReJQQpfXVKdbIiJC0DIUFCh2NRCBEzgeel+u0JB54LUB6iklKCN+ndHQmrWh5zKLOBMAJs1Z6vk65DjV0MWy7rpDeWDlph+mTdIqdDf/q7yLt9rP+NdOljl4hsXWt/HruaxggmrLw1LH2AZAikZ/ngATM2Va2pcimlc2tOojPbmHG6AmDkiJ4kx7Jr9hl6BGmfdl0xQzAhUxzGRwKwLTcjlvyr9yyhu6kN85FmLvyMGsDqOVgAG0Lx3+W3QWsKiCB1hbVYH3giZItlutXgLmo2bjGQ8WQfd5qm1e3uxTOlqhppuNEI0WqtZ4TyzKoGQGA1Yv6rc8QB5/PXxZNDgXm/ooEBkLfJeAaHO4Gb2YXxaIpOMNhZV4axPWwVoxX/HGcROqvMjQX2mf4SFKwoQUcmYclLA52KRFtkc7eBwauJlQ6pKNAVCtwHKKJVFK86xioiapdkfiL1hSPEFmUa/Zj6Rz3TnOv/CfFy9zODe+zf2c1dfXj56Y5w610Lys1hiQXp45mj6BpBte8DEswxqI+fLOiCDI5Aq7ITaR6g1+zO7lin8gukbbdYIVXmD+FQO58ZKEPXocEkXrge2ZARNJTfoQzk4M1+V9k7mB9aKnKStzOgzS3jOZRkZR64NtmZ222unBWbEg5P5SE4dbaOn6jX1Wv/KxNQw5zQ== X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(36840700001)(46966006)(36756003)(86362001)(83380400001)(6286002)(47076005)(336012)(55016002)(36860700001)(107886003)(82310400003)(356005)(7696005)(1076003)(7636003)(426003)(2906002)(316002)(2876002)(4326008)(5660300002)(26005)(186003)(16526019)(508600001)(70206006)(70586007)(6916009)(8936002)(2616005)(8676002); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Oct 2021 17:43:47.0408 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 9878705d-b820-4bd2-0a94-08d98a832e51 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: CO1NAM11FT047.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH0PR12MB5122 Subject: [dpdk-dev] [PATCH v3 9/9] doc: add CUDA example in GPU guide X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Elena Agostini Signed-off-by: Elena Agostini --- doc/guides/prog_guide/gpudev.rst | 122 +++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/doc/guides/prog_guide/gpudev.rst b/doc/guides/prog_guide/gpudev.rst index cbaec5a1e4..1baf0c6772 100644 --- a/doc/guides/prog_guide/gpudev.rst +++ b/doc/guides/prog_guide/gpudev.rst @@ -102,3 +102,125 @@ the list of mbuf payload addresses where received packet have been stored. The ``rte_gpu_comm_*()`` functions are responsible to create a list of packets that can be populated with receive mbuf payload addresses and communicated to the task running on the GPU. + + +CUDA Example +------------ + +In the example below, there is a pseudo-code to give an example +about how to use functions in this library in case of a CUDA application. + +.. code-block:: c + + ////////////////////////////////////////////////////////////////////////// + ///// gpudev library + CUDA functions + ////////////////////////////////////////////////////////////////////////// + #define GPU_PAGE_SHIFT 16 + #define GPU_PAGE_SIZE (1UL << GPU_PAGE_SHIFT) + + int main() { + struct rte_gpu_flag quit_flag; + struct rte_gpu_comm_list *comm_list; + int nb_rx = 0; + int comm_list_entry = 0; + struct rte_mbuf * rx_mbufs[max_rx_mbufs]; + cudaStream_t cstream; + struct rte_mempool *mpool_payload, *mpool_header; + struct rte_pktmbuf_extmem ext_mem; + int16_t dev_id; + int16_t port_id = 0; + + /** Initialize CUDA objects (cstream, context, etc..). */ + /** Use gpudev library to register a new CUDA context if any */ + /** Let's assume the application wants to use the default context of the GPU device 0 */ + + dev_id = 0; + + /** + * Create an external memory mempool using memory allocated on the GPU. + */ + ext_mem.elt_size = mbufs_headroom_size; + ext_mem.buf_len = RTE_ALIGN_CEIL(mbufs_num * ext_mem.elt_size, GPU_PAGE_SIZE); + ext_mem.buf_iova = RTE_BAD_IOVA; + ext_mem.buf_ptr = rte_gpu_malloc(dev_id, ext_mem.buf_len, 0); + rte_extmem_register(ext_mem.buf_ptr, ext_mem.buf_len, NULL, ext_mem.buf_iova, GPU_PAGE_SIZE); + rte_dev_dma_map(rte_eth_devices[port_id].device, ext_mem.buf_ptr, ext_mem.buf_iova, ext_mem.buf_len); + mpool_payload = rte_pktmbuf_pool_create_extbuf("gpu_mempool", mbufs_num, + 0, 0, ext_mem.elt_size, + rte_socket_id(), &ext_mem, 1); + + /** + * Create CPU - device communication flag. With this flag, the CPU can tell to the CUDA kernel + * to exit from the main loop. + */ + rte_gpu_comm_create_flag(dev_id, &quit_flag, RTE_GPU_COMM_FLAG_CPU); + rte_gpu_comm_set_flag(&quit_flag , 0); + + /** + * Create CPU - device communication list. Each entry of this list will be populated by the CPU + * with a new set of received mbufs that the CUDA kernel has to process. + */ + comm_list = rte_gpu_comm_create_list(dev_id, num_entries); + + /** A very simple CUDA kernel with just 1 CUDA block and RTE_GPU_COMM_LIST_PKTS_MAX CUDA threads. */ + cuda_kernel_packet_processing<<<1, RTE_GPU_COMM_LIST_PKTS_MAX, 0, cstream>>>(quit_flag->ptr, comm_list, num_entries, ...); + + /** + * For simplicity, the CPU here receives only 2 bursts of mbufs. + * In a real application, network activity and device processing should overlap. + */ + nb_rx = rte_eth_rx_burst(port_id, queue_id, &(rx_mbufs[0]), max_rx_mbufs); + rte_gpu_comm_populate_list_pkts(comm_list[0], rx_mbufs, nb_rx); + nb_rx = rte_eth_rx_burst(port_id, queue_id, &(rx_mbufs[0]), max_rx_mbufs); + rte_gpu_comm_populate_list_pkts(comm_list[1], rx_mbufs, nb_rx); + + /** + * CPU waits for the completion of the packets' processing on the CUDA kernel + * and then it does a cleanup of the received mbufs. + */ + while(rte_gpu_comm_cleanup_list(comm_list[0])); + while(rte_gpu_comm_cleanup_list(comm_list[1])); + + /** CPU notifies the CUDA kernel that it has to terminate */ + rte_gpu_comm_set_flag(&quit_flag, 1); + + /** gpudev objects cleanup/destruction */ + /** CUDA cleanup */ + + rte_gpu_free(dev_id, ext_mem.buf_len); + + /** DPDK cleanup */ + + return 0; + } + + ////////////////////////////////////////////////////////////////////////// + ///// CUDA kernel + ////////////////////////////////////////////////////////////////////////// + + void cuda_kernel(uint32_t * quit_flag_ptr, struct rte_gpu_comm_list *comm_list, int comm_list_entries) { + int comm_list_index = 0; + struct rte_gpu_comm_pkt *pkt_list = NULL; + + /** Do some pre-processing operations. */ + + /** GPU kernel keeps checking this flag to know if it has to quit or wait for more packets. */ + while(*quit_flag_ptr == 0) + { + if(comm_list[comm_list_index]->status != RTE_GPU_COMM_LIST_READY) + continue; + + if(threadIdx.x < comm_list[comm_list_index]->num_pkts) + { + /** Each CUDA thread processes a different packet. */ + packet_processing(comm_list[comm_list_index]->addr, comm_list[comm_list_index]->size, ..); + } + __threadfence(); + __syncthreads(); + + /** Wait for new packets on the next communication list entry. */ + comm_list_index = (comm_list_index+1) % comm_list_entries; + } + + /** Do some post-processing operations. */ + }