]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - drivers/pci/pci-sysfs.c
PCI: Lock each enable/disable num_vfs operation in sysfs
[mirror_ubuntu-zesty-kernel.git] / drivers / pci / pci-sysfs.c
index 9867e0cdea566e71cf0cb526c8fea4cabb1fa20f..c18ca5d0f5afa4d215cd6dc13f45234ae58f2857 100644 (file)
@@ -473,6 +473,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
                                  const char *buf, size_t count)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
+       struct pci_sriov *iov = pdev->sriov;
        int ret;
        u16 num_vfs;
 
@@ -483,38 +484,46 @@ static ssize_t sriov_numvfs_store(struct device *dev,
        if (num_vfs > pci_sriov_get_totalvfs(pdev))
                return -ERANGE;
 
+       mutex_lock(&iov->dev->sriov->lock);
+
        if (num_vfs == pdev->sriov->num_VFs)
-               return count;           /* no change */
+               goto exit;
 
        /* is PF driver loaded w/callback */
        if (!pdev->driver || !pdev->driver->sriov_configure) {
                dev_info(&pdev->dev, "Driver doesn't support SRIOV configuration via sysfs\n");
-               return -ENOSYS;
+               ret = -ENOENT;
+               goto exit;
        }
 
        if (num_vfs == 0) {
                /* disable VFs */
                ret = pdev->driver->sriov_configure(pdev, 0);
-               if (ret < 0)
-                       return ret;
-               return count;
+               goto exit;
        }
 
        /* enable VFs */
        if (pdev->sriov->num_VFs) {
                dev_warn(&pdev->dev, "%d VFs already enabled. Disable before enabling %d VFs\n",
                         pdev->sriov->num_VFs, num_vfs);
-               return -EBUSY;
+               ret = -EBUSY;
+               goto exit;
        }
 
        ret = pdev->driver->sriov_configure(pdev, num_vfs);
        if (ret < 0)
-               return ret;
+               goto exit;
 
        if (ret != num_vfs)
                dev_warn(&pdev->dev, "%d VFs requested; only %d enabled\n",
                         num_vfs, ret);
 
+exit:
+       mutex_unlock(&iov->dev->sriov->lock);
+
+       if (ret < 0)
+               return ret;
+
        return count;
 }