From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 0386E3F9 for ; Mon, 8 Dec 2014 09:28:08 +0100 (CET) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 08 Dec 2014 00:28:07 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.07,537,1413270000"; d="scan'208";a="650145976" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by orsmga002.jf.intel.com with ESMTP; 08 Dec 2014 00:28:06 -0800 Received: from shecgisg003.sh.intel.com (shecgisg003.sh.intel.com [10.239.29.90]) by shvmail01.sh.intel.com with ESMTP id sB88S4Ss028621; Mon, 8 Dec 2014 16:28:04 +0800 Received: from shecgisg003.sh.intel.com (localhost [127.0.0.1]) by shecgisg003.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id sB88S2GB007764; Mon, 8 Dec 2014 16:28:04 +0800 Received: (from dayuqiu@localhost) by shecgisg003.sh.intel.com (8.13.6/8.13.6/Submit) id sB88S1PJ007760; Mon, 8 Dec 2014 16:28:01 +0800 From: Michael Qiu To: dev@dpdk.org Date: Mon, 8 Dec 2014 16:27:35 +0800 Message-Id: <1418027255-7727-1-git-send-email-michael.qiu@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1417687227-21854-1-git-send-email-michael.qiu@intel.com> References: <1417687227-21854-1-git-send-email-michael.qiu@intel.com> Subject: [dpdk-dev] [PATCH v3] VFIO: Avoid to enable vfio while the module not loaded X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 08 Dec 2014 08:28:10 -0000 When vfio module is not loaded when kernel support vfio feature, the routine still try to open the container to get file description. This action is not safe, and of cause got error messages: EAL: Detected 40 lcore(s) EAL: unsupported IOMMU type! EAL: VFIO support could not be initialized EAL: Setting up memory... This may make user confuse, this patch make it reasonable and much more soomth to user. Signed-off-by: Michael Qiu --- v3 --> v2: 1. Add error log in rte_eal_check_module() 2. Some code clean up. v2 --> v1: 1. Move check_module() from rte_common.h to eal_private.h and rename to rte_eal_check_module(). To make it linuxapp only. 2. Some code clean up. lib/librte_eal/common/eal_private.h | 43 ++++++++++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/eal_pci_vfio.c | 30 ++++++++++++++++++--- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h index 232fcec..d1d8126 100644 --- a/lib/librte_eal/common/eal_private.h +++ b/lib/librte_eal/common/eal_private.h @@ -35,6 +35,9 @@ #define _EAL_PRIVATE_H_ #include +#include +#include +#include /** * Initialize the memzone subsystem (private to eal). @@ -203,4 +206,44 @@ int rte_eal_alarm_init(void); */ int rte_eal_dev_init(void); +/** + * Function is to check if the kernel module(like, vfio, vfio_iommu_type1, + * etc.) loaded. + * + * @param module_name + * The module's name which need to be checked + * + * @return + * -1 means some error happens(NULL pointer or open failure) + * 0 means the module not loaded + * 1 means the module loaded + */ +static inline int +rte_eal_check_module(const char *module_name) +{ + char mod_name[30]; /* Any module names can be longer than 30 bytes? */ + int ret = 0; + + if (NULL == module_name) { + RTE_LOG(ERR, EAL, "The module name is NULL\n"); + return -1; + } + FILE * fd = fopen("/proc/modules", "r"); + if (NULL == fd) { + RTE_LOG(ERR, EAL, "Open /proc/modules failed!" + " error %i (%s)\n", errno, strerror(errno)); + return -1; + } + while(!feof(fd)) { + fscanf(fd, "%s %*[^\n]", mod_name); + if(!strcmp(mod_name, module_name)) { + ret = 1; + break; + } + } + fclose(fd); + + return ret; +} + #endif /* _EAL_PRIVATE_H_ */ diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c index c1246e8..b34b3f5 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "eal_filesystem.h" #include "eal_pci_init.h" @@ -339,10 +340,15 @@ pci_vfio_get_container_fd(void) ret = ioctl(vfio_container_fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU); if (ret != 1) { if (ret < 0) - RTE_LOG(ERR, EAL, " could not get IOMMU type, " - "error %i (%s)\n", errno, strerror(errno)); + RTE_LOG(ERR, EAL, " could not get IOMMU type," + " error %i (%s)\n", errno, + strerror(errno)); else - RTE_LOG(ERR, EAL, " unsupported IOMMU type!\n"); + /* Better to show the IOMMU type return from + * kernel for easy debug + */ + RTE_LOG(ERR, EAL, " unsupported IOMMU type" + " detected: %d in VFIO\n", ret); close(vfio_container_fd); return -1; } @@ -783,11 +789,29 @@ pci_vfio_enable(void) { /* initialize group list */ int i; + int module_vfio, module_vfio_type1; for (i = 0; i < VFIO_MAX_GROUPS; i++) { vfio_cfg.vfio_groups[i].fd = -1; vfio_cfg.vfio_groups[i].group_no = -1; } + + module_vfio = rte_eal_check_module("vfio"); + module_vfio_type1 = rte_eal_check_module("vfio_iommu_type1"); + + /* return error directly */ + if (module_vfio == -1 || module_vfio_type1 == -1) { + RTE_LOG(INFO, EAL, "Could not get loaded module details!\n"); + return -1; + } + + /* return 0 if not all VFIO modules loaded */ + if (module_vfio == 0 || module_vfio_type1 == 0) { + RTE_LOG(INFO, EAL, "VFIO modules not all loaded," + " skip VFIO support ...\n"); + return 0; + } + vfio_cfg.vfio_container_fd = pci_vfio_get_container_fd(); /* check if we have VFIO driver enabled */ -- 1.9.3