An generic subarchitecture for 2.5.68

An generic subarchitecture for 2.5.68

Post by Andi Klee » Mon, 28 Apr 2003 03:30:12



This patch adds an generic x86 subarchitecture. It is intended to provide
an dynamic interface for APIC drivers. There are already three subarchitectures
(bigsmp, summit, default) that only differ in how they drive the local APIC.
A fourth - Unisys ES7000 - is scheduled to be merged soon.

The subarchitecture concept separated this nicely, but it has the big
drawback that they are compile time options. A Linux vendor cannot
ship own binary kernel rpms for all of these machines. Runtime probing
is needed instead.

This patch adds a new "generic" subarchitecture that just acts as a
dynamic switching layer for APIC drivers. It only tries to virtualize
the APICs, no attempt is made to cover further incompatiblities.
This means machines like the Visual Workstation, pc9800 or
Voyager are not covered; but these are unlikely to be supported by
binary distributions anyways.

The generic arch reuses the existing interface in mach_ipi / mach_mpparse.h /
mach_apic.h and just pulls it using some macros into an "struct genapic"
object. The main APIC code does not recognize it, it is all hidden
in the mach-generic include files.

Auto detection of APIC types is supported in the usual way used by
existing ports like Summit - checking ACPI or mptables for specific
signatures - or it can be specified by the user using a new "apic="
boot option. I also moved the DMI scan to before the generic
subarchitecture probe, so DMI could be used in future too to probe
specific machines.

Some minor hacks were needed to avoid circular declaration of a few
symbols, but overall it's fairly clean.

The patch has been tested on a Summit machine, an generic 4 virtual CPUs
Xeon and on an ES7000.

Patch for 2.5.68+bkcvs

Please consider applying,

-Andi

diff -u linux-apic/arch/i386/kernel/timers/Makefile-o linux-apic/arch/i386/kernel/timers/Makefile
--- linux-apic/arch/i386/kernel/timers/Makefile-o       2003-02-13 18:53:22.000000000 +0100
+++ linux-apic/arch/i386/kernel/timers/Makefile 2003-04-27 02:45:24.000000000 +0200
@@ -4,4 +4,4 @@

 obj-y := timer.o timer_none.o timer_tsc.o timer_pit.o

-obj-$(CONFIG_X86_SUMMIT)       += timer_cyclone.o
+obj-$(CONFIG_X86_CYCLONE_TIMER)        += timer_cyclone.o
diff -u linux-apic/arch/i386/kernel/timers/timer.c-o linux-apic/arch/i386/kernel/timers/timer.c
--- linux-apic/arch/i386/kernel/timers/timer.c-o        2003-04-14 23:37:04.000000000 +0200
+++ linux-apic/arch/i386/kernel/timers/timer.c  2003-04-27 02:45:24.000000000 +0200
@@ -6,12 +6,12 @@
 /* list of externed timers */
 extern struct timer_opts timer_pit;
 extern struct timer_opts timer_tsc;
