Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[RFC PATCH 3/4] x86: using logical flat for amd cpu too.

13 views
Skip to first unread message

Yinghai Lu

unread,
Jan 11, 2010, 9:50:01 PM1/11/10
to
not sure it works again, could be bios fix the irq routing dest ?

tested that amd support logical flat too when cpus num <= 8 and even
bsp apic id > 8

so could remove vendor check...

Signed-off-by: Yinghai Lu <yin...@kernel.org>

---
arch/x86/kernel/apic/apic.c | 11 ++---------
arch/x86/kernel/apic/probe_64.c | 13 ++-----------
2 files changed, 4 insertions(+), 20 deletions(-)

Index: linux-2.6/arch/x86/kernel/apic/apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/apic.c
+++ linux-2.6/arch/x86/kernel/apic/apic.c
@@ -1898,15 +1898,8 @@ void __cpuinit generic_processor_info(in
max_physical_apicid = apicid;

#ifdef CONFIG_X86_32
- switch (boot_cpu_data.x86_vendor) {
- case X86_VENDOR_INTEL:
- if (num_processors > 8)
- def_to_bigsmp = 1;
- break;
- case X86_VENDOR_AMD:
- if (max_physical_apicid >= 8)
- def_to_bigsmp = 1;
- }
+ if (num_processors > 8)
+ def_to_bigsmp = 1;
#endif

#if defined(CONFIG_SMP) || defined(CONFIG_X86_64)
Index: linux-2.6/arch/x86/kernel/apic/probe_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/probe_64.c
+++ linux-2.6/arch/x86/kernel/apic/probe_64.c
@@ -67,17 +67,8 @@ void __init default_setup_apic_routing(v
}
#endif

- if (apic == &apic_flat) {
- switch (boot_cpu_data.x86_vendor) {
- case X86_VENDOR_INTEL:
- if (num_processors > 8)
- apic = &apic_physflat;
- break;
- case X86_VENDOR_AMD:
- if (max_physical_apicid >= 8)
- apic = &apic_physflat;
- }
- }
+ if (apic == &apic_flat && num_processors > 8)
+ apic = &apic_physflat;

printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Yinghai Lu

unread,
Jan 11, 2010, 9:50:01 PM1/11/10
to
some systems that have disable cpus entries because same
BIOS will support 2 sockets and 4 sockets and more at
same time, BIOS just leave some disable entries, but
those system do not support cpu hotplug. we don't need
treat disabled_cpus as hotplug cpus.
so we can make nr_cpu_ids smaller and save more space
(pcpu data allocations), and could make some systems run
with logical flat instead of physical flat apic mode

Signed-off-by: Yinghai Lu <yin...@kernel.org>

---
arch/x86/kernel/smpboot.c | 39 +++++++++++++++++++++++++++++++++++++--
1 file changed, 37 insertions(+), 2 deletions(-)

Index: linux-2.6/arch/x86/kernel/smpboot.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/smpboot.c
+++ linux-2.6/arch/x86/kernel/smpboot.c
@@ -47,6 +47,7 @@
#include <linux/bootmem.h>
#include <linux/err.h>
#include <linux/nmi.h>
+#include <linux/dmi.h>
#include <linux/tboot.h>

#include <asm/acpi.h>
@@ -1180,6 +1181,24 @@ static int __init _setup_possible_cpus(c
}
early_param("possible_cpus", _setup_possible_cpus);

+static __initdata int treat_disabled_cpus_as_hotplug;
+static __init int hotplug_cpus_check(const struct dmi_system_id *d)
+{
+ printk(KERN_NOTICE "%s detected: treat disabled cpus as hotplug ones\n", d->ident);
+ treat_disabled_cpus_as_hotplug = 1;
+
+ return 0;
+}
+
+static struct dmi_system_id hotplug_cpus_dmi_table[] __initdata = {
+ { hotplug_cpus_check, "WHICH VENDOR WHAT SYSTEM",
+ { DMI_MATCH(DMI_BIOS_VENDOR, "WHAT VENDOR"),
+ DMI_MATCH(DMI_BIOS_VERSION, "WHAT VER"),
+ }
+ },
+ { } /* NULL entry stops DMI scanning */
+};
+

/*
* cpu_possible_mask should be static, it cannot change as cpu's
@@ -1206,8 +1225,24 @@ __init void prefill_possible_map(void)
if (!num_processors)
num_processors = 1;

- if (setup_possible_cpus == -1)
- possible = num_processors + disabled_cpus;
+ if (setup_possible_cpus == -1) {
+ possible = num_processors;
+ /*
+ * do we have better way to detect hotplug cpus?
+ *
+ * some systems that have disable cpus entries because same
+ * BIOS will support 2 sockets and 4 sockets and more at
+ * same time, BIOS just leave some disable entries, but
+ * those system do not support cpu hotplug. we don't need
+ * treat disabled_cpus as hotplug cpus.
+ * so we can make nr_cpu_ids smaller and save more space
+ * (pcpu data allocations), and could make some systems run
+ * with logical flat instead of physical flat apic mode
+ */
+ dmi_check_system(hotplug_cpus_dmi_table);
+ if (treat_disabled_cpus_as_hotplug)
+ possible += disabled_cpus;
+ }
else
possible = setup_possible_cpus;

Linus Torvalds

unread,
Jan 11, 2010, 10:20:02 PM1/11/10
to

On Mon, 11 Jan 2010, Yinghai Lu wrote:
>
> some systems that have disable cpus entries because same
> BIOS will support 2 sockets and 4 sockets and more at
> same time, BIOS just leave some disable entries, but
> those system do not support cpu hotplug. we don't need
> treat disabled_cpus as hotplug cpus.
>
> so we can make nr_cpu_ids smaller and save more space
> (pcpu data allocations), and could make some systems run
> with logical flat instead of physical flat apic mode

.. but this one I detest.

We can't play games that depend on us always filling in some DMI table
correctly. Things need to "just work".

So while 1/4 looks fine, 2/4 looks fundamentally unacceptable.

Is the flat APIC mode really so important?

I would suggest a few alternatives:

Truly static:

- only use that flat apic mode when you _know_ that you absolutely will
never have more than 8 cpu's. Ie when CONFIG_NR_CPUS <= 8 (or, with
1/3, when nr_cpu_ids <= 8) and/or when <= 8 CPU's were detected, and
CPU hotplug is disabled entirely.

Slightly more intelligent:

- Look at the ACPI socket count, and hey, if it says it might have more
sockets - whether they are really hotplug or not, don't use flat mode,
because we simply don't know. But do _not_ do some kind of DMI table to
say one way or the other.

And if it's _really_ important:

- if flat mode is so important that you want to enable it whenever
possible, what about enabling/disabling it dynamically at CPU hotplug
time? That does sound _very_ painful, but it's still better than having
to maintain some list of all systems that can ever hot-plug.

Hmm?

Linus

Linus Torvalds

unread,
Jan 11, 2010, 10:20:02 PM1/11/10
to

On Mon, 11 Jan 2010, Yinghai Lu wrote:
>

> tested that amd support logical flat too when cpus num <= 8 and even
> bsp apic id > 8
>
> so could remove vendor check...

At least this one makes code simpler.

What was the background for thinking that AMD didn't support the same APIC
addressing models? If there really is some issue external to the CPU's
themselves, whatever problem was attributed to AMD might be the same (or
similar) problem that Ananth had.

Linus

Ananth N Mavinakayanahalli

unread,
Jan 12, 2010, 3:30:01 AM1/12/10
to
On Mon, Jan 11, 2010 at 06:48:01PM -0800, Yinghai Lu wrote:

> not sure it works again, could be bios fix the irq routing dest ?

Nope, it doesn't. I applied this patchset.. no luck.

Ananth

Yinghai Lu

unread,
Jan 12, 2010, 3:50:02 AM1/12/10
to
On Mon, Jan 11, 2010 at 7:16 PM, Linus Torvalds
<torv...@linux-foundation.org> wrote:
>
>
> On Mon, 11 Jan 2010, Yinghai Lu wrote:
>>
>> tested that amd support logical flat too when cpus num <= 8 and even
>> bsp apic id > 8
>>
>> so could remove vendor check...
>
> At least this one makes code simpler.
>
> What was the background for thinking that AMD didn't support the same APIC
> addressing models? If there really is some issue external to the CPU's
> themselves, whatever problem was attributed to AMD might be the same (or
> similar) problem that Ananth had.

not sure.

i remembered that bios fix one apic dest apic id in ioapic register.
before that that field
is set to 0 always.

YH

Yinghai Lu

unread,
Jan 12, 2010, 4:00:02 AM1/12/10
to
On Mon, Jan 11, 2010 at 7:13 PM, Linus Torvalds
<torv...@linux-foundation.org> wrote:
>
>
> On Mon, 11 Jan 2010, Yinghai Lu wrote:
>>
>> some systems that have disable cpus entries because same
>> � BIOS will support 2 sockets and 4 sockets and more at
>> � same time, BIOS just leave some disable entries, but
>> � those system do not support cpu hotplug. we don't need
>> � treat disabled_cpus as hotplug cpus.
>>
>> so we can make nr_cpu_ids smaller and save more space
>> � (pcpu data allocations), and could make some systems run
>> � with logical flat instead of physical flat apic mode
>
> .. but this one I detest.
>
> We can't play games that depend on us always filling in some DMI table
> correctly. Things need to "just work".
>
> So while 1/4 looks fine, 2/4 looks fundamentally unacceptable.
>
> Is the flat APIC mode really so important?
>
> I would suggest a few alternatives:
>
> Truly static:
>
> �- only use that flat apic mode when you _know_ that you absolutely will
> � never have more than 8 cpu's. Ie when CONFIG_NR_CPUS <= 8 (or, with
> � 1/3, when nr_cpu_ids <= 8) and/or when <= 8 CPU's were detected, and
> � CPU hotplug is disabled entirely.
that is this patch try to do. but can not find out the system that does support
real hw support hotadd cpus.

>
> Slightly more intelligent:
>
> �- Look at the ACPI socket count, and hey, if it says it might have more
> � sockets - whether they are really hotplug or not, don't use flat mode,
> � because we simply don't know. But do _not_ do some kind of DMI table to
> � say one way or the other.

that acpi could lie, for example, some system share one BIOS between 2
socket/4 socket/8 sockets
model. and BIOS could have bunch disabled entries in MADT. or MPTABLE.

>
> And if it's _really_ important:
>
> �- if flat mode is so important that you want to enable it whenever
> � possible, what about enabling/disabling it dynamically at CPU hotplug
> � time? That does sound _very_ painful, but it's still better than having
> � to maintain some list of all systems that can ever hot-plug.

interesting, could be done.
init_apic_ldr is called even for physical flat on 64 bit.
could change apic on fly.

YH

Yinghai Lu

unread,
Jan 12, 2010, 4:20:02 AM1/12/10
to
On Mon, Jan 11, 2010 at 7:13 PM, Linus Torvalds
<torv...@linux-foundation.org> wrote:
>
>
> On Mon, 11 Jan 2010, Yinghai Lu wrote:
>>
>> some systems that have disable cpus entries because same
>> � BIOS will support 2 sockets and 4 sockets and more at
>> � same time, BIOS just leave some disable entries, but
>> � those system do not support cpu hotplug. we don't need
>> � treat disabled_cpus as hotplug cpus.
>>
>> so we can make nr_cpu_ids smaller and save more space
>> � (pcpu data allocations), and could make some systems run
>> � with logical flat instead of physical flat apic mode
>
> .. but this one I detest.
>
> We can't play games that depend on us always filling in some DMI table
> correctly. Things need to "just work".

maybe could change to list that doesn't need to treat disabled cpus as
hotplug cpus?

YH

Ingo Molnar

unread,
Jan 12, 2010, 4:50:02 AM1/12/10
to

* Linus Torvalds <torv...@linux-foundation.org> wrote:

>
>
> On Mon, 11 Jan 2010, Yinghai Lu wrote:
> >
> > some systems that have disable cpus entries because same
> > BIOS will support 2 sockets and 4 sockets and more at
> > same time, BIOS just leave some disable entries, but
> > those system do not support cpu hotplug. we don't need
> > treat disabled_cpus as hotplug cpus.
> >
> > so we can make nr_cpu_ids smaller and save more space
> > (pcpu data allocations), and could make some systems run
> > with logical flat instead of physical flat apic mode
>
> .. but this one I detest.
>
> We can't play games that depend on us always filling in some DMI table
> correctly. Things need to "just work".
>
> So while 1/4 looks fine, 2/4 looks fundamentally unacceptable.
>
> Is the flat APIC mode really so important?

it's not important at all. When it's proven safe it's fine but it's clearly
not unconditionally safe ...

> I would suggest a few alternatives:
>
> Truly static:
>
> - only use that flat apic mode when you _know_ that you absolutely will
> never have more than 8 cpu's. Ie when CONFIG_NR_CPUS <= 8 (or, with
> 1/3, when nr_cpu_ids <= 8) and/or when <= 8 CPU's were detected, and
> CPU hotplug is disabled entirely.
>
> Slightly more intelligent:
>
> - Look at the ACPI socket count, and hey, if it says it might have more
> sockets - whether they are really hotplug or not, don't use flat mode,
> because we simply don't know. But do _not_ do some kind of DMI table to
> say one way or the other.
>
> And if it's _really_ important:
>
> - if flat mode is so important that you want to enable it whenever
> possible, what about enabling/disabling it dynamically at CPU hotplug
> time? That does sound _very_ painful, but it's still better than having
> to maintain some list of all systems that can ever hot-plug.
>
> Hmm?

