diff mbox series

[RFC,1/2] PCI/IOV: Introduce pci_iov_sysfs_link() function

Message ID 20200506154139.90609-2-schnelle@linux.ibm.com
State New
Headers show
Series Enable PF-VF linking with pdev->no_vf_scan (s390) | expand

Commit Message

Niklas Schnelle May 6, 2020, 3:41 p.m. UTC
currently pci_iov_add_virtfn() scans the SR-IOV bars, adds the VF to the
bus and also creates the sysfs links between the newly added VF and its
parent PF.

With pdev->no_vf_scan fencing off the entire pci_iov_add_virtfn() call
s390 as the sole pdev->no_vf_scan user thus ends up missing these sysfs
links which are required for example by QEMU/libvirt.
Instead of duplicating the code introduce a new pci_iov_sysfs_link()
function for establishing sysfs links.

Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
---
 drivers/pci/iov.c   | 36 ++++++++++++++++++++++++------------
 include/linux/pci.h |  8 ++++++++
 2 files changed, 32 insertions(+), 12 deletions(-)

Comments

Bjorn Helgaas May 6, 2020, 9:10 p.m. UTC | #1
On Wed, May 06, 2020 at 05:41:38PM +0200, Niklas Schnelle wrote:
> currently pci_iov_add_virtfn() scans the SR-IOV bars, adds the VF to the
> bus and also creates the sysfs links between the newly added VF and its
> parent PF.

s/currently/Currently/
s/bars/BARs/

> With pdev->no_vf_scan fencing off the entire pci_iov_add_virtfn() call
> s390 as the sole pdev->no_vf_scan user thus ends up missing these sysfs
> links which are required for example by QEMU/libvirt.
> Instead of duplicating the code introduce a new pci_iov_sysfs_link()
> function for establishing sysfs links.

This looks like two paragraphs missing the blank line between.

This whole thing is not "introducing" any new functionality; it's
"refactoring" to move existing functionality around and make it
callable separately.

> Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>

With the fixes above and a few below:

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

