From patchwork Fri Oct 13 02:46:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ferruh Yigit X-Patchwork-Id: 30325 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id A6D771B633; Fri, 13 Oct 2017 04:46:54 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 92C2B1B61F for ; Fri, 13 Oct 2017 04:46:52 +0200 (CEST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 12 Oct 2017 19:46:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.43,369,1503385200"; d="scan'208"; a="1205328439" Received: from silpixa00372839.ir.intel.com (HELO silpixa00372839.ger.corp.intel.com) ([10.237.222.154]) by fmsmga001.fm.intel.com with ESMTP; 12 Oct 2017 19:46:49 -0700 From: Ferruh Yigit To: Ferruh Yigit Cc: dev@dpdk.org, patrick@patrickmacarthur.net, mark.b.kavanagh@intel.com, stephen@networkplumber.org, markus.theil@tu-ilmenau.de Date: Fri, 13 Oct 2017 03:46:44 +0100 Message-Id: <20171013024644.51248-1-ferruh.yigit@intel.com> X-Mailer: git-send-email 2.13.6 Subject: [dpdk-dev] [PATCH] igb_uio: fix unknown symbols X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" This patch partially reverts the commit d196343a258e and adds some functions from Markus' previous version of the patch [1]. igb_uio uses pci_msi_unmask_irq() and pci_msi_mask_irq() kernel APIs when kernel version is >= 3.19 because these APIs are implemented in this Linux kernel version. But these APIs only exported beginning from Linux kernel 4.5, so before this Linux kernel version igb_uio kernel module is not usable, and giving following warnings: "igb_uio: Unknown symbol pci_msi_unmask_irq" "igb_uio: Unknown symbol pci_msi_mask_irq" The support for these APIs increased to Linux kernel >= 4.5 For older version of Linux kernel unmask_msi_irq() and mask_msi_irq() are used but these functions are not exported at all. Instead of these functions switched back to previous implementation in igb_uio for MSI-X, and for MSI used igbuio_msi_mask_irq() from [1]. Fixes: d196343a258e ("igb_uio: use kernel functions for masking MSI-X") Cc: markus.theil@tu-ilmenau.de [1] http://dpdk.org/dev/patchwork/patch/28144/ Signed-off-by: Ferruh Yigit --- lib/librte_eal/linuxapp/igb_uio/compat.h | 25 ++++++++-- lib/librte_eal/linuxapp/igb_uio/igb_uio.c | 77 ++++++++++++++++++++++++++++--- 2 files changed, 91 insertions(+), 11 deletions(-) diff --git a/lib/librte_eal/linuxapp/igb_uio/compat.h b/lib/librte_eal/linuxapp/igb_uio/compat.h index 67a7ab3af..30508f35c 100644 --- a/lib/librte_eal/linuxapp/igb_uio/compat.h +++ b/lib/librte_eal/linuxapp/igb_uio/compat.h @@ -15,6 +15,21 @@ #define HAVE_PTE_MASK_PAGE_IOMAP #endif +#ifndef PCI_MSIX_ENTRY_SIZE +#define PCI_MSIX_ENTRY_SIZE 16 +#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 +#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 +#endif + +/* + * for kernels < 2.6.38 and backported patch that moves MSI-X entry definition + * to pci_regs.h Those kernels has PCI_MSIX_ENTRY_SIZE defined but not + * PCI_MSIX_ENTRY_CTRL_MASKBIT + */ +#ifndef PCI_MSIX_ENTRY_CTRL_MASKBIT +#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34) && \ (!(defined(RHEL_RELEASE_CODE) && \ RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5, 9))) @@ -110,10 +125,12 @@ static bool pci_check_and_mask_intx(struct pci_dev *pdev) #define HAVE_ALLOC_IRQ_VECTORS 1 #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) -#define HAVE_PCI_MSI_MASK_IRQ 1 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0) +#define HAVE_MSI_LIST_IN_GENERIC_DEVICE 1 #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) -#define HAVE_IRQ_DATA 1 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) +#define HAVE_PCI_MSI_MASK_IRQ 1 #endif + + diff --git a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c index c8dd5f4d0..2663a8f66 100644 --- a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c +++ b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c @@ -90,6 +90,74 @@ static const struct attribute_group dev_attr_grp = { .attrs = dev_attrs, }; +#ifndef HAVE_PCI_MSI_MASK_IRQ +/* + * It masks the msix on/off of generating MSI-X messages. + */ +static void +igbuio_msix_mask_irq(struct msi_desc *desc, s32 state) +{ + u32 mask_bits = desc->masked; + unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_VECTOR_CTRL; + + if (state != 0) + mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; + else + mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; + + if (mask_bits != desc->masked) { + writel(mask_bits, desc->mask_base + offset); + readl(desc->mask_base); + desc->masked = mask_bits; + } +} + +/* + * It masks the msi on/off of generating MSI messages. + */ +static void +igbuio_msi_mask_irq(struct pci_dev *pdev, struct msi_desc *desc, int32_t state) +{ + u32 mask_bits = desc->masked; + u32 offset = desc->irq - pdev->irq; + u32 mask = 1 << offset; + u32 flag = !!state << offset; + + if (!desc->msi_attrib.maskbit) + return; + + mask_bits &= ~mask; + mask_bits |= flag; + + if (mask_bits != desc->masked) { + pci_write_config_dword(pdev, desc->mask_pos, mask_bits); + desc->masked = mask_bits; + } +} + +static void +igbuio_mask_irq(struct pci_dev *pdev, enum rte_intr_mode mode, s32 irq_state) +{ + struct msi_desc *desc; + struct list_head *msi_list; + +#ifdef HAVE_MSI_LIST_IN_GENERIC_DEVICE + msi_list = &pdev->dev.msi_list; +#else + msi_list = &pdev->msi_list; +#endif + + if (mode == RTE_INTR_MODE_MSIX) { + list_for_each_entry(desc, msi_list, list) + igbuio_msix_mask_irq(desc, irq_state); + } else if (mode == RTE_INTR_MODE_MSI) { + list_for_each_entry(desc, msi_list, list) + igbuio_msi_mask_irq(pdev, desc, irq_state); + } +} +#endif + /** * This is the irqcontrol callback to be registered to uio_info. * It can be used to disable/enable interrupt from user space processes. @@ -109,10 +177,8 @@ igbuio_pci_irqcontrol(struct uio_info *info, s32 irq_state) struct rte_uio_pci_dev *udev = info->priv; struct pci_dev *pdev = udev->pdev; -#ifdef HAVE_IRQ_DATA +#ifdef HAVE_PCI_MSI_MASK_IRQ struct irq_data *irq = irq_get_irq_data(udev->info.irq); -#else - unsigned int irq = udev->info.irq; #endif pci_cfg_access_lock(pdev); @@ -124,10 +190,7 @@ igbuio_pci_irqcontrol(struct uio_info *info, s32 irq_state) else pci_msi_mask_irq(irq); #else - if (irq_state == 1) - unmask_msi_irq(irq); - else - mask_msi_irq(irq); + igbuio_mask_irq(pdev, udev->mode, irq_state); #endif }