I'd go for #1. If the (modest) micro-performance advantages of flat delivery
matter to a hardware vendor the system/BIOS can be built in a way to trigger
the optimization. But even single socket systems are quickly running out of
the space of 8 APIC ids so the relevance is dwindling ...

Ingo

Yinghai Lu

unread,
Jan 12, 2010, 7:20:01 AM1/12/10
to
not sure it works again, could be bios fix the irq routing dest ?

tested that amd support logical flat too when cpus num <= 8 and even
bsp apic id > 8

so could remove vendor check...

Signed-off-by: Yinghai Lu <yin...@kernel.org>

---

Yinghai Lu

unread,
Jan 12, 2010, 7:20:01 AM1/12/10
to
some systems that have disable cpus entries because same
BIOS will support 2 sockets and 4 sockets and more at
same time, BIOS just leave some disable entries, but
those system do not support cpu hotplug. we don't need
treat disabled_cpus as hotplug cpus.
so we can make nr_cpu_ids smaller and save more space
(pcpu data allocations), and could make some systems run
with logical flat instead of physical flat apic mode

-v2: change to black list instead

Signed-off-by: Yinghai Lu <yin...@kernel.org>

---
arch/x86/kernel/smpboot.c | 76 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 74 insertions(+), 2 deletions(-)

Index: linux-2.6/arch/x86/kernel/smpboot.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/smpboot.c
+++ linux-2.6/arch/x86/kernel/smpboot.c
@@ -47,6 +47,7 @@
#include <linux/bootmem.h>
#include <linux/err.h>
#include <linux/nmi.h>
+#include <linux/dmi.h>
#include <linux/tboot.h>

#include <asm/acpi.h>

@@ -1180,6 +1181,59 @@ static int __init _setup_possible_cpus(c
}
early_param("possible_cpus", _setup_possible_cpus);

+static __initdata int treat_disabled_cpus_as_hotplug = 1;


+static __init int hotplug_cpus_check(const struct dmi_system_id *d)
+{
+ printk(KERN_NOTICE "%s detected: treat disabled cpus as hotplug ones\n", d->ident);

+ treat_disabled_cpus_as_hotplug = 0;


+
+ return 0;
+}
+
+static struct dmi_system_id hotplug_cpus_dmi_table[] __initdata = {
+ {

+ .callback = hotplug_cpus_check,
+ .ident = "Sun Microsystems Sun Fire X4440",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sun Microsystems"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Sun Fire X4440"),
+ },
+ },
+ {
+ .callback = hotplug_cpus_check,
+ .ident = "Sun Microsystems Sun Fire X4240",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sun Microsystems"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Sun Fire X4240"),
+ },
+ },
+ {
+ .callback = hotplug_cpus_check,
+ .ident = "Sun Microsystems Sun Fire X4140",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sun Microsystems"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Sun Fire X4140"),
+ },
+ },
+ {
+ .callback = hotplug_cpus_check,
+ .ident = "Sun Microsystems Sun Fire X4600",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sun Microsystems"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Sun Fire X4600"),
+ },
+ },
+ {
+ .callback = hotplug_cpus_check,
+ .ident = "Sun Microsystems Sun Fire X4640",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sun Microsystems"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Sun Fire X4640"),
+ },


+ },
+ { } /* NULL entry stops DMI scanning */
+};
+

/*
* cpu_possible_mask should be static, it cannot change as cpu's

@@ -1206,8 +1260,26 @@ __init void prefill_possible_map(void)


if (!num_processors)
num_processors = 1;

- if (setup_possible_cpus == -1)
- possible = num_processors + disabled_cpus;
+ if (setup_possible_cpus == -1) {
+ possible = num_processors;
+ /*
+ * do we have better way to detect hotplug cpus?
+ *

+ * some systems that have disable cpus entries because same
+ * BIOS will support 2 sockets and 4 sockets and more at
+ * same time, BIOS just leave some disabled entries with wild
+ * apicid, but those system do not support cpu hotplug.
+ * we don't need treat disabled_cpus as hotplug cpus.
+ * so we can make nr_cpu_ids smaller and save more space
+ * (pcpu data allocations), and could make some systems run
+ * with logical flat instead of physical flat apic mode
+ */
+ if (disabled_cpus) {


+ dmi_check_system(hotplug_cpus_dmi_table);
+ if (treat_disabled_cpus_as_hotplug)
+ possible += disabled_cpus;
+ }
+ }
else
possible = setup_possible_cpus;

Linus Torvalds

unread,
Jan 12, 2010, 10:30:02 AM1/12/10
to

On Tue, 12 Jan 2010, Yinghai Lu wrote:
> >
> > Slightly more intelligent:
> >
> > �- Look at the ACPI socket count, and hey, if it says it might have more
> > � sockets - whether they are really hotplug or not, don't use flat mode,
> > � because we simply don't know. But do _not_ do some kind of DMI table to
> > � say one way or the other.
>
> that acpi could lie, for example, some system share one BIOS between 2
> socket/4 socket/8 sockets
> model. and BIOS could have bunch disabled entries in MADT. or MPTABLE.

That's fine. So it would mean that sometimes we'd use non-flat mode even
if we strictly didn't need to (because we _think_ that there could be four
sockets even though there is only one, and three are disabled). But things
would still work without any special cases.

> > And if it's _really_ important:
> >
> > �- if flat mode is so important that you want to enable it whenever
> > � possible, what about enabling/disabling it dynamically at CPU hotplug
> > � time? That does sound _very_ painful, but it's still better than having
> > � to maintain some list of all systems that can ever hot-plug.
>
> interesting, could be done.
> init_apic_ldr is called even for physical flat on 64 bit.
> could change apic on fly.

Quite frankly, while I suggested it as an option, I really suspect it's
too much complexity for very little real gain.

Say that you have only four cores, but the kernel decided that it can't
use logical flat APIC mode because it sees three disabled sockets and
thinks "ok, we may end up with a total of 16 cores if those sockets are
hotplugged". Is that such a disaster?

Realistically, do we really care? Do you have performance numbers that say
that logical flat mode is so important that we really _really_ want to use
it, even at the cost of nasty run-time complexity with having to
re-program the APIC setup entirely when going from 8->9 CPU's?

Linus

Valdis.K...@vt.edu

unread,
Jan 12, 2010, 11:20:02 AM1/12/10
to
On Mon, 11 Jan 2010 19:13:32 PST, Linus Torvalds said:

> - only use that flat apic mode when you _know_ that you absolutely will
> never have more than 8 cpu's. Ie when CONFIG_NR_CPUS <= 8 (or, with
> 1/3, when nr_cpu_ids <= 8) and/or when <= 8 CPU's were detected, and
> CPU hotplug is disabled entirely.

OK, I'll bite - how do you build an X86-64 kernel that doesn't have
CONFIG_HOTPLUG_CPU selected? Try as I might, even if I have PM_SLEEP=n,
PM_SLEEP_SMP insists on being set, and then selecting HOTPLUG_SMP. For the
record, I do *not* need/desire S2R, S2D, 'suspend', or similar functionality.

Is there some subtle reason why PM_SLEEP_SMP has to be on even without PM_SLEEP?

Linus Torvalds

unread,
Jan 12, 2010, 11:30:02 AM1/12/10
to

On Tue, 12 Jan 2010, Valdis.K...@vt.edu wrote:
>
> OK, I'll bite - how do you build an X86-64 kernel that doesn't have
> CONFIG_HOTPLUG_CPU selected? Try as I might, even if I have PM_SLEEP=n,
> PM_SLEEP_SMP insists on being set, and then selecting HOTPLUG_SMP.

If that is true, then there is some bug in the kconfig parser.
PM_SLEEP_SMP depends on PM_SLEEP, so with PM_SLEEP=n it should never be
set.

That said, regardless of any such problems, I do think that we should
think about splitting up HOTPLUG_CPU into two config options: one that
allows CPU's to be put to sleep (which is common, and needed for any
suspend/hibernate support), and one that actually has support for actual
physical hotplugging.

Valdis.K...@vt.edu

unread,
Jan 12, 2010, 12:20:03 PM1/12/10
to
On Tue, 12 Jan 2010 08:26:22 PST, Linus Torvalds said:
>
>
> On Tue, 12 Jan 2010, Valdis.K...@vt.edu wrote:
> >
> > OK, I'll bite - how do you build an X86-64 kernel that doesn't have
> > CONFIG_HOTPLUG_CPU selected? Try as I might, even if I have PM_SLEEP=n,
> > PM_SLEEP_SMP insists on being set, and then selecting HOTPLUG_SMP.
>
> If that is true, then there is some bug in the kconfig parser.
> PM_SLEEP_SMP depends on PM_SLEEP, so with PM_SLEEP=n it should never be
> set.

So now I go back and check, and it *was* possible to get a PM_SLEEP_SMP=n.
Apparently in my previous attempts, I tried turning stuff off and PM_SLEEP_SMP
stayed on just like this time as long as I was puttering around in menuconfig.
But turning it off, *exiting menuconfig*, and then re-starting menuconfig made
it work. Weird. It seems like if something does a 'select' on something
that isn't a visible symbol, and the symbol gets toggled, the selects
aren't redriven - and since it's not a visible symbol, you can't toggle it
yourself. But saving and restarting menuconfig forces a refresh and things
start acting right. Adding Roman and the kbuild list to the cc:

And turning off PM_SLEEP and HOTPLUG_CPU ended up saving a chunk of memory:

Before:
% size vmlinux
text data bss dec hex filename
8964445 1377200 6094320 16435965 facafd vmlinux

After:
% size vmlinux
text data bss dec hex filename
8889523 1378768 6089648 16357939 f99a33 vmlinux

Suresh Siddha

unread,
Jan 12, 2010, 1:00:01 PM1/12/10
to
On Tue, 2010-01-12 at 07:19 -0800, Linus Torvalds wrote:
> On Tue, 12 Jan 2010, Yinghai Lu wrote:
> > > And if it's _really_ important:
> > >
> > > - if flat mode is so important that you want to enable it whenever
> > > possible, what about enabling/disabling it dynamically at CPU hotplug
> > > time? That does sound _very_ painful, but it's still better than having
> > > to maintain some list of all systems that can ever hot-plug.
> >
> > interesting, could be done.
> > init_apic_ldr is called even for physical flat on 64 bit.
> > could change apic on fly.
>
> Quite frankly, while I suggested it as an option, I really suspect it's
> too much complexity for very little real gain.

I agree.

> Say that you have only four cores, but the kernel decided that it can't
> use logical flat APIC mode because it sees three disabled sockets and
> thinks "ok, we may end up with a total of 16 cores if those sockets are
> hotplugged". Is that such a disaster?
>
> Realistically, do we really care? Do you have performance numbers that say
> that logical flat mode is so important that we really _really_ want to use
> it,

We had some customers in the past who wanted to use logical flat mode
when there are only 8 logical cpus mainly because they can use chipset
based interrupt routing. I think in one case, they wanted to use HW's
round-robin algorithm so that the interrupt load was uniformly
distributed to all the logical cpu's etc. This is probably fine if all
the logical cpu's are in the same socket (/under same memory
controller). But this might be a bad idea if those 8 logical cpu's are
spread across different sockets etc.

Also, sending IPI's becomes easier as we can target multiple logical
cpu's in the logical IPI destination mask etc.

> even at the cost of nasty run-time complexity with having to
> re-program the APIC setup entirely when going from 8->9 CPU's?

No. I don't think it is worth it. As we have more and more cores, flat
mode usage will reduce and perhaps will remain mainly for
netbooks/laptops (before we have > 8 logical cpus in that space
aswell...). Also future generations will start supporting x2apic, where
we can use x2apic cluster mode.

For now, I think we should just make sure that for smaller HW configs
like laptops/desktops we should use flat mode when we have no more than
8 logical cpu's and use physical mode when there is a potential of
supporting more than 8 cpu's.

thanks,
suresh

Yinghai Lu

unread,
Jan 12, 2010, 1:20:03 PM1/12/10
to

ok let stay with option 1.

and would like to use DMI to blacklist those systems that do need treat disabled
cpus MADT as hotplug cpus.

YH

Suresh Siddha

unread,
Jan 12, 2010, 1:30:01 PM1/12/10
to
On Tue, 2010-01-12 at 10:13 -0800, Yinghai Lu wrote:
> ok let stay with option 1.
>
> and would like to use DMI to blacklist those systems that do need treat disabled
> cpus MADT as hotplug cpus.

Yinghai, I don't think we have to worry about disabled cpu's etc using
DMI etc. If we really come across such a system, they can use ACPI FADT
flags (ACPI_FADT_APIC_PHYSICAL) to specify that they need to use
physical mode.

thanks,
suresh

Yinghai Lu

unread,
Jan 12, 2010, 2:20:03 PM1/12/10
to
On Tue, Jan 12, 2010 at 10:24 AM, Suresh Siddha
<suresh....@intel.com> wrote:
> On Tue, 2010-01-12 at 10:13 -0800, Yinghai Lu wrote:
>> ok let stay with option 1.
>>
>> and would like to use DMI to blacklist those systems that do need treat disabled
>> cpus MADT as hotplug cpus.
>
> Yinghai, I don't think we have to worry about disabled cpu's etc using
> DMI etc. If we really come across such a system, they can use ACPI FADT
> flags (ACPI_FADT_APIC_PHYSICAL) to specify that they need to use
> physical mode.

i want other way.

