svn commit: r279904 - in stable/10/sys: dev/acpica dev/pci kern sys x86/acpica

Scott Long scottl at FreeBSD.org
Thu Mar 12 07:07:45 UTC 2015


Author: scottl
Date: Thu Mar 12 07:07:41 2015
New Revision: 279904
URL: https://svnweb.freebsd.org/changeset/base/279904

Log:
  MFC r271889, 272799, 272800, 274976
  This brings in bus_get_domain() and the related reporting via devinfo,
  dmesg, and sysctl.
  
  Obtained from:	adrian, jhb
  Sponsored by:	Netflix, Inc.

Modified:
  stable/10/sys/dev/acpica/acpi.c
  stable/10/sys/dev/acpica/acpi_pci.c
  stable/10/sys/dev/acpica/acpivar.h
  stable/10/sys/dev/pci/pci.c
  stable/10/sys/kern/bus_if.m
  stable/10/sys/kern/subr_bus.c
  stable/10/sys/sys/bus.h
  stable/10/sys/x86/acpica/srat.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/acpica/acpi.c
==============================================================================
--- stable/10/sys/dev/acpica/acpi.c	Thu Mar 12 07:05:28 2015	(r279903)
+++ stable/10/sys/dev/acpica/acpi.c	Thu Mar 12 07:07:41 2015	(r279904)
@@ -207,6 +207,7 @@ static device_method_t acpi_methods[] = 
     DEVMETHOD(bus_setup_intr,		bus_generic_setup_intr),
     DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
     DEVMETHOD(bus_hint_device_unit,	acpi_hint_device_unit),
+    DEVMETHOD(bus_get_domain,		acpi_get_domain),
 
     /* ACPI bus */
     DEVMETHOD(acpi_id_probe,		acpi_device_id_probe),
