Commit 83c3672b authored by Jialin Zhang's avatar Jialin Zhang
Browse files

PCI/IOV: Improve performance of creating VFs concurrently

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I9J08D



--------------------------------

Previous commit 083577ae ("PCI/IOV: Add pci_sriov_numvfs_lock
to support enable pci sriov concurrently")
reduce performance of creating VFs belongs to different PFs.
Fix it by checking whether a new bus will be created.

Fixes: 083577ae ("PCI/IOV: Add pci_sriov_numvfs_lock to support enable pci sriov concurrently")
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parent a37954d8
Loading
Loading
Loading
Loading
+33 −7
Original line number Diff line number Diff line
@@ -240,6 +240,16 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id)
	return rc;
}

int pci_iov_add_virtfn_locked(struct pci_dev *dev, int id)
{
	int rc;

	mutex_lock(&pci_sriov_numvfs_lock);
	rc = pci_iov_add_virtfn(dev, id);
	mutex_unlock(&pci_sriov_numvfs_lock);
	return rc;
}

void pci_iov_remove_virtfn(struct pci_dev *dev, int id)
{
	char buf[VIRTFN_ID_LEN];
@@ -269,6 +279,13 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id)
	pci_dev_put(dev);
}

void pci_iov_remove_virtfn_locked(struct pci_dev *dev, int id)
{
	mutex_lock(&pci_sriov_numvfs_lock);
	pci_iov_remove_virtfn(dev, id);
	mutex_unlock(&pci_sriov_numvfs_lock);
}

static ssize_t sriov_totalvfs_show(struct device *dev,
				   struct device_attribute *attr,
				   char *buf)
@@ -315,7 +332,6 @@ static ssize_t sriov_numvfs_store(struct device *dev,
	if (num_vfs > pci_sriov_get_totalvfs(pdev))
		return -ERANGE;

	mutex_lock(&pci_sriov_numvfs_lock);
	device_lock(&pdev->dev);

	if (num_vfs == pdev->sriov->num_VFs)
@@ -352,7 +368,6 @@ static ssize_t sriov_numvfs_store(struct device *dev,

exit:
	device_unlock(&pdev->dev);
	mutex_unlock(&pci_sriov_numvfs_lock);

	if (ret < 0)
		return ret;
@@ -463,14 +478,21 @@ static int sriov_add_vfs(struct pci_dev *dev, u16 num_vfs)
		return 0;

	for (i = 0; i < num_vfs; i++) {
		if (dev->bus->number != pci_iov_virtfn_bus(dev, i))
			rc = pci_iov_add_virtfn_locked(dev, i);
		else
			rc = pci_iov_add_virtfn(dev, i);
		if (rc)
			goto failed;
	}
	return 0;
failed:
	while (i--)
	while (i--) {
		if (dev->bus->number != pci_iov_virtfn_bus(dev, i))
			pci_iov_remove_virtfn_locked(dev, i);
		else
			pci_iov_remove_virtfn(dev, i);
	}

	return rc;
}
@@ -590,9 +612,13 @@ static void sriov_del_vfs(struct pci_dev *dev)
	struct pci_sriov *iov = dev->sriov;
	int i;

	for (i = 0; i < iov->num_VFs; i++)
	for (i = 0; i < iov->num_VFs; i++) {
		if (dev->bus->number != pci_iov_virtfn_bus(dev, i))
			pci_iov_remove_virtfn_locked(dev, i);
		else
			pci_iov_remove_virtfn(dev, i);
	}
}

static void sriov_disable(struct pci_dev *dev)
{
+8 −0
Original line number Diff line number Diff line
@@ -2125,7 +2125,9 @@ void pci_disable_sriov(struct pci_dev *dev);

int pci_iov_sysfs_link(struct pci_dev *dev, struct pci_dev *virtfn, int id);
int pci_iov_add_virtfn(struct pci_dev *dev, int id);
int pci_iov_add_virtfn_locked(struct pci_dev *dev, int id);
void pci_iov_remove_virtfn(struct pci_dev *dev, int id);
void pci_iov_remove_virtfn_locked(struct pci_dev *dev, int id);
int pci_num_vf(struct pci_dev *dev);
int pci_vfs_assigned(struct pci_dev *dev);
int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs);
@@ -2165,8 +2167,14 @@ static inline int pci_iov_add_virtfn(struct pci_dev *dev, int id)
{
	return -ENOSYS;
}
static inline int pci_iov_add_virtfn_locked(struct pci_dev *dev, int id)
{
	return -ENOSYS;
}
static inline void pci_iov_remove_virtfn(struct pci_dev *dev,
					 int id) { }
static inline void pci_iov_remove_virtfn_locked(struct pci_dev *dev,
						int id) { }
static inline void pci_disable_sriov(struct pci_dev *dev) { }
static inline int pci_num_vf(struct pci_dev *dev) { return 0; }
static inline int pci_vfs_assigned(struct pci_dev *dev)