X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=lib%2Flibrte_eal%2Flinuxapp%2Figb_uio%2Figb_uio.c;h=45d70272df7158701cf60ee061660cc3f258c2f2;hb=refs%2Fheads%2Fupstream-17.11-stable;hp=a3a98c1730890eb7e726889b2c83ecc6771426dd;hpb=055c52583a2794da8ba1e85a48cce3832372b12f;p=deb_dpdk.git diff --git a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c index a3a98c17..45d70272 100644 --- a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c +++ b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c @@ -45,6 +45,7 @@ struct rte_uio_pci_dev { struct uio_info info; struct pci_dev *pdev; enum rte_intr_mode mode; + atomic_t refcnt; }; static char *intr_mode; @@ -336,16 +337,19 @@ igbuio_pci_open(struct uio_info *info, struct inode *inode) struct pci_dev *dev = udev->pdev; int err; + if (atomic_inc_return(&udev->refcnt) != 1) + return 0; + /* set bus master, which was cleared by the reset function */ pci_set_master(dev); /* enable interrupts */ err = igbuio_pci_enable_interrupts(udev); if (err) { + atomic_dec(&udev->refcnt); dev_err(&dev->dev, "Enable interrupt fails\n"); - return err; } - return 0; + return err; } static int @@ -354,11 +358,13 @@ igbuio_pci_release(struct uio_info *info, struct inode *inode) struct rte_uio_pci_dev *udev = info->priv; struct pci_dev *dev = udev->pdev; - /* disable interrupts */ - igbuio_pci_disable_interrupts(udev); + if (atomic_dec_and_test(&udev->refcnt)) { + /* disable interrupts */ + igbuio_pci_disable_interrupts(udev); - /* stop the device from further DMA */ - pci_clear_master(dev); + /* stop the device from further DMA */ + pci_clear_master(dev); + } return 0; } @@ -519,6 +525,7 @@ igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) udev->info.release = igbuio_pci_release; udev->info.priv = udev; udev->pdev = dev; + atomic_set(&udev->refcnt, 0); err = sysfs_create_group(&dev->dev.kobj, &dev_attr_grp); if (err != 0)