@@ -797,6 +798,7 @@ acpi_print_child(device_t bus, device_t 
     retval += resource_list_print_type(rl, "drq",   SYS_RES_DRQ,    "%ld");
     if (device_get_flags(child))
 	retval += printf(" flags %#x", device_get_flags(child));
+    retval += bus_print_child_domain(bus, child);
     retval += bus_print_child_footer(bus, child);
 
     return (retval);
@@ -853,11 +855,18 @@ acpi_child_location_str_method(device_t 
     size_t buflen)
 {
     struct acpi_device *dinfo = device_get_ivars(child);
+    char buf2[32];
+    int pxm;
 
-    if (dinfo->ad_handle)
-	snprintf(buf, buflen, "handle=%s", acpi_name(dinfo->ad_handle));
-    else
-	snprintf(buf, buflen, "unknown");
+    if (dinfo->ad_handle) {
+        snprintf(buf, buflen, "handle=%s", acpi_name(dinfo->ad_handle));
+        if (ACPI_SUCCESS(acpi_GetInteger(dinfo->ad_handle, "_PXM", &pxm))) {
+                snprintf(buf2, 32, " _PXM=%d", pxm);
+                strlcat(buf, buf2, buflen);
+        }
+    } else {
+        snprintf(buf, buflen, "unknown");
+    }
     return (0);
 }
 
@@ -1063,6 +1072,35 @@ acpi_hint_device_unit(device_t acdev, de
 }
 
 /*
+ * Fech the NUMA domain for the given device.
+ *
+ * If a device has a _PXM method, map that to a NUMA domain.
+ *
+ * If none is found, then it'll call the parent method.
+ * If there's no domain, return ENOENT.
+ */
+int
+acpi_get_domain(device_t dev, device_t child, int *domain)
+{
+#if MAXMEMDOM > 1
+	ACPI_HANDLE h;
+	int d, pxm;
+
+	h = acpi_get_handle(child);
+	if ((h != NULL) &&
+	    ACPI_SUCCESS(acpi_GetInteger(h, "_PXM", &pxm))) {
+		d = acpi_map_pxm_to_vm_domainid(pxm);
+		if (d < 0)
+			return (ENOENT);
+		*domain = d;
+		return (0);
+	}
+#endif
+	/* No _PXM node; go up a level */
+	return (bus_generic_get_domain(dev, child, domain));
+}
+
+/*
  * Pre-allocate/manage all memory and IO resources.  Since rman can't handle
  * duplicates, we merge any in the sysresource attach routine.
  */

Modified: stable/10/sys/dev/acpica/acpi_pci.c
==============================================================================
--- stable/10/sys/dev/acpica/acpi_pci.c	Thu Mar 12 07:05:28 2015	(r279903)
+++ stable/10/sys/dev/acpica/acpi_pci.c	Thu Mar 12 07:07:41 2015	(r279904)
@@ -94,6 +94,7 @@ static device_method_t acpi_pci_methods[
 	DEVMETHOD(bus_write_ivar,	acpi_pci_write_ivar),
 	DEVMETHOD(bus_child_location_str, acpi_pci_child_location_str_method),
 	DEVMETHOD(bus_get_dma_tag,	acpi_pci_get_dma_tag),
+	DEVMETHOD(bus_get_domain,	acpi_get_domain),
 
 	/* PCI interface */
 	DEVMETHOD(pci_set_powerstate,	acpi_pci_set_powerstate_method),
@@ -149,12 +150,19 @@ acpi_pci_child_location_str_method(devic
     size_t buflen)
 {
     struct acpi_pci_devinfo *dinfo = device_get_ivars(child);
+    int pxm;
+    char buf2[32];
 
     pci_child_location_str_method(cbdev, child, buf, buflen);
-    
+
     if (dinfo->ap_handle) {
-	strlcat(buf, " handle=", buflen);
-	strlcat(buf, acpi_name(dinfo->ap_handle), buflen);
+        strlcat(buf, " handle=", buflen);
+        strlcat(buf, acpi_name(dinfo->ap_handle), buflen);
+
+        if (ACPI_SUCCESS(acpi_GetInteger(dinfo->ap_handle, "_PXM", &pxm))) {
+                snprintf(buf2, 32, " _PXM=%d", pxm);
+                strlcat(buf, buf2, buflen);
+        }
     }
     return (0);
 }

Modified: stable/10/sys/dev/acpica/acpivar.h
==============================================================================
--- stable/10/sys/dev/acpica/acpivar.h	Thu Mar 12 07:05:28 2015	(r279903)
+++ stable/10/sys/dev/acpica/acpivar.h	Thu Mar 12 07:07:41 2015	(r279904)
@@ -489,5 +489,16 @@ ACPI_HANDLE	acpi_GetReference(ACPI_HANDL
 
 SYSCTL_DECL(_debug_acpi);
 
+/*
+ * Map a PXM to a VM domain.
+ *
+ * Returns the VM domain ID if found, or -1 if not found / invalid.
+ */
+#if MAXMEMDOM > 1
+extern	int acpi_map_pxm_to_vm_domainid(int pxm);
+#endif
+
+extern	int acpi_get_domain(device_t dev, device_t child, int *domain);
+
 #endif /* _KERNEL */
 #endif /* !_ACPIVAR_H_ */

Modified: stable/10/sys/dev/pci/pci.c
==============================================================================
--- stable/10/sys/dev/pci/pci.c	Thu Mar 12 07:05:28 2015	(r279903)
+++ stable/10/sys/dev/pci/pci.c	Thu Mar 12 07:07:41 2015	(r279904)
@@ -3781,6 +3781,7 @@ pci_print_child(device_t dev, device_t c
 	retval += printf(" at device %d.%d", pci_get_slot(child),
 	    pci_get_function(child));
 
+	retval += bus_print_child_domain(dev, child);
 	retval += bus_print_child_footer(dev, child);
 
 	return (retval);

Modified: stable/10/sys/kern/bus_if.m
==============================================================================
--- stable/10/sys/kern/bus_if.m	Thu Mar 12 07:05:28 2015	(r279903)
+++ stable/10/sys/kern/bus_if.m	Thu Mar 12 07:07:41 2015	(r279904)
@@ -670,3 +670,16 @@ METHOD int remap_intr {
 	device_t	_child;
 	u_int		_irq;
 } DEFAULT null_remap_intr;
+
+/**
+ * @brief Get the VM domain handle for the given bus and child.
+ *
+ * @param _dev		the bus device
+ * @param _child	the child device
+ * @param _domain	a pointer to the bus's domain handle identifier
+ */
+METHOD int get_domain {
+	device_t	_dev;
+	device_t	_child;
+	int		*_domain;
+} DEFAULT bus_generic_get_domain;

Modified: stable/10/sys/kern/subr_bus.c
==============================================================================
--- stable/10/sys/kern/subr_bus.c	Thu Mar 12 07:05:28 2015	(r279903)
+++ stable/10/sys/kern/subr_bus.c	Thu Mar 12 07:07:41 2015	(r279904)
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/uio.h>
 #include <sys/bus.h>
 #include <sys/interrupt.h>
+#include <sys/cpuset.h>
 
 #include <net/vnet.h>
 
@@ -284,6 +285,7 @@ static void
 device_sysctl_init(device_t dev)
 {
 	devclass_t dc = dev->devclass;
+	int domain;
 
 	if (dev->sysctl_tree != NULL)
 		return;
@@ -313,6 +315,10 @@ device_sysctl_init(device_t dev)
 	    OID_AUTO, "%parent", CTLTYPE_STRING | CTLFLAG_RD,
 	    dev, DEVICE_SYSCTL_PARENT, device_sysctl_handler, "A",
 	    "parent device");
+	if (bus_get_domain(dev, &domain) == 0)
+		SYSCTL_ADD_INT(&dev->sysctl_ctx,
+		    SYSCTL_CHILDREN(dev->sysctl_tree), OID_AUTO, "%domain",
+		    CTLFLAG_RD, NULL, domain, "NUMA domain");
 }
 
 static void
@@ -3719,6 +3725,25 @@ bus_print_child_footer(device_t dev, dev
 /**
  * @brief Helper function for implementing BUS_PRINT_CHILD().
  *
+ * This function prints out the VM domain for the given device.
+ *
+ * @returns the number of characters printed
+ */
+int
+bus_print_child_domain(device_t dev, device_t child)
+{
+	int domain;
+
+	/* No domain? Don't print anything */
+	if (BUS_GET_DOMAIN(dev, child, &domain) != 0)
+		return (0);
+
+	return (printf(" numa-domain %d", domain));
+}
+
+/**
+ * @brief Helper function for implementing BUS_PRINT_CHILD().
+ *
  * This function simply calls bus_print_child_header() followed by
  * bus_print_child_footer().
  *
@@ -3730,6 +3755,7 @@ bus_generic_print_child(device_t dev, de
 	int	retval = 0;
 
 	retval += bus_print_child_header(dev, child);
+	retval += bus_print_child_domain(dev, child);
 	retval += bus_print_child_footer(dev, child);
 
 	return (retval);
@@ -4144,6 +4170,16 @@ bus_generic_child_present(device_t dev, 
 	return (BUS_CHILD_PRESENT(device_get_parent(dev), dev));
 }
 
+int
+bus_generic_get_domain(device_t dev, device_t child, int *domain)
+{
+
+	if (dev->parent)
+		return (BUS_GET_DOMAIN(dev->parent, dev, domain));
+
+	return (ENOENT);
+}
+
 /*
  * Some convenience functions to make it easier for drivers to use the
  * resource-management functions.  All these really do is hide the
@@ -4476,6 +4512,18 @@ bus_get_dma_tag(device_t dev)
 	return (BUS_GET_DMA_TAG(parent, dev));
 }
 
+/**
+ * @brief Wrapper function for BUS_GET_DOMAIN().
+ *
+ * This function simply calls the BUS_GET_DOMAIN() method of the
+ * parent of @p dev.
+ */
+int
+bus_get_domain(device_t dev, int *domain)
+{
+	return (BUS_GET_DOMAIN(device_get_parent(dev), dev, domain));
+}
+
 /* Resume all devices and then notify userland that we're up again. */
 static int
 root_resume(device_t dev)

Modified: stable/10/sys/sys/bus.h
==============================================================================
--- stable/10/sys/sys/bus.h	Thu Mar 12 07:05:28 2015	(r279903)
+++ stable/10/sys/sys/bus.h	Thu Mar 12 07:07:41 2015	(r279904)
@@ -332,6 +332,7 @@ struct resource_list *
 	bus_generic_get_resource_list (device_t, device_t);
 void	bus_generic_new_pass(device_t dev);
 int	bus_print_child_header(device_t dev, device_t child);
+int	bus_print_child_domain(device_t dev, device_t child);
 int	bus_print_child_footer(device_t dev, device_t child);
 int	bus_generic_print_child(device_t dev, device_t child);
 int	bus_generic_probe(device_t dev);
@@ -363,6 +364,8 @@ int	bus_generic_teardown_intr(device_t d
 int	bus_generic_write_ivar(device_t dev, device_t child, int which,
 			       uintptr_t value);
 
+int	bus_generic_get_domain(device_t dev, device_t child, int *domain);
+
 /*
  * Wrapper functions for the BUS_*_RESOURCE methods to make client code
  * a little simpler.
@@ -389,6 +392,7 @@ int	bus_activate_resource(device_t dev, 
 int	bus_deactivate_resource(device_t dev, int type, int rid,
 				struct resource *r);
 bus_dma_tag_t bus_get_dma_tag(device_t dev);
+int	bus_get_domain(device_t dev, int *domain);
 int	bus_release_resource(device_t dev, int type, int rid,
 			     struct resource *r);
 int	bus_free_resource(device_t dev, int type, struct resource *r);

Modified: stable/10/sys/x86/acpica/srat.c
==============================================================================
--- stable/10/sys/x86/acpica/srat.c	Thu Mar 12 07:05:28 2015	(r279903)
+++ stable/10/sys/x86/acpica/srat.c	Thu Mar 12 07:07:41 2015	(r279904)
@@ -62,6 +62,8 @@ int num_mem;
 static ACPI_TABLE_SRAT *srat;
 static vm_paddr_t srat_physaddr;
 
+static int vm_domains[VM_PHYSSEG_MAX];
+
 static void	srat_walk_table(acpi_subtable_handler *handler, void *arg);
 
 /*
@@ -247,7 +249,6 @@ check_phys_avail(void)
 static int
 renumber_domains(void)
 {
-	int domains[VM_PHYSSEG_MAX];
 	int i, j, slot;
 
 	/* Enumerate all the domains. */
@@ -255,17 +256,17 @@ renumber_domains(void)
 	for (i = 0; i < num_mem; i++) {
 		/* See if this domain is already known. */
 		for (j = 0; j < vm_ndomains; j++) {
-			if (domains[j] >= mem_info[i].domain)
+			if (vm_domains[j] >= mem_info[i].domain)
 				break;
 		}
-		if (j < vm_ndomains && domains[j] == mem_info[i].domain)
+		if (j < vm_ndomains && vm_domains[j] == mem_info[i].domain)
 			continue;
 
 		/* Insert the new domain at slot 'j'. */
 		slot = j;
 		for (j = vm_ndomains; j > slot; j--)
-			domains[j] = domains[j - 1];
-		domains[slot] = mem_info[i].domain;
+			vm_domains[j] = vm_domains[j - 1];
+		vm_domains[slot] = mem_info[i].domain;
 		vm_ndomains++;
 		if (vm_ndomains > MAXMEMDOM) {
 			vm_ndomains = 1;
@@ -280,15 +281,15 @@ renumber_domains(void)
 		 * If the domain is already the right value, no need
 		 * to renumber.
 		 */
-		if (domains[i] == i)
+		if (vm_domains[i] == i)
 			continue;
 
 		/* Walk the cpu[] and mem_info[] arrays to renumber. */
 		for (j = 0; j < num_mem; j++)
-			if (mem_info[j].domain == domains[i])
+			if (mem_info[j].domain == vm_domains[i])
 				mem_info[j].domain = i;
 		for (j = 0; j <= MAX_APIC_ID; j++)
-			if (cpus[j].enabled && cpus[j].domain == domains[i])
+			if (cpus[j].enabled && cpus[j].domain == vm_domains[i])
 				cpus[j].domain = i;
 	}
 	KASSERT(vm_ndomains > 0,
@@ -368,4 +369,23 @@ srat_set_cpus(void *dummy)
 	}
 }
 SYSINIT(srat_set_cpus, SI_SUB_CPU, SI_ORDER_ANY, srat_set_cpus, NULL);
+
+/*
+ * Map a _PXM value to a VM domain ID.
+ *
+ * Returns the domain ID, or -1 if no domain ID was found.
+ */
+int
+acpi_map_pxm_to_vm_domainid(int pxm)
+{
+	int i;
+
+	for (i = 0; i < vm_ndomains; i++) {
+		if (vm_domains[i] == pxm)
+			return (i);
+	}
+
+	return (-1);
+}
+
 #endif /* MAXMEMDOM > 1 */


More information about the svn-src-all mailing list