mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-02 23:27:06 +00:00
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86: Fix Moorestown VRTC fixmap placement x86/gpio: Implement x86 gpio_to_irq convert function x86, UV: Fix APICID shift for Westmere processors x86: Use PCI method for enabling AMD extended config space before MSR method x86: tsc: Prevent delayed init if initial tsc calibration failed x86, lapic-timer: Increase the max_delta to 31 bits x86: Fix sparse non-ANSI function warnings in smpboot.c x86, numa: Fix CONFIG_DEBUG_PER_CPU_MAPS without NUMA emulation x86, AMD, PCI: Add AMD northbridge PCI device id for CPU families 12h and 14h x86, numa: Fix cpu to node mapping for sparse node ids x86, numa: Fake node-to-cpumask for NUMA emulation x86, numa: Fake apicid and pxm mappings for NUMA emulation x86, numa: Avoid compiling NUMA emulation functions without CONFIG_NUMA_EMU x86, numa: Reduce minimum fake node size to 32M Fix up trivial conflict in arch/x86/kernel/apic/x2apic_uv_x.c
This commit is contained in:
commit
16ee8db6a9
16 changed files with 299 additions and 104 deletions
|
@ -185,17 +185,16 @@ struct bootnode;
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI_NUMA
|
#ifdef CONFIG_ACPI_NUMA
|
||||||
extern int acpi_numa;
|
extern int acpi_numa;
|
||||||
extern int acpi_get_nodes(struct bootnode *physnodes);
|
extern void acpi_get_nodes(struct bootnode *physnodes, unsigned long start,
|
||||||
|
unsigned long end);
|
||||||
extern int acpi_scan_nodes(unsigned long start, unsigned long end);
|
extern int acpi_scan_nodes(unsigned long start, unsigned long end);
|
||||||
#define NR_NODE_MEMBLKS (MAX_NUMNODES*2)
|
#define NR_NODE_MEMBLKS (MAX_NUMNODES*2)
|
||||||
|
|
||||||
|
#ifdef CONFIG_NUMA_EMU
|
||||||
extern void acpi_fake_nodes(const struct bootnode *fake_nodes,
|
extern void acpi_fake_nodes(const struct bootnode *fake_nodes,
|
||||||
int num_nodes);
|
int num_nodes);
|
||||||
#else
|
|
||||||
static inline void acpi_fake_nodes(const struct bootnode *fake_nodes,
|
|
||||||
int num_nodes)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* CONFIG_ACPI_NUMA */
|
||||||
|
|
||||||
#define acpi_unlazy_tlb(x) leave_mm(x)
|
#define acpi_unlazy_tlb(x) leave_mm(x)
|
||||||
|
|
||||||
|
|
|
@ -3,16 +3,27 @@
|
||||||
|
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
|
|
||||||
|
struct amd_nb_bus_dev_range {
|
||||||
|
u8 bus;
|
||||||
|
u8 dev_base;
|
||||||
|
u8 dev_limit;
|
||||||
|
};
|
||||||
|
|
||||||
extern struct pci_device_id amd_nb_misc_ids[];
|
extern struct pci_device_id amd_nb_misc_ids[];
|
||||||
|
extern const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[];
|
||||||
struct bootnode;
|
struct bootnode;
|
||||||
|
|
||||||
extern int early_is_amd_nb(u32 value);
|
extern int early_is_amd_nb(u32 value);
|
||||||
extern int amd_cache_northbridges(void);
|
extern int amd_cache_northbridges(void);
|
||||||
extern void amd_flush_garts(void);
|
extern void amd_flush_garts(void);
|
||||||
extern int amd_get_nodes(struct bootnode *nodes);
|
|
||||||
extern int amd_numa_init(unsigned long start_pfn, unsigned long end_pfn);
|
extern int amd_numa_init(unsigned long start_pfn, unsigned long end_pfn);
|
||||||
extern int amd_scan_nodes(void);
|
extern int amd_scan_nodes(void);
|
||||||
|
|
||||||
|
#ifdef CONFIG_NUMA_EMU
|
||||||
|
extern void amd_fake_nodes(const struct bootnode *nodes, int nr_nodes);
|
||||||
|
extern void amd_get_nodes(struct bootnode *nodes);
|
||||||
|
#endif
|
||||||
|
|
||||||
struct amd_northbridge {
|
struct amd_northbridge {
|
||||||
struct pci_dev *misc;
|
struct pci_dev *misc;
|
||||||
};
|
};
|
||||||
|
|
|
@ -116,11 +116,11 @@ enum fixed_addresses {
|
||||||
#endif
|
#endif
|
||||||
FIX_TEXT_POKE1, /* reserve 2 pages for text_poke() */
|
FIX_TEXT_POKE1, /* reserve 2 pages for text_poke() */
|
||||||
FIX_TEXT_POKE0, /* first page is last, because allocation is backward */
|
FIX_TEXT_POKE0, /* first page is last, because allocation is backward */
|
||||||
__end_of_permanent_fixed_addresses,
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_MRST
|
#ifdef CONFIG_X86_MRST
|
||||||
FIX_LNW_VRTC,
|
FIX_LNW_VRTC,
|
||||||
#endif
|
#endif
|
||||||
|
__end_of_permanent_fixed_addresses,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 256 temporary boot-time mappings, used by early_ioremap(),
|
* 256 temporary boot-time mappings, used by early_ioremap(),
|
||||||
* before ioremap() is functional.
|
* before ioremap() is functional.
|
||||||
|
|
|
@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned int gpio)
|
||||||
return __gpio_cansleep(gpio);
|
return __gpio_cansleep(gpio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Not implemented, yet.
|
|
||||||
*/
|
|
||||||
static inline int gpio_to_irq(unsigned int gpio)
|
static inline int gpio_to_irq(unsigned int gpio)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return __gpio_to_irq(gpio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int irq_to_gpio(unsigned int irq)
|
static inline int irq_to_gpio(unsigned int irq)
|
||||||
|
|
|
@ -38,7 +38,7 @@ extern void __cpuinit numa_add_cpu(int cpu);
|
||||||
extern void __cpuinit numa_remove_cpu(int cpu);
|
extern void __cpuinit numa_remove_cpu(int cpu);
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA_EMU
|
#ifdef CONFIG_NUMA_EMU
|
||||||
#define FAKE_NODE_MIN_SIZE ((u64)64 << 20)
|
#define FAKE_NODE_MIN_SIZE ((u64)32 << 20)
|
||||||
#define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1UL))
|
#define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1UL))
|
||||||
#endif /* CONFIG_NUMA_EMU */
|
#endif /* CONFIG_NUMA_EMU */
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -20,6 +20,13 @@ struct pci_device_id amd_nb_misc_ids[] = {
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL(amd_nb_misc_ids);
|
EXPORT_SYMBOL(amd_nb_misc_ids);
|
||||||
|
|
||||||
|
const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[] __initconst = {
|
||||||
|
{ 0x00, 0x18, 0x20 },
|
||||||
|
{ 0xff, 0x00, 0x20 },
|
||||||
|
{ 0xfe, 0x00, 0x20 },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
struct amd_northbridge_info amd_northbridges;
|
struct amd_northbridge_info amd_northbridges;
|
||||||
EXPORT_SYMBOL(amd_northbridges);
|
EXPORT_SYMBOL(amd_northbridges);
|
||||||
|
|
||||||
|
|
|
@ -39,18 +39,6 @@ int fallback_aper_force __initdata;
|
||||||
|
|
||||||
int fix_aperture __initdata = 1;
|
int fix_aperture __initdata = 1;
|
||||||
|
|
||||||
struct bus_dev_range {
|
|
||||||
int bus;
|
|
||||||
int dev_base;
|
|
||||||
int dev_limit;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct bus_dev_range bus_dev_ranges[] __initdata = {
|
|
||||||
{ 0x00, 0x18, 0x20},
|
|
||||||
{ 0xff, 0x00, 0x20},
|
|
||||||
{ 0xfe, 0x00, 0x20}
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource gart_resource = {
|
static struct resource gart_resource = {
|
||||||
.name = "GART",
|
.name = "GART",
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
|
@ -294,13 +282,13 @@ void __init early_gart_iommu_check(void)
|
||||||
search_agp_bridge(&agp_aper_order, &valid_agp);
|
search_agp_bridge(&agp_aper_order, &valid_agp);
|
||||||
|
|
||||||
fix = 0;
|
fix = 0;
|
||||||
for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
|
for (i = 0; amd_nb_bus_dev_ranges[i].dev_limit; i++) {
|
||||||
int bus;
|
int bus;
|
||||||
int dev_base, dev_limit;
|
int dev_base, dev_limit;
|
||||||
|
|
||||||
bus = bus_dev_ranges[i].bus;
|
bus = amd_nb_bus_dev_ranges[i].bus;
|
||||||
dev_base = bus_dev_ranges[i].dev_base;
|
dev_base = amd_nb_bus_dev_ranges[i].dev_base;
|
||||||
dev_limit = bus_dev_ranges[i].dev_limit;
|
dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;
|
||||||
|
|
||||||
for (slot = dev_base; slot < dev_limit; slot++) {
|
for (slot = dev_base; slot < dev_limit; slot++) {
|
||||||
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
|
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
|
||||||
|
@ -349,13 +337,13 @@ void __init early_gart_iommu_check(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* disable them all at first */
|
/* disable them all at first */
|
||||||
for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
|
for (i = 0; i < amd_nb_bus_dev_ranges[i].dev_limit; i++) {
|
||||||
int bus;
|
int bus;
|
||||||
int dev_base, dev_limit;
|
int dev_base, dev_limit;
|
||||||
|
|
||||||
bus = bus_dev_ranges[i].bus;
|
bus = amd_nb_bus_dev_ranges[i].bus;
|
||||||
dev_base = bus_dev_ranges[i].dev_base;
|
dev_base = amd_nb_bus_dev_ranges[i].dev_base;
|
||||||
dev_limit = bus_dev_ranges[i].dev_limit;
|
dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;
|
||||||
|
|
||||||
for (slot = dev_base; slot < dev_limit; slot++) {
|
for (slot = dev_base; slot < dev_limit; slot++) {
|
||||||
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
|
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
|
||||||
|
@ -390,14 +378,14 @@ int __init gart_iommu_hole_init(void)
|
||||||
|
|
||||||
fix = 0;
|
fix = 0;
|
||||||
node = 0;
|
node = 0;
|
||||||
for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
|
for (i = 0; i < amd_nb_bus_dev_ranges[i].dev_limit; i++) {
|
||||||
int bus;
|
int bus;
|
||||||
int dev_base, dev_limit;
|
int dev_base, dev_limit;
|
||||||
u32 ctl;
|
u32 ctl;
|
||||||
|
|
||||||
bus = bus_dev_ranges[i].bus;
|
bus = amd_nb_bus_dev_ranges[i].bus;
|
||||||
dev_base = bus_dev_ranges[i].dev_base;
|
dev_base = amd_nb_bus_dev_ranges[i].dev_base;
|
||||||
dev_limit = bus_dev_ranges[i].dev_limit;
|
dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;
|
||||||
|
|
||||||
for (slot = dev_base; slot < dev_limit; slot++) {
|
for (slot = dev_base; slot < dev_limit; slot++) {
|
||||||
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
|
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
|
||||||
|
@ -505,7 +493,7 @@ int __init gart_iommu_hole_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix up the north bridges */
|
/* Fix up the north bridges */
|
||||||
for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
|
for (i = 0; i < amd_nb_bus_dev_ranges[i].dev_limit; i++) {
|
||||||
int bus, dev_base, dev_limit;
|
int bus, dev_base, dev_limit;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -514,9 +502,9 @@ int __init gart_iommu_hole_init(void)
|
||||||
*/
|
*/
|
||||||
u32 ctl = DISTLBWALKPRB | aper_order << 1;
|
u32 ctl = DISTLBWALKPRB | aper_order << 1;
|
||||||
|
|
||||||
bus = bus_dev_ranges[i].bus;
|
bus = amd_nb_bus_dev_ranges[i].bus;
|
||||||
dev_base = bus_dev_ranges[i].dev_base;
|
dev_base = amd_nb_bus_dev_ranges[i].dev_base;
|
||||||
dev_limit = bus_dev_ranges[i].dev_limit;
|
dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;
|
||||||
for (slot = dev_base; slot < dev_limit; slot++) {
|
for (slot = dev_base; slot < dev_limit; slot++) {
|
||||||
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
|
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -684,7 +684,7 @@ static int __init calibrate_APIC_clock(void)
|
||||||
lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS,
|
lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS,
|
||||||
lapic_clockevent.shift);
|
lapic_clockevent.shift);
|
||||||
lapic_clockevent.max_delta_ns =
|
lapic_clockevent.max_delta_ns =
|
||||||
clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
|
clockevent_delta2ns(0x7FFFFFFF, &lapic_clockevent);
|
||||||
lapic_clockevent.min_delta_ns =
|
lapic_clockevent.min_delta_ns =
|
||||||
clockevent_delta2ns(0xF, &lapic_clockevent);
|
clockevent_delta2ns(0xF, &lapic_clockevent);
|
||||||
|
|
||||||
|
|
|
@ -378,7 +378,7 @@ struct apic __refdata apic_x2apic_uv_x = {
|
||||||
|
|
||||||
static __cpuinit void set_x2apic_extra_bits(int pnode)
|
static __cpuinit void set_x2apic_extra_bits(int pnode)
|
||||||
{
|
{
|
||||||
__this_cpu_write(x2apic_extra_bits, (pnode << 6));
|
__this_cpu_write(x2apic_extra_bits, pnode << uvh_apicid.s.pnode_shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -97,12 +97,12 @@ static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
|
||||||
*/
|
*/
|
||||||
static DEFINE_MUTEX(x86_cpu_hotplug_driver_mutex);
|
static DEFINE_MUTEX(x86_cpu_hotplug_driver_mutex);
|
||||||
|
|
||||||
void cpu_hotplug_driver_lock()
|
void cpu_hotplug_driver_lock(void)
|
||||||
{
|
{
|
||||||
mutex_lock(&x86_cpu_hotplug_driver_mutex);
|
mutex_lock(&x86_cpu_hotplug_driver_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_hotplug_driver_unlock()
|
void cpu_hotplug_driver_unlock(void)
|
||||||
{
|
{
|
||||||
mutex_unlock(&x86_cpu_hotplug_driver_mutex);
|
mutex_unlock(&x86_cpu_hotplug_driver_mutex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -965,7 +965,7 @@ static void tsc_refine_calibration_work(struct work_struct *work)
|
||||||
|
|
||||||
static int __init init_tsc_clocksource(void)
|
static int __init init_tsc_clocksource(void)
|
||||||
{
|
{
|
||||||
if (!cpu_has_tsc || tsc_disabled > 0)
|
if (!cpu_has_tsc || tsc_disabled > 0 || !tsc_khz)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (tsc_clocksource_reliable)
|
if (tsc_clocksource_reliable)
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <asm/amd_nb.h>
|
#include <asm/amd_nb.h>
|
||||||
|
|
||||||
static struct bootnode __initdata nodes[8];
|
static struct bootnode __initdata nodes[8];
|
||||||
|
static unsigned char __initdata nodeids[8];
|
||||||
static nodemask_t __initdata nodes_parsed = NODE_MASK_NONE;
|
static nodemask_t __initdata nodes_parsed = NODE_MASK_NONE;
|
||||||
|
|
||||||
static __init int find_northbridge(void)
|
static __init int find_northbridge(void)
|
||||||
|
@ -68,19 +69,6 @@ static __init void early_get_boot_cpu_id(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int __init amd_get_nodes(struct bootnode *physnodes)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
for_each_node_mask(i, nodes_parsed) {
|
|
||||||
physnodes[ret].start = nodes[i].start;
|
|
||||||
physnodes[ret].end = nodes[i].end;
|
|
||||||
ret++;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn)
|
int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn)
|
||||||
{
|
{
|
||||||
unsigned long start = PFN_PHYS(start_pfn);
|
unsigned long start = PFN_PHYS(start_pfn);
|
||||||
|
@ -113,7 +101,7 @@ int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn)
|
||||||
base = read_pci_config(0, nb, 1, 0x40 + i*8);
|
base = read_pci_config(0, nb, 1, 0x40 + i*8);
|
||||||
limit = read_pci_config(0, nb, 1, 0x44 + i*8);
|
limit = read_pci_config(0, nb, 1, 0x44 + i*8);
|
||||||
|
|
||||||
nodeid = limit & 7;
|
nodeids[i] = nodeid = limit & 7;
|
||||||
if ((base & 3) == 0) {
|
if ((base & 3) == 0) {
|
||||||
if (i < numnodes)
|
if (i < numnodes)
|
||||||
pr_info("Skipping disabled node %d\n", i);
|
pr_info("Skipping disabled node %d\n", i);
|
||||||
|
@ -193,6 +181,76 @@ int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_NUMA_EMU
|
||||||
|
static s16 fake_apicid_to_node[MAX_LOCAL_APIC] __initdata = {
|
||||||
|
[0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init amd_get_nodes(struct bootnode *physnodes)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for_each_node_mask(i, nodes_parsed) {
|
||||||
|
physnodes[i].start = nodes[i].start;
|
||||||
|
physnodes[i].end = nodes[i].end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init find_node_by_addr(unsigned long addr)
|
||||||
|
{
|
||||||
|
int ret = NUMA_NO_NODE;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
if (addr >= nodes[i].start && addr < nodes[i].end) {
|
||||||
|
ret = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For NUMA emulation, fake proximity domain (_PXM) to node id mappings must be
|
||||||
|
* setup to represent the physical topology but reflect the emulated
|
||||||
|
* environment. For each emulated node, the real node which it appears on is
|
||||||
|
* found and a fake pxm to nid mapping is created which mirrors the actual
|
||||||
|
* locality. node_distance() then represents the correct distances between
|
||||||
|
* emulated nodes by using the fake acpi mappings to pxms.
|
||||||
|
*/
|
||||||
|
void __init amd_fake_nodes(const struct bootnode *nodes, int nr_nodes)
|
||||||
|
{
|
||||||
|
unsigned int bits;
|
||||||
|
unsigned int cores;
|
||||||
|
unsigned int apicid_base = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
bits = boot_cpu_data.x86_coreid_bits;
|
||||||
|
cores = 1 << bits;
|
||||||
|
early_get_boot_cpu_id();
|
||||||
|
if (boot_cpu_physical_apicid > 0)
|
||||||
|
apicid_base = boot_cpu_physical_apicid;
|
||||||
|
|
||||||
|
for (i = 0; i < nr_nodes; i++) {
|
||||||
|
int index;
|
||||||
|
int nid;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
nid = find_node_by_addr(nodes[i].start);
|
||||||
|
if (nid == NUMA_NO_NODE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
index = nodeids[nid] << bits;
|
||||||
|
if (fake_apicid_to_node[index + apicid_base] == NUMA_NO_NODE)
|
||||||
|
for (j = apicid_base; j < cores + apicid_base; j++)
|
||||||
|
fake_apicid_to_node[index + j] = i;
|
||||||
|
#ifdef CONFIG_ACPI_NUMA
|
||||||
|
__acpi_map_pxm_to_node(nid, i);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
memcpy(apicid_to_node, fake_apicid_to_node, sizeof(apicid_to_node));
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NUMA_EMU */
|
||||||
|
|
||||||
int __init amd_scan_nodes(void)
|
int __init amd_scan_nodes(void)
|
||||||
{
|
{
|
||||||
unsigned int bits;
|
unsigned int bits;
|
||||||
|
|
|
@ -260,30 +260,30 @@ void __init numa_init_array(void)
|
||||||
#ifdef CONFIG_NUMA_EMU
|
#ifdef CONFIG_NUMA_EMU
|
||||||
/* Numa emulation */
|
/* Numa emulation */
|
||||||
static struct bootnode nodes[MAX_NUMNODES] __initdata;
|
static struct bootnode nodes[MAX_NUMNODES] __initdata;
|
||||||
static struct bootnode physnodes[MAX_NUMNODES] __initdata;
|
static struct bootnode physnodes[MAX_NUMNODES] __cpuinitdata;
|
||||||
static char *cmdline __initdata;
|
static char *cmdline __initdata;
|
||||||
|
|
||||||
static int __init setup_physnodes(unsigned long start, unsigned long end,
|
static int __init setup_physnodes(unsigned long start, unsigned long end,
|
||||||
int acpi, int amd)
|
int acpi, int amd)
|
||||||
{
|
{
|
||||||
int nr_nodes = 0;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
memset(physnodes, 0, sizeof(physnodes));
|
||||||
#ifdef CONFIG_ACPI_NUMA
|
#ifdef CONFIG_ACPI_NUMA
|
||||||
if (acpi)
|
if (acpi)
|
||||||
nr_nodes = acpi_get_nodes(physnodes);
|
acpi_get_nodes(physnodes, start, end);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_AMD_NUMA
|
#ifdef CONFIG_AMD_NUMA
|
||||||
if (amd)
|
if (amd)
|
||||||
nr_nodes = amd_get_nodes(physnodes);
|
amd_get_nodes(physnodes);
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* Basic sanity checking on the physical node map: there may be errors
|
* Basic sanity checking on the physical node map: there may be errors
|
||||||
* if the SRAT or AMD code incorrectly reported the topology or the mem=
|
* if the SRAT or AMD code incorrectly reported the topology or the mem=
|
||||||
* kernel parameter is used.
|
* kernel parameter is used.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < nr_nodes; i++) {
|
for (i = 0; i < MAX_NUMNODES; i++) {
|
||||||
if (physnodes[i].start == physnodes[i].end)
|
if (physnodes[i].start == physnodes[i].end)
|
||||||
continue;
|
continue;
|
||||||
if (physnodes[i].start > end) {
|
if (physnodes[i].start > end) {
|
||||||
|
@ -298,17 +298,6 @@ static int __init setup_physnodes(unsigned long start, unsigned long end,
|
||||||
physnodes[i].start = start;
|
physnodes[i].start = start;
|
||||||
if (physnodes[i].end > end)
|
if (physnodes[i].end > end)
|
||||||
physnodes[i].end = end;
|
physnodes[i].end = end;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Remove all nodes that have no memory or were truncated because of the
|
|
||||||
* limited address range.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < nr_nodes; i++) {
|
|
||||||
if (physnodes[i].start == physnodes[i].end)
|
|
||||||
continue;
|
|
||||||
physnodes[ret].start = physnodes[i].start;
|
|
||||||
physnodes[ret].end = physnodes[i].end;
|
|
||||||
ret++;
|
ret++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,6 +313,24 @@ static int __init setup_physnodes(unsigned long start, unsigned long end,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __init fake_physnodes(int acpi, int amd, int nr_nodes)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
BUG_ON(acpi && amd);
|
||||||
|
#ifdef CONFIG_ACPI_NUMA
|
||||||
|
if (acpi)
|
||||||
|
acpi_fake_nodes(nodes, nr_nodes);
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_AMD_NUMA
|
||||||
|
if (amd)
|
||||||
|
amd_fake_nodes(nodes, nr_nodes);
|
||||||
|
#endif
|
||||||
|
if (!acpi && !amd)
|
||||||
|
for (i = 0; i < nr_cpu_ids; i++)
|
||||||
|
numa_set_node(i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setups up nid to range from addr to addr + size. If the end
|
* Setups up nid to range from addr to addr + size. If the end
|
||||||
* boundary is greater than max_addr, then max_addr is used instead.
|
* boundary is greater than max_addr, then max_addr is used instead.
|
||||||
|
@ -352,8 +359,7 @@ static int __init setup_node_range(int nid, u64 *addr, u64 size, u64 max_addr)
|
||||||
* Sets up nr_nodes fake nodes interleaved over physical nodes ranging from addr
|
* Sets up nr_nodes fake nodes interleaved over physical nodes ranging from addr
|
||||||
* to max_addr. The return value is the number of nodes allocated.
|
* to max_addr. The return value is the number of nodes allocated.
|
||||||
*/
|
*/
|
||||||
static int __init split_nodes_interleave(u64 addr, u64 max_addr,
|
static int __init split_nodes_interleave(u64 addr, u64 max_addr, int nr_nodes)
|
||||||
int nr_phys_nodes, int nr_nodes)
|
|
||||||
{
|
{
|
||||||
nodemask_t physnode_mask = NODE_MASK_NONE;
|
nodemask_t physnode_mask = NODE_MASK_NONE;
|
||||||
u64 size;
|
u64 size;
|
||||||
|
@ -384,7 +390,7 @@ static int __init split_nodes_interleave(u64 addr, u64 max_addr,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < nr_phys_nodes; i++)
|
for (i = 0; i < MAX_NUMNODES; i++)
|
||||||
if (physnodes[i].start != physnodes[i].end)
|
if (physnodes[i].start != physnodes[i].end)
|
||||||
node_set(i, physnode_mask);
|
node_set(i, physnode_mask);
|
||||||
|
|
||||||
|
@ -553,11 +559,9 @@ static int __init numa_emulation(unsigned long start_pfn,
|
||||||
{
|
{
|
||||||
u64 addr = start_pfn << PAGE_SHIFT;
|
u64 addr = start_pfn << PAGE_SHIFT;
|
||||||
u64 max_addr = last_pfn << PAGE_SHIFT;
|
u64 max_addr = last_pfn << PAGE_SHIFT;
|
||||||
int num_phys_nodes;
|
|
||||||
int num_nodes;
|
int num_nodes;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
num_phys_nodes = setup_physnodes(addr, max_addr, acpi, amd);
|
|
||||||
/*
|
/*
|
||||||
* If the numa=fake command-line contains a 'M' or 'G', it represents
|
* If the numa=fake command-line contains a 'M' or 'G', it represents
|
||||||
* the fixed node size. Otherwise, if it is just a single number N,
|
* the fixed node size. Otherwise, if it is just a single number N,
|
||||||
|
@ -572,7 +576,7 @@ static int __init numa_emulation(unsigned long start_pfn,
|
||||||
unsigned long n;
|
unsigned long n;
|
||||||
|
|
||||||
n = simple_strtoul(cmdline, NULL, 0);
|
n = simple_strtoul(cmdline, NULL, 0);
|
||||||
num_nodes = split_nodes_interleave(addr, max_addr, num_phys_nodes, n);
|
num_nodes = split_nodes_interleave(addr, max_addr, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_nodes < 0)
|
if (num_nodes < 0)
|
||||||
|
@ -595,7 +599,8 @@ static int __init numa_emulation(unsigned long start_pfn,
|
||||||
nodes[i].end >> PAGE_SHIFT);
|
nodes[i].end >> PAGE_SHIFT);
|
||||||
setup_node_bootmem(i, nodes[i].start, nodes[i].end);
|
setup_node_bootmem(i, nodes[i].start, nodes[i].end);
|
||||||
}
|
}
|
||||||
acpi_fake_nodes(nodes, num_nodes);
|
setup_physnodes(addr, max_addr, acpi, amd);
|
||||||
|
fake_physnodes(acpi, amd, num_nodes);
|
||||||
numa_init_array();
|
numa_init_array();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -610,8 +615,12 @@ void __init initmem_init(unsigned long start_pfn, unsigned long last_pfn,
|
||||||
nodes_clear(node_online_map);
|
nodes_clear(node_online_map);
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA_EMU
|
#ifdef CONFIG_NUMA_EMU
|
||||||
|
setup_physnodes(start_pfn << PAGE_SHIFT, last_pfn << PAGE_SHIFT,
|
||||||
|
acpi, amd);
|
||||||
if (cmdline && !numa_emulation(start_pfn, last_pfn, acpi, amd))
|
if (cmdline && !numa_emulation(start_pfn, last_pfn, acpi, amd))
|
||||||
return;
|
return;
|
||||||
|
setup_physnodes(start_pfn << PAGE_SHIFT, last_pfn << PAGE_SHIFT,
|
||||||
|
acpi, amd);
|
||||||
nodes_clear(node_possible_map);
|
nodes_clear(node_possible_map);
|
||||||
nodes_clear(node_online_map);
|
nodes_clear(node_online_map);
|
||||||
#endif
|
#endif
|
||||||
|
@ -767,6 +776,7 @@ void __cpuinit numa_clear_node(int cpu)
|
||||||
|
|
||||||
#ifndef CONFIG_DEBUG_PER_CPU_MAPS
|
#ifndef CONFIG_DEBUG_PER_CPU_MAPS
|
||||||
|
|
||||||
|
#ifndef CONFIG_NUMA_EMU
|
||||||
void __cpuinit numa_add_cpu(int cpu)
|
void __cpuinit numa_add_cpu(int cpu)
|
||||||
{
|
{
|
||||||
cpumask_set_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
|
cpumask_set_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
|
||||||
|
@ -776,34 +786,115 @@ void __cpuinit numa_remove_cpu(int cpu)
|
||||||
{
|
{
|
||||||
cpumask_clear_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
|
cpumask_clear_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void __cpuinit numa_add_cpu(int cpu)
|
||||||
|
{
|
||||||
|
unsigned long addr;
|
||||||
|
u16 apicid;
|
||||||
|
int physnid;
|
||||||
|
int nid = NUMA_NO_NODE;
|
||||||
|
|
||||||
|
apicid = early_per_cpu(x86_cpu_to_apicid, cpu);
|
||||||
|
if (apicid != BAD_APICID)
|
||||||
|
nid = apicid_to_node[apicid];
|
||||||
|
if (nid == NUMA_NO_NODE)
|
||||||
|
nid = early_cpu_to_node(cpu);
|
||||||
|
BUG_ON(nid == NUMA_NO_NODE || !node_online(nid));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use the starting address of the emulated node to find which physical
|
||||||
|
* node it is allocated on.
|
||||||
|
*/
|
||||||
|
addr = node_start_pfn(nid) << PAGE_SHIFT;
|
||||||
|
for (physnid = 0; physnid < MAX_NUMNODES; physnid++)
|
||||||
|
if (addr >= physnodes[physnid].start &&
|
||||||
|
addr < physnodes[physnid].end)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map the cpu to each emulated node that is allocated on the physical
|
||||||
|
* node of the cpu's apic id.
|
||||||
|
*/
|
||||||
|
for_each_online_node(nid) {
|
||||||
|
addr = node_start_pfn(nid) << PAGE_SHIFT;
|
||||||
|
if (addr >= physnodes[physnid].start &&
|
||||||
|
addr < physnodes[physnid].end)
|
||||||
|
cpumask_set_cpu(cpu, node_to_cpumask_map[nid]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cpuinit numa_remove_cpu(int cpu)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for_each_online_node(i)
|
||||||
|
cpumask_clear_cpu(cpu, node_to_cpumask_map[i]);
|
||||||
|
}
|
||||||
|
#endif /* !CONFIG_NUMA_EMU */
|
||||||
|
|
||||||
#else /* CONFIG_DEBUG_PER_CPU_MAPS */
|
#else /* CONFIG_DEBUG_PER_CPU_MAPS */
|
||||||
|
static struct cpumask __cpuinit *debug_cpumask_set_cpu(int cpu, int enable)
|
||||||
/*
|
|
||||||
* --------- debug versions of the numa functions ---------
|
|
||||||
*/
|
|
||||||
static void __cpuinit numa_set_cpumask(int cpu, int enable)
|
|
||||||
{
|
{
|
||||||
int node = early_cpu_to_node(cpu);
|
int node = early_cpu_to_node(cpu);
|
||||||
struct cpumask *mask;
|
struct cpumask *mask;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
mask = node_to_cpumask_map[node];
|
mask = node_to_cpumask_map[node];
|
||||||
if (mask == NULL) {
|
if (!mask) {
|
||||||
printk(KERN_ERR "node_to_cpumask_map[%i] NULL\n", node);
|
pr_err("node_to_cpumask_map[%i] NULL\n", node);
|
||||||
dump_stack();
|
dump_stack();
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cpulist_scnprintf(buf, sizeof(buf), mask);
|
||||||
|
printk(KERN_DEBUG "%s cpu %d node %d: mask now %s\n",
|
||||||
|
enable ? "numa_add_cpu" : "numa_remove_cpu",
|
||||||
|
cpu, node, buf);
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --------- debug versions of the numa functions ---------
|
||||||
|
*/
|
||||||
|
#ifndef CONFIG_NUMA_EMU
|
||||||
|
static void __cpuinit numa_set_cpumask(int cpu, int enable)
|
||||||
|
{
|
||||||
|
struct cpumask *mask;
|
||||||
|
|
||||||
|
mask = debug_cpumask_set_cpu(cpu, enable);
|
||||||
|
if (!mask)
|
||||||
|
return;
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
cpumask_set_cpu(cpu, mask);
|
cpumask_set_cpu(cpu, mask);
|
||||||
else
|
else
|
||||||
cpumask_clear_cpu(cpu, mask);
|
cpumask_clear_cpu(cpu, mask);
|
||||||
|
|
||||||
cpulist_scnprintf(buf, sizeof(buf), mask);
|
|
||||||
printk(KERN_DEBUG "%s cpu %d node %d: mask now %s\n",
|
|
||||||
enable ? "numa_add_cpu" : "numa_remove_cpu", cpu, node, buf);
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static void __cpuinit numa_set_cpumask(int cpu, int enable)
|
||||||
|
{
|
||||||
|
int node = early_cpu_to_node(cpu);
|
||||||
|
struct cpumask *mask;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for_each_online_node(i) {
|
||||||
|
unsigned long addr;
|
||||||
|
|
||||||
|
addr = node_start_pfn(i) << PAGE_SHIFT;
|
||||||
|
if (addr < physnodes[node].start ||
|
||||||
|
addr >= physnodes[node].end)
|
||||||
|
continue;
|
||||||
|
mask = debug_cpumask_set_cpu(cpu, enable);
|
||||||
|
if (!mask)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
cpumask_set_cpu(cpu, mask);
|
||||||
|
else
|
||||||
|
cpumask_clear_cpu(cpu, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NUMA_EMU */
|
||||||
|
|
||||||
void __cpuinit numa_add_cpu(int cpu)
|
void __cpuinit numa_add_cpu(int cpu)
|
||||||
{
|
{
|
||||||
|
|
|
@ -349,18 +349,19 @@ static int __init nodes_cover_memory(const struct bootnode *nodes)
|
||||||
|
|
||||||
void __init acpi_numa_arch_fixup(void) {}
|
void __init acpi_numa_arch_fixup(void) {}
|
||||||
|
|
||||||
int __init acpi_get_nodes(struct bootnode *physnodes)
|
#ifdef CONFIG_NUMA_EMU
|
||||||
|
void __init acpi_get_nodes(struct bootnode *physnodes, unsigned long start,
|
||||||
|
unsigned long end)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
for_each_node_mask(i, nodes_parsed) {
|
for_each_node_mask(i, nodes_parsed) {
|
||||||
physnodes[ret].start = nodes[i].start;
|
cutoff_node(i, start, end);
|
||||||
physnodes[ret].end = nodes[i].end;
|
physnodes[i].start = nodes[i].start;
|
||||||
ret++;
|
physnodes[i].end = nodes[i].end;
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_NUMA_EMU */
|
||||||
|
|
||||||
/* Use the information discovered above to actually set up the nodes. */
|
/* Use the information discovered above to actually set up the nodes. */
|
||||||
int __init acpi_scan_nodes(unsigned long start, unsigned long end)
|
int __init acpi_scan_nodes(unsigned long start, unsigned long end)
|
||||||
|
@ -505,8 +506,6 @@ void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
printk(KERN_INFO "Faking PXM affinity for fake nodes on real "
|
|
||||||
"topology.\n");
|
|
||||||
for (i = 0; i < num_nodes; i++) {
|
for (i = 0; i < num_nodes; i++) {
|
||||||
int nid, pxm;
|
int nid, pxm;
|
||||||
|
|
||||||
|
@ -526,6 +525,17 @@ void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes)
|
||||||
fake_apicid_to_node[j] == NUMA_NO_NODE)
|
fake_apicid_to_node[j] == NUMA_NO_NODE)
|
||||||
fake_apicid_to_node[j] = i;
|
fake_apicid_to_node[j] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there are apicid-to-node mappings for physical nodes that do not
|
||||||
|
* have a corresponding emulated node, it should default to a guaranteed
|
||||||
|
* value.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < MAX_LOCAL_APIC; i++)
|
||||||
|
if (apicid_to_node[i] != NUMA_NO_NODE &&
|
||||||
|
fake_apicid_to_node[i] == NUMA_NO_NODE)
|
||||||
|
fake_apicid_to_node[i] = 0;
|
||||||
|
|
||||||
for (i = 0; i < num_nodes; i++)
|
for (i = 0; i < num_nodes; i++)
|
||||||
__acpi_map_pxm_to_node(fake_node_to_pxm_map[i], i);
|
__acpi_map_pxm_to_node(fake_node_to_pxm_map[i], i);
|
||||||
memcpy(apicid_to_node, fake_apicid_to_node, sizeof(apicid_to_node));
|
memcpy(apicid_to_node, fake_apicid_to_node, sizeof(apicid_to_node));
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <linux/cpu.h>
|
#include <linux/cpu.h>
|
||||||
#include <linux/range.h>
|
#include <linux/range.h>
|
||||||
|
|
||||||
|
#include <asm/amd_nb.h>
|
||||||
#include <asm/pci_x86.h>
|
#include <asm/pci_x86.h>
|
||||||
|
|
||||||
#include <asm/pci-direct.h>
|
#include <asm/pci-direct.h>
|
||||||
|
@ -378,6 +379,34 @@ static struct notifier_block __cpuinitdata amd_cpu_notifier = {
|
||||||
.notifier_call = amd_cpu_notify,
|
.notifier_call = amd_cpu_notify,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void __init pci_enable_pci_io_ecs(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_AMD_NB
|
||||||
|
unsigned int i, n;
|
||||||
|
|
||||||
|
for (n = i = 0; !n && amd_nb_bus_dev_ranges[i].dev_limit; ++i) {
|
||||||
|
u8 bus = amd_nb_bus_dev_ranges[i].bus;
|
||||||
|
u8 slot = amd_nb_bus_dev_ranges[i].dev_base;
|
||||||
|
u8 limit = amd_nb_bus_dev_ranges[i].dev_limit;
|
||||||
|
|
||||||
|
for (; slot < limit; ++slot) {
|
||||||
|
u32 val = read_pci_config(bus, slot, 3, 0);
|
||||||
|
|
||||||
|
if (!early_is_amd_nb(val))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
val = read_pci_config(bus, slot, 3, 0x8c);
|
||||||
|
if (!(val & (ENABLE_CF8_EXT_CFG >> 32))) {
|
||||||
|
val |= ENABLE_CF8_EXT_CFG >> 32;
|
||||||
|
write_pci_config(bus, slot, 3, 0x8c, val);
|
||||||
|
}
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pr_info("Extended Config Space enabled on %u nodes\n", n);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static int __init pci_io_ecs_init(void)
|
static int __init pci_io_ecs_init(void)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
|
@ -386,6 +415,10 @@ static int __init pci_io_ecs_init(void)
|
||||||
if (boot_cpu_data.x86 < 0x10)
|
if (boot_cpu_data.x86 < 0x10)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* Try the PCI method first. */
|
||||||
|
if (early_pci_allowed())
|
||||||
|
pci_enable_pci_io_ecs();
|
||||||
|
|
||||||
register_cpu_notifier(&amd_cpu_notifier);
|
register_cpu_notifier(&amd_cpu_notifier);
|
||||||
for_each_online_cpu(cpu)
|
for_each_online_cpu(cpu)
|
||||||
amd_cpu_notify(&amd_cpu_notifier, (unsigned long)CPU_ONLINE,
|
amd_cpu_notify(&amd_cpu_notifier, (unsigned long)CPU_ONLINE,
|
||||||
|
|
|
@ -518,6 +518,7 @@
|
||||||
#define PCI_DEVICE_ID_AMD_11H_NB_MISC 0x1303
|
#define PCI_DEVICE_ID_AMD_11H_NB_MISC 0x1303
|
||||||
#define PCI_DEVICE_ID_AMD_11H_NB_LINK 0x1304
|
#define PCI_DEVICE_ID_AMD_11H_NB_LINK 0x1304
|
||||||
#define PCI_DEVICE_ID_AMD_15H_NB_MISC 0x1603
|
#define PCI_DEVICE_ID_AMD_15H_NB_MISC 0x1603
|
||||||
|
#define PCI_DEVICE_ID_AMD_CNB17H_F3 0x1703
|
||||||
#define PCI_DEVICE_ID_AMD_LANCE 0x2000
|
#define PCI_DEVICE_ID_AMD_LANCE 0x2000
|
||||||
#define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001
|
#define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001
|
||||||
#define PCI_DEVICE_ID_AMD_SCSI 0x2020
|
#define PCI_DEVICE_ID_AMD_SCSI 0x2020
|
||||||
|
|
Loading…
Reference in a new issue