[PATCH OLK-6.6 0/2] support enable pci sriov concurrently

Jialin Zhang (2): PCI/IOV: Add pci_sriov_numvfs_lock to support enable pci sriov concurrently PCI/IOV: Improve performance of creating VFs concurrently drivers/pci/iov.c | 40 +++++++++++++++++++++++++++++++++++----- include/linux/pci.h | 8 ++++++++ 2 files changed, 43 insertions(+), 5 deletions(-) -- 2.20.1

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,转换为PR失败! 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/RT5... 失败原因:应用补丁/补丁集失败,Patch failed at 0002 PCI/IOV: Improve performance of creating VFs concurrently 建议解决方法:请查看失败原因, 确认补丁是否可以应用在当前期望分支的最新代码上 FeedBack: The patch(es) which you have sent to kernel@openeuler.org has been converted to PR failed! Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/RT5... Failed Reason: apply patch(es) failed, Patch failed at 0002 PCI/IOV: Improve performance of creating VFs concurrently Suggest Solution: please checkout if the failed patch(es) can work on the newest codes in expected branch

From: Jialin Zhang <zhangjialin11@huawei.com> hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICJPQ5 -------------------------------- "echo sriov_totalvfs > /sys/bus/pci/devices/$PF_BDF/sriov_numvfs" concurrently may cause the following warnings: Warning 1: sysfs: cannot create duplicate filename '/devices/pci0000:95/0000:95:00.0/pci_bus/0000:97' Call trace: dump_backtrace+0x0/0x200 show_stack+0x20/0x30 dump_stack+0xf0/0x138 sysfs_warn_dup+0x6c/0x90 sysfs_create_dir_ns+0xf8/0x11c create_dir+0x30/0x18c kobject_add_internal+0x5c/0x190 kobject_add+0x98/0x110 device_add+0x100/0x4a0 device_register+0x28/0x40 pci_alloc_child_bus+0x184/0x24c pci_add_new_bus+0x20/0xa4 pci_iov_add_virtfn+0x2a8/0x31c sriov_enable+0x20c/0x4d0 pci_enable_sriov+0x38/0x50 virtio_pci_sriov_configure+0x3c/0xf4 [virtio_pci] sriov_numvfs_store+0xb0/0x1b0 dev_attr_store+0x20/0x34 sysfs_kf_write+0x4c/0x5c kernfs_fop_write_iter+0x130/0x1c0 new_sync_write+0xf0/0x194 vfs_write+0x224/0x2c0 ksys_write+0x74/0x104 __arm64_sys_write+0x24/0x30 el0_svc_common.constprop.0+0x7c/0x1bc do_el0_svc+0x2c/0xa4 el0_svc+0x20/0x30 el0_sync_handler+0xb0/0xb4 el0_sync+0x160/0x180 The reason is that different VFs may create the same pci bus number and try to add new bus concurrently in virtfn_add_bus. Warning 2: proc_dir_entry 'pci/0000:97' already registered Call trace: proc_register+0x100/0x190 proc_mkdir+0x6c/0xa0 pci_proc_attach_device+0xfc/0x120 pci_bus_add_device+0x40/0xd0 pci_iov_add_virtfn+0x2c8/0x31c sriov_enable+0x20c/0x4d0 pci_enable_sriov+0x38/0x50 virtio_pci_sriov_configure+0x3c/0xf4 [virtio_pci] sriov_numvfs_store+0xb0/0x1b0 dev_attr_store+0x20/0x34 sysfs_kf_write+0x4c/0x5c kernfs_fop_write_iter+0x130/0x1c0 new_sync_write+0xf0/0x194 vfs_write+0x224/0x2c0 ksys_write+0x74/0x104 __arm64_sys_write+0x24/0x30 el0_svc_common.constprop.0+0x7c/0x1bc do_el0_svc+0x2c/0xa4 el0_svc+0x20/0x30 el0_sync_handler+0xb0/0xb4 el0_sync+0x160/0x180 The reason is that different VFs may create '/proc/bus/pci/bus_number' directory using the same bus number in pci_proc_attach_device concurrently. Mutex lock can avoid potential conflict. With the patch below the warnings above are no longer appear. Fixes: dd7cc44d0bce ("PCI: add SR-IOV API for Physical Function driver") Signed-off-by: Jialin Zhang <zhangjialin11@huawei.com> Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com> --- drivers/pci/iov.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 25dbe85c4217..9e4f02120031 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -16,6 +16,8 @@ #define VIRTFN_ID_LEN 17 /* "virtfn%u\0" for 2^32 - 1 */ +static DEFINE_MUTEX(pci_sriov_numvfs_lock); + int pci_iov_virtfn_bus(struct pci_dev *dev, int vf_id) { if (!dev->is_physfn) @@ -426,6 +428,7 @@ 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) @@ -469,6 +472,7 @@ 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; -- 2.20.1

From: Jialin Zhang <zhangjialin11@huawei.com> hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICJPQ5 -------------------------------- Previous commit 99daa9e5bd15 ("[Huawei] 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: 99daa9e5bd15 ("[Huawei] PCI/IOV: Add pci_sriov_numvfs_lock to support enable pci sriov concurrently") Signed-off-by: Jialin Zhang <zhangjialin11@huawei.com> Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com> --- drivers/pci/iov.c | 40 +++++++++++++++++++++++++++++++++------- include/linux/pci.h | 8 ++++++++ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 9e4f02120031..f1c60759ef08 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -354,6 +354,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]; @@ -383,6 +393,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) @@ -428,7 +445,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) @@ -472,7 +488,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; @@ -586,14 +601,21 @@ static int sriov_add_vfs(struct pci_dev *dev, u16 num_vfs) return 0; for (i = 0; i < num_vfs; i++) { - rc = pci_iov_add_virtfn(dev, 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--) - pci_iov_remove_virtfn(dev, 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; } @@ -713,8 +735,12 @@ 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++) - pci_iov_remove_virtfn(dev, 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) diff --git a/include/linux/pci.h b/include/linux/pci.h index 9b1b2265da1f..96fe2624b8ce 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -2376,7 +2376,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); @@ -2422,8 +2424,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) -- 2.20.1
participants (2)
-
patchwork bot
-
Xiongfeng Wang