From mboxrd@z Thu Jan 1 00:00:00 1970 From: Markus Theil Subject: [PATCH v5 4/5] igb_uio: use msi mask functions from kernel, little corrections Date: Thu, 31 Aug 2017 23:46:59 +0200 Message-ID: <1504216020-16067-4-git-send-email-markus.theil@tu-ilmenau.de> References: <1504174949-25656-3-git-send-email-markus.theil@tu-ilmenau.de> <1504216020-16067-1-git-send-email-markus.theil@tu-ilmenau.de> Cc: ferruh.yigit@intel.com, stephen@networkplumber.org, Markus Theil To: dev@dpdk.org Return-path: Received: from smail.rz.tu-ilmenau.de (smail.rz.tu-ilmenau.de [141.24.186.67]) by dpdk.org (Postfix) with ESMTP id 7BE632C17 for ; Thu, 31 Aug 2017 23:47:23 +0200 (CEST) In-Reply-To: <1504216020-16067-1-git-send-email-markus.theil@tu-ilmenau.de> 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 substitutes the custom MSI/MSI-X mask code and uses already existing kernel APIs. Feedback/small corrections to the previous patch of this series are also incorporated. Signed-off-by: Markus Theil --- lib/librte_eal/linuxapp/igb_uio/compat.h | 26 +++------ lib/librte_eal/linuxapp/igb_uio/igb_uio.c | 88 ++++++++----------------------- 2 files changed, 31 insertions(+), 83 deletions(-) diff --git a/lib/librte_eal/linuxapp/igb_uio/compat.h b/lib/librte_eal/linuxapp/igb_uio/compat.h index 3825933..67a7ab3 100644 --- a/lib/librte_eal/linuxapp/igb_uio/compat.h +++ b/lib/librte_eal/linuxapp/igb_uio/compat.h @@ -15,24 +15,6 @@ #define HAVE_PTE_MASK_PAGE_IOMAP #endif -#ifndef PCI_MSIX_ENTRY_SIZE -#define PCI_MSIX_ENTRY_SIZE 16 -#define PCI_MSIX_ENTRY_LOWER_ADDR 0 -#define PCI_MSIX_ENTRY_UPPER_ADDR 4 -#define PCI_MSIX_ENTRY_DATA 8 -#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))) @@ -127,3 +109,11 @@ static bool pci_check_and_mask_intx(struct pci_dev *pdev) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) #define HAVE_ALLOC_IRQ_VECTORS 1 #endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) +#define HAVE_PCI_MSI_MASK_IRQ 1 +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) +#define HAVE_IRQ_DATA 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 99a085a..5830453 100644 --- a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c +++ b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c @@ -92,51 +92,6 @@ static const struct attribute_group dev_attr_grp = { .attrs = dev_attrs, }; -/* - * It masks the msix on/off of generating MSI-X messages. - */ -static void -igbuio_msix_mask_irq(struct msi_desc *desc, int32_t 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; - } -} - /** * This is the irqcontrol callback to be registered to uio_info. * It can be used to disable/enable interrupt from user space processes. @@ -156,31 +111,31 @@ igbuio_pci_irqcontrol(struct uio_info *info, s32 irq_state) struct rte_uio_pci_dev *udev = info->priv; struct pci_dev *pdev = udev->pdev; - pci_cfg_access_lock(pdev); - if (udev->mode == RTE_INTR_MODE_LEGACY) - pci_intx(pdev, !!irq_state); - - else if (udev->mode == RTE_INTR_MODE_MSIX) { - struct msi_desc *desc; - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)) - list_for_each_entry(desc, &pdev->msi_list, list) - igbuio_msix_mask_irq(desc, irq_state); +#ifdef HAVE_IRQ_DATA + struct irq_data *irq = irq_get_irq_data(udev->info.irq); #else - list_for_each_entry(desc, &pdev->dev.msi_list, list) - igbuio_msix_mask_irq(desc, irq_state); + unsigned int irq = udev->info.irq; #endif - } else if (udev->mode == RTE_INTR_MODE_MSI) { - struct msi_desc *desc; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)) - list_for_each_entry(desc, &pdev->msi_list, list) - igbuio_msi_mask_irq(pdev, desc, irq_state); + pci_cfg_access_lock(pdev); + + if (udev->mode == RTE_INTR_MODE_MSIX || udev->mode == RTE_INTR_MODE_MSI) { +#ifdef HAVE_PCI_MSI_MASK_IRQ + if (irq_state == 1) + pci_msi_unmask_irq(irq); + else + pci_msi_mask_irq(irq); #else - list_for_each_entry(desc, &pdev->dev.msi_list, list) - igbuio_msi_mask_irq(pdev, desc, irq_state); + if (irq_state == 1) + unmask_msi_irq(irq); + else + mask_msi_irq(irq); #endif } + + if (udev->mode == RTE_INTR_MODE_LEGACY) + pci_intx(pdev, !!irq_state); + pci_cfg_access_unlock(pdev); return 0; @@ -365,11 +320,13 @@ igbuio_pci_enable_interrupts(struct rte_uio_pci_dev *udev) #else if (pci_alloc_irq_vectors(udev->pdev, 1, 1, PCI_IRQ_MSIX) == 1) { dev_dbg(&udev->pdev->dev, "using MSI-X"); + udev->info.irq_flags = IRQF_NO_THREAD; udev->info.irq = pci_irq_vector(udev->pdev, 0); udev->mode = RTE_INTR_MODE_MSIX; break; } #endif + /* fall back to MSI */ case RTE_INTR_MODE_MSI: #ifndef HAVE_ALLOC_IRQ_VECTORS if (pci_enable_msi(udev->pdev) == 0) { @@ -382,6 +339,7 @@ igbuio_pci_enable_interrupts(struct rte_uio_pci_dev *udev) #else if (pci_alloc_irq_vectors(udev->pdev, 1, 1, PCI_IRQ_MSI) == 1) { dev_dbg(&udev->pdev->dev, "using MSI"); + udev->info.irq_flags = IRQF_NO_THREAD; udev->info.irq = pci_irq_vector(udev->pdev, 0); udev->mode = RTE_INTR_MODE_MSI; break; @@ -397,7 +355,7 @@ igbuio_pci_enable_interrupts(struct rte_uio_pci_dev *udev) break; } dev_notice(&udev->pdev->dev, "PCI INTX mask not supported\n"); - /* fall back to no IRQ */ + /* fall back to no IRQ */ case RTE_INTR_MODE_NONE: udev->mode = RTE_INTR_MODE_NONE; udev->info.irq = 0; -- 2.7.4