Index: linux/arch/x86_64/mm/srat.c =================================================================== --- linux.orig/arch/x86_64/mm/srat.c +++ linux/arch/x86_64/mm/srat.c @@ -25,6 +25,15 @@ static nodemask_t nodes_found __initdata static struct node nodes[MAX_NUMNODES] __initdata; static __u8 pxm2node[256] = { [0 ... 255] = 0xff }; +int pci_pxm_available; + +int pxm_to_node(int pxm) +{ + if ((unsigned)pxm >= 256) + return 0; + return pxm2node[pxm]; +} + static __init int setup_node(int pxm) { unsigned node = pxm2node[pxm]; Index: linux/arch/i386/kernel/srat.c =================================================================== --- linux.orig/arch/i386/kernel/srat.c +++ linux/arch/i386/kernel/srat.c @@ -61,6 +61,8 @@ static unsigned long zholes_size[MAX_NUM extern void * boot_ioremap(unsigned long, unsigned long); +int pci_pxm_available; + /* Identify CPU proximity domains */ static void __init parse_cpu_affinity_structure(char *p) { @@ -213,12 +215,18 @@ static __init void node_read_chunk(int n node_end_pfn[nid] = memory_chunk->end_pfn; } +static u8 pxm_to_nid_map[MAX_PXM_DOMAINS];/* _PXM to logical node ID map */ + +int pxm_to_node(int pxm) +{ + return pxm_to_nid_map[pxm]; +} + /* Parse the ACPI Static Resource Affinity Table */ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) { u8 *start, *end, *p; int i, j, nid; - u8 pxm_to_nid_map[MAX_PXM_DOMAINS];/* _PXM to logical node ID map */ u8 nid_to_pxm_map[MAX_NUMNODES];/* logical node ID to _PXM map */ start = (u8 *)(&(sratp->reserved) + 1); /* skip header */ Index: linux/include/asm-i386/numa.h =================================================================== --- /dev/null +++ linux/include/asm-i386/numa.h @@ -0,0 +1,13 @@ +#ifndef _ASM_I386_NUMA_H +#define _ASM_I386_NUMA_H 1 + +#include + +int pxm_to_node(int pxm); + +#ifdef CONFIG_ACPI_SRAT +extern int pci_pxm_available; +#else +#define pci_pxm_available 0 +#endif +#endif Index: linux/include/asm-x86_64/numa.h =================================================================== --- linux.orig/include/asm-x86_64/numa.h +++ linux/include/asm-x86_64/numa.h @@ -1,6 +1,7 @@ #ifndef _ASM_X8664_NUMA_H #define _ASM_X8664_NUMA_H 1 +#include #include #include @@ -9,6 +10,7 @@ struct node { }; extern int compute_hash_shift(struct node *nodes, int numnodes); +extern int pxm_to_node(int nid); #define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT)) @@ -16,6 +18,12 @@ extern void numa_add_cpu(int cpu); extern void numa_init_array(void); extern int numa_off; +#ifdef CONFIG_ACPI_NUMA +extern int pci_pxm_available; +#else +#define pci_pxm_available 0 +#endif + #define NUMA_NO_NODE 0xff #endif Index: linux/arch/i386/pci/acpi.c =================================================================== --- linux.orig/arch/i386/pci/acpi.c +++ linux/arch/i386/pci/acpi.c @@ -3,16 +3,32 @@ #include #include #include +#include #include "pci.h" struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum) { + struct pci_bus *bus; + if (domain != 0) { printk(KERN_WARNING "PCI: Multiple domains not supported\n"); return NULL; } - return pcibios_scan_root(busnum); + bus = pcibios_scan_root(busnum); +#ifdef CONFIG_NUMA + if (bus != NULL) { + int pxm = acpi_get_pxm(device->handle); + if (pxm >= 0) { + pci_pxm_available = 1; + bus->sysdata = (void *)(unsigned long)pxm_to_node(pxm); + printk("bus %d -> pxm %d -> node %ld\n", + busnum, pxm, (long)(bus->sysdata)); + } + } +#endif + + return bus; } extern int pci_routeirq; Index: linux/include/asm-i386/topology.h =================================================================== --- linux.orig/include/asm-i386/topology.h +++ linux/include/asm-i386/topology.h @@ -60,7 +60,7 @@ static inline int node_to_first_cpu(int return first_cpu(mask); } -#define pcibus_to_node(bus) mp_bus_id_to_node[(bus)->number] +#define pcibus_to_node(bus) ((long) (bus)->sysdata) #define pcibus_to_cpumask(bus) node_to_cpumask(pcibus_to_node(bus)) /* sched_domains SD_NODE_INIT for NUMAQ machines */ Index: linux/include/asm-x86_64/topology.h =================================================================== --- linux.orig/include/asm-x86_64/topology.h +++ linux/include/asm-x86_64/topology.h @@ -26,7 +26,7 @@ extern int __node_distance(int, int); #define parent_node(node) (node) #define node_to_first_cpu(node) (__ffs(node_to_cpumask[node])) #define node_to_cpumask(node) (node_to_cpumask[node]) -#define pcibus_to_node(bus) pci_bus_to_node[(bus)->number] +#define pcibus_to_node(bus) ((long)(bus->sysdata)) #define pcibus_to_cpumask(bus) node_to_cpumask(pcibus_to_node(bus)); /* sched_domains SD_NODE_INIT for x86_64 machines */