Skip to content

Commit

Permalink
x86: make generic arch support NUMAQ
Browse files Browse the repository at this point in the history
... so it could fall back to normal numa and we'd reduce the impact of the
NUMAQ subarch.

NUMAQ depends on GENERICARCH
also decouple genericarch numa from acpi.
also make it fall back to bigsmp if apicid > 8.

Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Yinghai Lu authored and Ingo Molnar committed Jun 10, 2008
1 parent e0da336 commit d49c428
Show file tree
Hide file tree
Showing 24 changed files with 219 additions and 216 deletions.
74 changes: 36 additions & 38 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -268,36 +268,6 @@ config X86_VOYAGER
If you do not specifically know you have a Voyager based machine,
say N here, otherwise the kernel you build will not be bootable.

config X86_NUMAQ
bool "NUMAQ (IBM/Sequent)"
depends on SMP && X86_32
select NUMA
help
This option is used for getting Linux to run on a (IBM/Sequent) NUMA
multiquad box. This changes the way that processors are bootstrapped,
and uses Clustered Logical APIC addressing mode instead of Flat Logical.
You will need a new lynxer.elf file to flash your firmware with - send
email to <Martin.Bligh@us.ibm.com>.

config X86_SUMMIT
bool "Summit/EXA (IBM x440)"
depends on X86_32 && SMP
help
This option is needed for IBM systems that use the Summit/EXA chipset.
In particular, it is needed for the x440.

If you don't have one of these computers, you should say N here.
If you want to build a NUMA kernel, you must select ACPI.

config X86_BIGSMP
bool "Support for other sub-arch SMP systems with more than 8 CPUs"
depends on X86_32 && SMP
help
This option is needed for the systems that have more than 8 CPUs
and if the system is not of any sub-arch type above.

If you don't have such a system, you should say N here.

config X86_VISWS
bool "SGI 320/540 (Visual Workstation)"
depends on X86_32
Expand All @@ -311,21 +281,49 @@ config X86_VISWS
and vice versa. See <file:Documentation/sgi-visws.txt> for details.

config X86_GENERICARCH
bool "Generic architecture (Summit, bigsmp, ES7000, default)"
bool "Generic architecture"
depends on X86_32
help
This option compiles in the Summit, bigsmp, ES7000, default subarchitectures.
It is intended for a generic binary kernel.
If you want a NUMA kernel, select ACPI. We need SRAT for NUMA.
This option compiles in the NUMAQ, Summit, bigsmp, ES7000, default
subarchitectures. It is intended for a generic binary kernel.
if you select them all, kernel will probe it one by one. and will
fallback to default.

if X86_GENERICARCH

config X86_NUMAQ
bool "NUMAQ (IBM/Sequent)"
depends on SMP && X86_32
select NUMA
help
This option is used for getting Linux to run on a NUMAQ (IBM/Sequent)
NUMA multiquad box. This changes the way that processors are
bootstrapped, and uses Clustered Logical APIC addressing mode instead
of Flat Logical. You will need a new lynxer.elf file to flash your
firmware with - send email to <Martin.Bligh@us.ibm.com>.

config X86_SUMMIT
bool "Summit/EXA (IBM x440)"
depends on X86_32 && SMP
help
This option is needed for IBM systems that use the Summit/EXA chipset.
In particular, it is needed for the x440.

config X86_ES7000
bool "Support for Unisys ES7000 IA32 series"
depends on X86_32 && SMP
help
Support for Unisys ES7000 systems. Say 'Y' here if this kernel is
supposed to run on an IA32-based Unisys ES7000 system.
Only choose this option if you have such a system, otherwise you
should say N here.

config X86_BIGSMP
bool "Support for big SMP systems with more than 8 CPUs"
depends on X86_32 && SMP
help
This option is needed for the systems that have more than 8 CPUs
and if the system is not of any sub-arch type above.

endif

config X86_RDC321X
bool "RDC R-321x SoC"
Expand Down Expand Up @@ -913,9 +911,9 @@ config X86_PAE
config NUMA
bool "Numa Memory Allocation and Scheduler Support (EXPERIMENTAL)"
depends on SMP
depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT || X86_GENERICARCH) && ACPI) && EXPERIMENTAL)
depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || X86_GENERICARCH || X86_SUMMIT && ACPI) && EXPERIMENTAL)
default n if X86_PC
default y if (X86_NUMAQ || X86_SUMMIT)
default y if (X86_NUMAQ || X86_SUMMIT || X86_GENERICARCH)
help
Enable NUMA (Non Uniform Memory Access) support.
The kernel will try to allocate memory used by a CPU on the
Expand Down
18 changes: 0 additions & 18 deletions arch/x86/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -117,29 +117,11 @@ mcore-$(CONFIG_X86_VOYAGER) := arch/x86/mach-voyager/
mflags-$(CONFIG_X86_VISWS) := -Iinclude/asm-x86/mach-visws
mcore-$(CONFIG_X86_VISWS) := arch/x86/mach-visws/

