From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id D443058E4 for ; Thu, 5 Jun 2014 16:39:30 +0200 (CEST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 05 Jun 2014 07:39:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.98,981,1392192000"; d="scan'208";a="542939356" Received: from sie-lab-212-143.ir.intel.com (HELO silpixa00385294.ir.intel.com) ([10.237.212.143]) by fmsmga001.fm.intel.com with ESMTP; 05 Jun 2014 07:39:32 -0700 From: Alan Carew To: dev@dpdk.org Date: Thu, 5 Jun 2014 15:39:17 +0100 Message-Id: <1401979159-14576-3-git-send-email-alan.carew@intel.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1401979159-14576-1-git-send-email-alan.carew@intel.com> References: <1401979159-14576-1-git-send-email-alan.carew@intel.com> Subject: [dpdk-dev] [PATCH 2/4] [PATCH 2/4] eal_pci: Add interrupt mode to rte_pci_device and parsing to eal_pci 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: Thu, 05 Jun 2014 14:39:32 -0000 This patch adds a shared enum between user and kernel space to rte_pci_device. The value of intr_mode is parsed by eal_pci during pci_uio_map_resource Signed-off-by: Alan Carew --- lib/librte_eal/common/Makefile | 1 + lib/librte_eal/common/include/rte_pci.h | 2 + lib/librte_eal/linuxapp/eal/eal_pci.c | 78 +++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 0 deletions(-) diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile index 0016fc5..52d46f3 100644 --- a/lib/librte_eal/common/Makefile +++ b/lib/librte_eal/common/Makefile @@ -35,6 +35,7 @@ INC := rte_atomic.h rte_branch_prediction.h rte_byteorder.h rte_common.h INC += rte_cycles.h rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h INC += rte_log.h rte_memcpy.h rte_memory.h rte_memzone.h rte_pci.h INC += rte_pci_dev_ids.h rte_per_lcore.h rte_prefetch.h rte_random.h +INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h INC += rte_rwlock.h rte_spinlock.h rte_tailq.h rte_interrupts.h rte_alarm.h INC += rte_string_fns.h rte_cpuflags.h rte_version.h rte_tailq_elem.h INC += rte_eal_memconfig.h rte_malloc_heap.h diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h index c793773..5883cd9 100644 --- a/lib/librte_eal/common/include/rte_pci.h +++ b/lib/librte_eal/common/include/rte_pci.h @@ -81,6 +81,7 @@ extern "C" { #include #include #include +#include TAILQ_HEAD(pci_device_list, rte_pci_device); /**< PCI devices in D-linked Q. */ TAILQ_HEAD(pci_driver_list, rte_pci_driver); /**< PCI drivers in D-linked Q. */ @@ -150,6 +151,7 @@ struct rte_pci_device { const struct rte_pci_driver *driver; /**< Associated driver */ uint16_t max_vfs; /**< sriov enable if not zero */ int numa_node; /**< NUMA node connection */ + enum igbuio_intr_mode intr_mode; /**< Interrupt mode */ struct rte_devargs *devargs; /**< Device user arguments */ }; diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c index ac2c1fe..7dba446 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c @@ -67,6 +67,7 @@ #include #include "rte_pci_dev_ids.h" +#include "rte_pci_dev_feature_defs.h" #include "eal_filesystem.h" #include "eal_private.h" @@ -89,6 +90,17 @@ struct uio_map { uint64_t phaddr; }; +struct rte_pci_dev_intr_mode { + enum igbuio_intr_mode mode; + const char *name; +}; + +/* Table of interrupt modes */ +const struct rte_pci_dev_intr_mode interrupt_modes[] = { +#define RTE_PCI_DEV_INTR_MODE(id, mode_name) {INTR_MODE(id, mode_name)}, +#include +}; + /* * For multi-process we need to reproduce all PCI mappings in secondary * processes, so save them in a tailq. @@ -106,6 +118,7 @@ TAILQ_HEAD(uio_res_list, uio_resource); static struct uio_res_list *uio_res_list = NULL; static int pci_parse_sysfs_value(const char *filename, uint64_t *val); +static int pci_parse_sysfs_intr_mode(const char *filename, struct rte_pci_device *dev); /* unbind kernel driver for this device */ static int @@ -400,6 +413,7 @@ pci_uio_map_resource(struct rte_pci_device *dev) int i, j; char dirname[PATH_MAX]; char devname[PATH_MAX]; /* contains the /dev/uioX */ + char filename[PATH_MAX]; void *mapaddr; int uio_num; uint64_t phaddr; @@ -435,6 +449,18 @@ pci_uio_map_resource(struct rte_pci_device *dev) } dev->intr_handle.type = RTE_INTR_HANDLE_UIO; + rte_snprintf(filename, sizeof(filename), + SYSFS_PCI_DEVICES "/" PCI_PRI_FMT + "/"RTE_PCI_DEV_FEATURE_INTR_MODE, + loc->domain, loc->bus, loc->devid, loc->function); + + /* Get the kernel configured interrupt mode */ + if (pci_parse_sysfs_intr_mode(filename, dev) < 0) { + RTE_LOG(ERR, EAL, "%s(): cannot determine interrupt_mode\n", + __func__); + return -1; + } + /* allocate the mapping details for secondary processes*/ if ((uio_res = rte_zmalloc("UIO_RES", sizeof (*uio_res), 0)) == NULL) { RTE_LOG(ERR, EAL, @@ -591,6 +617,58 @@ pci_parse_sysfs_value(const char *filename, uint64_t *val) return 0; } +/* + * Parse a sysfs file containing a string + */ +static int +pci_parse_sysfs_string(const char *filename, char *result_str, int max_len) +{ + FILE *f; + size_t len; + + f = fopen(filename, "r"); + if (f == NULL) { + RTE_LOG(ERR, EAL, "%s(): cannot open sysfs value %s\n", + __func__, filename); + return -1; + } + if (fgets(result_str, max_len, f) == NULL) { + RTE_LOG(ERR, EAL, "%s(): cannot read sysfs value %s\n", + __func__, filename); + fclose(f); + return -1; + } + len = strnlen(result_str, max_len) -1; + if (result_str[len] == '\n') + result_str[len] = '\0'; + + fclose(f); + return 0; +} + +/* + * Determine the kernel configured interrupt mode + */ +static int +pci_parse_sysfs_intr_mode(const char *filename, struct rte_pci_device *dev) +{ + char intr_mode[INTR_NAME_LEN]; + unsigned int i, num_intr_modes = RTE_DIM(interrupt_modes); + + if (pci_parse_sysfs_string(filename, intr_mode, RTE_DIM(intr_mode)) < 0) { + RTE_LOG(ERR, EAL, "%s(): cannot parse interrupt_mode\n", + __func__); + return -1; + } + + for (i = 0; i < num_intr_modes; i++) + if (!strncmp(intr_mode, interrupt_modes[i].name, INTR_NAME_LEN)) { + dev->intr_mode = interrupt_modes[i].mode; + return 0; + } + return -1; +} + /* Compare two PCI device addresses. */ static int pci_addr_comparison(struct rte_pci_addr *addr, struct rte_pci_addr *addr2) -- 1.7.0.7