Linux PCI subsystem development
 help / color / mirror / Atom feed
* [PATCH v4 1/6] PCI/IOV: Return unsigned int from pci_sriov_get_totalvfs()
       [not found] <20260709150206.1046839-1-zhiw@nvidia.com>
@ 2026-07-09 15:02 ` Zhi Wang
  2026-07-09 22:46   ` Bjorn Helgaas
  2026-07-09 15:02 ` [PATCH v4 2/6] rust: pci: add sriov_get_totalvfs() helper Zhi Wang
  1 sibling, 1 reply; 5+ messages in thread
From: Zhi Wang @ 2026-07-09 15:02 UTC (permalink / raw)
  To: dakr, acourbot
  Cc: airlied, simona, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, jhubbard, ecourtney,
	joelagnelf, apopple, cjia, smitra, kjaju, alkumar, ankita,
	aniketa, kwankhede, targupta, nova-gpu, linux-kernel, zhiwang,
	Zhi Wang, Bjorn Helgaas, David Laight, linux-pci

pci_sriov_get_totalvfs() reports a VF count, not an errno-style
status. It returns 0 when SR-IOV is unavailable or the device is not a
PF, and otherwise returns the PF's driver_max_VFs value.

driver_max_VFs is stored as a u16 in struct pci_sriov. It is derived
from the SR-IOV TotalVFs field or from a driver-provided limit, so the
implementation cannot return a negative value.

Change the declaration, CONFIG_PCI_IOV stub, and implementation to
return unsigned int.

Suggested-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: David Laight <david.laight.linux@gmail.com>
Cc: Gary Guo <gary@garyguo.net>
Cc: linux-pci@vger.kernel.org
Link: https://lore.kernel.org/all/DJHPRE4TGGT8.BUTMYOF5YE05@nvidia.com/
Signed-off-by: Zhi Wang <zhiw@nvidia.com>
---
 drivers/pci/iov.c   | 2 +-
 include/linux/pci.h | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index b0d24839c084..9d408fb8ac25 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -1283,7 +1283,7 @@ EXPORT_SYMBOL_GPL(pci_sriov_set_totalvfs);
  * SRIOV capability value of TotalVFs or the value of driver_max_VFs
  * if the driver reduced it.  Otherwise 0.
  */
-int pci_sriov_get_totalvfs(struct pci_dev *dev)
+unsigned int pci_sriov_get_totalvfs(struct pci_dev *dev)
 {
 	if (!dev->is_physfn)
 		return 0;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index ebb5b9d76360..2b9c61de5f67 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -2569,7 +2569,7 @@ void pci_iov_remove_virtfn(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);
-int pci_sriov_get_totalvfs(struct pci_dev *dev);
+unsigned int pci_sriov_get_totalvfs(struct pci_dev *dev);
 int pci_sriov_configure_simple(struct pci_dev *dev, int nr_virtfn);
 resource_size_t pci_iov_resource_size(const struct pci_dev *dev, int resno);
 int pci_iov_vf_bar_set_size(struct pci_dev *dev, int resno, int size);
@@ -2622,7 +2622,7 @@ static inline int pci_vfs_assigned(struct pci_dev *dev)
 { return 0; }
 static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
 { return 0; }
-static inline int pci_sriov_get_totalvfs(struct pci_dev *dev)
+static inline unsigned int pci_sriov_get_totalvfs(struct pci_dev *dev)
 { return 0; }
 #define pci_sriov_configure_simple	NULL
 static inline resource_size_t pci_iov_resource_size(const struct pci_dev *dev,
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v4 2/6] rust: pci: add sriov_get_totalvfs() helper
       [not found] <20260709150206.1046839-1-zhiw@nvidia.com>
  2026-07-09 15:02 ` [PATCH v4 1/6] PCI/IOV: Return unsigned int from pci_sriov_get_totalvfs() Zhi Wang
@ 2026-07-09 15:02 ` Zhi Wang
  2026-07-09 23:00   ` Danilo Krummrich
  1 sibling, 1 reply; 5+ messages in thread
From: Zhi Wang @ 2026-07-09 15:02 UTC (permalink / raw)
  To: dakr, acourbot
  Cc: airlied, simona, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, jhubbard, ecourtney,
	joelagnelf, apopple, cjia, smitra, kjaju, alkumar, ankita,
	aniketa, kwankhede, targupta, nova-gpu, linux-kernel, zhiwang,
	Zhi Wang, Bjorn Helgaas, David Laight, linux-pci

Expose pci_sriov_get_totalvfs() to Rust PCI drivers so they can query
how many SR-IOV VFs a device supports.

Use a conditional C helper because the !CONFIG_PCI_IOV version of
pci_sriov_get_totalvfs() is a static inline function and is therefore
not emitted into the Rust bindings. Return Option<NonZero<u16>> so Rust
callers must handle the zero value that represents unavailable SR-IOV.