# NUMAQ subarch support
mflags-$(CONFIG_X86_NUMAQ) := -Iinclude/asm-x86/mach-numaq
mcore-$(CONFIG_X86_NUMAQ) := arch/x86/mach-default/

# BIGSMP subarch support
mflags-$(CONFIG_X86_BIGSMP) := -Iinclude/asm-x86/mach-bigsmp
mcore-$(CONFIG_X86_BIGSMP) := arch/x86/mach-default/

#Summit subarch support
mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-x86/mach-summit
mcore-$(CONFIG_X86_SUMMIT) := arch/x86/mach-default/

# generic subarchitecture
mflags-$(CONFIG_X86_GENERICARCH):= -Iinclude/asm-x86/mach-generic
fcore-$(CONFIG_X86_GENERICARCH) += arch/x86/mach-generic/
mcore-$(CONFIG_X86_GENERICARCH) := arch/x86/mach-default/


# ES7000 subarch support
mflags-$(CONFIG_X86_ES7000) := -Iinclude/asm-x86/mach-es7000
fcore-$(CONFIG_X86_ES7000) := arch/x86/mach-es7000/
mcore-$(CONFIG_X86_ES7000) := arch/x86/mach-default/

# RDC R-321x subarch support
mflags-$(CONFIG_X86_RDC321X) := -Iinclude/asm-x86/mach-rdc321x
mcore-$(CONFIG_X86_RDC321X) := arch/x86/mach-default/
Expand Down
4 changes: 0 additions & 4 deletions arch/x86/boot/compressed/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,6 @@ static char *vidmem;
static int vidport;
static int lines, cols;

#ifdef CONFIG_X86_NUMAQ
void *xquad_portio;
#endif

#include "../../../../lib/inflate.c"

static void *malloc(int size)
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/kernel/acpi/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ static int __init acpi_parse_madt_lapic_entries(void)
#ifdef CONFIG_X86_IO_APIC
#define MP_ISA_BUS 0

#if defined(CONFIG_X86_ES7000) || defined(CONFIG_X86_GENERICARCH)
#ifdef CONFIG_X86_ES7000
extern int es7000_plat;
#endif

Expand Down Expand Up @@ -997,7 +997,7 @@ void __init mp_config_acpi_legacy_irqs(void)
set_bit(MP_ISA_BUS, mp_bus_not_pci);
Dprintk("Bus #%d is ISA\n", MP_ISA_BUS);

#if defined(CONFIG_X86_ES7000) || defined(CONFIG_X86_GENERICARCH)
#ifdef CONFIG_X86_ES7000
/*
* Older generations of ES7000 have no legacy identity mappings
*/
Expand Down
9 changes: 5 additions & 4 deletions arch/x86/kernel/io_apic_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -1722,7 +1722,6 @@ void disable_IO_APIC(void)
* by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999
*/

#ifndef CONFIG_X86_NUMAQ
static void __init setup_ioapic_ids_from_mpc(void)
{
union IO_APIC_reg_00 reg_00;
Expand All @@ -1732,6 +1731,11 @@ static void __init setup_ioapic_ids_from_mpc(void)
unsigned char old_id;
unsigned long flags;

#ifdef CONFIG_X86_NUMAQ
if (found_numaq)
return;
#endif

/*
* Don't check I/O APIC IDs for xAPIC systems. They have
* no meaning without the serial APIC bus.
Expand Down Expand Up @@ -1828,9 +1832,6 @@ static void __init setup_ioapic_ids_from_mpc(void)
apic_printk(APIC_VERBOSE, " ok.\n");
}
}
#else
static void __init setup_ioapic_ids_from_mpc(void) { }
#endif

int no_timer_check __initdata;

Expand Down
73 changes: 70 additions & 3 deletions arch/x86/kernel/mpparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,73 @@ static int __init mpf_checksum(unsigned char *mp, int len)
}

#ifdef CONFIG_X86_NUMAQ
int found_numaq;
/*
* Have to match translation table entries to main table entries by counter
* hence the mpc_record variable .... can't see a less disgusting way of
* doing this ....
*/
struct mpc_config_translation {
unsigned char mpc_type;
unsigned char trans_len;
unsigned char trans_type;
unsigned char trans_quad;
unsigned char trans_global;
unsigned char trans_local;
unsigned short trans_reserved;
};


static int mpc_record;
static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY]
__cpuinitdata;

static inline int generate_logical_apicid(int quad, int phys_apicid)
{
return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1);
}


