Date: Thu, 12 Mar 2015 07:07:42 +0000 (UTC) From: Scott Long <scottl@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r279904 - in stable/10/sys: dev/acpica dev/pci kern sys x86/acpica Message-ID: <201503120707.t2C77gvq015746@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201503120707.t2C77gvq015746>