Cc: Alexandre Courbot <acourbot@nvidia.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: David Laight <david.laight.linux@gmail.com>
Cc: Gary Guo <gary@garyguo.net>
Cc: linux-pci@vger.kernel.org
Link: https://lore.kernel.org/all/DJHPRE4TGGT8.BUTMYOF5YE05@nvidia.com/
Signed-off-by: Zhi Wang <zhiw@nvidia.com>
---
 rust/helpers/pci.c |  8 ++++++++
 rust/kernel/pci.rs | 13 +++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/rust/helpers/pci.c b/rust/helpers/pci.c
index e44905317d75..4ebf256dff23 100644
--- a/rust/helpers/pci.c
+++ b/rust/helpers/pci.c
@@ -24,6 +24,14 @@ __rust_helper bool rust_helper_dev_is_pci(const struct device *dev)
 	return dev_is_pci(dev);
 }
 
+#ifndef CONFIG_PCI_IOV
+__rust_helper unsigned int
+rust_helper_pci_sriov_get_totalvfs(struct pci_dev *pdev)
+{
+	return pci_sriov_get_totalvfs(pdev);
+}
+#endif
+
 #ifndef CONFIG_PCI_MSI
 __rust_helper int rust_helper_pci_alloc_irq_vectors(struct pci_dev *dev,
 						    unsigned int min_vecs,
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index 5071cae6543f..280e84201d9a 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -25,6 +25,7 @@
 use core::{
     marker::PhantomData,
     mem::offset_of,
+    num::NonZero,
     ptr::{
         addr_of_mut,
         NonNull, //
@@ -450,6 +451,18 @@ pub fn pci_class(&self) -> Class {
         // SAFETY: `self.as_raw` is a valid pointer to a `struct pci_dev`.
         Class::from_raw(unsafe { (*self.as_raw()).class })
     }
+
+    /// Returns the total number of VFs, or [`None`] if SR-IOV is not available.
+    #[inline]
+    pub fn sriov_get_totalvfs(&self) -> Option<NonZero<u16>> {
+        // SAFETY: `self.as_raw()` is a valid pointer to a `struct pci_dev`.
+        let total_vfs = unsafe { bindings::pci_sriov_get_totalvfs(self.as_raw()) };
+
+        // CAST: The C function returns `unsigned int`, but the value originates
+        // from TotalVFs/driver_max_VFs (which are defined as `u16`), so this cast
+        // cannot truncate.
+        NonZero::new(total_vfs as u16)
+    }
 }
 
 impl<'a> Device<device::Core<'a>> {
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v4 1/6] PCI/IOV: Return unsigned int from pci_sriov_get_totalvfs()
  2026-07-09 15:02 ` [PATCH v4 1/6] PCI/IOV: Return unsigned int from pci_sriov_get_totalvfs() Zhi Wang
@ 2026-07-09 22:46   ` Bjorn Helgaas
  2026-07-09 22:58     ` Danilo Krummrich
  0 siblings, 1 reply; 5+ messages in thread
From: Bjorn Helgaas @ 2026-07-09 22:46 UTC (permalink / raw)
  To: Zhi Wang
  Cc: dakr, acourbot, airlied, simona, ojeda, alex.gaynor, boqun.feng,
	gary, bjorn3_gh, lossin, a.hindborg, aliceryhl, tmgross, jhubbard,
	ecourtney, joelagnelf, apopple, cjia, smitra, kjaju, alkumar,
	ankita, aniketa, kwankhede, targupta, nova-gpu, linux-kernel,
	zhiwang, Bjorn Helgaas, David Laight, linux-pci

On Thu, Jul 09, 2026 at 06:02:01PM +0300, Zhi Wang wrote:
> pci_sriov_get_totalvfs() reports a VF count, not an errno-style
> status. It returns 0 when SR-IOV is unavailable or the device is not a
> PF, and otherwise returns the PF's driver_max_VFs value.
> 
> driver_max_VFs is stored as a u16 in struct pci_sriov. It is derived
> from the SR-IOV TotalVFs field or from a driver-provided limit, so the
> implementation cannot return a negative value.
> 
> Change the declaration, CONFIG_PCI_IOV stub, and implementation to
> return unsigned int.
> 
> Suggested-by: Alexandre Courbot <acourbot@nvidia.com>
> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: David Laight <david.laight.linux@gmail.com>
> Cc: Gary Guo <gary@garyguo.net>
> Cc: linux-pci@vger.kernel.org
> Link: https://lore.kernel.org/all/DJHPRE4TGGT8.BUTMYOF5YE05@nvidia.com/
> Signed-off-by: Zhi Wang <zhiw@nvidia.com>

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

Feel free to merge via another tree, or let me know if you want me to
take just this patch via PCI.

> ---
>  drivers/pci/iov.c   | 2 +-
>  include/linux/pci.h | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
> index b0d24839c084..9d408fb8ac25 100644
> --- a/drivers/pci/iov.c
> +++ b/drivers/pci/iov.c
> @@ -1283,7 +1283,7 @@ EXPORT_SYMBOL_GPL(pci_sriov_set_totalvfs);
>   * SRIOV capability value of TotalVFs or the value of driver_max_VFs
>   * if the driver reduced it.  Otherwise 0.
>   */
> -int pci_sriov_get_totalvfs(struct pci_dev *dev)
> +unsigned int pci_sriov_get_totalvfs(struct pci_dev *dev)
>  {
>  	if (!dev->is_physfn)
>  		return 0;
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index ebb5b9d76360..2b9c61de5f67 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -2569,7 +2569,7 @@ void pci_iov_remove_virtfn(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);
> -int pci_sriov_get_totalvfs(struct pci_dev *dev);
> +unsigned int pci_sriov_get_totalvfs(struct pci_dev *dev);
>  int pci_sriov_configure_simple(struct pci_dev *dev, int nr_virtfn);
>  resource_size_t pci_iov_resource_size(const struct pci_dev *dev, int resno);
>  int pci_iov_vf_bar_set_size(struct pci_dev *dev, int resno, int size);
> @@ -2622,7 +2622,7 @@ static inline int pci_vfs_assigned(struct pci_dev *dev)
>  { return 0; }
>  static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
>  { return 0; }
> -static inline int pci_sriov_get_totalvfs(struct pci_dev *dev)
> +static inline unsigned int pci_sriov_get_totalvfs(struct pci_dev *dev)
>  { return 0; }
>  #define pci_sriov_configure_simple	NULL
>  static inline resource_size_t pci_iov_resource_size(const struct pci_dev *dev,
> -- 
> 2.51.0
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v4 1/6] PCI/IOV: Return unsigned int from pci_sriov_get_totalvfs()
  2026-07-09 22:46   ` Bjorn Helgaas
@ 2026-07-09 22:58     ` Danilo Krummrich
  0 siblings, 0 replies; 5+ messages in thread
From: Danilo Krummrich @ 2026-07-09 22:58 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Zhi Wang, acourbot, airlied, simona, ojeda, alex.gaynor,
	boqun.feng, gary, bjorn3_gh, lossin, a.hindborg, aliceryhl,
	tmgross, jhubbard, ecourtney, joelagnelf, apopple, cjia, smitra,
	kjaju, alkumar, ankita, aniketa, kwankhede, targupta, nova-gpu,
	linux-kernel, zhiwang, Bjorn Helgaas, David Laight, linux-pci

On Fri Jul 10, 2026 at 12:46 AM CEST, Bjorn Helgaas wrote:
> Feel free to merge via another tree, or let me know if you want me to
> take just this patch via PCI.

Thanks, will take it through the drm-rust tree then.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v4 2/6] rust: pci: add sriov_get_totalvfs() helper
  2026-07-09 15:02 ` [PATCH v4 2/6] rust: pci: add sriov_get_totalvfs() helper Zhi Wang
@ 2026-07-09 23:00   ` Danilo Krummrich
  0 siblings, 0 replies; 5+ messages in thread
From: Danilo Krummrich @ 2026-07-09 23:00 UTC (permalink / raw)
  To: Zhi Wang
  Cc: acourbot, airlied, simona, ojeda, alex.gaynor, boqun.feng, gary,
	bjorn3_gh, lossin, a.hindborg, aliceryhl, tmgross, jhubbard,
	ecourtney, joelagnelf, apopple, cjia, smitra, kjaju, alkumar,
	ankita, aniketa, kwankhede, targupta, nova-gpu, linux-kernel,
	zhiwang, Bjorn Helgaas, David Laight, linux-pci

On Thu Jul 9, 2026 at 5:02 PM CEST, Zhi Wang wrote:
> +    /// Returns the total number of VFs, or [`None`] if SR-IOV is not available.
> +    #[inline]
> +    pub fn sriov_get_totalvfs(&self) -> Option<NonZero<u16>> {
> +        // SAFETY: `self.as_raw()` is a valid pointer to a `struct pci_dev`.
> +        let total_vfs = unsafe { bindings::pci_sriov_get_totalvfs(self.as_raw()) };
> +
> +        // CAST: The C function returns `unsigned int`, but the value originates
> +        // from TotalVFs/driver_max_VFs (which are defined as `u16`), so this cast
> +        // cannot truncate.
> +        NonZero::new(total_vfs as u16)
> +    }
>  }
>  
>  impl<'a> Device<device::Core<'a>> {

It is not a problem yet, but sriov_get_totalvfs() should go into the
Device<Core> impl above.

Once we also have sriov_set_totalvfs() this would otherwise be a potential data
race.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-07-09 23:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20260709150206.1046839-1-zhiw@nvidia.com>
2026-07-09 15:02 ` [PATCH v4 1/6] PCI/IOV: Return unsigned int from pci_sriov_get_totalvfs() Zhi Wang
2026-07-09 22:46   ` Bjorn Helgaas
2026-07-09 22:58     ` Danilo Krummrich
2026-07-09 15:02 ` [PATCH v4 2/6] rust: pci: add sriov_get_totalvfs() helper Zhi Wang
2026-07-09 23:00   ` Danilo Krummrich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox