From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id D0A70A0C43; Thu, 30 Sep 2021 19:40:24 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5B78C4113A; Thu, 30 Sep 2021 19:39:52 +0200 (CEST) Received: from NAM12-BN8-obe.outbound.protection.outlook.com (mail-bn8nam12on2083.outbound.protection.outlook.com [40.107.237.83]) by mails.dpdk.org (Postfix) with ESMTP id 82A4C410E5 for ; Thu, 30 Sep 2021 19:28:57 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=J3TkDL8Lr8VXVc73XWJ/t8idKNUMLE9xJwcMOUrJUKLtbW9K28m8UOXnHlJ/ISFmRMWsX6WU2lfKK456RghVqbLJDTLhN1n4lJT6PlQb0KBTDa60teUNfIxeQie+0q6pw5/tQ6dx/sn72A2vZhPw7CMgIZ0J2Wl/LnAcjFmBz+UibH9rzhGcR9dK7z3R67/uFJDHRxN6Pn4RZkzmIdjoc1OXlOGw4oTFlaVM6mw1X68tt0o1NQ0cREoe70pXL0FqTv0OfbSTndtZTX/7dJQWp9lRo6Y+ZFBm4pdziQ6o+SX8P5MdWVcwPSnQnEk7fHQoLl9TsjidDp7m/DMRCu1BLw== 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; bh=y/ueSUHu/js52gAvMmtWld2kOVcJnMUyQem30hnwhzY=; b=Gq04RML9FwGjN6WypPsh00OhGDDGHKNQnecxW0b/L0I4Nem/dHPicOSf88o+WEN0+pd/M3My7UcP9SqYc4mGjKlZngGOVM8TdAveAR60QV84ST+U80vlKI4iJKUnqA0gmHbbBJnRHPqB4i5swdB+BMPzH4Lpqe76swRtvmSFKbnwpzria+EXoF4ZEl12c4n+F49lopoFax3w0TpwGJg5/k9XOCmxYu5jQNldHwHqgPluNGivM6+DNY5KWXWhIW/DQIi5QwDcfLnxS5dAW5bOJCkqLvRv0uGz5t4QzITavYAI+SlQh6Djj/t8jQu8IcEJZAf3gux2LymPrSdnsk14oA== 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=y/ueSUHu/js52gAvMmtWld2kOVcJnMUyQem30hnwhzY=; b=mNH74890n13gznvYEYBrubCwFEk435kfpTvUIycPKRTRERwdQW+2se9w1NCrLEtV0o0q3D4smK9W92okpugPi2/fxohmJv4m+G84IX9e60bX/tWxBD/MHbReOfB9gnFOh/xmqarS49smHzDQHjFhflhNLH0BILXx87pcCZEgdUevpHihgi/zphG7oUQABzAz1diFFDhq5EVYv4a01sXHbB49DTteD+QgUGUrRlDK2sEVMmJQawmSxNwa6ub18J58IsMwzbuywak25iI1zCgFTXf/DbCD/Y7c6yaN1PjUEVfFcZUAUwmv8EcQP3Uczr8RrGDkAK7hsesqm1ey6RFZcA== Received: from BN0PR02CA0057.namprd02.prod.outlook.com (2603:10b6:408:e5::32) by DM6PR12MB3273.namprd12.prod.outlook.com (2603:10b6:5:188::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4566.14; Thu, 30 Sep 2021 17:28:55 +0000 Received: from BN8NAM11FT010.eop-nam11.prod.protection.outlook.com (2603:10b6:408:e5:cafe::b3) by BN0PR02CA0057.outlook.office365.com (2603:10b6:408:e5::32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4566.14 via Frontend Transport; Thu, 30 Sep 2021 17:28:55 +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 BN8NAM11FT010.mail.protection.outlook.com (10.13.177.53) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4566.14 via Frontend Transport; Thu, 30 Sep 2021 17:28:54 +0000 Received: from nvidia.com (172.20.187.5) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Thu, 30 Sep 2021 17:28:52 +0000 From: To: CC: Matan Azrad , Thomas Monjalon , Michael Baum Date: Thu, 30 Sep 2021 20:28:10 +0300 Message-ID: <20210930172822.1949969-7-michaelba@nvidia.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210930172822.1949969-1-michaelba@nvidia.com> References: <20210930172822.1949969-1-michaelba@nvidia.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [172.20.187.5] X-ClientProxiedBy: HQMAIL107.nvidia.com (172.20.187.13) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 729e1248-c216-4fd0-6820-08d98437c735 X-MS-TrafficTypeDiagnostic: DM6PR12MB3273: X-LD-Processed: 43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:2; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: wt/NIqhEx9M8nIs8nFzwQyB9vY3/4wvNdQDtPzEZNC7yaPWiQx7hDzw9z9m23ZUjf7k1FWW5HFbi07n70fR6fGENIJ6xdGm9vlzm8WC8Ofu3p2P1cp2tCav6VsJgqkvyRkZ9wHVtGfFFAW8szKRAGSZFUJ53jfn2zJmu+lfERIyFljYTg8OAb4yoNTs0LHSnoIRuf5qr10xC218Lsy3NZgj5PgdGSKAy6Alfmxgix11QSPqKk4WECsQ6+ccuiSEm+bSeuuzg2uR/xTNcDymhtKIq6/DRhcD1eFgSixZojUIOVhhILHbsAWbyXIUL00K2Ky946Ij4AnXjBSew3Z2kVeus+DHG8jMSqORxXni8RWGd9fd8GE47qrjD/znjHpOsdFZhfWhiPBgCHRudOemEOAkKVbfpiI7hbF0Ill2f6HwU4mU8rrYZn57jZv52EqqB5yx9xDsZx5I6cFf2htAHT1HKgpGaPOm1csi9wcF+x9Tly+a5Nc0T9MDyLQTYiu1ZgJe3b0LjpeyxawDIxdT65B4dR25US8PVYsz8gAdGwW5kskw+rFBX7d3Z0iokztI25y3ljSSRiECi2oTnZ9VrdUlRaZSZ7ARp2ftlTDkGBcdkl9nMyVLCSKOdIvbsFkbs5gYrUPruG10EULHLU9OPuPkaSLPLn8Cfmq//jvLER4ed4iAt4wn6htq55U2fYtafVlBjZtVqBJdohAjspIx67M7u5FGtClTG0zYEdcecMAs= 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)(8936002)(8676002)(5660300002)(6666004)(6286002)(316002)(7696005)(70206006)(47076005)(508600001)(6916009)(30864003)(70586007)(426003)(54906003)(83380400001)(336012)(26005)(107886003)(36756003)(356005)(4326008)(2876002)(55016002)(2616005)(2906002)(1076003)(186003)(16526019)(7636003)(86362001)(36860700001)(82310400003)(309714004); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Sep 2021 17:28:54.6681 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 729e1248-c216-4fd0-6820-08d98437c735 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: BN8NAM11FT010.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB3273 X-Mailman-Approved-At: Thu, 30 Sep 2021 19:39:43 +0200 Subject: [dpdk-dev] [PATCH 06/18] common/mlx5: move basic probing functions to common 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: Michael Baum Move open IBV/DevX device function to common. Signed-off-by: Michael Baum Acked-by: Matan Azrad --- drivers/common/mlx5/linux/mlx5_common_os.c | 86 ++++++ drivers/common/mlx5/linux/mlx5_common_os.h | 3 + drivers/common/mlx5/linux/mlx5_common_verbs.c | 70 +++++ drivers/common/mlx5/mlx5_common.h | 6 + drivers/common/mlx5/version.map | 1 + drivers/common/mlx5/windows/mlx5_common_os.c | 161 ++++++++++ drivers/net/mlx5/linux/mlx5_os.c | 289 ++++-------------- drivers/net/mlx5/mlx5.c | 8 +- drivers/net/mlx5/mlx5.h | 5 +- drivers/net/mlx5/windows/mlx5_os.c | 181 +---------- 10 files changed, 411 insertions(+), 399 deletions(-) diff --git a/drivers/common/mlx5/linux/mlx5_common_os.c b/drivers/common/mlx5/linux/mlx5_common_os.c index 9e0c823c97..2aa5684b05 100644 --- a/drivers/common/mlx5/linux/mlx5_common_os.c +++ b/drivers/common/mlx5/linux/mlx5_common_os.c @@ -16,6 +16,7 @@ #include "mlx5_common.h" #include "mlx5_common_log.h" +#include "mlx5_common_defs.h" #include "mlx5_common_os.h" #include "mlx5_glue.h" @@ -428,3 +429,88 @@ mlx5_os_get_ibv_device(const struct rte_pci_addr *addr) mlx5_glue->free_device_list(ibv_list); return ibv_match; } + +static int +mlx5_config_doorbell_mapping_env(int dbnc) +{ + char *env; + int value; + + MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY); + /* Get environment variable to store. */ + env = getenv(MLX5_SHUT_UP_BF); + value = env ? !!strcmp(env, "0") : MLX5_ARG_UNSET; + if (dbnc == MLX5_ARG_UNSET) + setenv(MLX5_SHUT_UP_BF, MLX5_SHUT_UP_BF_DEFAULT, 1); + else + setenv(MLX5_SHUT_UP_BF, + dbnc == MLX5_TXDB_NCACHED ? "1" : "0", 1); + return value; +} + +static void +mlx5_restore_doorbell_mapping_env(int value) +{ + MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY); + /* Restore the original environment variable state. */ + if (value == MLX5_ARG_UNSET) + unsetenv(MLX5_SHUT_UP_BF); + else + setenv(MLX5_SHUT_UP_BF, value ? "1" : "0", 1); +} + +/** + * Function API to open IB device. + * + * + * @param cdev + * Pointer to the mlx5 device. + * @param ctx_ptr + * Pointer to fill inside pointer to device context. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_os_open_device(struct mlx5_common_device *cdev, void **ctx_ptr) +{ + struct ibv_device *ibv; + struct ibv_context *ctx = NULL; + int dbmap_env; + + ibv = mlx5_os_get_ibv_dev(cdev->dev); + if (!ibv) + return -rte_errno; + DRV_LOG(INFO, "Dev information matches for device \"%s\".", ibv->name); + /* + * Configure environment variable "MLX5_BF_SHUT_UP" before the device + * creation. The rdma_core library checks the variable at device + * creation and stores the result internally. + */ + dbmap_env = mlx5_config_doorbell_mapping_env(cdev->config.dbnc); + /* Try to open IB device with DV first, then usual Verbs. */ + errno = 0; + ctx = mlx5_glue->dv_open_device(ibv); + if (ctx) { + cdev->config.devx = 1; + DRV_LOG(DEBUG, "DevX is supported."); + } else { + /* The environment variable is still configured. */ + ctx = mlx5_glue->open_device(ibv); + if (ctx == NULL) + goto error; + DRV_LOG(DEBUG, "DevX is NOT supported."); + } + /* The device is created, no need for environment. */ + mlx5_restore_doorbell_mapping_env(dbmap_env); + /* Hint libmlx5 to use PMD allocator for data plane resources */ + mlx5_set_context_attr(cdev->dev, ctx); + *ctx_ptr = (void *)ctx; + return 0; +error: + rte_errno = errno ? errno : ENODEV; + /* The device creation is failed, no need for environment. */ + mlx5_restore_doorbell_mapping_env(dbmap_env); + DRV_LOG(ERR, "Failed to open IB device \"%s\".", ibv->name); + return -rte_errno; +} diff --git a/drivers/common/mlx5/linux/mlx5_common_os.h b/drivers/common/mlx5/linux/mlx5_common_os.h index c3202b6786..05c8ae1ba5 100644 --- a/drivers/common/mlx5/linux/mlx5_common_os.h +++ b/drivers/common/mlx5/linux/mlx5_common_os.h @@ -296,4 +296,7 @@ __rte_internal struct ibv_device * mlx5_os_get_ibv_dev(const struct rte_device *dev); +void +mlx5_set_context_attr(struct rte_device *dev, struct ibv_context *ctx); + #endif /* RTE_PMD_MLX5_COMMON_OS_H_ */ diff --git a/drivers/common/mlx5/linux/mlx5_common_verbs.c b/drivers/common/mlx5/linux/mlx5_common_verbs.c index 9080bd3e87..e5a1244867 100644 --- a/drivers/common/mlx5/linux/mlx5_common_verbs.c +++ b/drivers/common/mlx5/linux/mlx5_common_verbs.c @@ -12,6 +12,7 @@ #include #include +#include #include #include "mlx5_common_utils.h" @@ -19,6 +20,7 @@ #include "mlx5_common_private.h" #include "mlx5_autoconf.h" #include +#include #include #include @@ -38,6 +40,74 @@ mlx5_os_get_ibv_dev(const struct rte_device *dev) return ibv; } +/** + * Verbs callback to allocate a memory. This function should allocate the space + * according to the size provided residing inside a huge page. + * Please note that all allocation must respect the alignment from libmlx5 + * (i.e. currently rte_mem_page_size()). + * + * @param[in] size + * The size in bytes of the memory to allocate. + * @param[in] data + * A pointer to the callback data. + * + * @return + * Allocated buffer, NULL otherwise and rte_errno is set. + */ +static void * +mlx5_alloc_verbs_buf(size_t size, void *data) +{ + struct rte_device *dev = data; + void *ret; + size_t alignment = rte_mem_page_size(); + if (alignment == (size_t)-1) { + DRV_LOG(ERR, "Failed to get mem page size"); + rte_errno = ENOMEM; + return NULL; + } + + MLX5_ASSERT(data != NULL); + ret = mlx5_malloc(0, size, alignment, dev->numa_node); + if (!ret && size) + rte_errno = ENOMEM; + return ret; +} + +/** + * Verbs callback to free a memory. + * + * @param[in] ptr + * A pointer to the memory to free. + * @param[in] data + * A pointer to the callback data. + */ +static void +mlx5_free_verbs_buf(void *ptr, void *data __rte_unused) +{ + MLX5_ASSERT(data != NULL); + mlx5_free(ptr); +} + +/** + * Hint libmlx5 to use PMD allocator for data plane resources. + * + * @param dev + * Pointer to the generic device. + */ +void +mlx5_set_context_attr(struct rte_device *dev, struct ibv_context *ctx) +{ + struct mlx5dv_ctx_allocators allocator = { + .alloc = &mlx5_alloc_verbs_buf, + .free = &mlx5_free_verbs_buf, + .data = dev, + }; + + /* Hint libmlx5 to use PMD allocator for data plane resources */ + mlx5_glue->dv_set_context_attr(ctx, MLX5DV_CTX_ATTR_BUF_ALLOCATORS, + (void *)((uintptr_t)&allocator)); +} + /** * Register mr. Given protection domain pointer, pointer to addr and length * register the memory region. diff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h index f922757da1..f36791f24e 100644 --- a/drivers/common/mlx5/mlx5_common.h +++ b/drivers/common/mlx5/mlx5_common.h @@ -334,6 +334,7 @@ void mlx5_common_init(void); */ struct mlx5_common_dev_config { int dbnc; /* Skip doorbell register write barrier. */ + unsigned int devx:1; /* Whether devx interface is available or not. */ unsigned int sys_mem_en:1; /* The default memory allocator. */ unsigned int mr_mempool_reg_en:1; /* Allow/prevent implicit mempool memory registration. */ @@ -443,4 +444,9 @@ __rte_internal bool mlx5_dev_is_pci(const struct rte_device *dev); +/* mlx5_common_os.c */ + +__rte_internal +int mlx5_os_open_device(struct mlx5_common_device *cdev, void **ctx); + #endif /* RTE_PMD_MLX5_COMMON_H_ */ diff --git a/drivers/common/mlx5/version.map b/drivers/common/mlx5/version.map index 37a0ffef4b..bcee26b7ea 100644 --- a/drivers/common/mlx5/version.map +++ b/drivers/common/mlx5/version.map @@ -141,6 +141,7 @@ INTERNAL { mlx5_os_dealloc_pd; mlx5_os_dereg_mr; mlx5_os_get_ibv_dev; # WINDOWS_NO_EXPORT + mlx5_os_open_device; mlx5_os_reg_mr; mlx5_os_umem_dereg; mlx5_os_umem_reg; diff --git a/drivers/common/mlx5/windows/mlx5_common_os.c b/drivers/common/mlx5/windows/mlx5_common_os.c index 5031bdca26..e426a955ff 100644 --- a/drivers/common/mlx5/windows/mlx5_common_os.c +++ b/drivers/common/mlx5/windows/mlx5_common_os.c @@ -72,6 +72,167 @@ mlx5_os_dealloc_pd(void *pd) return 0; } +/** + * Detect if a devx_device_bdf object has identical DBDF values to the + * rte_pci_addr found in bus/pci probing. + * + * @param[in] devx_bdf + * Pointer to the devx_device_bdf structure. + * @param[in] addr + * Pointer to the rte_pci_addr structure. + * + * @return + * 1 on Device match, 0 on mismatch. + */ +static int +mlx5_match_devx_bdf_to_addr(struct devx_device_bdf *devx_bdf, + struct rte_pci_addr *addr) +{ + if (addr->domain != (devx_bdf->bus_id >> 8) || + addr->bus != (devx_bdf->bus_id & 0xff) || + addr->devid != devx_bdf->dev_id || + addr->function != devx_bdf->fnc_id) { + return 0; + } + return 1; +} + +/** + * Detect if a devx_device_bdf object matches the rte_pci_addr + * found in bus/pci probing + * Compare both the Native/PF BDF and the raw_bdf representing a VF BDF. + * + * @param[in] devx_bdf + * Pointer to the devx_device_bdf structure. + * @param[in] addr + * Pointer to the rte_pci_addr structure. + * + * @return + * 1 on Device match, 0 on mismatch, rte_errno code on failure. + */ +static int +mlx5_match_devx_devices_to_addr(struct devx_device_bdf *devx_bdf, + struct rte_pci_addr *addr) +{ + int err; + struct devx_device mlx5_dev; + + if (mlx5_match_devx_bdf_to_addr(devx_bdf, addr)) + return 1; + /* + * Didn't match on Native/PF BDF, could still match a VF BDF, + * check it next. + */ + err = mlx5_glue->query_device(devx_bdf, &mlx5_dev); + if (err) { + DRV_LOG(ERR, "query_device failed"); + rte_errno = err; + return rte_errno; + } + if (mlx5_match_devx_bdf_to_addr(&mlx5_dev.raw_bdf, addr)) + return 1; + return 0; +} + +/** + * Look for DevX device that match to given rte_device. + * + * @param dev + * Pointer to the generic device. + * @param devx_list + * Pointer to head of DevX devices list. + * @param n + * Number of devices in given DevX devices list. + * + * @return + * A device match on success, NULL otherwise and rte_errno is set. + */ +static struct devx_device_bdf * +mlx5_os_get_devx_device(struct rte_device *dev, + struct devx_device_bdf *devx_list, int n) +{ + struct devx_device_bdf *devx_match = NULL; + struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev); + struct rte_pci_addr *addr = &pci_dev->addr; + + while (n-- > 0) { + int ret = mlx5_match_devx_devices_to_addr(devx_list, addr); + if (!ret) { + devx_list++; + continue; + } + if (ret != 1) { + rte_errno = ret; + return NULL; + } + devx_match = devx_list; + break; + } + if (devx_match == NULL) { + /* No device matches, just complain and bail out. */ + DRV_LOG(WARNING, + "No DevX device matches PCI device " PCI_PRI_FMT "," + " is DevX Configured?", + addr->domain, addr->bus, addr->devid, addr->function); + rte_errno = ENOENT; + } + return devx_match; +} + +/** + * Function API open device under Windows. + * + * This function calls the Windows glue APIs to open a device. + * + * @param dev + * Pointer to mlx5 device structure. + * @param ctx + * Pointer to fill inside pointer to device context. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_os_open_device(struct mlx5_common_device *cdev, void **ctx) +{ + struct devx_device_bdf *devx_bdf_dev = NULL; + struct devx_device_bdf *devx_list; + struct mlx5_context *mlx5_ctx = NULL; + int n; + + errno = 0; + devx_list = mlx5_glue->get_device_list(&n); + if (devx_list == NULL) { + rte_errno = errno ? errno : ENOSYS; + DRV_LOG(ERR, "Cannot list devices, is DevX enabled?"); + return -rte_errno; + } + devx_bdf_dev = mlx5_os_get_devx_device(cdev->dev, devx_list, n); + if (devx_bdf_dev == NULL) + goto error; + /* Try to open DevX device with DV. */ + mlx5_ctx = mlx5_glue->open_device(devx_bdf_dev); + if (mlx5_ctx == NULL) { + DRV_LOG(ERR, "Failed to open DevX device."); + rte_errno = errno; + goto error; + } + if (mlx5_glue->query_device(devx_bdf_dev, &mlx5_ctx->mlx5_dev)) { + DRV_LOG(ERR, "Failed to query device context fields."); + rte_errno = errno; + goto error; + } + cdev->config.devx = 1; + *ctx = (void *)mlx5_ctx; + mlx5_glue->free_device_list(devx_list); + return 0; +error: + if (mlx5_ctx != NULL) + claim_zero(mlx5_glue->close_device(mlx5_ctx)); + mlx5_glue->free_device_list(devx_list); + return -rte_errno; +} + /** * Register umem. * diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c index a808325412..c1b828a422 100644 --- a/drivers/net/mlx5/linux/mlx5_os.c +++ b/drivers/net/mlx5/linux/mlx5_os.c @@ -197,39 +197,6 @@ mlx5_os_get_dev_attr(void *ctx, struct mlx5_dev_attr *device_attr) return err; } -/** - * Verbs callback to allocate a memory. This function should allocate the space - * according to the size provided residing inside a huge page. - * Please note that all allocation must respect the alignment from libmlx5 - * (i.e. currently rte_mem_page_size()). - * - * @param[in] size - * The size in bytes of the memory to allocate. - * @param[in] data - * A pointer to the callback data. - * - * @return - * Allocated buffer, NULL otherwise and rte_errno is set. - */ -static void * -mlx5_alloc_verbs_buf(size_t size, void *data) -{ - struct mlx5_dev_ctx_shared *sh = data; - void *ret; - size_t alignment = rte_mem_page_size(); - if (alignment == (size_t)-1) { - DRV_LOG(ERR, "Failed to get mem page size"); - rte_errno = ENOMEM; - return NULL; - } - - MLX5_ASSERT(data != NULL); - ret = mlx5_malloc(0, size, alignment, sh->numa_node); - if (!ret && size) - rte_errno = ENOMEM; - return ret; -} - /** * Detect misc5 support or not * @@ -303,21 +270,6 @@ __mlx5_discovery_misc5_cap(struct mlx5_priv *priv) } #endif -/** - * Verbs callback to free a memory. - * - * @param[in] ptr - * A pointer to the memory to free. - * @param[in] data - * A pointer to the callback data. - */ -static void -mlx5_free_verbs_buf(void *ptr, void *data __rte_unused) -{ - MLX5_ASSERT(data != NULL); - mlx5_free(ptr); -} - /** * Initialize DR related data within private structure. * Routine checks the reference counter and does actual @@ -938,7 +890,7 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn, * Verbs device parameters (name, port, switch_info) to spawn. * @param config * Device configuration parameters. - * @param config + * @param eth_da * Device arguments. * * @return @@ -997,12 +949,10 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, /* Bonding device. */ if (!switch_info->representor) { err = snprintf(name, sizeof(name), "%s_%s", - dpdk_dev->name, - mlx5_os_get_dev_device_name(spawn->phys_dev)); + dpdk_dev->name, spawn->phys_dev_name); } else { err = snprintf(name, sizeof(name), "%s_%s_representor_c%dpf%d%s%u", - dpdk_dev->name, - mlx5_os_get_dev_device_name(spawn->phys_dev), + dpdk_dev->name, spawn->phys_dev_name, switch_info->ctrl_num, switch_info->pf_num, switch_info->name_type == @@ -1224,9 +1174,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, &vport_info); if (err) { DRV_LOG(WARNING, - "can't query devx port %d on device %s", - spawn->phys_port, - mlx5_os_get_dev_device_name(spawn->phys_dev)); + "Cannot query devx port %d on device %s", + spawn->phys_port, spawn->phys_dev_name); vport_info.query_flags = 0; } } @@ -1234,20 +1183,16 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, priv->vport_meta_tag = vport_info.vport_meta_tag; priv->vport_meta_mask = vport_info.vport_meta_mask; if (!priv->vport_meta_mask) { - DRV_LOG(ERR, "vport zero mask for port %d" - " on bonding device %s", - spawn->phys_port, - mlx5_os_get_dev_device_name - (spawn->phys_dev)); + DRV_LOG(ERR, + "vport zero mask for port %d on bonding device %s", + spawn->phys_port, spawn->phys_dev_name); err = ENOTSUP; goto error; } if (priv->vport_meta_tag & ~priv->vport_meta_mask) { - DRV_LOG(ERR, "invalid vport tag for port %d" - " on bonding device %s", - spawn->phys_port, - mlx5_os_get_dev_device_name - (spawn->phys_dev)); + DRV_LOG(ERR, + "Invalid vport tag for port %d on bonding device %s", + spawn->phys_port, spawn->phys_dev_name); err = ENOTSUP; goto error; } @@ -1256,10 +1201,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, priv->vport_id = vport_info.vport_id; } else if (spawn->pf_bond >= 0 && (switch_info->representor || switch_info->master)) { - DRV_LOG(ERR, "can't deduce vport index for port %d" - " on bonding device %s", - spawn->phys_port, - mlx5_os_get_dev_device_name(spawn->phys_dev)); + DRV_LOG(ERR, + "Cannot deduce vport index for port %d on bonding device %s", + spawn->phys_port, spawn->phys_dev_name); err = ENOTSUP; goto error; } else { @@ -1742,14 +1686,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, priv->mtr_profile_tbl = mlx5_l3t_create(MLX5_L3T_TYPE_PTR); if (!priv->mtr_profile_tbl) goto error; - /* Hint libmlx5 to use PMD allocator for data plane resources */ - mlx5_glue->dv_set_context_attr(sh->ctx, - MLX5DV_CTX_ATTR_BUF_ALLOCATORS, - (void *)((uintptr_t)&(struct mlx5dv_ctx_allocators){ - .alloc = &mlx5_alloc_verbs_buf, - .free = &mlx5_free_verbs_buf, - .data = sh, - })); /* Bring Ethernet device up. */ DRV_LOG(DEBUG, "port %u forcing Ethernet interface up", eth_dev->data->port_id); @@ -2155,7 +2091,7 @@ mlx5_os_config_default(struct mlx5_dev_config *config) * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, +mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, void *ctx, struct rte_eth_devargs *req_eth_da, uint16_t owner_id) { @@ -2197,7 +2133,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, ibv_list = mlx5_glue->get_device_list(&ret); if (!ibv_list) { rte_errno = errno ? errno : ENOSYS; - DRV_LOG(ERR, "cannot list devices, is ib_uverbs loaded?"); + DRV_LOG(ERR, "Cannot list devices, is ib_uverbs loaded?"); return -rte_errno; } /* @@ -2212,7 +2148,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, while (ret-- > 0) { struct rte_pci_addr pci_addr; - DRV_LOG(DEBUG, "checking device \"%s\"", ibv_list[ret]->name); + DRV_LOG(DEBUG, "Checking device \"%s\"", ibv_list[ret]->name); bd = mlx5_device_bond_pci_match (ibv_list[ret], &owner_pci, nl_rdma, owner_id, &bond_info); @@ -2259,7 +2195,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, if (!nd) { /* No device matches, just complain and bail out. */ DRV_LOG(WARNING, - "no Verbs device matches PCI device " PCI_PRI_FMT "," + "No Verbs device matches PCI device " PCI_PRI_FMT "," " are kernel drivers loaded?", owner_pci.domain, owner_pci.bus, owner_pci.devid, owner_pci.function); @@ -2276,26 +2212,22 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, if (nl_rdma >= 0) np = mlx5_nl_portnum(nl_rdma, ibv_match[0]->name); if (!np) - DRV_LOG(WARNING, "can not get IB device \"%s\"" - " ports number", ibv_match[0]->name); + DRV_LOG(WARNING, + "Cannot get IB device \"%s\" ports number.", + ibv_match[0]->name); if (bd >= 0 && !np) { - DRV_LOG(ERR, "can not get ports" - " for bonding device"); + DRV_LOG(ERR, "Cannot get ports for bonding device."); rte_errno = ENOENT; ret = -rte_errno; goto exit; } } - /* - * Now we can determine the maximal - * amount of devices to be spawned. - */ + /* Now we can determine the maximal amount of devices to be spawned. */ list = mlx5_malloc(MLX5_MEM_ZERO, - sizeof(struct mlx5_dev_spawn_data) * - (np ? np : nd), + sizeof(struct mlx5_dev_spawn_data) * (np ? np : nd), RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY); if (!list) { - DRV_LOG(ERR, "spawn data array allocation failure"); + DRV_LOG(ERR, "Spawn data array allocation failure."); rte_errno = ENOMEM; ret = -rte_errno; goto exit; @@ -2314,15 +2246,15 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, list[ns].bond_info = &bond_info; list[ns].max_port = np; list[ns].phys_port = i; - list[ns].phys_dev = ibv_match[0]; + list[ns].phys_dev_name = ibv_match[0]->name; + list[ns].ctx = ctx; list[ns].eth_dev = NULL; list[ns].pci_dev = pci_dev; list[ns].cdev = cdev; list[ns].pf_bond = bd; - list[ns].ifindex = mlx5_nl_ifindex - (nl_rdma, - mlx5_os_get_dev_device_name - (list[ns].phys_dev), i); + list[ns].ifindex = mlx5_nl_ifindex(nl_rdma, + ibv_match[0]->name, + i); if (!list[ns].ifindex) { /* * No network interface index found for the @@ -2335,10 +2267,9 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, } ret = -1; if (nl_route >= 0) - ret = mlx5_nl_switch_info - (nl_route, - list[ns].ifindex, - &list[ns].info); + ret = mlx5_nl_switch_info(nl_route, + list[ns].ifindex, + &list[ns].info); if (ret || (!list[ns].info.representor && !list[ns].info.master)) { /* @@ -2346,9 +2277,8 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, * Netlink, let's try to perform the task * with sysfs. */ - ret = mlx5_sysfs_switch_info - (list[ns].ifindex, - &list[ns].info); + ret = mlx5_sysfs_switch_info(list[ns].ifindex, + &list[ns].info); } if (!ret && bd >= 0) { switch (list[ns].info.name_type) { @@ -2384,8 +2314,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, } if (!ns) { DRV_LOG(ERR, - "unable to recognize master/representors" - " on the IB device with multiple ports"); + "Unable to recognize master/representors on the IB device with multiple ports."); rte_errno = ENOENT; ret = -rte_errno; goto exit; @@ -2413,7 +2342,8 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, list[ns].bond_info = NULL; list[ns].max_port = 1; list[ns].phys_port = 1; - list[ns].phys_dev = ibv_match[i]; + list[ns].phys_dev_name = ibv_match[i]->name; + list[ns].ctx = ctx; list[ns].eth_dev = NULL; list[ns].pci_dev = pci_dev; list[ns].cdev = cdev; @@ -2421,9 +2351,9 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, list[ns].ifindex = 0; if (nl_rdma >= 0) list[ns].ifindex = mlx5_nl_ifindex - (nl_rdma, - mlx5_os_get_dev_device_name - (list[ns].phys_dev), 1); + (nl_rdma, + ibv_match[i]->name, + 1); if (!list[ns].ifindex) { char ifname[IF_NAMESIZE]; @@ -2473,9 +2403,8 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, * Netlink, let's try to perform the task * with sysfs. */ - ret = mlx5_sysfs_switch_info - (list[ns].ifindex, - &list[ns].info); + ret = mlx5_sysfs_switch_info(list[ns].ifindex, + &list[ns].info); } if (!ret && (list[ns].info.representor ^ list[ns].info.master)) { @@ -2484,21 +2413,19 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, !list[ns].info.representor && !list[ns].info.master) { /* - * Single IB device with - * one physical port and + * Single IB device with one physical port and * attached network device. - * May be SRIOV is not enabled - * or there is no representors. + * May be SRIOV is not enabled or there is no + * representors. */ - DRV_LOG(INFO, "no E-Switch support detected"); + DRV_LOG(INFO, "No E-Switch support detected."); ns++; break; } } if (!ns) { DRV_LOG(ERR, - "unable to recognize master/representors" - " on the multiple IB devices"); + "Unable to recognize master/representors on the multiple IB devices."); rte_errno = ENOENT; ret = -rte_errno; goto exit; @@ -2681,7 +2608,7 @@ mlx5_os_parse_eth_devargs(struct rte_device *dev, * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -mlx5_os_pci_probe(struct mlx5_common_device *cdev) +mlx5_os_pci_probe(struct mlx5_common_device *cdev, void *ctx) { struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(cdev->dev); struct rte_eth_devargs eth_da = { .nb_ports = 0 }; @@ -2695,7 +2622,7 @@ mlx5_os_pci_probe(struct mlx5_common_device *cdev) if (eth_da.nb_ports > 0) { /* Iterate all port if devargs pf is range: "pf[0-1]vf[...]". */ for (p = 0; p < eth_da.nb_ports; p++) { - ret = mlx5_os_pci_probe_pf(cdev, ð_da, + ret = mlx5_os_pci_probe_pf(cdev, ctx, ð_da, eth_da.ports[p]); if (ret) break; @@ -2709,14 +2636,14 @@ mlx5_os_pci_probe(struct mlx5_common_device *cdev) mlx5_net_remove(cdev); } } else { - ret = mlx5_os_pci_probe_pf(cdev, ð_da, 0); + ret = mlx5_os_pci_probe_pf(cdev, ctx, ð_da, 0); } return ret; } /* Probe a single SF device on auxiliary bus, no representor support. */ static int -mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev) +mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev, void *ctx) { struct rte_eth_devargs eth_da = { .nb_ports = 0 }; struct mlx5_dev_config config; @@ -2736,9 +2663,8 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev) /* Init spawn data. */ spawn.max_port = 1; spawn.phys_port = 1; - spawn.phys_dev = mlx5_os_get_ibv_dev(dev); - if (spawn.phys_dev == NULL) - return -rte_errno; + spawn.ctx = ctx; + spawn.phys_dev_name = mlx5_os_get_ctx_device_name(ctx); ret = mlx5_auxiliary_get_ifindex(dev->name); if (ret < 0) { DRV_LOG(ERR, "failed to get ethdev ifindex: %s", dev->name); @@ -2776,48 +2702,28 @@ int mlx5_os_net_probe(struct mlx5_common_device *cdev) { int ret; + void *ctx = NULL; - if (rte_eal_process_type() == RTE_PROC_PRIMARY) + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + ret = mlx5_os_open_device(cdev, &ctx); + if (ret) { + DRV_LOG(ERR, "Fail to open device %s", cdev->dev->name); + return -rte_errno; + } mlx5_pmd_socket_init(); + } ret = mlx5_init_once(); if (ret) { DRV_LOG(ERR, "Unable to init PMD global data: %s", strerror(rte_errno)); + if (ctx != NULL) + claim_zero(mlx5_glue->close_device(ctx)); return -rte_errno; } if (mlx5_dev_is_pci(cdev->dev)) - return mlx5_os_pci_probe(cdev); - else - return mlx5_os_auxiliary_probe(cdev); -} - -static int -mlx5_config_doorbell_mapping_env(const struct mlx5_common_dev_config *config) -{ - char *env; - int value; - - MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY); - /* Get environment variable to store. */ - env = getenv(MLX5_SHUT_UP_BF); - value = env ? !!strcmp(env, "0") : MLX5_ARG_UNSET; - if (config->dbnc == MLX5_ARG_UNSET) - setenv(MLX5_SHUT_UP_BF, MLX5_SHUT_UP_BF_DEFAULT, 1); + return mlx5_os_pci_probe(cdev, ctx); else - setenv(MLX5_SHUT_UP_BF, - config->dbnc == MLX5_TXDB_NCACHED ? "1" : "0", 1); - return value; -} - -static void -mlx5_restore_doorbell_mapping_env(int value) -{ - MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY); - /* Restore the original environment variable state. */ - if (value == MLX5_ARG_UNSET) - unsetenv(MLX5_SHUT_UP_BF); - else - setenv(MLX5_SHUT_UP_BF, value ? "1" : "0", 1); + return mlx5_os_auxiliary_probe(cdev, ctx); } /** @@ -2855,69 +2761,6 @@ mlx5_os_get_pdn(void *pd, uint32_t *pdn) #endif /* HAVE_IBV_FLOW_DV_SUPPORT */ } -/** - * Function API to open IB device. - * - * This function calls the Linux glue APIs to open a device. - * - * @param[in] spawn - * Pointer to the IB device attributes (name, port, etc). - * @param[out] sh - * Pointer to shared context structure. - * - * @return - * 0 on success, a positive error value otherwise. - */ -int -mlx5_os_open_device(const struct mlx5_dev_spawn_data *spawn, - struct mlx5_dev_ctx_shared *sh) -{ - int dbmap_env; - int err = 0; - - pthread_mutex_init(&sh->txpp.mutex, NULL); - /* - * Configure environment variable "MLX5_BF_SHUT_UP" - * before the device creation. The rdma_core library - * checks the variable at device creation and - * stores the result internally. - */ - dbmap_env = mlx5_config_doorbell_mapping_env(&spawn->mlx5_dev->config); - /* Try to open IB device with DV first, then usual Verbs. */ - errno = 0; - sh->ctx = mlx5_glue->dv_open_device(spawn->phys_dev); - if (sh->ctx) { - sh->devx = 1; - DRV_LOG(DEBUG, "DevX is supported"); - /* The device is created, no need for environment. */ - mlx5_restore_doorbell_mapping_env(dbmap_env); - } else { - /* The environment variable is still configured. */ - sh->ctx = mlx5_glue->open_device(spawn->phys_dev); - err = errno ? errno : ENODEV; - /* - * The environment variable is not needed anymore, - * all device creation attempts are completed. - */ - mlx5_restore_doorbell_mapping_env(dbmap_env); - if (!sh->ctx) - return err; - DRV_LOG(DEBUG, "DevX is NOT supported"); - err = 0; - } - if (!err && sh->ctx) { - /* Hint libmlx5 to use PMD allocator for data plane resources */ - mlx5_glue->dv_set_context_attr(sh->ctx, - MLX5DV_CTX_ATTR_BUF_ALLOCATORS, - (void *)((uintptr_t)&(struct mlx5dv_ctx_allocators){ - .alloc = &mlx5_alloc_verbs_buf, - .free = &mlx5_free_verbs_buf, - .data = sh, - })); - } - return err; -} - /** * Install shared asynchronous device events handler. * This function is implemented to support event sharing diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index b5af21b0f6..bfdce8da72 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -1262,7 +1262,7 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn, /* Search for IB context by device name. */ LIST_FOREACH(sh, &mlx5_dev_ctx_list, next) { if (!strcmp(sh->ibdev_name, - mlx5_os_get_dev_device_name(spawn->phys_dev))) { + mlx5_os_get_ctx_device_name(spawn->ctx))) { sh->refcnt++; goto exit; } @@ -1279,13 +1279,13 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn, rte_errno = ENOMEM; goto exit; } + pthread_mutex_init(&sh->txpp.mutex, NULL); sh->numa_node = spawn->cdev->dev->numa_node; sh->cdev = spawn->cdev; + sh->devx = sh->cdev->config.devx; + sh->ctx = spawn->ctx; if (spawn->bond_info) sh->bond = *spawn->bond_info; - err = mlx5_os_open_device(spawn, sh); - if (!sh->ctx) - goto error; err = mlx5_os_get_dev_attr(sh->ctx, &sh->device_attr); if (err) { DRV_LOG(DEBUG, "mlx5_os_get_dev_attr() failed"); diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 4c8e633fb6..becd8722de 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -136,7 +136,8 @@ struct mlx5_dev_spawn_data { uint32_t phys_port; /**< Device physical port index. */ int pf_bond; /**< bonding device PF index. < 0 - no bonding */ struct mlx5_switch_info info; /**< Switch information. */ - void *phys_dev; /**< Associated physical device. */ + const char *phys_dev_name; /**< Name of physical device. */ + void *ctx; /**< Associated physical device context. */ struct rte_eth_dev *eth_dev; /**< Associated Ethernet device. */ struct rte_pci_device *pci_dev; /**< Backend PCI device. */ struct mlx5_common_device *cdev; /**< Backend common device. */ @@ -1771,8 +1772,6 @@ void mlx5_flow_meter_rxq_flush(struct rte_eth_dev *dev); struct rte_pci_driver; int mlx5_os_get_dev_attr(void *ctx, struct mlx5_dev_attr *dev_attr); void mlx5_os_free_shared_dr(struct mlx5_priv *priv); -int mlx5_os_open_device(const struct mlx5_dev_spawn_data *spawn, - struct mlx5_dev_ctx_shared *sh); int mlx5_os_get_pdn(void *pd, uint32_t *pdn); int mlx5_os_net_probe(struct mlx5_common_device *cdev); void mlx5_os_dev_shared_handler_install(struct mlx5_dev_ctx_shared *sh); diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c index 90e21479e3..1e76f63fc1 100644 --- a/drivers/net/mlx5/windows/mlx5_os.c +++ b/drivers/net/mlx5/windows/mlx5_os.c @@ -253,46 +253,6 @@ mlx5_os_set_nonblock_channel_fd(int fd) return -ENOTSUP; } -/** - * Function API open device under Windows - * - * This function calls the Windows glue APIs to open a device. - * - * @param[in] spawn - * Pointer to the device attributes (name, port, etc). - * @param[out] sh - * Pointer to shared context structure. - * - * @return - * 0 on success, a positive error value otherwise. - */ -int -mlx5_os_open_device(const struct mlx5_dev_spawn_data *spawn, - struct mlx5_dev_ctx_shared *sh) -{ - int err = 0; - struct mlx5_context *mlx5_ctx; - - pthread_mutex_init(&sh->txpp.mutex, NULL); - /* Set numa node from pci probe */ - sh->numa_node = spawn->pci_dev->device.numa_node; - - /* Try to open device with DevX */ - rte_errno = 0; - sh->ctx = mlx5_glue->open_device(spawn->phys_dev); - if (!sh->ctx) { - DRV_LOG(ERR, "open_device failed"); - err = errno; - return err; - } - sh->devx = 1; - mlx5_ctx = (struct mlx5_context *)sh->ctx; - err = mlx5_glue->query_device(spawn->phys_dev, &mlx5_ctx->mlx5_dev); - if (err) - DRV_LOG(ERR, "Failed to query device context fields."); - return err; -} - /** * DV flow counter mode detect and config. * @@ -909,114 +869,6 @@ mlx5_os_set_allmulti(struct rte_eth_dev *dev, int enable) return -ENOTSUP; } -/** - * Detect if a devx_device_bdf object has identical DBDF values to the - * rte_pci_addr found in bus/pci probing - * - * @param[in] devx_bdf - * Pointer to the devx_device_bdf structure. - * @param[in] addr - * Pointer to the rte_pci_addr structure. - * - * @return - * 1 on Device match, 0 on mismatch. - */ -static int -mlx5_match_devx_bdf_to_addr(struct devx_device_bdf *devx_bdf, - struct rte_pci_addr *addr) -{ - if (addr->domain != (devx_bdf->bus_id >> 8) || - addr->bus != (devx_bdf->bus_id & 0xff) || - addr->devid != devx_bdf->dev_id || - addr->function != devx_bdf->fnc_id) { - return 0; - } - return 1; -} - -/** - * Detect if a devx_device_bdf object matches the rte_pci_addr - * found in bus/pci probing - * Compare both the Native/PF BDF and the raw_bdf representing a VF BDF. - * - * @param[in] devx_bdf - * Pointer to the devx_device_bdf structure. - * @param[in] addr - * Pointer to the rte_pci_addr structure. - * - * @return - * 1 on Device match, 0 on mismatch, rte_errno code on failure. - */ -static int -mlx5_match_devx_devices_to_addr(struct devx_device_bdf *devx_bdf, - struct rte_pci_addr *addr) -{ - int err; - struct devx_device mlx5_dev; - - if (mlx5_match_devx_bdf_to_addr(devx_bdf, addr)) - return 1; - /* - * Didn't match on Native/PF BDF, could still match a VF BDF, - * check it next. - */ - err = mlx5_glue->query_device(devx_bdf, &mlx5_dev); - if (err) { - DRV_LOG(ERR, "query_device failed"); - rte_errno = err; - return rte_errno; - } - if (mlx5_match_devx_bdf_to_addr(&mlx5_dev.raw_bdf, addr)) - return 1; - return 0; -} - -/** - * Look for DevX device that match to given rte_device. - * - * @param dev - * Pointer to the generic device. - * @param orig_devx_list - * Pointer to head of DevX devices list. - * @param n - * Number of devices in given DevX devices list. - * - * @return - * A device match on success, NULL otherwise and rte_errno is set. - */ -static struct devx_device_bdf * -mlx5_os_get_devx_device(struct rte_device *dev, - struct devx_device_bdf *orig_devx_list, int n) -{ - struct devx_device_bdf *devx_list = orig_devx_list; - struct devx_device_bdf *devx_match = NULL; - struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev); - struct rte_pci_addr *addr = &pci_dev->addr; - - while (n-- > 0) { - int ret = mlx5_match_devx_devices_to_addr(devx_list, addr); - if (!ret) { - devx_list++; - continue; - } - if (ret != 1) { - rte_errno = ret; - return NULL; - } - devx_match = devx_list; - break; - } - if (devx_match == NULL) { - /* No device matches, just complain and bail out. */ - DRV_LOG(WARNING, - "No DevX device matches PCI device " PCI_PRI_FMT "," - " is DevX Configured?", - addr->domain, addr->bus, addr->devid, addr->function); - rte_errno = ENOENT; - } - return devx_match; -} - /** * DPDK callback to register a PCI device. * @@ -1032,8 +884,6 @@ int mlx5_os_net_probe(struct mlx5_common_device *cdev) { struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(cdev->dev); - struct devx_device_bdf *devx_list; - struct devx_device_bdf *devx_bdf_match; struct mlx5_dev_spawn_data spawn = { .pf_bond = -1, .max_port = 1, @@ -1058,33 +908,28 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev) .dv_flow_en = 1, .log_hp_size = MLX5_ARG_UNSET, }; + void *ctx; int ret; - int n; uint32_t restore; if (rte_eal_process_type() == RTE_PROC_SECONDARY) { DRV_LOG(ERR, "Secondary process is not supported on Windows."); return -ENOTSUP; } + ret = mlx5_os_open_device(cdev, &ctx); + if (ret) { + DRV_LOG(ERR, "Fail to open DevX device %s", cdev->dev->name); + return -rte_errno; + } ret = mlx5_init_once(); if (ret) { DRV_LOG(ERR, "unable to init PMD global data: %s", strerror(rte_errno)); + claim_zero(mlx5_glue->close_device(ctx)); return -rte_errno; } - errno = 0; - devx_list = mlx5_glue->get_device_list(&n); - if (devx_list == NULL) { - rte_errno = errno ? errno : ENOSYS; - DRV_LOG(ERR, "Cannot list devices, is DevX enabled?"); - return -rte_errno; - } - devx_bdf_match = mlx5_os_get_devx_device(cdev->dev, devx_list, n); - if (devx_bdf_match == NULL) { - ret = -rte_errno; - goto exit; - } - spawn.phys_dev = devx_bdf_match; + spawn.ctx = ctx; + spawn.phys_dev_name = mlx5_os_get_ctx_device_name(ctx); /* Device specific configuration. */ switch (pci_dev->id.device_id) { case PCI_DEVICE_ID_MELLANOX_CONNECTX4VF: @@ -1102,17 +947,15 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev) } spawn.eth_dev = mlx5_dev_spawn(cdev->dev, &spawn, &dev_config); if (!spawn.eth_dev) { - ret = -rte_errno; - goto exit; + claim_zero(mlx5_glue->close_device(ctx)); + return -rte_errno; } restore = spawn.eth_dev->data->dev_flags; rte_eth_copy_pci_info(spawn.eth_dev, pci_dev); /* Restore non-PCI flags cleared by the above call. */ spawn.eth_dev->data->dev_flags |= restore; rte_eth_dev_probing_finish(spawn.eth_dev); -exit: - mlx5_glue->free_device_list(devx_list); - return ret; + return 0; } /** -- 2.25.1