-#ifdef CONFIG_X86_SUMMIT
+#ifdef CONFIG_X86_CYCLONE_TIMER
 extern struct timer_opts timer_cyclone;
 #endif
 /* list of timers, ordered by preference, NULL terminated */
 static struct timer_opts* timers[] = {
-#ifdef CONFIG_X86_SUMMIT
+#ifdef CONFIG_X86_CYCLONE_TIMER
        &timer_cyclone,
 #endif
        &timer_tsc,
diff -u linux-apic/arch/i386/kernel/setup.c-o linux-apic/arch/i386/kernel/setup.c
--- linux-apic/arch/i386/kernel/setup.c-o       2003-04-25 01:17:20.000000000 +0200
+++ linux-apic/arch/i386/kernel/setup.c 2003-04-27 02:45:25.000000000 +0200
@@ -91,6 +91,7 @@

 extern void early_cpu_init(void);
 extern void dmi_scan_machine(void);
+extern void generic_apic_probe(char *);
 extern int root_mountflags;
 extern char _text, _etext, _edata, _end;
 extern int blk_nohighio;
@@ -909,6 +910,13 @@
        smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
 #endif
        paging_init();
+
+       dmi_scan_machine();
+
+#ifdef CONFIG_X86_GENERICARCH
+       generic_apic_probe(*cmdline_p);
+#endif
+
 #ifdef CONFIG_ACPI_BOOT
        /*
         * Parse the ACPI tables for possible boot-time SMP configuration.
@@ -930,7 +938,6 @@
        conswitchp = &dummy_con;
 #endif
 #endif
-       dmi_scan_machine();
 }

 static int __init highio_setup(char *str)
diff -u linux-apic/arch/i386/kernel/io_apic.c-o linux-apic/arch/i386/kernel/io_apic.c
--- linux-apic/arch/i386/kernel/io_apic.c-o     2003-04-27 02:40:32.000000000 +0200
+++ linux-apic/arch/i386/kernel/io_apic.c       2003-04-27 02:45:25.000000000 +0200
@@ -280,7 +280,9 @@
 extern unsigned long irq_affinity[NR_IRQS];

 static int __cacheline_aligned pending_irq_balance_apicid[NR_IRQS];
-static int irqbalance_disabled = NO_BALANCE_IRQ;
+
+#define IRQBALANCE_CHECK_ARCH -999
+static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH;
 static int physical_balance = 0;

 struct irq_cpu_info {
@@ -342,8 +344,10 @@
        unsigned long allowed_mask;
        unsigned int new_cpu;

-       if (irqbalance_disabled)
+       if (irqbalance_disabled == IRQBALANCE_CHECK_ARCH && NO_BALANCE_IRQ)
                return;
+       else if (irqbalance_disabled)
+               return;

        allowed_mask = cpu_online_map & irq_affinity[irq];
        new_cpu = move(cpu, allowed_mask, now, 1);
diff -u linux-apic/arch/i386/kernel/mpparse.c-o linux-apic/arch/i386/kernel/mpparse.c
--- linux-apic/arch/i386/kernel/mpparse.c-o     2003-04-25 01:17:20.000000000 +0200
+++ linux-apic/arch/i386/kernel/mpparse.c       2003-04-27 02:45:25.000000000 +0200
@@ -73,7 +73,9 @@
 /* Bitmask of physically existing CPUs */
 unsigned long phys_cpu_present_map;

+#ifndef CONFIG_X86_GENERICARCH
 int x86_summit = 0;
+#endif
 u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };

 /*
diff -u linux-apic/arch/i386/kernel/smp.c-o linux-apic/arch/i386/kernel/smp.c
--- linux-apic/arch/i386/kernel/smp.c-o 2003-04-14 23:37:04.000000000 +0200
+++ linux-apic/arch/i386/kernel/smp.c   2003-04-27 02:45:25.000000000 +0200
@@ -123,7 +123,7 @@
        return SET_APIC_DEST_FIELD(mask);
 }

-static inline void __send_IPI_shortcut(unsigned int shortcut, int vector)
+inline void __send_IPI_shortcut(unsigned int shortcut, int vector)
 {
        /*
         * Subtle. In the case of the 'never do double writes' workaround
@@ -155,7 +155,7 @@
        __send_IPI_shortcut(APIC_DEST_SELF, vector);
 }

-static inline void send_IPI_mask_bitmask(int mask, int vector)
+inline void send_IPI_mask_bitmask(int mask, int vector)
 {
        unsigned long cfg;
        unsigned long flags;
@@ -186,7 +186,7 @@
        local_irq_restore(flags);
 }

-static inline void send_IPI_mask_sequence(int mask, int vector)
+inline void send_IPI_mask_sequence(int mask, int vector)
 {
        unsigned long cfg, flags;
        unsigned int query_cpu, query_mask;
diff -u linux-apic/arch/i386/mach-generic/default.c-o linux-apic/arch/i386/mach-generic/default.c
--- linux-apic/arch/i386/mach-generic/default.c-o       2003-04-27 02:45:25.000000000 +0200
+++ linux-apic/arch/i386/mach-generic/default.c 2003-04-27 02:45:25.000000000 +0200
@@ -0,0 +1,22 @@
+/*
+ * Default generic APIC driver. This handles upto 8 CPUs.
+ */
+#define APIC_DEFINITION 1
+#include <asm/genapic.h>
+#include <asm/fixmap.h>
+#include <asm/apicdef.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <asm/mach-default/mach_apic.h>
+#include <asm/mach-default/mach_ipi.h>
+#include <asm/mach-default/mach_mpparse.h>
+
+/* should be called last. */
+static __init int probe_default(void)
+{
+       return 1;
+}
+
+struct genapic apic_default = APIC_INIT("default", probe_default);
diff -u linux-apic/arch/i386/mach-generic/Makefile-o linux-apic/arch/i386/mach-generic/Makefile
--- linux-apic/arch/i386/mach-generic/Makefile-o        2003-04-27 02:45:25.000000000 +0200
+++ linux-apic/arch/i386/mach-generic/Makefile  2003-04-27 02:45:25.000000000 +0200
@@ -0,0 +1,9 @@
+#
+# Makefile for the generic architecture
+#
+
+EXTRA_CFLAGS   += -I../kernel
+
+obj-y                          := probe.o summit.o bigsmp.o default.o
+
+
diff -u linux-apic/arch/i386/mach-generic/summit.c-o linux-apic/arch/i386/mach-generic/summit.c
--- linux-apic/arch/i386/mach-generic/summit.c-o        2003-04-27 02:45:25.000000000 +0200
+++ linux-apic/arch/i386/mach-generic/summit.c  2003-04-27 02:45:25.000000000 +0200
@@ -0,0 +1,22 @@
+/*
+ * APIC driver for the IBM "Summit" chipset.
+ */
+#define APIC_DEFINITION 1
+#include <asm/genapic.h>
+#include <asm/fixmap.h>
+#include <asm/apicdef.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <asm/mach-summit/mach_apic.h>
+#include <asm/mach-summit/mach_ipi.h>
+#include <asm/mach-summit/mach_mpparse.h>
+
+static __init int probe_summit(void)
+{
+       /* probed later in mptable/ACPI hooks */
+       return 0;
+}
+
+struct genapic apic_summit = APIC_INIT("summit", probe_summit);
diff -u linux-apic/arch/i386/mach-generic/bigsmp.c-o linux-apic/arch/i386/mach-generic/bigsmp.c
--- linux-apic/arch/i386/mach-generic/bigsmp.c-o        2003-04-27 02:45:25.000000000 +0200
+++ linux-apic/arch/i386/mach-generic/bigsmp.c  2003-04-27 02:45:25.000000000 +0200
@@ -0,0 +1,23 @@
+/*
+ * APIC driver for "bigsmp" XAPIC machines with more than 8 virtual CPUs.
+ * Drives the local APIC in "clustered mode".
+ */
+#define APIC_DEFINITION 1
+#include <asm/genapic.h>
+#include <asm/fixmap.h>
+#include <asm/apicdef.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <asm/mach-bigsmp/mach_apic.h>
+#include <asm/mach-bigsmp/mach_ipi.h>
+#include <asm/mach-default/mach_mpparse.h>
+
+int dmi_bigsmp; /* can be set by dmi scanners */
+
+static __init int probe_bigsmp(void)
+{
+       return dmi_bigsmp;
+}
+
+struct genapic apic_bigsmp = APIC_INIT("bigsmp", probe_bigsmp);
diff -u linux-apic/arch/i386/mach-generic/probe.c-o linux-apic/arch/i386/mach-generic/probe.c
--- linux-apic/arch/i386/mach-generic/probe.c-o 2003-04-27 02:45:25.000000000 +0200
+++ linux-apic/arch/i386/mach-generic/probe.c   2003-04-27 02:45:25.000000000 +0200
@@ -0,0 +1,96 @@
+/* Copyright 2003 Andi Kleen, SuSE Labs.
+ * Subject to the GNU Public License, v.2
+ *
+ * Generic x86 APIC driver probe layer.
+ */  
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <asm/fixmap.h>
+#include <asm/apicdef.h>
+#include <asm/genapic.h>
+
+extern struct genapic apic_summit;
+extern struct genapic apic_bigsmp;
+extern struct genapic apic_default;
+
+struct genapic *genapic = &apic_default;
+
+struct genapic *apic_probe[] __initdata = {
+ ...

read more »

 
 
 

An generic subarchitecture for 2.5.68

Post by Andrew Morto » Mon, 28 Apr 2003 08:20:06



> This patch adds an generic x86 subarchitecture.

It causes a large number of compilation errors with the config at
http://www.zip.com.au/~akpm/linux/patches/stuff/config

Some Kconfig help would be nice...
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

An generic subarchitecture for 2.5.68

Post by Andi Klee » Mon, 28 Apr 2003 15:50:11




> > This patch adds an generic x86 subarchitecture.

> It causes a large number of compilation errors with the config at
> http://www.zip.com.au/~akpm/linux/patches/stuff/config

> Some Kconfig help would be nice...

Ah - you didn't compile it with CONFIG_SMP. Ok, that was not tested
and frankly doesn't make any sense because you don't need an APIC
driver for > 8 CPUs for an UP kernel.

Really BIGSMP, SUMMIT, GENERICARCH need to be only enabled with
SMP is enabled.

But Kconfig seems to ignore depends inside choice. Roman, any ideas
how to fix that?

-Andi

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

An generic subarchitecture for 2.5.68

Post by Roman Zippe » Mon, 28 Apr 2003 16:10:06


Hi,


> Really BIGSMP, SUMMIT, GENERICARCH need to be only enabled with
> SMP is enabled.

> But Kconfig seems to ignore depends inside choice. Roman, any ideas
> how to fix that?

What did you try? E.g. this works fine here:

config X86_BIGSMP
        bool "Support for other sub-arch SMP systems with more than 8 CPUs"
        depends on SMP
        help
        ...

bye, Roman

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

An generic subarchitecture for 2.5.68

Post by Andi Klee » Mon, 28 Apr 2003 16:20:08



> Hi,


> > Really BIGSMP, SUMMIT, GENERICARCH need to be only enabled with
> > SMP is enabled.

> > But Kconfig seems to ignore depends inside choice. Roman, any ideas
> > how to fix that?

> What did you try? E.g. this works fine here:

> config X86_BIGSMP
>    bool "Support for other sub-arch SMP systems with more than 8 CPUs"
>    depends on SMP
>    help
>    ...

I made GENERICARCH depend on SMP and it was still defined after an
make oldconfig

-Andi
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

An generic subarchitecture for 2.5.68

Post by Andi Klee » Mon, 28 Apr 2003 16:30:12


Quote:> I made GENERICARCH depend on SMP and it was still defined after an
> make oldconfig

Never mind. It was a typo on my side.

-Andi
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

An generic subarchitecture for 2.5.68

Post by Andi Klee » Mon, 28 Apr 2003 16:40:08




> > This patch adds an generic x86 subarchitecture.

> It causes a large number of compilation errors with the config at
> http://www.zip.com.au/~akpm/linux/patches/stuff/config

> Some Kconfig help would be nice...

This incremental patch fixes it by just disallowing SMP in the dependencies.

-Andi

--- linux-subarch/arch/i386/Kconfig-o   2003-04-27 16:32:53.000000000 +0200

 config X86_SUMMIT
        bool "Summit/EXA (IBM x440)"
+       depends on SMP
        help
          This option is needed for IBM systems that use the Summit/EXA chipset.

 config X86_BIGSMP
        bool "Support for other sub-arch SMP systems with more than 8 CPUs"
+       depends on SMP
        help
          This option is needed for the systems that have more than 8 CPUs

 config X86_GENERICARCH
        bool "Generic architecture (Summit, bigsmp, default)"
+       depends on SMP
        help
           This option compiles in the Summit, bigsmp, default subarchitectures.
          It is intended for a generic binary kernel.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/