static inline int mpc_apic_id(struct mpc_config_processor *m,
struct mpc_config_translation *translation_record)
{
int quad = translation_record->trans_quad;
int logical_apicid = generate_logical_apicid(quad, m->mpc_apicid);

printk(KERN_DEBUG "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n",
m->mpc_apicid,
(m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
(m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
m->mpc_apicver, quad, logical_apicid);
return logical_apicid;
}

int mp_bus_id_to_node[MAX_MP_BUSSES];

int mp_bus_id_to_local[MAX_MP_BUSSES];

static void mpc_oem_bus_info(struct mpc_config_bus *m, char *name,
struct mpc_config_translation *translation)
{
int quad = translation->trans_quad;
int local = translation->trans_local;

mp_bus_id_to_node[m->mpc_busid] = quad;
mp_bus_id_to_local[m->mpc_busid] = local;
printk(KERN_INFO "Bus #%d is %s (node %d)\n",
m->mpc_busid, name, quad);
}

int quad_local_to_mp_bus_id [NR_CPUS/4][4];
static void mpc_oem_pci_bus(struct mpc_config_bus *m,
struct mpc_config_translation *translation)
{
int quad = translation->trans_quad;
int local = translation->trans_local;

quad_local_to_mp_bus_id[quad][local] = m->mpc_busid;
}

#endif

static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
Expand Down Expand Up @@ -321,11 +379,11 @@ static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable,
}
}

static inline void mps_oem_check(struct mp_config_table *mpc, char *oem,
void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem,
char *productid)
{
if (strncmp(oem, "IBM NUMA", 8))
printk("Warning! May not be a NUMA-Q system!\n");
printk("Warning! Not a NUMA-Q system!\n");
else
found_numaq = 1;

Expand Down Expand Up @@ -388,7 +446,16 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
return 0;

#ifdef CONFIG_X86_32
mps_oem_check(mpc, oem, str);
/*
* need to make sure summit and es7000's mps_oem_check is safe to be
* called early via genericarch 's mps_oem_check
*/
if (early) {
#ifdef CONFIG_X86_NUMAQ
numaq_mps_oem_check(mpc, oem, str);
#endif
} else
mps_oem_check(mpc, oem, str);
#endif

/* save the local APIC address, it might be non-default */
Expand Down
2 changes: 0 additions & 2 deletions arch/x86/kernel/numaq_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@

#define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT))

int found_numaq;

/*
* Function: smp_dump_qct()
*
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/kernel/summit_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ static struct rio_table_hdr *rio_table_hdr __initdata;
static struct scal_detail *scal_devs[MAX_NUMNODES] __initdata;
static struct rio_detail *rio_devs[MAX_NUMNODES*4] __initdata;

#ifndef CONFIG_X86_NUMAQ
static int mp_bus_id_to_node[MAX_MP_BUSSES] __initdata;
#endif

static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus)
{
Expand Down
1 change: 0 additions & 1 deletion arch/x86/mach-es7000/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@
#

obj-$(CONFIG_X86_ES7000) := es7000plat.o
obj-$(CONFIG_X86_GENERICARCH) := es7000plat.o
47 changes: 0 additions & 47 deletions arch/x86/mach-es7000/es7000plat.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,53 +177,6 @@ find_unisys_acpi_oem_table(unsigned long *oem_addr)
}
#endif

/*
* This file also gets compiled if CONFIG_X86_GENERICARCH is set. Generic
* arch already has got following function definitions (asm-generic/es7000.c)
* hence no need to define these for that case.
*/
#ifndef CONFIG_X86_GENERICARCH
void es7000_sw_apic(void);
void __init enable_apic_mode(void)
{
es7000_sw_apic();
return;
}

__init int mps_oem_check(struct mp_config_table *mpc, char *oem,
char *productid)
{
if (mpc->mpc_oemptr) {
struct mp_config_oemtable *oem_table =
(struct mp_config_oemtable *)mpc->mpc_oemptr;
if (!strncmp(oem, "UNISYS", 6))
return parse_unisys_oem((char *)oem_table);
}
return 0;
}
#ifdef CONFIG_ACPI
/* Hook from generic ACPI tables.c */
int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
unsigned long oem_addr;
if (!find_unisys_acpi_oem_table(&oem_addr)) {
if (es7000_check_dsdt())
return parse_unisys_oem((char *)oem_addr);
else {
setup_unisys();
return 1;
}
}
return 0;
}
#else
int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
return 0;
}
#endif
#endif /* COFIG_X86_GENERICARCH */

static void
es7000_spin(int n)
{
Expand Down
10 changes: 7 additions & 3 deletions arch/x86/mach-generic/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
# Makefile for the generic architecture
#

EXTRA_CFLAGS := -Iarch/x86/kernel
EXTRA_CFLAGS := -Iarch/x86/kernel

obj-y := probe.o summit.o bigsmp.o es7000.o default.o
obj-y += ../../x86/mach-es7000/
obj-y := probe.o default.o
obj-$(CONFIG_X86_NUMAQ) += numaq.o
obj-$(CONFIG_X86_SUMMIT) += summit.o
obj-$(CONFIG_X86_BIGSMP) += bigsmp.o
obj-$(CONFIG_X86_ES7000) += es7000.o
obj-$(CONFIG_X86_ES7000) += ../../x86/mach-es7000/
Loading

0 comments on commit d49c428

Please sign in to comment.