> ---
>  drivers/pci/iov.c   | 36 ++++++++++++++++++++++++------------
>  include/linux/pci.h |  8 ++++++++
>  2 files changed, 32 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
> index 4d1f392b05f9..d0ddf5f5484c 100644
> --- a/drivers/pci/iov.c
> +++ b/drivers/pci/iov.c
> @@ -113,7 +113,6 @@ resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno)
>  static void pci_read_vf_config_common(struct pci_dev *virtfn)
>  {
>  	struct pci_dev *physfn = virtfn->physfn;
> -
>  	/*
>  	 * Some config registers are the same across all associated VFs.
>  	 * Read them once from VF0 so we can skip reading them from the
> @@ -133,12 +132,34 @@ static void pci_read_vf_config_common(struct pci_dev *virtfn)
>  			     &physfn->sriov->subsystem_device);
>  }
>  
> +int pci_iov_sysfs_link(struct pci_dev *dev,
> +		struct pci_dev *virtfn, int id)
> +{
> +	int rc;
> +	char buf[VIRTFN_ID_LEN];

Swap the order so these are declared in the order they're used below.

> +	sprintf(buf, "virtfn%u", id);
> +	rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
> +	if (rc)
> +		goto failed;
> +	rc = sysfs_create_link(&virtfn->dev.kobj, &dev->dev.kobj, "physfn");
> +	if (rc)
> +		goto failed1;
> +
> +	kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE);
> +
> +	return 0;

Add a blank link here to separate the "success" return from the error
paths.

> +failed1:
> +	sysfs_remove_link(&dev->dev.kobj, buf);
> +failed:
> +	return rc;
> +}
> +
>  int pci_iov_add_virtfn(struct pci_dev *dev, int id)
>  {
>  	int i;
>  	int rc = -ENOMEM;
>  	u64 size;
> -	char buf[VIRTFN_ID_LEN];
>  	struct pci_dev *virtfn;
>  	struct resource *res;
>  	struct pci_sriov *iov = dev->sriov;
> @@ -182,23 +203,14 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id)
>  	}
>  
>  	pci_device_add(virtfn, virtfn->bus);
> -
> -	sprintf(buf, "virtfn%u", id);
> -	rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
> +	rc = pci_iov_sysfs_link(dev, virtfn, id);
>  	if (rc)
>  		goto failed1;
> -	rc = sysfs_create_link(&virtfn->dev.kobj, &dev->dev.kobj, "physfn");
> -	if (rc)
> -		goto failed2;
> -
> -	kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE);
>  
>  	pci_bus_add_device(virtfn);
>  
>  	return 0;
>  
> -failed2:
> -	sysfs_remove_link(&dev->dev.kobj, buf);
>  failed1:
>  	pci_stop_and_remove_bus_device(virtfn);
>  	pci_dev_put(dev);
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 83ce1cdf5676..e97d27ac350a 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -2048,6 +2048,8 @@ int pci_iov_virtfn_devfn(struct pci_dev *dev, int id);
>  
>  int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);
>  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);
>  void pci_iov_remove_virtfn(struct pci_dev *dev, int id);
>  int pci_num_vf(struct pci_dev *dev);
> @@ -2073,6 +2075,12 @@ static inline int pci_iov_virtfn_devfn(struct pci_dev *dev, int id)
>  }
>  static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn)
>  { return -ENODEV; }
> +
> +static inline int pci_iov_sysfs_link(struct pci_dev *dev,
> +		struct pci_dev *virtfn, int id)

Align the second line with the args in the first line, as the rest of
this file does.

> +{
> +	return -ENODEV;
> +}
>  static inline int pci_iov_add_virtfn(struct pci_dev *dev, int id)
>  {
>  	return -ENOSYS;
> -- 
> 2.17.1
>
Niklas Schnelle May 7, 2020, 7:48 a.m. UTC | #2
On 5/6/20 11:10 PM, Bjorn Helgaas wrote:
> On Wed, May 06, 2020 at 05:41:38PM +0200, Niklas Schnelle wrote:
>> currently pci_iov_add_virtfn() scans the SR-IOV bars, adds the VF to the
>> bus and also creates the sysfs links between the newly added VF and its
>> parent PF.
> 
> s/currently/Currently/
> s/bars/BARs/
> 
>> With pdev->no_vf_scan fencing off the entire pci_iov_add_virtfn() call
>> s390 as the sole pdev->no_vf_scan user thus ends up missing these sysfs
>> links which are required for example by QEMU/libvirt.
>> Instead of duplicating the code introduce a new pci_iov_sysfs_link()
>> function for establishing sysfs links.
> 
> This looks like two paragraphs missing the blank line between.
> 
> This whole thing is not "introducing" any new functionality; it's
> "refactoring" to move existing functionality around and make it
> callable separately.
You're right I'll keep it in the subject for easier reference
if that's okay with you.
> 
>> Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
> 
> With the fixes above and a few below:
> 
> Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Thank you for the very quick and useful feedback.
I've incorporated the changes and will resend with the PATCH prefix.
If/when accepted what tree should the first patch go to?

And yes I plan to let the second patch go via the s390 tree.
> 
>> ---
>>  drivers/pci/iov.c   | 36 ++++++++++++++++++++++++------------
>>  include/linux/pci.h |  8 ++++++++
>>  2 files changed, 32 insertions(+), 12 deletions(-)
>>
... snip ...
Bjorn Helgaas May 7, 2020, 3:51 p.m. UTC | #3
On Thu, May 07, 2020 at 09:48:30AM +0200, Niklas Schnelle wrote:
> On 5/6/20 11:10 PM, Bjorn Helgaas wrote:
> > On Wed, May 06, 2020 at 05:41:38PM +0200, Niklas Schnelle wrote:
> >> currently pci_iov_add_virtfn() scans the SR-IOV bars, adds the VF to the
> >> bus and also creates the sysfs links between the newly added VF and its
> >> parent PF.
> > 
> > s/currently/Currently/
> > s/bars/BARs/
> > 
> >> With pdev->no_vf_scan fencing off the entire pci_iov_add_virtfn() call
> >> s390 as the sole pdev->no_vf_scan user thus ends up missing these sysfs
> >> links which are required for example by QEMU/libvirt.
> >> Instead of duplicating the code introduce a new pci_iov_sysfs_link()
> >> function for establishing sysfs links.
> > 
> > This looks like two paragraphs missing the blank line between.
> > 
> > This whole thing is not "introducing" any new functionality; it's
> > "refactoring" to move existing functionality around and make it
> > callable separately.
> You're right I'll keep it in the subject for easier reference
> if that's okay with you.
> > 
> >> Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
> > 
> > With the fixes above and a few below:
> > 
> > Acked-by: Bjorn Helgaas <bhelgaas@google.com>
>
> Thank you for the very quick and useful feedback.
> I've incorporated the changes and will resend with the PATCH prefix.
> If/when accepted what tree should the first patch go to?

I'd expect them both to go via the s390 tree so there's no dependency
between the PCI merge and the s390 merge.

> And yes I plan to let the second patch go via the s390 tree.
diff mbox series

Patch

diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 4d1f392b05f9..d0ddf5f5484c 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -113,7 +113,6 @@  resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno)
 static void pci_read_vf_config_common(struct pci_dev *virtfn)
 {
 	struct pci_dev *physfn = virtfn->physfn;
-
 	/*
 	 * Some config registers are the same across all associated VFs.
 	 * Read them once from VF0 so we can skip reading them from the
@@ -133,12 +132,34 @@  static void pci_read_vf_config_common(struct pci_dev *virtfn)
 			     &physfn->sriov->subsystem_device);
 }
 
+int pci_iov_sysfs_link(struct pci_dev *dev,
+		struct pci_dev *virtfn, int id)
+{
+	int rc;
+	char buf[VIRTFN_ID_LEN];
+
+	sprintf(buf, "virtfn%u", id);
+	rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
+	if (rc)
+		goto failed;
+	rc = sysfs_create_link(&virtfn->dev.kobj, &dev->dev.kobj, "physfn");
+	if (rc)
+		goto failed1;
+
+	kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE);
+
+	return 0;
+failed1:
+	sysfs_remove_link(&dev->dev.kobj, buf);
+failed:
+	return rc;
+}
+
 int pci_iov_add_virtfn(struct pci_dev *dev, int id)
 {
 	int i;
 	int rc = -ENOMEM;
 	u64 size;
-	char buf[VIRTFN_ID_LEN];
 	struct pci_dev *virtfn;
 	struct resource *res;
 	struct pci_sriov *iov = dev->sriov;
@@ -182,23 +203,14 @@  int pci_iov_add_virtfn(struct pci_dev *dev, int id)
 	}
 
 	pci_device_add(virtfn, virtfn->bus);
-
-	sprintf(buf, "virtfn%u", id);
-	rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
+	rc = pci_iov_sysfs_link(dev, virtfn, id);
 	if (rc)
 		goto failed1;
-	rc = sysfs_create_link(&virtfn->dev.kobj, &dev->dev.kobj, "physfn");
-	if (rc)
-		goto failed2;
-
-	kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE);
 
 	pci_bus_add_device(virtfn);
 
 	return 0;
 
-failed2:
-	sysfs_remove_link(&dev->dev.kobj, buf);
 failed1:
 	pci_stop_and_remove_bus_device(virtfn);
 	pci_dev_put(dev);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 83ce1cdf5676..e97d27ac350a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -2048,6 +2048,8 @@  int pci_iov_virtfn_devfn(struct pci_dev *dev, int id);
 
 int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);
 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);
 void pci_iov_remove_virtfn(struct pci_dev *dev, int id);
 int pci_num_vf(struct pci_dev *dev);
@@ -2073,6 +2075,12 @@  static inline int pci_iov_virtfn_devfn(struct pci_dev *dev, int id)
 }
 static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn)
 { return -ENODEV; }
+
+static inline int pci_iov_sysfs_link(struct pci_dev *dev,
+		struct pci_dev *virtfn, int id)
+{
+	return -ENODEV;
+}
 static inline int pci_iov_add_virtfn(struct pci_dev *dev, int id)
 {
 	return -ENOSYS;