From patchwork Thu Dec 7 19:20:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tyler Retzlaff X-Patchwork-Id: 134940 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 F081B43699; Thu, 7 Dec 2023 20:21:00 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C040642F5D; Thu, 7 Dec 2023 20:20:56 +0100 (CET) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by mails.dpdk.org (Postfix) with ESMTP id 0CDB242E7B for ; Thu, 7 Dec 2023 20:20:54 +0100 (CET) Received: by linux.microsoft.com (Postfix, from userid 1086) id 32DD820B74C1; Thu, 7 Dec 2023 11:20:53 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 32DD820B74C1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1701976853; bh=rUpI2t2/HefRK2PllTUISeN/zuPrPxoeU4eNfczGBmo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kT7C8tJyA3czR4vGYxT7LIEOvU95bWxptP7HYuahoZBPSZ6+9xUF+EfG/oBhBazuK jq4qdd+8LpaEWvzlKOFI7ocMgoOMx+2mpHGxf8mdwGDnJncxfNCuRNNNDJ2BrO5qbo hW5IqAQ4ZV1y50AvW/x4BabfP48PIJigAB0D3jtA= From: Tyler Retzlaff To: dev@dpdk.org Cc: Dmitry Kozlyuk , Pallavi Kadam , Tyler Retzlaff Subject: [PATCH] eal: initialize shared plugins on Windows Date: Thu, 7 Dec 2023 11:20:51 -0800 Message-Id: <1701976851-17275-2-git-send-email-roretzla@linux.microsoft.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1701976851-17275-1-git-send-email-roretzla@linux.microsoft.com> References: <1701976851-17275-1-git-send-email-roretzla@linux.microsoft.com> 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 When EAL is built with MSVC it is possible to dynamically load plugins on Windows. Hook eal_plugins_init into rte_eal_init if built with MSVC and provide code to load plugins on Windows. Signed-off-by: Tyler Retzlaff --- lib/eal/common/eal_common_options.c | 92 ++++++++++++++++++++++++++++++------- lib/eal/windows/eal.c | 8 ++++ 2 files changed, 84 insertions(+), 16 deletions(-) diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c index a6d21f1..3f9a030 100644 --- a/lib/eal/common/eal_common_options.c +++ b/lib/eal/common/eal_common_options.c @@ -18,9 +18,7 @@ #include #endif #include -#ifndef RTE_EXEC_ENV_WINDOWS #include -#endif #include #include @@ -74,7 +72,7 @@ {OPT_HELP, 0, NULL, OPT_HELP_NUM }, {OPT_HUGE_DIR, 1, NULL, OPT_HUGE_DIR_NUM }, {OPT_HUGE_UNLINK, 2, NULL, OPT_HUGE_UNLINK_NUM }, - {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, + {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, {OPT_TRACE, 1, NULL, OPT_TRACE_NUM }, @@ -123,10 +121,8 @@ struct shared_driver { static struct shared_driver_list solib_list = TAILQ_HEAD_INITIALIZER(solib_list); -#ifndef RTE_EXEC_ENV_WINDOWS /* Default path of external loadable drivers */ static const char *default_solib_dir = RTE_EAL_PMD_PATH; -#endif /* * Stringified version of solib path used by dpdk-pmdinfo.py @@ -371,12 +367,12 @@ struct device_option { } #ifdef RTE_EXEC_ENV_WINDOWS -int -eal_plugins_init(void) -{ - return 0; -} +#define SOEXT ".dll" #else +#define SOEXT ".so" +#endif + +#define SOABIEXT SOEXT"."ABI_VERSION static int eal_plugindir_init(const char *path) @@ -397,12 +393,14 @@ struct device_option { while ((dent = readdir(d)) != NULL) { struct stat sb; - int nlen = strnlen(dent->d_name, sizeof(dent->d_name)); + size_t nlen = strnlen(dent->d_name, sizeof(dent->d_name)); - /* check if name ends in .so or .so.ABI_VERSION */ - if (strcmp(&dent->d_name[nlen - 3], ".so") != 0 && - strcmp(&dent->d_name[nlen - 4 - strlen(ABI_VERSION)], - ".so."ABI_VERSION) != 0) + if (nlen < strlen(SOABIEXT)) + continue; + + /* check if name ends in SOEXT or SOABIEXT */ + if (strcmp(&dent->d_name[nlen - strlen(SOEXT)], SOEXT) != 0 && + strcmp(&dent->d_name[nlen - strlen(SOABIEXT)], SOABIEXT) != 0) continue; snprintf(sopath, sizeof(sopath), "%s/%s", path, dent->d_name); @@ -420,6 +418,68 @@ struct device_option { return (dent == NULL) ? 0 : -1; } +#ifdef RTE_EXEC_ENV_WINDOWS +static void* +eal_dlopen(const char *pathname) +{ + void *retval = NULL; + struct stat pathstat; + char *fullpath = _fullpath(NULL, pathname, 0); + + const char *loadpath = fullpath; + DWORD loadflags = 0; + + if (fullpath == NULL) { + RTE_LOG(ERR, EAL, "Error expanding full path for %s, %s\n", + pathname, strerror(errno)); + } else { + /* Verify that the path exists */ + if ((stat(fullpath, &pathstat) != 0) && (errno == ENOENT)) { + /* not a full or relative path, try a load from default dirs */ + loadpath = pathname; + loadflags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS; + } + + retval = LoadLibraryExA(loadpath, NULL, loadflags); + if (retval == NULL) + RTE_LOG(ERR, EAL, "Error loading %s, error code: %" PRIu32 "\n", + loadpath, GetLastError()); + } + + free(fullpath); + return retval; +} + +static int +is_shared_build(void) +{ + int shared = 0; + HMODULE apphandle = NULL; + HMODULE libhandle = NULL; + + /* if fail to get handle, assume statically linked */ + apphandle = GetModuleHandleA(NULL); + if (apphandle == NULL) { + RTE_LOG(ERR, EAL, "Cannot get handle to the app\n"); + goto out; + } + + /* if fail to get handle, assume statically linked */ + if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCSTR)&eal_plugins_init, + &libhandle)) { + if (apphandle != libhandle) { + /* lib and app handles are different. */ + /* Therefore lib is dynamically linked */ + shared = 1; + } + } + +out: + return shared; +} +#else static int verify_perms(const char *dirpath) { @@ -527,6 +587,7 @@ struct device_option { RTE_LOG(INFO, EAL, "Detected static linkage of DPDK\n"); return 0; } +#endif int eal_plugins_init(void) @@ -565,7 +626,6 @@ struct device_option { } return 0; } -#endif /* * Parse the coremask given as argument (hexadecimal string) and fill diff --git a/lib/eal/windows/eal.c b/lib/eal/windows/eal.c index 7ec2152..af51bf3 100644 --- a/lib/eal/windows/eal.c +++ b/lib/eal/windows/eal.c @@ -305,6 +305,14 @@ enum rte_proc_type_t if (fctret < 0) exit(1); +#ifdef RTE_TOOLCHAIN_MSVC + if (eal_plugins_init() < 0) { + rte_eal_init_alert("Cannot init plugins"); + rte_errno = EINVAL; + return -1; + } +#endif + if (eal_option_device_parse()) { rte_errno = ENODEV; return -1; From patchwork Mon Jan 8 23:38:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tyler Retzlaff X-Patchwork-Id: 135805 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 63EC14386A; Tue, 9 Jan 2024 00:38:15 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D71B140298; Tue, 9 Jan 2024 00:38:14 +0100 (CET) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by mails.dpdk.org (Postfix) with ESMTP id 4B09740298 for ; Tue, 9 Jan 2024 00:38:13 +0100 (CET) Received: by linux.microsoft.com (Postfix, from userid 1086) id 8EE5D20AEC83; Mon, 8 Jan 2024 15:38:12 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 8EE5D20AEC83 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1704757092; bh=3/Ss0Ecd6srfqgbSZSU6AMhDQboWG+MyIvDlaDDsMeM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=A7Oam9DSVNvWgPqnFCdkKXnKizJJxfv4RL2c+TMy6MdiYd1qNr2OItzle3oIEPnYO YmzVg1/X7fo23wb3Y9jrJSGYI/3fIcma7uPQHROEGV9RyFHfXkhZcgN/rgEmc+rcxT Q45+TF8bXEU0sbjeeX0aKDrwcF8ZMrTXg1ZnX1FM= From: Tyler Retzlaff To: dev@dpdk.org Cc: Dmitry Kozlyuk , Pallavi Kadam , Tyler Retzlaff Subject: [PATCH v4 2/2] eal: initialize shared plugins on Windows Date: Mon, 8 Jan 2024 15:38:11 -0800 Message-Id: <1704757091-7964-3-git-send-email-roretzla@linux.microsoft.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1704757091-7964-1-git-send-email-roretzla@linux.microsoft.com> References: <1701976851-17275-1-git-send-email-roretzla@linux.microsoft.com> <1704757091-7964-1-git-send-email-roretzla@linux.microsoft.com> 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 When EAL is built with MSVC it is possible to dynamically load plugins on Windows. Hook eal_plugins_init into rte_eal_init if built with MSVC and provide code to load plugins on Windows. Signed-off-by: Tyler Retzlaff Acked-by: Dmitry Kozlyuk --- lib/eal/common/eal_common_options.c | 90 ++++++++++++++++++++++++++++++------- lib/eal/windows/eal.c | 8 ++++ 2 files changed, 83 insertions(+), 15 deletions(-) diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c index d974807..d519a55 100644 --- a/lib/eal/common/eal_common_options.c +++ b/lib/eal/common/eal_common_options.c @@ -18,9 +18,7 @@ #include #endif #include -#ifndef RTE_EXEC_ENV_WINDOWS #include -#endif #include #include @@ -123,10 +121,8 @@ struct shared_driver { static struct shared_driver_list solib_list = TAILQ_HEAD_INITIALIZER(solib_list); -#ifndef RTE_EXEC_ENV_WINDOWS /* Default path of external loadable drivers */ static const char *default_solib_dir = RTE_EAL_PMD_PATH; -#endif /* * Stringified version of solib path used by dpdk-pmdinfo.py @@ -371,12 +367,12 @@ struct device_option { } #ifdef RTE_EXEC_ENV_WINDOWS -int -eal_plugins_init(void) -{ - return 0; -} +#define SOEXT ".dll" #else +#define SOEXT ".so" +#endif + +#define SOABIEXT SOEXT"."ABI_VERSION static int eal_plugindir_init(const char *path) @@ -397,12 +393,14 @@ struct device_option { while ((dent = readdir(d)) != NULL) { struct stat sb; - int nlen = strnlen(dent->d_name, sizeof(dent->d_name)); + size_t nlen = strnlen(dent->d_name, sizeof(dent->d_name)); - /* check if name ends in .so or .so.ABI_VERSION */ - if (strcmp(&dent->d_name[nlen - 3], ".so") != 0 && - strcmp(&dent->d_name[nlen - 4 - strlen(ABI_VERSION)], - ".so."ABI_VERSION) != 0) + if (nlen < strlen(SOABIEXT)) + continue; + + /* check if name ends in SOEXT or SOABIEXT */ + if (strcmp(&dent->d_name[nlen - strlen(SOEXT)], SOEXT) != 0 && + strcmp(&dent->d_name[nlen - strlen(SOABIEXT)], SOABIEXT) != 0) continue; snprintf(sopath, sizeof(sopath), "%s/%s", path, dent->d_name); @@ -420,6 +418,68 @@ struct device_option { return (dent == NULL) ? 0 : -1; } +#ifdef RTE_EXEC_ENV_WINDOWS +static void* +eal_dlopen(const char *pathname) +{ + void *retval = NULL; + struct stat pathstat; + char *fullpath = _fullpath(NULL, pathname, 0); + + const char *loadpath = fullpath; + DWORD loadflags = 0; + + if (fullpath == NULL) { + RTE_LOG(ERR, EAL, "Error expanding full path for %s, %s\n", + pathname, strerror(errno)); + } else { + /* Verify that the path exists */ + if ((stat(fullpath, &pathstat) != 0) && (errno == ENOENT)) { + /* not a full or relative path, try a load from default dirs */ + loadpath = pathname; + loadflags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS; + } + + retval = LoadLibraryExA(loadpath, NULL, loadflags); + if (retval == NULL) + RTE_LOG(ERR, EAL, "Error loading %s, error code: %lu\n", + loadpath, GetLastError()); + } + + free(fullpath); + return retval; +} + +static int +is_shared_build(void) +{ + int shared = 0; + HMODULE apphandle = NULL; + HMODULE libhandle = NULL; + + /* if fail to get handle, assume statically linked */ + apphandle = GetModuleHandleA(NULL); + if (apphandle == NULL) { + RTE_LOG(ERR, EAL, "Cannot get handle to the app\n"); + goto out; + } + + /* if fail to get handle, assume statically linked */ + if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCSTR)&eal_plugins_init, + &libhandle)) { + if (apphandle != libhandle) { + /* lib and app handles are different. */ + /* Therefore lib is dynamically linked */ + shared = 1; + } + } + +out: + return shared; +} +#else static int verify_perms(const char *dirpath) { @@ -527,6 +587,7 @@ struct device_option { EAL_LOG(INFO, "Detected static linkage of DPDK"); return 0; } +#endif int eal_plugins_init(void) @@ -565,7 +626,6 @@ struct device_option { } return 0; } -#endif /* * Parse the coremask given as argument (hexadecimal string) and fill diff --git a/lib/eal/windows/eal.c b/lib/eal/windows/eal.c index 52f0e74..dc2bcb7 100644 --- a/lib/eal/windows/eal.c +++ b/lib/eal/windows/eal.c @@ -305,6 +305,14 @@ enum rte_proc_type_t if (fctret < 0) exit(1); +#ifdef RTE_TOOLCHAIN_MSVC + if (eal_plugins_init() < 0) { + rte_eal_init_alert("Cannot init plugins"); + rte_errno = EINVAL; + return -1; + } +#endif + if (eal_option_device_parse()) { rte_errno = ENODEV; return -1;