1. after use nr_cpu_ids instead of num_processors to decide if we need
switch to physflat.
some systems that disabled cpus entries that will use physflat even
those system doesn't support
CPU hotplug and could use logical flat.
2. those systems are several model (2 sockets or 4 sockets or 8
sockets) but share one BIOS, and BIOS guys are
too lazy to remove the disabled entries.
3. so I want to use DMI list to state that those system doesn't need
to treat those disabled cpu as hot plug cpu.
then we could use logical flat with them.

YH

H. Peter Anvin

unread,
Jan 12, 2010, 6:00:02 PM1/12/10
to
On 01/12/2010 12:27 AM, Ananth N Mavinakayanahalli wrote:
> On Mon, Jan 11, 2010 at 06:48:01PM -0800, Yinghai Lu wrote:
>
>> not sure it works again, could be bios fix the irq routing dest ?
>
> Nope, it doesn't. I applied this patchset.. no luck.

Okay, I have been monitoring this discussion, but I would like to make
sure I have understood all the relevant details:

1. The original patch is already reverted in Linus' tree.

2. The Intel/AMD thing is likely to be a red herring; specifically it's
a proxy for some other platform difference.

3. There is at least one platform ("an IBM platform with two quad-core
Xeon X7350 CPUs" -- which platform?) for which the logical
destination mode fails even though it should have been supported.
Currently there is no known workaround for this platform other than
forcing physical mode on this machine, which is what the current
code does, for valid or invalid reasons.

It would be good to clean up this code for .34, and I would really like
to know *which* platform this is; furthermore, Ananth, if you could send
as much technical information on this platform as possible including DMI
and lspci dumps I would appreciate it.

Furthermore, is this a production or preproduction system?

-hpa

Ananth N Mavinakayanahalli

unread,
Jan 13, 2010, 12:00:02 AM1/13/10
to
On Tue, Jan 12, 2010 at 02:50:58PM -0800, H. Peter Anvin wrote:
> On 01/12/2010 12:27 AM, Ananth N Mavinakayanahalli wrote:
> > On Mon, Jan 11, 2010 at 06:48:01PM -0800, Yinghai Lu wrote:
> >
> >> not sure it works again, could be bios fix the irq routing dest ?
> >
> > Nope, it doesn't. I applied this patchset.. no luck.

Hi Peter,

> Okay, I have been monitoring this discussion, but I would like to make
> sure I have understood all the relevant details:
>
> 1. The original patch is already reverted in Linus' tree.
>
> 2. The Intel/AMD thing is likely to be a red herring; specifically it's
> a proxy for some other platform difference.
>
> 3. There is at least one platform ("an IBM platform with two quad-core
> Xeon X7350 CPUs" -- which platform?) for which the logical
> destination mode fails even though it should have been supported.
> Currently there is no known workaround for this platform other than
> forcing physical mode on this machine, which is what the current
> code does, for valid or invalid reasons.

The machine in question is has 2 quad-core Tigerton processors, with a
provision to upgrade to 4 processors.



> It would be good to clean up this code for .34, and I would really like
> to know *which* platform this is; furthermore, Ananth, if you could send
> as much technical information on this platform as possible including DMI
> and lspci dumps I would appreciate it.

As Suresh cited in another email,
http://www.redbooks.ibm.com/redbooks/pdfs/sg247630.pdf has more
information about the system. The one I have access to is a 7141-4RA.

[1] is the lspci output.
[2] is the dmidecode output.

Chris McDermott, on cc should be able to provide more information about
the platform, etc.

> Furthermore, is this a production or preproduction system?

This is a System x3850 M2 and is Generally Available.

Ananth

--------
[1] lspci output:

00:1c.0 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 1 (rev 01) (prog-if 00 [Normal decode])
Flags: bus master, fast devsel, latency 0
Bus: primary=00, secondary=02, subordinate=02, sec-latency=0
Memory behind bridge: f2000000-f5ffffff
Capabilities: [40] Express Root Port (Slot-) IRQ 0
Capabilities: [80] Message Signalled Interrupts: 64bit- Queue=0/0 Enable+
Capabilities: [90] #0d [0000]
Capabilities: [a0] Power Management version 2
Capabilities: [100] Virtual Channel
Capabilities: [180] Unknown (5)

00:1d.0 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI Controller #1 (rev 01) (prog-if 00 [UHCI])
Subsystem: IBM Unknown device 0381
Flags: bus master, medium devsel, latency 0, IRQ 23
I/O ports at 3000 [size=32]

00:1d.1 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI Controller #2 (rev 01) (prog-if 00 [UHCI])
Subsystem: IBM Unknown device 0381
Flags: bus master, medium devsel, latency 0, IRQ 17
I/O ports at 3100 [size=32]

00:1d.2 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI Controller #3 (rev 01) (prog-if 00 [UHCI])
Subsystem: IBM Unknown device 0381
Flags: bus master, medium devsel, latency 0, IRQ 18
I/O ports at 3200 [size=32]

00:1d.3 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI Controller #4 (rev 01) (prog-if 00 [UHCI])
Subsystem: IBM Unknown device 0381
Flags: bus master, medium devsel, latency 0, IRQ 19
I/O ports at 3300 [size=32]

00:1d.7 USB Controller: Intel Corporation 82801G (ICH7 Family) USB2 EHCI Controller (rev 01) (prog-if 20 [EHCI])
Subsystem: IBM Unknown device 0381
Flags: bus master, medium devsel, latency 0, IRQ 23
Memory at f6100000 (32-bit, non-prefetchable) [size=1K]
Capabilities: [50] Power Management version 2
Capabilities: [58] Debug port

00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev e1) (prog-if 01 [Subtractive decode])
Flags: bus master, fast devsel, latency 0
Bus: primary=00, secondary=01, subordinate=01, sec-latency=32
I/O behind bridge: 00002000-00002fff
Memory behind bridge: f6000000-f60fffff
Prefetchable memory behind bridge: 00000000e8000000-00000000eff00000
Capabilities: [50] #0d [0000]

00:1f.0 ISA bridge: Intel Corporation 82801GB/GR (ICH7 Family) LPC Interface Bridge (rev 01)
Subsystem: IBM Unknown device 0381
Flags: bus master, medium devsel, latency 0
Capabilities: [e0] Vendor Specific Information

00:1f.1 IDE interface: Intel Corporation 82801G (ICH7 Family) IDE Controller (rev 01) (prog-if 8a [Master SecP PriP])
Subsystem: IBM Unknown device 0381
Flags: bus master, medium devsel, latency 0
I/O ports at 01f0 [size=8]
I/O ports at 03f4 [size=1]
I/O ports at 0170 [size=8]
I/O ports at 0374 [size=1]
I/O ports at 0700 [size=16]

01:00.0 VGA compatible controller: ATI Technologies Inc ES1000 (rev 02) (prog-if 00 [VGA controller])
Subsystem: IBM Unknown device 0319
Flags: bus master, stepping, medium devsel, latency 240, IRQ 3
Memory at e8000000 (32-bit, prefetchable) [size=128M]
I/O ports at 2000 [size=256]
Memory at f6020000 (32-bit, non-prefetchable) [size=64K]
[virtual] Expansion ROM at f6000000 [disabled] [size=128K]
Capabilities: [50] Power Management version 2

02:00.0 Ethernet controller: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 01)
Subsystem: IBM Unknown device 037c
Flags: bus master, fast devsel, latency 0, IRQ 102
Memory at f2000000 (64-bit, non-prefetchable) [size=32M]
Capabilities: [48] Power Management version 3
Capabilities: [50] Vital Product Data
Capabilities: [58] Message Signalled Interrupts: 64bit+ Queue=0/3 Enable+
Capabilities: [a0] MSI-X: Enable- Mask- TabSize=8
Capabilities: [ac] Express Endpoint IRQ 0
Capabilities: [100] Device Serial Number b4-66-36-fe-ff-64-1a-00
Capabilities: [110] Advanced Error Reporting
Capabilities: [150] Power Budgeting
Capabilities: [160] Virtual Channel

02:00.1 Ethernet controller: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 01)
Subsystem: IBM Unknown device 037c
Flags: bus master, fast devsel, latency 0, IRQ 17
Memory at f4000000 (64-bit, non-prefetchable) [size=32M]
Capabilities: [48] Power Management version 3
Capabilities: [50] Vital Product Data
Capabilities: [58] Message Signalled Interrupts: 64bit+ Queue=0/3 Enable-
Capabilities: [a0] MSI-X: Enable- Mask- TabSize=8
Capabilities: [ac] Express Endpoint IRQ 0
Capabilities: [100] Device Serial Number b6-66-36-fe-ff-64-1a-00
Capabilities: [110] Advanced Error Reporting
Capabilities: [150] Power Budgeting
Capabilities: [160] Virtual Channel

03:00.0 PCI bridge: IBM CalIOC2 PCI-E Root Port (rev 01) (prog-if 01 [Subtractive decode])
Flags: bus master, fast devsel, latency 0
Bus: primary=03, secondary=04, subordinate=04, sec-latency=0
Prefetchable memory behind bridge: 00000000e0000000-00000000e0000000
Capabilities: [40] Power Management version 3
Capabilities: [80] Express Root Port (Slot-) IRQ 0
Capabilities: [100] Advanced Error Reporting

04:00.0 RAID bus controller: LSI Logic / Symbios Logic MegaRAID SAS 1078 (rev 03)
Subsystem: IBM MegaRAID SAS PCI Express ROMB
Flags: bus master, fast devsel, latency 0, IRQ 46
Memory at f6200000 (64-bit, non-prefetchable) [size=256K]
I/O ports at 3400 [size=256]
Memory at f6240000 (64-bit, non-prefetchable) [size=256K]
[virtual] Expansion ROM at e0000000 [disabled] [size=128K]
Capabilities: [b0] Express Endpoint IRQ 0
Capabilities: [c4] Message Signalled Interrupts: 64bit+ Queue=0/2 Enable-
Capabilities: [d4] MSI-X: Enable- Mask- TabSize=4
Capabilities: [e0] Power Management version 2
Capabilities: [ec] Vital Product Data
Capabilities: [100] Power Budgeting

05:00.0 PCI bridge: IBM CalIOC2 PCI-E Root Port (rev 01) (prog-if 01 [Subtractive decode])
Flags: bus master, fast devsel, latency 0
Bus: primary=05, secondary=06, subordinate=0a, sec-latency=0
Capabilities: [40] Power Management version 3
Capabilities: [80] Express Root Port (Slot+) IRQ 0
Capabilities: [100] Advanced Error Reporting

0b:00.0 PCI bridge: IBM CalIOC2 PCI-E Root Port (rev 01) (prog-if 01 [Subtractive decode])
Flags: bus master, fast devsel, latency 0
Bus: primary=0b, secondary=0c, subordinate=10, sec-latency=0
I/O behind bridge: 00001000-00001fff
Memory behind bridge: e0200000-e03fffff
Prefetchable memory behind bridge: 00000000e0400000-00000000e0500000
Capabilities: [40] Power Management version 3
Capabilities: [80] Express Root Port (Slot+) IRQ 0
Capabilities: [100] Advanced Error Reporting

11:00.0 PCI bridge: IBM CalIOC2 PCI-E Root Port (rev 01) (prog-if 01 [Subtractive decode])
Flags: bus master, fast devsel, latency 0
Bus: primary=11, secondary=12, subordinate=16, sec-latency=0
I/O behind bridge: 00004000-00004fff
Memory behind bridge: e0600000-e07fffff
Prefetchable memory behind bridge: 00000000e0800000-00000000e0900000
Capabilities: [40] Power Management version 3
Capabilities: [80] Express Root Port (Slot+) IRQ 0
Capabilities: [100] Advanced Error Reporting

17:00.0 PCI bridge: IBM CalIOC2 PCI-E Root Port (rev 01) (prog-if 01 [Subtractive decode])
Flags: bus master, fast devsel, latency 0
Bus: primary=17, secondary=18, subordinate=1c, sec-latency=0
Capabilities: [40] Power Management version 3
Capabilities: [80] Express Root Port (Slot+) IRQ 0
Capabilities: [100] Advanced Error Reporting

1d:00.0 PCI bridge: IBM CalIOC2 PCI-E Root Port (rev 01) (prog-if 01 [Subtractive decode])
Flags: bus master, fast devsel, latency 0
Bus: primary=1d, secondary=1e, subordinate=22, sec-latency=0
Prefetchable memory behind bridge: 00000000e0100000-00000000e0100000
Capabilities: [40] Power Management version 3
Capabilities: [80] Express Root Port (Slot+) IRQ 0
Capabilities: [100] Advanced Error Reporting

1e:00.0 Ethernet controller: Intel Corporation 82571EB Gigabit Ethernet Controller (rev 06)
Subsystem: Intel Corporation PRO/1000 PT Dual Port Server Adapter
Flags: bus master, fast devsel, latency 0, IRQ 100
Memory at f6320000 (32-bit, non-prefetchable) [size=128K]
Memory at f6340000 (32-bit, non-prefetchable) [size=128K]
I/O ports at 3500 [size=32]
[virtual] Expansion ROM at e0100000 [disabled] [size=128K]
Capabilities: [c8] Power Management version 2
Capabilities: [d0] Message Signalled Interrupts: 64bit+ Queue=0/0 Enable+
Capabilities: [e0] Express Endpoint IRQ 0
Capabilities: [100] Advanced Error Reporting
Capabilities: [140] Device Serial Number cc-3b-73-ff-ff-17-15-00

