git: 1a2a88684a01 - main - acpi_pci: Inherit PF locality for SR-IOV VFs

From: Kevin Bowling <kbowling_at_FreeBSD.org>
Date: Thu, 27 Aug 2026 05:02:29 UTC
The branch main has been updated by kbowling:

URL: https://cgit.FreeBSD.org/src/commit/?id=1a2a88684a0126be8d7172362d5ec7dbb7a41c81

commit 1a2a88684a0126be8d7172362d5ec7dbb7a41c81
Author:     Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-08-21 02:27:49 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-08-27 05:01:34 +0000

    acpi_pci: Inherit PF locality for SR-IOV VFs
    
    SR-IOV VFs are instantiated from their PF and intentionally do not
    receive an ACPI handle by matching their runtime BDF.  Consequently,
    ACPI locality queries for a VF fall back to the upstream bus.  This is
    usually sufficient, but loses a _PXM supplied specifically for the PF.
    
    Use the PCI core's owning-PF accessor for BUS_GET_DOMAIN and
    BUS_GET_CPUS requests made for a VF.  This preserves the VF's lack of
    an ACPI handle while allowing its CPU and NUMA placement to follow the
    PF.
    
    Reviewed by:    jhb
    MFC after:      2 weeks
    Sponsored by:   BBOX.io
    Differential Revision:  https://reviews.freebsd.org/D59062
---
 sys/dev/acpica/acpi_pci.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/sys/dev/acpica/acpi_pci.c b/sys/dev/acpica/acpi_pci.c
index 0ff938cfd6b8..56ae2ce3dda4 100644
--- a/sys/dev/acpica/acpi_pci.c
+++ b/sys/dev/acpica/acpi_pci.c
@@ -90,7 +90,10 @@ static int	acpi_pci_set_powerstate_method(device_t dev, device_t child,
 		    int state);
 static void	acpi_pci_update_device(ACPI_HANDLE handle, device_t pci_child);
 static bus_dma_tag_t acpi_pci_get_dma_tag(device_t bus, device_t child);
+static int	acpi_pci_get_cpus(device_t dev, device_t child,
+		    enum cpu_sets op, size_t setsize, cpuset_t *cpuset);
 static int	acpi_pci_get_domain(device_t dev, device_t child, int *domain);
+static device_t acpi_pci_get_locality_device(device_t child);
 
 static device_method_t acpi_pci_methods[] = {
 	/* Device interface */
@@ -104,7 +107,7 @@ static device_method_t acpi_pci_methods[] = {
 	DEVMETHOD(bus_child_deleted,	acpi_pci_child_deleted),
 	DEVMETHOD(bus_child_location,	acpi_pci_child_location_method),
 	DEVMETHOD(bus_get_device_path,	acpi_pci_get_device_path),
-	DEVMETHOD(bus_get_cpus,		acpi_get_cpus),
+	DEVMETHOD(bus_get_cpus,		acpi_pci_get_cpus),
 	DEVMETHOD(bus_get_dma_tag,	acpi_pci_get_dma_tag),
 	DEVMETHOD(bus_get_domain,	acpi_pci_get_domain),
 
@@ -204,6 +207,25 @@ acpi_pci_get_device_path(device_t bus, device_t child, const char *locator, stru
 	return 	(pci_get_device_path_method(bus, child, locator, sb));
 }
 
+/* Use a VF's PF as the source of its ACPI locality information. */
+static device_t
+acpi_pci_get_locality_device(device_t child)
+{
+	device_t pf;
+
+	pf = pci_iov_get_pf(child);
+	return (pf != NULL ? pf : child);
+}
+
+static int
+acpi_pci_get_cpus(device_t dev, device_t child, enum cpu_sets op,
+    size_t setsize, cpuset_t *cpuset)
+{
+
+	child = acpi_pci_get_locality_device(child);
+	return (acpi_get_cpus(dev, child, op, setsize, cpuset));
+}
+
 /*
  * Fetch the NUMA domain for the given device 'dev'.
  *
@@ -217,6 +239,7 @@ acpi_pci_get_domain(device_t dev, device_t child, int *domain)
 {
 	int d;
 
+	child = acpi_pci_get_locality_device(child);
 	d = acpi_pxm_parse(child);
 	if (d >= 0) {
 		*domain = d;