Hello, IGB_UIO driver does not close port PCI activities after DPDK process exits. DPDK API provides rte_eth_dev_close() to manage port PCI, but it can be skipped if process receives SIGKILL signal The patches below provide IGB_UIO release callback and IXGBEVF release function With the patches, each time DPDK process terminates, UIO release callback will trigger port PCI close. On the down side, patched IGB_UIO can be bound to a single adapter type
Regards, Gregory diff --git a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c index df41e45..97b8501 100644 --- a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c +++ b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c @@ -170,6 +170,16 @@ igbuio_pci_irqhandler(int irq, struct uio_info *info) return IRQ_HANDLED; } +static int +igbuio_pci_release(struct uio_info *info, struct inode *inode) +{ + extern int ixgbevf_uio_release(struct pci_dev *pdev, u8 __iomem *hw_addr); + int ret; + struct rte_uio_pci_dev *udev = info->priv; + ret = ixgbevf_uio_release(udev->pdev, info->mem[0].internal_addr); + return 0; +} + #ifdef CONFIG_XEN_DOM0 static int igbuio_dom0_mmap_phys(struct uio_info *info, struct vm_area_struct *vma) @@ -368,6 +378,7 @@ igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) udev->info.version = "0.1"; udev->info.handler = igbuio_pci_irqhandler; udev->info.irqcontrol = igbuio_pci_irqcontrol; + udev->info.release = igbuio_pci_release; #ifdef CONFIG_XEN_DOM0 /* check if the driver run on Xen Dom0 */ if (xen_initial_domain()) diff --git a/src/ixgbevf_main.c b/src/ixgbevf_main.c index c5a922f..b96d9f0 100644 --- a/src/ixgbevf_main.c +++ b/src/ixgbevf_main.c @@ -3002,6 +3002,39 @@ static void ixgbevf_clear_interrupt_scheme(struct ixgbevf_adapter *adapter) ixgbevf_reset_interrupt_capability(adapter); } +int ixgbevf_uio_release(struct pci_dev *pdev, u8 __iomem *hw_addr) +{ + int err; + struct ixgbe_hw __hw; + struct ixgbe_hw *hw = &__hw; + + if (!hw_addr) { + dev_warn(&pdev->dev, "ixgbevf_uio_release: no HW addr. Bailing out\n"); + } + + memset(hw, 0, sizeof(*hw)); + hw->hw_addr = hw_addr; + + /* PCI config space info */ + hw->vendor_id = pdev->vendor; + hw->device_id = pdev->device; + pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id); + hw->subsystem_vendor_id = pdev->subsystem_vendor; + hw->subsystem_device_id = pdev->subsystem_device; + + ixgbe_init_ops_vf(hw); + hw->mbx.ops.init_params(hw); + + /* assume legacy case in which PF would only give VF 2 queues */ + hw->mac.max_tx_queues = 2; + hw->mac.max_rx_queues = 2; + + err = hw->mac.ops.stop_adapter(hw); + dev_info(&pdev->dev, "ixgbevf_uio_release: UIO adapter stopped\n"); + return err; +} +EXPORT_SYMBOL(ixgbevf_uio_release); + /** * ixgbevf_sw_init - Initialize general software structures * (struct ixgbevf_adapter)