1e:00.1 Ethernet controller: Intel Corporation 82571EB Gigabit Ethernet Controller (rev 06)
Subsystem: Intel Corporation PRO/1000 PT Dual Port Server Adapter
Flags: bus master, fast devsel, latency 0, IRQ 101
Memory at f6360000 (32-bit, non-prefetchable) [size=128K]
Memory at f6380000 (32-bit, non-prefetchable) [size=128K]
I/O ports at 3600 [size=32]
Capabilities: [c8] Power Management version 2
Capabilities: [d0] Message Signalled Interrupts: 64bit+ Queue=0/0 Enable+
Capabilities: [e0] Express Endpoint IRQ 0
Capabilities: [100] Advanced Error Reporting
Capabilities: [140] Device Serial Number cc-3b-73-ff-ff-17-15-00

23:00.0 PCI bridge: IBM CalIOC2 PCI-E Root Port (rev 01) (prog-if 01 [Subtractive decode])
Flags: bus master, fast devsel, latency 0
Bus: primary=23, secondary=24, subordinate=28, sec-latency=0
Capabilities: [40] Power Management version 3
Capabilities: [80] Express Root Port (Slot+) IRQ 0
Capabilities: [100] Advanced Error Reporting

29:00.0 PCI bridge: IBM CalIOC2 PCI-E Root Port (rev 01) (prog-if 01 [Subtractive decode])
Flags: bus master, fast devsel, latency 0
Bus: primary=29, secondary=2a, subordinate=2e, sec-latency=0
Capabilities: [40] Power Management version 3
Capabilities: [80] Express Root Port (Slot+) IRQ 0
Capabilities: [100] Advanced Error Reporting


--------
[2] dmidecode output:

# dmidecode 2.9
SMBIOS 2.4 present.
82 structures occupying 4995 bytes.
Table at 0xBFF57B40.

Handle 0x0000, DMI type 0, 24 bytes
BIOS Information
Vendor: IBM
Version: -[A3E148AUS-1.07]-
Release Date: 11/05/2008
Address: 0xF01E0
Runtime Size: 65056 bytes
ROM Size: 8192 kB
Characteristics:
PCI is supported
BIOS is upgradeable
BIOS shadowing is allowed
Boot from CD is supported
Selectable boot is supported
Japanese floppy for NEC 9800 1.2 MB is supported (int 13h)
Japanese floppy for Toshiba 1.2 MB is supported (int 13h)
5.25"/360 KB floppy services are supported (int 13h)
5.25"/1.2 MB floppy services are supported (int 13h)
3.5"/720 KB floppy services are supported (int 13h)
3.5"/2.88 MB floppy services are supported (int 13h)
Print screen service is supported (int 5h)
8042 keyboard services are supported (int 9h)
Serial services are supported (int 14h)
Printer services are supported (int 17h)
CGA/mono video services are supported (int 10h)
ACPI is supported
USB legacy is supported
I2O boot is supported
LS-120 boot is supported
Function key-initiated network boot is supported
Targeted content distribution is supported
BIOS Revision: 1.7

Handle 0x0001, DMI type 1, 27 bytes
System Information
Manufacturer: IBM
Product Name: IBM 3850 M2 / x3950 M2 -[71414RA]-
Version: Not Specified
Serial Number: 99B0888
UUID: 40AA2C62-7B67-B601-759D-001A643666B4
Wake-up Type: Power Switch
SKU Number: Not Specified
Family: Not Specified

Handle 0x0002, DMI type 2, 95 bytes
Base Board Information
Manufacturer: IBM
Product Name: Node1 Processor Card
Version: Not Specified
Serial Number: Not Specified
Asset Tag: Not Specified
Features:
Board is a hosting board
Board is replaceable
Location In Chassis: Node1, Bottom Front
Chassis Handle: 0x003A
Type: Processor Module
Contained Object Handles: 20
0x0042
0x0043
0x0044
0x0045
0x0046
0x0047
0x0048
0x0049
0x004A
0x004B
0x004C
0x004D
0x00A2
0x00A3
0x00A4
0x00A5
0x00C2
0x00C3
0x00C4
0x0274

Handle 0x0003, DMI type 2, 95 bytes
Base Board Information
Manufacturer: IBM
Product Name: Node1 PCI I/O Planar
Version: Not Specified
Serial Number: Not Specified
Asset Tag: Not Specified
Features:
Board is removable
Board is replaceable
Location In Chassis: Node1, Rear Center
Chassis Handle: 0x003A
Type: I/O Module
Contained Object Handles: 19
0x00C5
0x00C6
0x00C7
0x00C8
0x00C9
0x00CA
0x00CB
0x00CC
0x00CD
0x00CE
0x00CF
0x012B
0x012C
0x012D
0x012E
0x012F
0x0130
0x0131
0x0163

Handle 0x0005, DMI type 2, 31 bytes
Base Board Information
Manufacturer: IBM
Product Name: Node1 Memory Card1
Version: Not Specified
Serial Number: Not Specified
Asset Tag: Not Specified
Features:
Board requires at least one daughter board
Board is removable
Board is replaceable
Board is hot swappable
Location In Chassis: Node1, Rear Left 1st From Top
Chassis Handle: 0x003A
Type: Memory Module
Contained Object Handles: 8
0x0172
0x0173
0x0174
0x0175
0x0176
0x0177
0x0178
0x0179

Handle 0x0006, DMI type 2, 31 bytes
Base Board Information
Manufacturer: IBM
Product Name: Node1 Memory Card2
Version: Not Specified
Serial Number: Not Specified
Asset Tag: Not Specified
Features:
Board requires at least one daughter board
Board is removable
Board is replaceable
Board is hot swappable
Location In Chassis: Node1, Rear Left 2nd From Top
Chassis Handle: 0x003A
Type: Memory Module
Contained Object Handles: 8
0x017A
0x017B
0x017C
0x017D
0x017E
0x017F
0x0180
0x0181

Handle 0x0007, DMI type 2, 31 bytes
Base Board Information
Manufacturer: IBM
Product Name: Node1 Memory Card3
Version: Not Specified
Serial Number: Not Specified
Asset Tag: Not Specified
Features:
Board requires at least one daughter board
Board is removable
Board is replaceable
Board is hot swappable
Location In Chassis: Node1, Rear Left 3rd From Top
Chassis Handle: 0x003A
Type: Memory Module
Contained Object Handles: 8
0x0182
0x0183
0x0184
0x0185
0x0186
0x0187
0x0188
0x0189

Handle 0x0008, DMI type 2, 31 bytes
Base Board Information
Manufacturer: IBM
Product Name: Node1 Memory Card4
Version: Not Specified
Serial Number: Not Specified
Asset Tag: Not Specified
Features:
Board requires at least one daughter board
Board is removable
Board is replaceable
Board is hot swappable
Location In Chassis: Node1, Rear Left 4th From Top
Chassis Handle: 0x003A
Type: Memory Module
Contained Object Handles: 8
0x018A
0x018B
0x018C
0x018D
0x018E
0x018F
0x0190
0x0191

Handle 0x003A, DMI type 3, 13 bytes
Chassis Information
Manufacturer: IBM
Type: Main Server Chassis
Lock: Not Present
Version: Not Specified
Serial Number: Not Specified
Asset Tag:
Boot-up State: Safe
Power Supply State: Unknown
Thermal State: Unknown
Security Status: Unknown

Handle 0x0046, DMI type 7, 19 bytes
Cache Information
Socket Designation: Internal L2 Cache
Configuration: Enabled, Not Socketed, Level 2
Operational Mode: Write Back
Location: Internal
Installed Size: 8192 KB
Maximum Size: 4096 KB
Supported SRAM Types:
Burst
Installed SRAM Type: Burst
Speed: Unknown
Error Correction Type: Single-bit ECC
System Type: Unified
Associativity: 8-way Set-associative

Handle 0x0049, DMI type 7, 19 bytes
Cache Information
Socket Designation: Internal L2 Cache
Configuration: Enabled, Not Socketed, Level 2
Operational Mode: Write Back
Location: Internal
Installed Size: 8192 KB
Maximum Size: 4096 KB
Supported SRAM Types:
Burst
Installed SRAM Type: Burst
Speed: Unknown
Error Correction Type: Single-bit ECC
System Type: Unified
Associativity: 8-way Set-associative

Handle 0x00A2, DMI type 4, 40 bytes
Processor Information
Socket Designation: Node 1 CPU 3
Type: Central Processor
Family: Xeon MP
Manufacturer: GenuineIntel
ID: 00 00 00 00 00 00 00 00
Signature: Type 0, Family 0, Model 0, Stepping 0
Flags: None
Version: Intel Xeon MP Quad-Core
Voltage: 1.5 V
External Clock: Unknown
Max Speed: 4000 MHz
Current Speed: Unknown
Status: Unpopulated
Upgrade: ZIF Socket
L1 Cache Handle: 0x0042
L2 Cache Handle: 0x0043
L3 Cache Handle: 0x0044
Serial Number: Not Specified
Asset Tag: Not Specified
Part Number: Not Specified
Characteristics:
64-bit capable

Handle 0x00A3, DMI type 4, 40 bytes
Processor Information
Socket Designation: Node 1 CPU 1
Type: Central Processor
Family: Xeon MP
Manufacturer: GenuineIntel
ID: FB 06 00 00 00 00 00 00
Signature: Type 0, Family 6, Model 15, Stepping 11
Flags: None
Version: Intel Xeon MP
Voltage: 1.5 V
External Clock: 133 MHz
Max Speed: 4000 MHz
Current Speed: 2933 MHz
Status: Populated, Enabled
Upgrade: ZIF Socket
L1 Cache Handle: 0x0045
L2 Cache Handle: 0x0046
L3 Cache Handle: 0x0047
Serial Number: Not Specified
Asset Tag: Not Specified
Part Number: Not Specified
Core Count: 4
Core Enabled: 4
Thread Count: 4
Characteristics:
64-bit capable

Handle 0x00A4, DMI type 4, 40 bytes
Processor Information
Socket Designation: Node 1 CPU 2
Type: Central Processor
Family: Xeon MP
Manufacturer: GenuineIntel
ID: FB 06 00 00 00 00 00 00
Signature: Type 0, Family 6, Model 15, Stepping 11
Flags: None
Version: Intel Xeon MP
Voltage: 1.5 V
External Clock: 133 MHz
Max Speed: 4000 MHz
Current Speed: 2933 MHz
Status: Populated, Enabled
Upgrade: ZIF Socket
L1 Cache Handle: 0x0048
L2 Cache Handle: 0x0049
L3 Cache Handle: 0x004A
Serial Number: Not Specified
Asset Tag: Not Specified
Part Number: Not Specified
Core Count: 4
Core Enabled: 4
Thread Count: 4
Characteristics:
64-bit capable

Handle 0x00A5, DMI type 4, 40 bytes
Processor Information
Socket Designation: Node 1 CPU 4
Type: Central Processor
Family: Xeon MP
Manufacturer: GenuineIntel
ID: 00 00 00 00 00 00 00 00
Signature: Type 0, Family 0, Model 0, Stepping 0
Flags: None
Version: Intel Xeon MP Quad-Core
Voltage: 1.5 V
External Clock: Unknown
Max Speed: 4000 MHz
Current Speed: Unknown
Status: Unpopulated
Upgrade: ZIF Socket
L1 Cache Handle: 0x004B
L2 Cache Handle: 0x004C
L3 Cache Handle: 0x004D
Serial Number: Not Specified
Asset Tag: Not Specified
Part Number: Not Specified
Characteristics:
64-bit capable

Handle 0x00C2, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Not Specified
Internal Connector Type: None
External Reference Designator: Scalability 1
External Connector Type: Proprietary
Port Type: Other

Handle 0x00C3, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Not Specified
Internal Connector Type: None
External Reference Designator: Scalability 2
External Connector Type: Proprietary
Port Type: Other

Handle 0x00C4, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Not Specified
Internal Connector Type: None
External Reference Designator: Scalability 3
External Connector Type: Proprietary
Port Type: Other

Handle 0x00C5, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Not Specified
Internal Connector Type: None
External Reference Designator: 10/100/1000 Ethernet (port A)
External Connector Type: RJ-45
Port Type: Network Port

Handle 0x00C6, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Not Specified
Internal Connector Type: None
External Reference Designator: 10/100/1000 Ethernet (port B)
External Connector Type: RJ-45
Port Type: Network Port

Handle 0x00C7, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Not Specified
Internal Connector Type: None
External Reference Designator: USB 1
External Connector Type: Access Bus (USB)
Port Type: USB

Handle 0x00C8, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Not Specified
Internal Connector Type: None
External Reference Designator: USB 2
External Connector Type: Access Bus (USB)
Port Type: USB

Handle 0x00C9, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Not Specified
Internal Connector Type: None
External Reference Designator: USB 3
External Connector Type: Access Bus (USB)
Port Type: USB

Handle 0x00CA, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Not Specified
Internal Connector Type: None
External Reference Designator: Video
External Connector Type: DB-15 female
Port Type: Video Port

Handle 0x00CB, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Diskette/CDROM
Internal Connector Type: Other
External Reference Designator: Not Specified
External Connector Type: None
Port Type: Other

Handle 0x00CC, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Internal SAS SCSI
Internal Connector Type: Other
External Reference Designator: Not Specified
External Connector Type: None
Port Type: Other

Handle 0x00CD, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: External SAS SCSI
Internal Connector Type: Other
External Reference Designator: Not Specified
External Connector Type: None
Port Type: Other

Handle 0x00CE, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Not Specified
Internal Connector Type: None
External Reference Designator: Serial-A / System Management
External Connector Type: DB-9 male
Port Type: Serial Port 16550A Compatible

Handle 0x00CF, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Not Specified
Internal Connector Type: None
External Reference Designator: RSA Ethernet
External Connector Type: RJ-45
Port Type: Network Port

Handle 0x00D0, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Not Specified
Internal Connector Type: None
External Reference Designator: Scalability 1
External Connector Type: Proprietary
Port Type: Other

Handle 0x00D1, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Not Specified
Internal Connector Type: None
External Reference Designator: Scalability 2
External Connector Type: Proprietary
Port Type: Other

Handle 0x00D2, DMI type 8, 9 bytes
Port Connector Information
Internal Reference Designator: Not Specified
Internal Connector Type: None
External Reference Designator: Scalability 3
External Connector Type: Proprietary
Port Type: Other

Handle 0x012B, DMI type 9, 13 bytes
System Slot Information
Designation: Node1 PCI-Express Slot 1
Type: x8 PCI Express
Current Usage: Available
Length: Long
ID: 1
Characteristics:
3.3 V is provided
PME signal is supported

Handle 0x012C, DMI type 9, 13 bytes
System Slot Information
Designation: Node1 PCI-Express Slot 2
Type: x8 PCI Express
Current Usage: In Use
Length: Long
ID: 2
Characteristics:
3.3 V is provided
PME signal is supported

Handle 0x012D, DMI type 9, 13 bytes
System Slot Information
Designation: Node1 PCI-Express Slot 3
Type: x8 PCI Express
Current Usage: Available
Length: Long
ID: 3
Characteristics:
3.3 V is provided
PME signal is supported

Handle 0x012E, DMI type 9, 13 bytes
System Slot Information
Designation: Node1 PCI-Express Slot 4
Type: x8 PCI Express
Current Usage: Available
Length: Long
ID: 4
Characteristics:
3.3 V is provided
PME signal is supported

Handle 0x012F, DMI type 9, 13 bytes
System Slot Information
Designation: Node1 PCI-Express Slot 5
Type: x8 PCI Express
Current Usage: Available
Length: Long
ID: 5
Characteristics:
3.3 V is provided
PME signal is supported

Handle 0x0130, DMI type 9, 13 bytes
System Slot Information
Designation: Node1 PCI-Express Slot 6
Type: x8 PCI Express
Current Usage: Available
Length: Long
ID: 6
Characteristics:
3.3 V is provided
PME signal is supported
Hot-plug devices are supported

Handle 0x0131, DMI type 9, 13 bytes
System Slot Information
Designation: Node1 PCI-Express Slot 7
Type: x8 PCI Express
Current Usage: Available
Length: Long
ID: 7
Characteristics:
3.3 V is provided
PME signal is supported
Hot-plug devices are supported

Handle 0x016B, DMI type 11, 5 bytes
OEM Strings
String 1: IBM Preboot Diagnostics (DSA) 1.00.55 -[A3YT55AUS-1.00.55]-
String 2: IBM CRTM Code 1.00 -[A3CP08AUS-1.00]-
String 3: IBM Backup CRTM Code 1.00 -[A3CP08AUS-1.00]-
String 4: IBM BaseBoard Management Controller -[A3BT50A ]-
String 5: IBM Remote Supervisor Adapter -[A3EP29BUS]-
String 6: IBM Processor Card FPGA Version 001.006
String 7: IBM PCI I/O Planar FPGA Version 001.004

Handle 0x016C, DMI type 12, 5 bytes
System Configuration Options
Option 1: J33-Power on Password Override jumper
Option 2: Changing the position of this jumper bypasses the
Option 3: power-on password checking on the next power-on.
Option 4: You do not need to move the jumper back to the
Option 5: default position after the password is overridden.
Option 6: Changing the position of this jumper does not affect
Option 7: the administrator password check if an administrator
Option 8: password is set.

Handle 0x016D, DMI type 12, 5 bytes
System Configuration Options
Option 1: J17-Flash ROM page swap jumper
Option 2: Primary-on pins 1-2, Backup-on pins 2-3
Option 3: The Primary(default) position is a jumper installed
Option 4: on pins marked by a white block under the pins.
Option 5: Changing the position of this jumper will change
Option 6: which of the two pages of flash ROM is used when
Option 7: the system is started.

Handle 0x016E, DMI type 12, 5 bytes
System Configuration Options
Option 1: J16- Force Power On Jumper
Option 2: Pin 1-2 Force Power On disabled
Option 3: Pin 2-3 Force Power On enabled

Handle 0x016F, DMI type 12, 5 bytes
System Configuration Options
Option 1: J21- BMC Disable Jumper
Option 2: Pin 1-2 BMC Enabled
Option 3: Pin 2-3 BMC Disabled

Handle 0x0170, DMI type 13, 22 bytes
BIOS Language Information
Installable Languages: 1
en|US|iso8859-1
Currently Installed Language: en|US|iso8859-1

Handle 0x0171, DMI type 16, 15 bytes
Physical Memory Array
Location: Proprietary Add-on Card
Use: System Memory
Error Correction Type: Multi-bit ECC
Maximum Capacity: Unknown
Error Information Handle: Not Provided
Number Of Devices: 32

Handle 0x0172, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 1024 MB
Form Factor: DIMM
Set: 1
Locator: DIMM1
Bank Locator: Node1/Bank1/MemCard1
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0173, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 1024 MB
Form Factor: DIMM
Set: 1
Locator: DIMM5
Bank Locator: Node1/Bank1/MemCard1
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0174, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 2048 MB
Form Factor: DIMM
Set: 2
Locator: DIMM2
Bank Locator: Node1/Bank2/MemCard1
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0175, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 2048 MB
Form Factor: DIMM
Set: 2
Locator: DIMM6
Bank Locator: Node1/Bank2/MemCard1
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0176, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 2048 MB
Form Factor: DIMM
Set: 3
Locator: DIMM3
Bank Locator: Node1/Bank3/MemCard1
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0177, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 2048 MB
Form Factor: DIMM
Set: 3
Locator: DIMM7
Bank Locator: Node1/Bank3/MemCard1
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0178, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: No Module Installed
Form Factor: DIMM
Set: 4
Locator: DIMM4
Bank Locator: Node1/Bank4/MemCard1
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0179, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: No Module Installed
Form Factor: DIMM
Set: 4
Locator: DIMM8
Bank Locator: Node1/Bank4/MemCard1
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x017A, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 1024 MB
Form Factor: DIMM
Set: 5
Locator: DIMM1
Bank Locator: Node1/Bank5/MemCard2
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x017B, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 1024 MB
Form Factor: DIMM
Set: 5
Locator: DIMM5
Bank Locator: Node1/Bank5/MemCard2
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x017C, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 2048 MB
Form Factor: DIMM
Set: 6
Locator: DIMM2
Bank Locator: Node1/Bank6/MemCard2
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x017D, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 2048 MB
Form Factor: DIMM
Set: 6
Locator: DIMM6
Bank Locator: Node1/Bank6/MemCard2
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x017E, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: No Module Installed
Form Factor: DIMM
Set: 7
Locator: DIMM3
Bank Locator: Node1/Bank7/MemCard2
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x017F, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: No Module Installed
Form Factor: DIMM
Set: 7
Locator: DIMM7
Bank Locator: Node1/Bank7/MemCard2
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0180, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: No Module Installed
Form Factor: DIMM
Set: 8
Locator: DIMM4
Bank Locator: Node1/Bank8/MemCard2
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0181, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: No Module Installed
Form Factor: DIMM
Set: 8
Locator: DIMM8
Bank Locator: Node1/Bank8/MemCard2
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0182, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 1024 MB
Form Factor: DIMM
Set: 9
Locator: DIMM1
Bank Locator: Node1/Bank9/MemCard3
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0183, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 1024 MB
Form Factor: DIMM
Set: 9
Locator: DIMM5
Bank Locator: Node1/Bank9/MemCard3
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0184, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 2048 MB
Form Factor: DIMM
Set: 10
Locator: DIMM2
Bank Locator: Node1/Bank10/MemCard3
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0185, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 2048 MB
Form Factor: DIMM
Set: 10
Locator: DIMM6
Bank Locator: Node1/Bank10/MemCard3
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0186, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: No Module Installed
Form Factor: DIMM
Set: 11
Locator: DIMM3
Bank Locator: Node1/Bank11/MemCard3
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0187, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: No Module Installed
Form Factor: DIMM
Set: 11
Locator: DIMM7
Bank Locator: Node1/Bank11/MemCard3
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0188, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: No Module Installed
Form Factor: DIMM
Set: 12
Locator: DIMM4
Bank Locator: Node1/Bank12/MemCard3
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0189, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: No Module Installed
Form Factor: DIMM
Set: 12
Locator: DIMM8
Bank Locator: Node1/Bank12/MemCard3
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x018A, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 1024 MB
Form Factor: DIMM
Set: 13
Locator: DIMM1
Bank Locator: Node1/Bank13/MemCard4
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x018B, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 1024 MB
Form Factor: DIMM
Set: 13
Locator: DIMM5
Bank Locator: Node1/Bank13/MemCard4
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x018C, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 2048 MB
Form Factor: DIMM
Set: 14
Locator: DIMM2
Bank Locator: Node1/Bank14/MemCard4
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x018D, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 2048 MB
Form Factor: DIMM
Set: 14
Locator: DIMM6
Bank Locator: Node1/Bank14/MemCard4
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x018E, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 2048 MB
Form Factor: DIMM
Set: 15
Locator: DIMM3
Bank Locator: Node1/Bank15/MemCard4
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x018F, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 2048 MB
Form Factor: DIMM
Set: 15
Locator: DIMM7
Bank Locator: Node1/Bank15/MemCard4
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0190, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: No Module Installed
Form Factor: DIMM
Set: 16
Locator: DIMM4
Bank Locator: Node1/Bank16/MemCard4
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0191, DMI type 17, 23 bytes
Memory Device
Array Handle: 0x0171
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: No Module Installed
Form Factor: DIMM
Set: 16
Locator: DIMM8
Bank Locator: Node1/Bank16/MemCard4
Type: DDR2
Type Detail: Synchronous
Speed: 533 MHz (1.9 ns)

Handle 0x0272, DMI type 19, 15 bytes
Memory Array Mapped Address
Starting Address: 0x00000000000
Ending Address: 0x007FFFFFFFF
Range Size: 32 GB
Physical Array Handle: 0x0171
Partition Width: 0

Handle 0x0273, DMI type 32, 11 bytes
System Boot Information
Status: No errors detected

Handle 0x0274, DMI type 38, 18 bytes
IPMI Device Information
Interface Type: KCS (Keyboard Control Style)
Specification Version: 2.0
I2C Slave Address: 0x10
NV Storage Device: Not Present
Base Address: 0x0000000000000CA8 (I/O)
Register Spacing: 32-bit Boundaries

Handle 0x027C, DMI type 127, 4 bytes
End Of Table

Yinghai Lu

unread,
Jan 15, 2010, 10:10:01 PM1/15/10
to
not sure it works again, could be bios fix the irq routing dest ?

tested that amd support logical flat too when cpus num <= 8 and even
bsp apic id > 8

so could remove vendor check...

Signed-off-by: Yinghai Lu <yin...@kernel.org>
---


arch/x86/kernel/apic/apic.c | 11 ++---------
arch/x86/kernel/apic/probe_64.c | 13 ++-----------
2 files changed, 4 insertions(+), 20 deletions(-)

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index aa57c07..c5f4906 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1898,15 +1898,8 @@ void __cpuinit generic_processor_info(int apicid, int version)


max_physical_apicid = apicid;

#ifdef CONFIG_X86_32
- switch (boot_cpu_data.x86_vendor) {
- case X86_VENDOR_INTEL:
- if (num_processors > 8)
- def_to_bigsmp = 1;
- break;
- case X86_VENDOR_AMD:
- if (max_physical_apicid >= 8)
- def_to_bigsmp = 1;
- }
+ if (num_processors > 8)
+ def_to_bigsmp = 1;
#endif

#if defined(CONFIG_SMP) || defined(CONFIG_X86_64)

diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c
index c4cbd30..0a428dd 100644
--- a/arch/x86/kernel/apic/probe_64.c
+++ b/arch/x86/kernel/apic/probe_64.c
@@ -67,17 +67,8 @@ void __init default_setup_apic_routing(void)


}
#endif

- if (apic == &apic_flat) {
- switch (boot_cpu_data.x86_vendor) {
- case X86_VENDOR_INTEL:
- if (num_processors > 8)
- apic = &apic_physflat;
- break;
- case X86_VENDOR_AMD:
- if (max_physical_apicid >= 8)
- apic = &apic_physflat;
- }
- }
+ if (apic == &apic_flat && num_processors > 8)
+ apic = &apic_physflat;

printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);

--

1.6.4.2

Yinghai Lu

unread,
Jan 15, 2010, 10:10:02 PM1/15/10
to
some systems that have disable cpus entries because same
BIOS will support 2 sockets and 4 sockets and more at
same time, BIOS just leave some disable entries, but
those system do not support cpu hotplug. we don't need
treat disabled_cpus as hotplug cpus.
so we can make nr_cpu_ids smaller and save more space
(pcpu data allocations), and could make some systems run
with logical flat instead of physical flat apic mode

-v2: change to black list instead

-v3: just remove that, and the one use possible_cpus= directly.

Signed-off-by: Yinghai Lu <yin...@kernel.org>
---

arch/x86/kernel/smpboot.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index f741c33..642440c 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1190,7 +1190,6 @@ early_param("possible_cpus", _setup_possible_cpus);
* - Ashok Raj
*
* Three ways to find out the number of additional hotplug CPUs:
- * - If the BIOS specified disabled CPUs in ACPI/mptables use that.
* - The user can overwrite it with possible_cpus=NUM
* - Otherwise don't reserve additional CPUs.
* We do this because additional CPUs waste a lot of memory.
@@ -1205,7 +1204,7 @@ __init void prefill_possible_map(void)
num_processors = 1;



if (setup_possible_cpus == -1)
- possible = num_processors + disabled_cpus;

+ possible = num_processors;
else
possible = setup_possible_cpus;

Yinghai Lu

unread,
Jan 15, 2010, 10:10:01 PM1/15/10
to
simplify setup_node_mem, do use bootmem from other node.
instead just find_e820_area in early_node_mem.

so we can keep the boundary between early_res and boot mem more clear.
and only call civertion one time instead of for all nodes.

Signed-off-by: Yinghai Lu <yin...@kernel.org>
---

arch/x86/kernel/setup.c | 1 +
arch/x86/mm/init_32.c | 1 -
arch/x86/mm/init_64.c | 3 +-
arch/x86/mm/numa_64.c | 62 +++++++++++++++-------------------------------
4 files changed, 22 insertions(+), 45 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f7b8b98..3ab0bf4 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -942,6 +942,7 @@ void __init setup_arch(char **cmdline_p)
#endif

initmem_init(0, max_pfn, acpi, k8);
+ early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT);

#ifdef CONFIG_X86_64
/*
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 9a0c258..2dccde0 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -764,7 +764,6 @@ static unsigned long __init setup_node_bootmem(int nodeid,
printk(KERN_INFO " node %d bootmap %08lx - %08lx\n",
nodeid, bootmap, bootmap + bootmap_size);
free_bootmem_with_active_regions(nodeid, end_pfn);
- early_res_to_bootmem(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);

return bootmap + bootmap_size;
}
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 5198b9b..1ea79ad 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -578,13 +578,12 @@ void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,
PAGE_SIZE);
if (bootmap == -1L)
panic("Cannot find bootmem map of size %ld\n", bootmap_size);
+ reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP");
/* don't touch min_low_pfn */
bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap >> PAGE_SHIFT,
0, end_pfn);
e820_register_active_regions(0, start_pfn, end_pfn);
free_bootmem_with_active_regions(0, end_pfn);
- early_res_to_bootmem(0, end_pfn<<PAGE_SHIFT);
- reserve_bootmem(bootmap, bootmap_size, BOOTMEM_DEFAULT);
}
#endif

diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 83bbc70..3232148 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -164,18 +164,21 @@ static void * __init early_node_mem(int nodeid, unsigned long start,
unsigned long align)
{
unsigned long mem = find_e820_area(start, end, size, align);
- void *ptr;

if (mem != -1L)
return __va(mem);

- ptr = __alloc_bootmem_nopanic(size, align, __pa(MAX_DMA_ADDRESS));
- if (ptr == NULL) {
- printk(KERN_ERR "Cannot find %lu bytes in node %d\n",
+
+ start = __pa(MAX_DMA_ADDRESS);
+ end = max_low_pfn_mapped << PAGE_SHIFT;
+ mem = find_e820_area(start, end, size, align);
+ if (mem != -1L)
+ return __va(mem);
+
+ printk(KERN_ERR "Cannot find %lu bytes in node %d\n",
size, nodeid);
- return NULL;
- }
- return ptr;
+
+ return NULL;
}

/* Initialize bootmem allocator for a node */
@@ -211,8 +214,12 @@ setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
if (node_data[nodeid] == NULL)
return;
nodedata_phys = __pa(node_data[nodeid]);
+ reserve_early(nodedata_phys, nodedata_phys + pgdat_size, "NODE_DATA");
printk(KERN_INFO " NODE_DATA [%016lx - %016lx]\n", nodedata_phys,
nodedata_phys + pgdat_size - 1);
+ nid = phys_to_nid(nodedata_phys);
+ if (nid != nodeid)
+ printk(KERN_INFO " NODE_DATA(%d) on node %d\n", nodeid, nid);

memset(NODE_DATA(nodeid), 0, sizeof(pg_data_t));
NODE_DATA(nodeid)->bdata = &bootmem_node_data[nodeid];
@@ -227,11 +234,7 @@ setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
* of alloc_bootmem, that could clash with reserved range
*/
bootmap_pages = bootmem_bootmap_pages(last_pfn - start_pfn);
- nid = phys_to_nid(nodedata_phys);
- if (nid == nodeid)
- bootmap_start = roundup(nodedata_phys + pgdat_size, PAGE_SIZE);
- else
- bootmap_start = roundup(start, PAGE_SIZE);
+ bootmap_start = roundup(nodedata_phys + pgdat_size, PAGE_SIZE);
/*
* SMP_CACHE_BYTES could be enough, but init_bootmem_node like
* to use that to align to PAGE_SIZE
@@ -239,18 +242,13 @@ setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
bootmap = early_node_mem(nodeid, bootmap_start, end,
bootmap_pages<<PAGE_SHIFT, PAGE_SIZE);
if (bootmap == NULL) {
- if (nodedata_phys < start || nodedata_phys >= end) {
- /*
- * only need to free it if it is from other node
- * bootmem
- */
- if (nid != nodeid)
- free_bootmem(nodedata_phys, pgdat_size);
- }
+ free_early(nodedata_phys, nodedata_phys + pgdat_size);
node_data[nodeid] = NULL;
return;
}
bootmap_start = __pa(bootmap);
+ reserve_early(bootmap_start, bootmap_start+(bootmap_pages<<PAGE_SHIFT),
+ "BOOTMAP");

bootmap_size = init_bootmem_node(NODE_DATA(nodeid),
bootmap_start >> PAGE_SHIFT,
@@ -259,31 +257,11 @@ setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
printk(KERN_INFO " bootmap [%016lx - %016lx] pages %lx\n",
bootmap_start, bootmap_start + bootmap_size - 1,
bootmap_pages);
-
- free_bootmem_with_active_regions(nodeid, end);
-
- /*
- * convert early reserve to bootmem reserve earlier
- * otherwise early_node_mem could use early reserved mem
- * on previous node
- */
- early_res_to_bootmem(start, end);
-
- /*
- * in some case early_node_mem could use alloc_bootmem
- * to get range on other node, don't reserve that again
- */
- if (nid != nodeid)
- printk(KERN_INFO " NODE_DATA(%d) on node %d\n", nodeid, nid);
- else
- reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys,
- pgdat_size, BOOTMEM_DEFAULT);
nid = phys_to_nid(bootmap_start);
if (nid != nodeid)
printk(KERN_INFO " bootmap(%d) on node %d\n", nodeid, nid);
- else
- reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start,
- bootmap_pages<<PAGE_SHIFT, BOOTMEM_DEFAULT);
+
+ free_bootmem_with_active_regions(nodeid, end);

node_set_online(nodeid);

Yinghai Lu

unread,
Jan 15, 2010, 10:10:01 PM1/15/10
to
Signed-off-by: Yinghai Lu <yin...@kernel.org>
---
arch/x86/kernel/cpu/mtrr/cleanup.c | 180 +++---------------------------------
arch/x86/kernel/mmconf-fam10h_64.c | 7 +-
arch/x86/pci/amd_bus.c | 70 ++------------
include/linux/range.h | 22 +++++
kernel/Makefile | 2 +-
kernel/range.c | 154 ++++++++++++++++++++++++++++++
6 files changed, 205 insertions(+), 230 deletions(-)
create mode 100644 include/linux/range.h
create mode 100644 kernel/range.c

diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c
index 09b1698..669da09 100644
--- a/arch/x86/kernel/cpu/mtrr/cleanup.c
+++ b/arch/x86/kernel/cpu/mtrr/cleanup.c
@@ -22,10 +22,10 @@
#include <linux/pci.h>
#include <linux/smp.h>
#include <linux/cpu.h>
-#include <linux/sort.h>
#include <linux/mutex.h>
#include <linux/uaccess.h>
#include <linux/kvm_para.h>
+#include <linux/range.h>

#include <asm/processor.h>
#include <asm/e820.h>
@@ -34,11 +34,6 @@

#include "mtrr.h"

-struct res_range {
- unsigned long start;
- unsigned long end;
-};
-
struct var_mtrr_range_state {
unsigned long base_pfn;
unsigned long size_pfn;
@@ -56,7 +51,7 @@ struct var_mtrr_state {
/* Should be related to MTRR_VAR_RANGES nums */
#define RANGE_NUM 256

-static struct res_range __initdata range[RANGE_NUM];
+static struct range __initdata range[RANGE_NUM];
static int __initdata nr_range;

static struct var_mtrr_range_state __initdata range_state[RANGE_NUM];
@@ -64,152 +59,11 @@ static struct var_mtrr_range_state __initdata range_state[RANGE_NUM];
static int __initdata debug_print;
#define Dprintk(x...) do { if (debug_print) printk(KERN_DEBUG x); } while (0)

-
-static int __init
-add_range(struct res_range *range, int nr_range,
- unsigned long start, unsigned long end)
-{
- /* Out of slots: */
- if (nr_range >= RANGE_NUM)
- return nr_range;
-
- range[nr_range].start = start;
- range[nr_range].end = end;
-
- nr_range++;
-
- return nr_range;
-}
-
-static int __init
-add_range_with_merge(struct res_range *range, int nr_range,
- unsigned long start, unsigned long end)
-{
- int i;
-
- /* Try to merge it with old one: */
- for (i = 0; i < nr_range; i++) {
- unsigned long final_start, final_end;
- unsigned long common_start, common_end;
-
- if (!range[i].end)
- continue;
-
- common_start = max(range[i].start, start);
- common_end = min(range[i].end, end);
- if (common_start > common_end + 1)
- continue;
-
- final_start = min(range[i].start, start);
- final_end = max(range[i].end, end);
-
- range[i].start = final_start;
- range[i].end = final_end;
- return nr_range;
- }
-
- /* Need to add it: */
- return add_range(range, nr_range, start, end);
-}
-
-static void __init
-subtract_range(struct res_range *range, unsigned long start, unsigned long end)
-{
- int i, j;
-
- for (j = 0; j < RANGE_NUM; j++) {
- if (!range[j].end)
- continue;
-
- if (start <= range[j].start && end >= range[j].end) {
- range[j].start = 0;
- range[j].end = 0;
- continue;
- }
-
- if (start <= range[j].start && end < range[j].end &&
- range[j].start < end + 1) {
- range[j].start = end + 1;
- continue;
- }
-
-
- if (start > range[j].start && end >= range[j].end &&
- range[j].end > start - 1) {
- range[j].end = start - 1;
- continue;
- }
-
- if (start > range[j].start && end < range[j].end) {
- /* Find the new spare: */
- for (i = 0; i < RANGE_NUM; i++) {
- if (range[i].end == 0)
- break;
- }
- if (i < RANGE_NUM) {
- range[i].end = range[j].end;
- range[i].start = end + 1;
- } else {
- printk(KERN_ERR "run of slot in ranges\n");
- }
- range[j].end = start - 1;
- continue;
- }
- }
-}
-
-static int __init cmp_range(const void *x1, const void *x2)
-{
- const struct res_range *r1 = x1;
- const struct res_range *r2 = x2;
- long start1, start2;
-
- start1 = r1->start;
- start2 = r2->start;
-
- return start1 - start2;
-}
-
-static int __init clean_sort_range(struct res_range *range, int az)
-{
- int i, j, k = az - 1, nr_range = 0;
-
- for (i = 0; i < k; i++) {
- if (range[i].end)
- continue;
- for (j = k; j > i; j--) {
- if (range[j].end) {
- k = j;
- break;
- }
- }
- if (j == i)
- break;
- range[i].start = range[k].start;
- range[i].end = range[k].end;
- range[k].start = 0;
- range[k].end = 0;
- k--;
- }
- /* count it */
- for (i = 0; i < az; i++) {
- if (!range[i].end) {
- nr_range = i;
- break;
- }
- }
-
- /* sort them */
- sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
-
- return nr_range;
-}
-
#define BIOS_BUG_MSG KERN_WARNING \
"WARNING: BIOS bug: VAR MTRR %d contains strange UC entry under 1M, check with your system vendor!\n"

static int __init
-x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
+x86_get_mtrr_mem_range(struct range *range, int nr_range,
unsigned long extra_remove_base,
unsigned long extra_remove_size)
{
@@ -223,13 +77,13 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
continue;
base = range_state[i].base_pfn;
size = range_state[i].size_pfn;
- nr_range = add_range_with_merge(range, nr_range, base,
- base + size - 1);
+ nr_range = add_range_with_merge(range, RANGE_NUM, nr_range,
+ base, base + size - 1);
}
if (debug_print) {
printk(KERN_DEBUG "After WB checking\n");
for (i = 0; i < nr_range; i++)
- printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
+ printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
range[i].start, range[i].end + 1);
}

@@ -252,10 +106,10 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
size -= (1<<(20-PAGE_SHIFT)) - base;
base = 1<<(20-PAGE_SHIFT);
}
- subtract_range(range, base, base + size - 1);
+ subtract_range(range, RANGE_NUM, base, base + size - 1);
}
if (extra_remove_size)
- subtract_range(range, extra_remove_base,
+ subtract_range(range, RANGE_NUM, extra_remove_base,
extra_remove_base + extra_remove_size - 1);

if (debug_print) {
@@ -263,7 +117,7 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
for (i = 0; i < RANGE_NUM; i++) {
if (!range[i].end)
continue;
- printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
+ printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
range[i].start, range[i].end + 1);
}
}
@@ -273,20 +127,16 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
if (debug_print) {
printk(KERN_DEBUG "After sorting\n");
for (i = 0; i < nr_range; i++)
- printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
+ printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
range[i].start, range[i].end + 1);
}

- /* clear those is not used */
- for (i = nr_range; i < RANGE_NUM; i++)
- memset(&range[i], 0, sizeof(range[i]));
-
return nr_range;
}

#ifdef CONFIG_MTRR_SANITIZER

-static unsigned long __init sum_ranges(struct res_range *range, int nr_range)
+static unsigned long __init sum_ranges(struct range *range, int nr_range)
{
unsigned long sum = 0;
int i;
@@ -621,7 +471,7 @@ static int __init parse_mtrr_spare_reg(char *arg)
early_param("mtrr_spare_reg_nr", parse_mtrr_spare_reg);

static int __init
-x86_setup_var_mtrrs(struct res_range *range, int nr_range,
+x86_setup_var_mtrrs(struct range *range, int nr_range,
u64 chunk_size, u64 gran_size)
{
struct var_mtrr_state var_state;
@@ -742,7 +592,7 @@ mtrr_calc_range_state(u64 chunk_size, u64 gran_size,
unsigned long x_remove_base,
unsigned long x_remove_size, int i)
{
- static struct res_range range_new[RANGE_NUM];
+ static struct range range_new[RANGE_NUM];
unsigned long range_sums_new;
static int nr_range_new;
int num_reg;
@@ -869,10 +719,10 @@ int __init mtrr_cleanup(unsigned address_bits)
* [0, 1M) should always be covered by var mtrr with WB
* and fixed mtrrs should take effect before var mtrr for it:
*/
- nr_range = add_range_with_merge(range, nr_range, 0,
+ nr_range = add_range_with_merge(range, RANGE_NUM, nr_range, 0,
(1ULL<<(20 - PAGE_SHIFT)) - 1);
/* Sort the ranges: */
- sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
+ sort_range(range, nr_range);

range_sums = sum_ranges(range, nr_range);
printk(KERN_INFO "total RAM covered: %ldM\n",
diff --git a/arch/x86/kernel/mmconf-fam10h_64.c b/arch/x86/kernel/mmconf-fam10h_64.c
index 712d15f..7182580 100644
--- a/arch/x86/kernel/mmconf-fam10h_64.c
+++ b/arch/x86/kernel/mmconf-fam10h_64.c
@@ -7,6 +7,8 @@
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/dmi.h>
+#include <linux/range.h>
+
#include <asm/pci-direct.h>
#include <linux/sort.h>
#include <asm/io.h>
@@ -30,11 +32,6 @@ static struct pci_hostbridge_probe pci_probes[] __cpuinitdata = {
{ 0xff, 0, PCI_VENDOR_ID_AMD, 0x1200 },
};

-struct range {
- u64 start;
- u64 end;
-};
-
static int __cpuinit cmp_range(const void *x1, const void *x2)
{
const struct range *r1 = x1;
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
index 95ecbd4..2356ea1 100644
--- a/arch/x86/pci/amd_bus.c
+++ b/arch/x86/pci/amd_bus.c
@@ -2,6 +2,8 @@
#include <linux/pci.h>
#include <linux/topology.h>
#include <linux/cpu.h>
+#include <linux/range.h>
+
#include <asm/pci_x86.h>

#ifdef CONFIG_X86_64
@@ -17,58 +19,6 @@

#ifdef CONFIG_X86_64

-#define RANGE_NUM 16
-
-struct res_range {
- size_t start;
- size_t end;
-};
-
-static void __init update_range(struct res_range *range, size_t start,
- size_t end)
-{
- int i;
- int j;
-
- for (j = 0; j < RANGE_NUM; j++) {
- if (!range[j].end)
- continue;
-
- if (start <= range[j].start && end >= range[j].end) {
- range[j].start = 0;
- range[j].end = 0;
- continue;
- }
-
- if (start <= range[j].start && end < range[j].end && range[j].start < end + 1) {
- range[j].start = end + 1;
- continue;
- }
-
-
- if (start > range[j].start && end >= range[j].end && range[j].end > start - 1) {
- range[j].end = start - 1;
- continue;
- }
-
- if (start > range[j].start && end < range[j].end) {
- /* find the new spare */
- for (i = 0; i < RANGE_NUM; i++) {
- if (range[i].end == 0)
- break;
- }
- if (i < RANGE_NUM) {
- range[i].end = range[j].end;
- range[i].start = end + 1;
- } else {
- printk(KERN_ERR "run of slot in ranges\n");
- }
- range[j].end = start - 1;
- continue;
- }
- }
-}
-
struct pci_hostbridge_probe {
u32 bus;
u32 slot;
@@ -111,6 +61,8 @@ static void __init get_pci_mmcfg_amd_fam10h_range(void)
fam10h_mmconf_end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
}

+#define RANGE_NUM 16
+
/**
* early_fill_mp_bus_to_node()
* called before pcibios_scan_root and pci_scan_bus
@@ -132,7 +84,7 @@ static int __init early_fill_mp_bus_info(void)
struct resource *res;
size_t start;
size_t end;
- struct res_range range[RANGE_NUM];
+ struct range range[RANGE_NUM];
u64 val;
u32 address;

@@ -226,7 +178,7 @@ static int __init early_fill_mp_bus_info(void)
if (end > 0xffff)
end = 0xffff;
update_res(info, start, end, IORESOURCE_IO, 1);
- update_range(range, start, end);
+ subtract_range(range, RANGE_NUM, start, end);
}
/* add left over io port range to def node/link, [0, 0xffff] */
/* find the position */
@@ -256,14 +208,14 @@ static int __init early_fill_mp_bus_info(void)
end = (val & 0xffffff800000ULL);
printk(KERN_INFO "TOM: %016lx aka %ldM\n", end, end>>20);
if (end < (1ULL<<32))
- update_range(range, 0, end - 1);
+ subtract_range(range, RANGE_NUM, 0, end - 1);

/* get mmconfig */
get_pci_mmcfg_amd_fam10h_range();
/* need to take out mmconf range */
if (fam10h_mmconf_end) {
printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", fam10h_mmconf_start, fam10h_mmconf_end);
- update_range(range, fam10h_mmconf_start, fam10h_mmconf_end);
+ subtract_range(range, RANGE_NUM, fam10h_mmconf_start, fam10h_mmconf_end);
}

/* mmio resource */
@@ -318,7 +270,7 @@ static int __init early_fill_mp_bus_info(void)
/* we got a hole */
endx = fam10h_mmconf_start - 1;
update_res(info, start, endx, IORESOURCE_MEM, 0);
- update_range(range, start, endx);
+ subtract_range(range, RANGE_NUM, start, endx);
printk(KERN_CONT " ==> [%llx, %llx]", (u64)start, endx);
start = fam10h_mmconf_end + 1;
changed = 1;
@@ -334,7 +286,7 @@ static int __init early_fill_mp_bus_info(void)
}

update_res(info, start, end, IORESOURCE_MEM, 1);
- update_range(range, start, end);
+ subtract_range(range, RANGE_NUM, start, end);
printk(KERN_CONT "\n");
}

@@ -349,7 +301,7 @@ static int __init early_fill_mp_bus_info(void)
rdmsrl(address, val);
end = (val & 0xffffff800000ULL);
printk(KERN_INFO "TOM2: %016lx aka %ldM\n", end, end>>20);
- update_range(range, 1ULL<<32, end - 1);
+ subtract_range(range, RANGE_NUM, 1ULL<<32, end - 1);
}

/*
diff --git a/include/linux/range.h b/include/linux/range.h
new file mode 100644
index 0000000..0789f14
--- /dev/null
+++ b/include/linux/range.h
@@ -0,0 +1,22 @@
+#ifndef _LINUX_RANGE_H
+#define _LINUX_RANGE_H
+
+struct range {
+ u64 start;
+ u64 end;
+};
+
+int add_range(struct range *range, int az, int nr_range,
+ u64 start, u64 end);
+
+
+int add_range_with_merge(struct range *range, int az, int nr_range,
+ u64 start, u64 end);
+
+void subtract_range(struct range *range, int az, u64 start, u64 end);
+
+int clean_sort_range(struct range *range, int az);
+
+void sort_range(struct range *range, int nr_range);
+
+#endif
diff --git a/kernel/Makefile b/kernel/Makefile
index 864ff75..ad47330 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -10,7 +10,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o \
kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \
- async.o
+ async.o range.o
obj-y += groups.o

ifdef CONFIG_FUNCTION_TRACER
diff --git a/kernel/range.c b/kernel/range.c
new file mode 100644
index 0000000..46a10c8
--- /dev/null
+++ b/kernel/range.c
@@ -0,0 +1,154 @@
+/*
+ * Range add and subtract
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sort.h>
+
+#include <linux/range.h>
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+
+int add_range(struct range *range, int az, int nr_range, u64 start, u64 end)
+{
+ /* Out of slots: */
+ if (nr_range >= az)
+ return nr_range;
+
+ range[nr_range].start = start;
+ range[nr_range].end = end;
+
+ nr_range++;
+
+ return nr_range;
+}
+
+int add_range_with_merge(struct range *range, int az, int nr_range,
+ u64 start, u64 end)
+{
+ int i;
+
+ /* Try to merge it with old one: */
+ for (i = 0; i < nr_range; i++) {
+ u64 final_start, final_end;
+ u64 common_start, common_end;
+
+ if (!range[i].end)
+ continue;
+
+ common_start = max(range[i].start, start);
+ common_end = min(range[i].end, end);
+ if (common_start > common_end + 1)
+ continue;
+
+ final_start = min(range[i].start, start);
+ final_end = max(range[i].end, end);
+
+ range[i].start = final_start;
+ range[i].end = final_end;
+ return nr_range;
+ }
+
+ /* Need to add it: */
+ return add_range(range, az, nr_range, start, end);
+}
+
+void subtract_range(struct range *range, int az, u64 start, u64 end)
+{
+ int i, j;
+
+ for (j = 0; j < az; j++) {
+ if (!range[j].end)
+ continue;
+
+ if (start <= range[j].start && end >= range[j].end) {
+ range[j].start = 0;
+ range[j].end = 0;
+ continue;
+ }
+
+ if (start <= range[j].start && end < range[j].end &&
+ range[j].start < end + 1) {
+ range[j].start = end + 1;
+ continue;
+ }
+
+
+ if (start > range[j].start && end >= range[j].end &&
+ range[j].end > start - 1) {
+ range[j].end = start - 1;
+ continue;
+ }
+
+ if (start > range[j].start && end < range[j].end) {
+ /* Find the new spare: */
+ for (i = 0; i < az; i++) {
+ if (range[i].end == 0)
+ break;
+ }
+ if (i < az) {
+ range[i].end = range[j].end;
+ range[i].start = end + 1;
+ } else {
+ printk(KERN_ERR "run of slot in ranges\n");
+ }
+ range[j].end = start - 1;
+ continue;
+ }
+ }
+}
+
+static int cmp_range(const void *x1, const void *x2)
+{
+ const struct range *r1 = x1;
+ const struct range *r2 = x2;
+ s64 start1, start2;
+
+ start1 = r1->start;
+ start2 = r2->start;
+
+ return start1 - start2;
+}
+
+int clean_sort_range(struct range *range, int az)
+{
+ int i, j, k = az - 1, nr_range = 0;
+
+ for (i = 0; i < k; i++) {
+ if (range[i].end)
+ continue;
+ for (j = k; j > i; j--) {
+ if (range[j].end) {
+ k = j;
+ break;
+ }
+ }
+ if (j == i)
+ break;
+ range[i].start = range[k].start;
+ range[i].end = range[k].end;
+ range[k].start = 0;
+ range[k].end = 0;
+ k--;
+ }
+ /* count it */
+ for (i = 0; i < az; i++) {
+ if (!range[i].end) {
+ nr_range = i;
+ break;
+ }
+ }
+
+ /* sort them */
+ sort(range, nr_range, sizeof(struct range), cmp_range, NULL);
+
+ return nr_range;
+}
+
+void sort_range(struct range *range, int nr_range)
+{
+ /* sort them */
+ sort(range, nr_range, sizeof(struct range), cmp_range, NULL);
+}

Yinghai Lu

unread,
Jan 15, 2010, 10:10:02 PM1/15/10
to
should use nr_cpu_ids instead of num_processor, in case we have hotplug cpus.

if current only have 8 cpus is up, but if we will have more cpus that
will be hot added later, we should use physical flat at first.

nr_cpu_ids is the total cpus that could be supported.

-v2: per linus, chenage default_setup_apic_routing to _init, and call it for uni_processor

Signed-off-by: Yinghai Lu <yin...@kernel.org>
---

arch/x86/kernel/apic/apic.c | 2 --
arch/x86/kernel/apic/probe_32.c | 20 ++++++++++++++++++--
arch/x86/kernel/apic/probe_64.c | 3 ++-
arch/x86/kernel/smpboot.c | 2 --
4 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index c5f4906..b4f47c5 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1647,9 +1647,7 @@ int __init APIC_init_uniprocessor(void)
#endif

enable_IR_x2apic();
-#ifdef CONFIG_X86_64
default_setup_apic_routing();
-#endif

verify_local_APIC();
connect_bsp_APIC();
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
index 1a6559f..d657558 100644
--- a/arch/x86/kernel/apic/probe_32.c
+++ b/arch/x86/kernel/apic/probe_32.c
@@ -52,7 +52,7 @@ static int __init print_ipi_mode(void)
}
late_initcall(print_ipi_mode);

-void default_setup_apic_routing(void)
+static void local_default_setup_apic_routing(void)
{
#ifdef CONFIG_X86_IO_APIC
printk(KERN_INFO
@@ -103,7 +103,7 @@ struct apic apic_default = {
.init_apic_ldr = default_init_apic_ldr,

.ioapic_phys_id_map = default_ioapic_phys_id_map,
- .setup_apic_routing = default_setup_apic_routing,
+ .setup_apic_routing = local_default_setup_apic_routing,
.multi_timer_check = NULL,
.apicid_to_node = default_apicid_to_node,
.cpu_to_logical_apicid = default_cpu_to_logical_apicid,
@@ -212,6 +212,22 @@ void __init generic_bigsmp_probe(void)
#endif
}

+void __init default_setup_apic_routing(void)
+{
+#ifdef CONFIG_X86_BIGSMP
+ /*
+ * make sure we go to bigsmp according to real nr_cpu_ids
+ */
+ if (!cmdline_apic && apic == &apic_default) {
+ if (nr_cpu_ids > 8) {
+ apic = &apic_bigsmp;
+ printk(KERN_INFO "Overriding APIC driver with %s\n",
+ apic->name);
+ }
+ }
+#endif
+}
+
void __init generic_apic_probe(void)
{
if (!cmdline_apic) {
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c
index 0a428dd..7163cf8 100644
--- a/arch/x86/kernel/apic/probe_64.c
+++ b/arch/x86/kernel/apic/probe_64.c
@@ -67,7 +67,8 @@ void __init default_setup_apic_routing(void)
}
#endif

- if (apic == &apic_flat && num_processors > 8)
+ /* not just num_processors, we could have hotplug cpus */
+ if (apic == &apic_flat && nr_cpu_ids > 8)


apic = &apic_physflat;

printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);

diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index eff2fe1..96f5f40 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1083,9 +1083,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
set_cpu_sibling_map(0);

enable_IR_x2apic();
-#ifdef CONFIG_X86_64
default_setup_apic_routing();
-#endif

if (smp_sanity_check(max_cpus) < 0) {
printk(KERN_INFO "SMP disabled\n");

Yinghai Lu

unread,
Jan 15, 2010, 10:10:02 PM1/15/10
to
should be good for 32bit too.

-v3: cast res->start

Signed-off-by: Yinghai Lu <yin...@kernel.org>
Acked-by: Jesse Barnes <jba...@virtuousgeek.org>
---
arch/x86/pci/Makefile | 3 +--
arch/x86/pci/amd_bus.c | 14 +-------------
arch/x86/pci/bus_numa.h | 4 ++--
arch/x86/pci/i386.c | 4 ----
arch/x86/pci/intel_bus.c | 2 +-
5 files changed, 5 insertions(+), 22 deletions(-)

diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index 564b008..30e55d7 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -14,8 +14,7 @@ obj-$(CONFIG_X86_VISWS) += visws.o
obj-$(CONFIG_X86_NUMAQ) += numaq_32.o

obj-y += common.o early.o
-obj-y += amd_bus.o
-obj-$(CONFIG_X86_64) += bus_numa.o intel_bus.o
+obj-y += amd_bus.o bus_numa.o intel_bus.o

ifeq ($(CONFIG_PCI_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
index 66a5d5a..6221720 100644
--- a/arch/x86/pci/amd_bus.c
+++ b/arch/x86/pci/amd_bus.c
@@ -6,9 +6,7 @@

#include <asm/pci_x86.h>

-#ifdef CONFIG_X86_64
#include <asm/pci-direct.h>
-#endif

#include "bus_numa.h"

@@ -17,8 +15,6 @@
* also get peer root bus resource for io,mmio
*/

-#ifdef CONFIG_X86_64


-
struct pci_hostbridge_probe {
u32 bus;
u32 slot;

@@ -341,21 +337,13 @@ static int __init early_fill_mp_bus_info(void)
printk(KERN_DEBUG "bus: %02x index %x %s: [%llx, %llx]\n",
busnum, j,
(res->flags & IORESOURCE_IO)?"io port":"mmio",
- res->start, res->end);
+ (u64)res->start, (u64)res->end);
}
}

return 0;
}

-#else /* !CONFIG_X86_64 */
-
-static int __init early_fill_mp_bus_info(void) { return 0; }
-
-#endif /* !CONFIG_X86_64 */
-
-/* common 32/64 bit code */
-
#define ENABLE_CF8_EXT_CFG (1ULL << 46)

static void enable_pci_io_ecs(void *unused)
diff --git a/arch/x86/pci/bus_numa.h b/arch/x86/pci/bus_numa.h
index adbc23f..66d4ea0 100644
--- a/arch/x86/pci/bus_numa.h
+++ b/arch/x86/pci/bus_numa.h
@@ -1,5 +1,5 @@
-#ifdef CONFIG_X86_64
-
+#ifndef __BUS_NUMA_H
+#define __BUS_NUMA_H
/*
* sub bus (transparent) will use entres from 3 to store extra from
* root, so need to make sure we have enough slot there, Should we
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 5dc9e8c..f4e8481 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -257,10 +257,6 @@ void __init pcibios_resource_survey(void)
*/
fs_initcall(pcibios_assign_resources);

-void __weak x86_pci_root_bus_res_quirks(struct pci_bus *b)
-{
-}
-
/*
* If we set up a device for bus mastering, we need to check the latency
* timer as certain crappy BIOSes forget to set it properly.
diff --git a/arch/x86/pci/intel_bus.c b/arch/x86/pci/intel_bus.c
index 145e0dd..603b9ab 100644
--- a/arch/x86/pci/intel_bus.c
+++ b/arch/x86/pci/intel_bus.c
@@ -30,7 +30,7 @@ static inline void print_ioh_resources(struct pci_root_info *info)
busnum, i,
(res->flags & IORESOURCE_IO) ? "io port" :
"mmio",
- res->start, res->end);
+ (u64)res->start, (u64)res->end);

Yinghai Lu

unread,
Jan 15, 2010, 10:20:02 PM1/15/10
to
prepare for 32bit pci root bus

-v2: hpa said we should compare with (resource_size_t)~0

Signed-off-by: Yinghai Lu <yin...@kernel.org>
Acked-by: Jesse Barnes <jba...@virtuousgeek.org>
---

arch/x86/pci/amd_bus.c | 8 +++++---
arch/x86/pci/bus_numa.c | 3 +++
arch/x86/pci/intel_bus.c | 5 ++++-
include/linux/range.h | 8 ++++++++
4 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
index 467dcac..66a5d5a 100644
--- a/arch/x86/pci/amd_bus.c
+++ b/arch/x86/pci/amd_bus.c
@@ -200,7 +200,7 @@ static int __init early_fill_mp_bus_info(void)

memset(range, 0, sizeof(range));
/* 0xfd00000000-0xffffffffff for HT */
- range[0].end = (0xfdULL<<32) - 1;
+ range[0].end = cap_resource((0xfdULL<<32) - 1);

/* need to take out [0, TOM) for RAM*/
address = MSR_K8_TOP_MEM1;
@@ -285,7 +285,8 @@ static int __init early_fill_mp_bus_info(void)
}
}

- update_res(info, start, end, IORESOURCE_MEM, 1);
+ update_res(info, cap_resource(start), cap_resource(end),
+ IORESOURCE_MEM, 1);


subtract_range(range, RANGE_NUM, start, end);
printk(KERN_CONT "\n");
}

@@ -320,7 +321,8 @@ static int __init early_fill_mp_bus_info(void)


if (!range[i].end)
continue;

- update_res(info, range[i].start, range[i].end,
+ update_res(info, cap_resource(range[i].start),
+ cap_resource(range[i].end),
IORESOURCE_MEM, 1);
}
}
diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c
index f939d60..b267919 100644
--- a/arch/x86/pci/bus_numa.c
+++ b/arch/x86/pci/bus_numa.c
@@ -60,6 +60,9 @@ void __devinit update_res(struct pci_root_info *info, size_t start,
if (start > end)
return;

+ if (start == (resource_size_t)~0)
+ return;
+
if (!merge)
goto addit;

diff --git a/arch/x86/pci/intel_bus.c b/arch/x86/pci/intel_bus.c
index f81a2fa..145e0dd 100644
--- a/arch/x86/pci/intel_bus.c
+++ b/arch/x86/pci/intel_bus.c
@@ -6,6 +6,8 @@
#include <linux/dmi.h>
#include <linux/pci.h>
#include <linux/init.h>


+#include <linux/range.h>
+
#include <asm/pci_x86.h>

#include "bus_numa.h"
@@ -85,7 +87,8 @@ static void __devinit pci_root_bus_res(struct pci_dev *dev)
mmioh_base |= ((u64)(dword & 0x7ffff)) << 32;
pci_read_config_dword(dev, IOH_LMMIOH_LIMITU, &dword);
mmioh_end |= ((u64)(dword & 0x7ffff)) << 32;
- update_res(info, mmioh_base, mmioh_end, IORESOURCE_MEM, 0);
+ update_res(info, cap_resource(mmioh_base), cap_resource(mmioh_end),
+ IORESOURCE_MEM, 0);

print_ioh_resources(info);
}
diff --git a/include/linux/range.h b/include/linux/range.h
index 0789f14..17a23d2 100644
--- a/include/linux/range.h
+++ b/include/linux/range.h
@@ -19,4 +19,12 @@ int clean_sort_range(struct range *range, int az);



void sort_range(struct range *range, int nr_range);

+

+static inline resource_size_t cap_resource(u64 val)
+{
+ if (val > (resource_size_t)~0)
+ return (resource_size_t)~0;
+ else
+ return val;
+}
#endif

Yinghai Lu

unread,
Jan 15, 2010, 10:20:02 PM1/15/10
to
mem_init is moved early already.

Signed-off-by: Yinghai Lu <yin...@kernel.org>
---

kernel/irq/handle.c | 14 +++-----------
1 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 814940e..0e823c0 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -19,7 +19,6 @@
#include <linux/kernel_stat.h>
#include <linux/rculist.h>
#include <linux/hash.h>
-#include <linux/bootmem.h>
#include <trace/events/irq.h>

#include "internals.h"
@@ -87,12 +86,8 @@ void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr)
{
void *ptr;

- if (slab_is_available())
- ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs),
- GFP_ATOMIC, node);
- else
- ptr = alloc_bootmem_node(NODE_DATA(node),
- nr * sizeof(*desc->kstat_irqs));
+ ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs),
+ GFP_ATOMIC, node);

/*
* don't overwite if can not get new one
@@ -219,10 +214,7 @@ struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
if (desc)
goto out_unlock;

- if (slab_is_available())
- desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
- else
- desc = alloc_bootmem_node(NODE_DATA(node), sizeof(*desc));
+ desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);

printk(KERN_DEBUG " alloc irq_desc for %d on node %d\n", irq, node);
if (!desc) {

Christoph Lameter

unread,
Jan 19, 2010, 12:00:03 PM1/19/10
to

On Fri, 15 Jan 2010, Yinghai Lu wrote:

<need more text here describing f.e. how you changed the API and merged
some functions doing similar work>

> Signed-off-by: Yinghai Lu <yin...@kernel.org>

> -
> -static int __init cmp_range(const void *x1, const void *x2)
> -{
> - const struct res_range *r1 = x1;
> - const struct res_range *r2 = x2;
> - long start1, start2;
> -
> - start1 = r1->start;
> - start2 = r2->start;
> -
> - return start1 - start2;
> -}


Function is passed to sort() should not be used directly. Maybe add
comments.

> - static struct res_range range_new[RANGE_NUM];
> + static struct range range_new[RANGE_NUM];

Renaming res_range -> range. Good but explain.

> - nr_range = add_range_with_merge(range, nr_range, 0,
> + nr_range = add_range_with_merge(range, RANGE_NUM, nr_range, 0,
> (1ULL<<(20 - PAGE_SHIFT)) - 1);

add_range_with_merge semantics changed. Explain.

> update_res(info, start, end, IORESOURCE_IO, 1);
> - update_range(range, start, end);
> + subtract_range(range, RANGE_NUM, start, end);

Two functions merged?

> +void subtract_range(struct range *range, int az, u64 start, u64 end)

Subtract range can now do what update_range did? How so?

Looks quite good. Just add some ornaments describing things to make it
clearer.

Yinghai Lu

unread,
Jan 20, 2010, 2:40:01 PM1/20/10
to

update_range was introduced at first. and actually it did sth like subtract range.

and subtract range is more accurate.

Yinghai

Christoph Lameter

unread,
Jan 20, 2010, 3:00:02 PM1/20/10
to
On Wed, 20 Jan 2010, Yinghai Lu wrote:

> > Subtract range can now do what update_range did? How so?
>
> update_range was introduced at first. and actually it did sth like subtract range.
>
> and subtract range is more accurate.

Subtract range suggest that you may be removing the range.

subtract_from_range?

Yinghai Lu

unread,
Jan 20, 2010, 3:10:03 PM1/20/10
to
On 01/20/2010 11:51 AM, Christoph Lameter wrote:
> On Wed, 20 Jan 2010, Yinghai Lu wrote:
>
>>> Subtract range can now do what update_range did? How so?
>>
>> update_range was introduced at first. and actually it did sth like subtract range.
>>
>> and subtract range is more accurate.
>
> Subtract range suggest that you may be removing the range.
>
> subtract_from_range?

void subtract_range(struct range *range, int az, u64 start, u64 end)

struct range *range, int az : is the original range holder.

and will remove [start, end)

0 new messages