another discontig patch
Subsystems (2)
Quoted 10 lines · Jesse Barnes
(quoted diff) +2
-0@@ -703,6 +702,8 @@ * get_free_pages() cannot be used before cpu_init() done. BSP allocates * "NR_CPUS" pages for all CPUs to avoid that AP calls get_zeroed_page(). */ +#ifndef CONFIG_DISCONTIGMEM + /* for discontig machines, we do this in discontig.c */ if (smp_processor_id() = 0) { cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS, PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
Review line 720
Quoted 8 lines
(quoted diff) +1
-0@@ -712,15 +713,13 @@ cpu_data += PERCPU_PAGE_SIZE; } } +#endif cpu_data = __per_cpu_start + __per_cpu_offset[smp_processor_id()]; #else /* !CONFIG_SMP */ cpu_data = __phys_per_cpu_start; #endif /* !CONFIG_SMP */
Maybe this whole code should better be abstracted out then? Also the use of smp_processor_id() here is not preempt-safe but I 'm not sure whether preemption is already enabled at that point.
Review line 725
Quoted 5 lines
(quoted diff) +5
-0+static struct ia64_node_data *boot_node_data[NR_NODES] __initdata; +static pg_data_t *pg_data_ptr[NR_NODES] __initdata; +static bootmem_data_t bdata[NR_NODES] __initdata; +static unsigned long boot_pernode[NR_NODES] __initdata; +static unsigned long boot_pernodesize[NR_NODES] __initdata;
Maybe it's time for special pernode data like the percpu data? Okay, okay, not revelant for this patch yet...
Quoted 3 lines
struct page
*zero_page_memmap_ptr; /* map entry for zero page */+extern int
filter_rsvd_memory(unsigned long start, unsigned long end, void *arg);
Move this to a header?
Review
Quoted 10 lines
(quoted diff) +10
-0+#if defined(CONFIG_VIRTUAL_MEM_MAP) && !defined(CONFIG_DISCONTIGMEM) + extern int ia64_pfn_valid (unsigned long pfn); +# define pfn_valid(pfn) (((pfn) < max_mapnr) && ia64_pfn_valid(pfn)) +#elif defined(CONFIG_VIRTUAL_MEM_MAP) && defined(CONFIG_DISCONTIGMEM) + extern int ia64_pfn_valid (unsigned long pfn); + extern unsigned long max_low_pfn; +# define pfn_valid(pfn) (((pfn) < max_low_pfn) && ia64_pfn_valid(pfn)) +#else +# define pfn_valid(pfn) ((pfn) < max_mapnr) +#endif
Hmm, this ifdef mess look ugly. Can't we use max_low_pfn for the !CONFIG_DISCONTIGMEM case, too and simp;ify it to something like:
#if defined(CONFIG_VIRTUAL_MEM_MAP)
extern int ia64_pfn_valid(unsigned long pfn);
#else
# define ia64_pfn_valid(pfn) (1) #endif
#define pfn_valid(pfn) (((pfn) < max_low_pfn) && ia64_pfn_valid(pfn))
Review
Quoted 10 lines
(quoted diff) +10
-0+ +#if defined(CONFIG_DISCONTIGMEM) && defined(CONFIG_VIRTUAL_MEM_MAP) + extern struct page *vmem_map; +# define pfn_to_page(pfn) (vmem_map + (pfn)) +# define page_to_pfn(page) ((unsigned long) (page - vmem_map)) +#else +# define pfn_to_page(pfn) (mem_map + (pfn)) +# define page_to_pfn(page) ((unsigned long) (page - mem_map)) +#endif /* CONFIG_DISCONTIGMEM && CONFIG_VIRTUAL_MEM_MAP */ +
Hmm, doesn't CONFIG_VIRTUAL_MEM_MAP && !CONFIG_DISCONTIGMEM need vmem_map also. Again, the ifdef mess is horrible :)
What about:
#ifndef CONFIG_VIRTUAL_MEM_MAP
#define vmem_map mem_map
#endif
#define pfn_to_page(pfn) (vmem_map + (pfn))
#define page_to_pfn(page) ((unsigned long) (page - vmem_map))
In fact I wonder what's so special about mem_map that the symbol can't be used for the vmalloc'ed version..
BTW, what about per-node memmaps for SN2 like it's done for NUMAQ?
Review
Quoted 5 lines
#ifdef
CONFIG_NUMA(quoted diff) +2
-0struct ia64_node_data *node_data; + int nodeid; + struct cpuinfo_ia64 *cpu_data[NR_CPUS]; #endif
Should the big array be before the nodeid field?
Quoted 5 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+static struct ia64_node_data *boot_node_data[NR_NODES] __initdata; +static pg_data_t *pg_data_ptr[NR_NODES] __initdata; +static bootmem_data_t bdata[NR_NODES] __initdata; +static unsigned long boot_pernode[NR_NODES] __initdata; +static unsigned long boot_pernodesize[NR_NODES] __initdata;
The only use that I can *see* (without looking very hard) for pg_data_ptr is as pg_data_ptr[node]->bdata, for which you already have bdata[node], don't you? The fact that you have both pg_data_ptr and pg_data_ptrs, which seem to do the same thing, but one as initdata, and one not, is also rather confusing ...
memcpy(boot_node_data[0]->pg_data_ptrs, pg_data_ptr, sizeof(pg_data_ptr));
hmmm.
And aren't boot_pernode and boot_pernodesize really part of bdata? Seems like there's a lot of complexity in order to save a couple of pointer dereferences ... during boot ;-) But maybe I'm just misreading it ;-)
Quoted 7 lines
Maybe it's time for special pernode data like the percpu data? Okay, okay, not revelant for this patch yet...
# ifndef CONFIG_VIRTUAL_MEM_MAP # define vmem_map mem_map # endif
Quoted 7 lines
# define pfn_to_page(pfn) (vmem_map + (pfn)) # define page_to_pfn(page) ((unsigned long) (page - vmem_map))In fact I wonder what's so special about
mem_mapthat the symbol can't be used for the vmalloc'ed version..BTW, what about per-node memmaps for SN2 like it's done for NUMAQ?
I really don't see how you *can't* do that, and have it still work. If the mem_map is placed in node local memory, and not a size that happens to be a complete number of pages, even if you pack it down into a vmem_map, it's still not contiguous. So adding a pfn (physical page frame number) to the base of vmem_map can NOT give you the correct address.
Presumably this *is* working for you ... but I'm buggered if I know how ;-) Maybe I just need more coffee ;-)
Thanks,
M.
Thanks for looking at this, Christoph. Comments below.
Quoted 8 lines · Christoph Hellwig
Quoted 3 lines · Jesse Barnes
#else /* !CONFIG_SMP */
cpu_data=__phys_per_cpu_start;
#endif /* !CONFIG_SMP */Maybe this whole code should better be abstracted out then? Also the use of
smp_processor_id()here is not preempt-safe but I 'm not sure whether preemption is already enabled at that point.
I think we're ok preempt wise here, but you're right that it could probably be abstracted a bit. The issue is that we need to create per-node data structures containing each node's info before the per-cpu stuff is initialized, so we do it all before the bootmem allocator is even setup while we discover memory (see discontig.c:find_pernode_space() I think).
Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+static struct ia64_node_data *boot_node_data[NR_NODES] __initdata; +static pg_data_t *pg_data_ptr[NR_NODES] __initdata; +static bootmem_data_t bdata[NR_NODES] __initdata; +static unsigned long boot_pernode[NR_NODES] __initdata; +static unsigned long boot_pernodesize[NR_NODES] __initdata;Maybe it's time for special pernode data like the percpu data? Okay, okay, not revelant for this patch yet...
It's already there. It's really necessary to get decent performance, and you have to watch out for cache aliasing effects.
Quoted 3 lines
Quoted 1 line
+extern int
filter_rsvd_memory(unsigned long start, unsigned long end, void *arg);Move this to a header?
Yeah, maybe it should be in asm/page.h? Or maybe we need an asm/discontig.h?
Quoted 5 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+# define pfn_valid(pfn) ((pfn) < max_mapnr) +#endifHmm, this ifdef mess look ugly. Can't we use
max_low_pfnfor the !CONFIG_DISCONTIGMEM case, too and simp;ify it to something like:
Agreed, no question. I think this could use some additional cleanup.
Quoted 8 lines
#if
defined(CONFIG_VIRTUAL_MEM_MAP)
extern intia64_pfn_valid(unsigned long pfn);
#else# define ia64_pfn_valid(pfn) (1) #endif#define
pfn_valid(pfn)(((pfn) <max_low_pfn) &&ia64_pfn_valid(pfn))
Quoted 10 lines
Review
Quoted 10 lines
(quoted diff) +10
-0+ +#if defined(CONFIG_DISCONTIGMEM) && defined(CONFIG_VIRTUAL_MEM_MAP) + extern struct page *vmem_map; +# define pfn_to_page(pfn) (vmem_map + (pfn)) +# define page_to_pfn(page) ((unsigned long) (page - vmem_map)) +#else +# define pfn_to_page(pfn) (mem_map + (pfn)) +# define page_to_pfn(page) ((unsigned long) (page - mem_map)) +#endif /* CONFIG_DISCONTIGMEM && CONFIG_VIRTUAL_MEM_MAP */ +
Though I'm not sure if this is the right way to do it... If discontig on ia64 is going to depend on virtual mem map, then making this one #ifdef somehow is probably best.
Quoted 9 lines
Hmm, doesn't
CONFIG_VIRTUAL_MEM_MAP&& !CONFIG_DISCONTIGMEM needvmem_mapalso. Again, the ifdef mess is horrible :)What about:
#ifndef
CONFIG_VIRTUAL_MEM_MAP
#definevmem_mapmem_map
#endif
Quoted 5 lines
#define
pfn_to_page(pfn)(vmem_map+ (pfn))
#definepage_to_pfn(page)((unsigned long) (page -vmem_map))In fact I wonder what's so special about
mem_mapthat the symbol can't be used for the vmalloc'ed version..
Don't know, I'll have to look some more.
Quoted 1 line
BTW, what about per-node memmaps for SN2 like it's done for NUMAQ?
AFAIK, the per-node memmaps index into the big virtual memmap, but I'd have to look at it some more. If we made per-node memory maps, then we probably wouldn't need to use the virtual mem map, except that it makes dealing with holes a bit easier (since on sn2 even memory within a node isn't contiguous, and there are big holes between nodes).
Quoted 7 lines
Review
Quoted 5 lines
#ifdef
CONFIG_NUMA(quoted diff) +2
-0struct ia64_node_data *node_data; + int nodeid; + struct cpuinfo_ia64 *cpu_data[NR_CPUS]; #endifShould the big array be before the nodeid field?
Good catch, probably not. :)
Thanks,
Jesse
Quoted 11 lines · Martin J. Bligh
Quoted 5 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+static struct ia64_node_data *boot_node_data[NR_NODES] __initdata; +static pg_data_t *pg_data_ptr[NR_NODES] __initdata; +static bootmem_data_t bdata[NR_NODES] __initdata; +static unsigned long boot_pernode[NR_NODES] __initdata; +static unsigned long boot_pernodesize[NR_NODES] __initdata;The only use that I can *see* (without looking very hard) for
pg_data_ptris as pg_data_ptr[node]->bdata, for which you already have bdata[node], don't you? The fact that you have bothpg_data_ptrandpg_data_ptrs, which seem to do the same thing, but one as initdata, and one not, is also rather confusing ...
Yeah, that's one thing that I keep meaning to remove, but didn't in the initial versions to keep the 2.4 and 2.5 patches as close as possible.
Quoted 8 lines
memcpy(boot_node_data[0]->pg_data_ptrs, pg_data_ptr, sizeof(pg_data_ptr));hmmm.
And aren't
boot_pernodeandboot_pernodesizereally part of bdata? Seems like there's a lot of complexity in order to save a couple of pointer dereferences ... during boot ;-) But maybe I'm just misreading it ;-)
Well, there's definitely some pointer magic going on here, but I think we use that stuff once the system is up as well, though from a different pointer.
Quoted 23 lines
Quoted 8 lines
Maybe it's time for special pernode data like the percpu data? Okay, okay, not revelant for this patch yet...
# ifndef CONFIG_VIRTUAL_MEM_MAP # define vmem_map mem_map # endifQuoted 7 lines
# define pfn_to_page(pfn) (vmem_map + (pfn)) # define page_to_pfn(page) ((unsigned long) (page - vmem_map))In fact I wonder what's so special about
mem_mapthat the symbol can't be used for the vmalloc'ed version..BTW, what about per-node memmaps for SN2 like it's done for NUMAQ?
I really don't see how you *can't* do that, and have it still work. If the
mem_mapis placed in node local memory, and not a size that happens to be a complete number of pages, even if you pack it down into avmem_map, it's still not contiguous. So adding a pfn (physical page frame number) to the base ofvmem_mapcan NOT give you the correct address.
Quoted 2 lines
Presumably this *is* working for you ... but I'm buggered if I know how ;-) Maybe I just need more coffee ;-)
No, there are some mixed metaphors here for sure (at least, as far as I understand it!) :). You can find stuff either using the global vmemmap or the per-node maps I think, but honestly, I'm still coming up to speed on this code myself, Jack and Kimi are the real experts.
Thanks,
Jesse
Quoted 12 lines
Quoted 11 lines
Quoted 5 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+static struct ia64_node_data *boot_node_data[NR_NODES] __initdata; +static pg_data_t *pg_data_ptr[NR_NODES] __initdata; +static bootmem_data_t bdata[NR_NODES] __initdata; +static unsigned long boot_pernode[NR_NODES] __initdata; +static unsigned long boot_pernodesize[NR_NODES] __initdata;The only use that I can *see* (without looking very hard) for
pg_data_ptris as pg_data_ptr[node]->bdata, for which you already have bdata[node], don't you? The fact that you have bothpg_data_ptrandpg_data_ptrs, which seem to do the same thing, but one as initdata, and one not, is also rather confusing ...
Quoted 2 lines
Yeah, that's one thing that I keep meaning to remove, but didn't in the initial versions to keep the 2.4 and 2.5 patches as close as possible.
OK, I don't think it's something you're introducing with your patch, so it's probably best done separately anyway - you seem to be making the current situation better in general ;-)
Quoted 9 lines
Quoted 9 lines
Quoted 1 line
BTW, what about per-node memmaps for SN2 like it's done for NUMAQ?
I really don't see how you *can't* do that, and have it still work. If the
mem_mapis placed in node local memory, and not a size that happens to be a complete number of pages, even if you pack it down into avmem_map, it's still not contiguous. So adding a pfn (physical page frame number) to the base ofvmem_mapcan NOT give you the correct address.
Quoted 7 lines
Quoted 2 lines
Presumably this *is* working for you ... but I'm buggered if I know how ;-) Maybe I just need more coffee ;-)
No, there are some mixed metaphors here for sure (at least, as far as I understand it!) :). You can find stuff either using the global vmemmap or the per-node maps I think, but honestly, I'm still coming up to speed on this code myself, Jack and Kimi are the real experts.
OK. Am I mistaken in thinking that the point of vmem_map is to skip over physical holes in RAM? If not, then disregard the following ;-) Perhaps it's just about node locality of the struct pages, but that seems odd?
Maybe if the start end of memory areas are always hitting boundaries aligned on PAGE_SIZE number of pages, (ie 16MB for 4K pages), then your mem_map is always page aligned because it's in (sizeof (struct page) * PAGE_SIZE) chunks. If you (plural) are relying on that, then I think it needs a huge stinking comment - isn't terribly obvious to innocent bystanders ;-)
Whilst that would enable you to make the array node_local, you still can't just add a pfn to the base as an offset anyway, which is what it looks like you were doing - that assumes it's all contig. eg this:
pfn_to_page(pfn) (vmem_map + (pfn))
Unless you somehow warped the definition of pfn into a contiguous version of the space, in which case, I think people's heads may explode ... we've always had pfn = phys_addr / PAGE_SIZE as an identity.
M.
Quoted 2 lines · someone
Quoted 2 lines
# define pfn_to_page(pfn) (vmem_map + (pfn)) # define page_to_pfn(page) ((unsigned long) (page - vmem_map))
Quoted 8 lines · Martin J. Bligh
I really don't see how you *can't* do that, and have it still work. If the
mem_mapis placed in node local memory, and not a size that happens to be a complete number of pages, even if you pack it down into avmem_map, it's still not contiguous. So adding a pfn (physical page frame number) to the base ofvmem_mapcan NOT give you the correct address.
Presumably this *is* working for you ... but I'm buggered if I know how ;-) Maybe I just need more coffee ;-)
It's a sparse array. The interstices between nodes are padded with empty virtualspace in order to cheapen the indexing operation. i.e. the nodes' local mem_map's are virtually positioned according to the range of pfns they span. If 32-bit weren't as pressed for virtualspace it could do likewise.
-- wli
Sorry it took so long for me to reply to this, but I've been on vacation for the past 3 weeks. Here's a new discontig patch that incorporates some of the feeback from this thread. Comments and/or integration into 2.6 appreciated.
Thanks,
Jesse
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.1396 -> 1.1397
# include/asm-ia64/page.h 1.19 -> 1.20
# arch/ia64/kernel/setup.c 1.53 -> 1.54
# include/asm-ia64/pgtable.h 1.28 -> 1.29
# mm/bootmem.c 1.18 -> 1.19
# include/asm-ia64/numa.h 1.5 -> 1.6
# include/asm-ia64/processor.h 1.48 -> 1.49
# arch/ia64/mm/init.c 1.46 -> 1.47
# include/asm-ia64/nodedata.h 1.3 -> 1.4
# arch/ia64/mm/discontig.c 1.4 -> 1.5
# arch/ia64/Kconfig 1.38 -> 1.39
# drivers/acpi/Kconfig 1.12 -> 1.13
# include/asm-ia64/mmzone.h 1.4 -> 1.5
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/07/16 [email protected] 1.1397
# discontig update # -------------------------------------------- # diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Wed Jul 16 12:28:28 2003 +++ b/arch/ia64/Kconfig Wed Jul 16 12:28:28 2003 @@ -210,8 +210,8 @@ system with an A0 or A1 stepping CPU.
config NUMA
- bool "Enable NUMA support" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
- default y if IA64_SGI_SN2
+ bool
+ default y if IA64_SGI_SN2 || IA64_GENERIC
help
Say Y to compile the kernel to support NUMA (Non-Uniform Memory Access). This option is for configuring high-end multiprocessor
@@ -235,8 +235,7 @@
config DISCONTIGMEM
bool
- depends on IA64_SGI_SN2 || (IA64_GENERIC || IA64_DIG || IA64_HP_ZX1) && NUMA
- default y
+ default y if IA64_SGI_SN2 || IA64_GENERIC
help
Say Y to support efficient handling of discontiguous physical memory, for architectures which are either NUMA (Non-Uniform Memory Access)
@@ -245,8 +244,7 @@
config VIRTUAL_MEM_MAP
bool "Enable Virtual Mem Map"
- depends on !NUMA
- default y if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
+ default y if !IA64_HP_SIM
help
Say Y to compile the kernel with support for a virtual mem map. This is an alternate method of supporting large holes in the
@@ -259,8 +257,8 @@
are unsure, say Y.
config IA64_MCA
- bool "Enable IA-64 Machine Check Abort" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
- default y if IA64_SGI_SN2
+ bool "Enable IA-64 Machine Check Abort"
+ default y if !IA64_HP_SIM
help
Say Y here to enable machine check support for IA-64. If you're unsure, answer Y.
@@ -292,43 +290,12 @@
depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 || IA64_SGI_SN2 default y
-config IA64_SGI_SN_DEBUG
- bool "Enable extra debugging code"
- depends on IA64_SGI_SN2
- help
- Turns on extra debugging code in the SGI SN (Scalable NUMA) platform - for IA-64. Unless you are debugging problems on an SGI SN IA-64 box, - say N.
-
config IA64_SGI_SN_SIM
bool "Enable SGI Medusa Simulator Support"
depends on IA64_SGI_SN2
help
If you are compiling a kernel that will run under SGI's IA-64 simulator (Medusa) then say Y, otherwise say N.
-
-config IA64_SGI_AUTOTEST
- bool "Enable autotest (llsc). Option to run cache test instead of booting"
- depends on IA64_SGI_SN2
- help
- Build a kernel used for hardware validation. If you include the - keyword "autotest" on the boot command line, the kernel does NOT boot. - Instead, it starts all cpus and runs cache coherency tests instead.
-
- If unsure, say N.
-
-config SERIAL_SGI_L1_PROTOCOL
- bool "Enable protocol mode for the L1 console"
- depends on IA64_SGI_SN2
- help
- Uses protocol mode instead of raw mode for the level 1 console on the - SGI SN (Scalable NUMA) platform for IA-64. If you are compiling for - an SGI SN box then Y is the recommended value, otherwise say N.
-
-config PERCPU_IRQ
- bool
- depends on IA64_SGI_SN2
- default y
# On IA-64, we always want an ELF /proc/kcore.
config KCORE_ELF
arch/ia64/kernel/setup.c +15 -13
@@ -138,7 +138,7 @@ call_pernode_memory (unsigned long start, unsigned long end, void *arg) {unsigned long rs, re; -void (*func)(unsigned long ,unsigned long ,int ,int ); +void (*func)(unsigned long ,unsigned long ,int );int i; start =PAGE_ALIGN (start);
@@ -149,22 +149,21 @@ func = arg;if (!num_memblks) { -/* -* This machine doesn't have SRAT, so call func with -* nid=0, bank=0. -*/ +/* No SRAT table, to assume one node (node 0) */ if (start < end) - (*func)(start, end - start,0 ,0 ); + (*func)(start, end,0 );return ; }for (i =0 ; i < num_memblks; i++) { - rs =max (start, node_memblk[i].start_paddr); - re =min (end, node_memblk[i].start_paddr+node_memblk[i].size); + rs =max (__pa (start), node_memblk[i].start_paddr); + re =min (__pa (end), node_memblk[i].start_paddr+node_memblk[i].size);if (rs < re) - (*func)(rs, re-rs, node_memblk[i].nid, - node_memblk[i].bank); + (*func)((unsigned long )__va (rs), (unsigned long )__va (re), node_memblk[i].nid); + +if ((unsigned long )__va (re) = end) +break ; } }
@@ -180,7 +179,7 @@ filter_rsvd_memory (unsigned long start, unsigned long end, void *arg) {unsigned long range_start, range_end, prev_start; -void (*func)(unsigned long ,unsigned long ); +void (*func)(unsigned long ,unsigned long ,int );int i;#if IGNORE_PFN0
@@ -202,9 +201,9 @@ if (range_start < range_end)#ifdef CONFIG_DISCONTIGMEM -call_pernode_memory (__pa (range_start),__pa (range_end), func); +call_pernode_memory (range_start, range_end, func);#else - (*func)(__pa (range_start), range_end - range_start); + (*func)(range_start, range_end,0 );#endif /* nothing more available in this segment */
@@ -703,6 +702,8 @@* get_free_pages() cannot be used before cpu_init() done. BSP allocates * "NR_CPUS" pages for all CPUs to avoid that AP calls get_zeroed_page(). */ +#ifndef CONFIG_DISCONTIGMEM +/* for discontig machines, we do this in discontig.c */ if (smp_processor_id () =0 ) { cpu_data =__alloc_bootmem (PERCPU_PAGE_SIZE *NR_CPUS ,PERCPU_PAGE_SIZE ,__pa (MAX_DMA_ADDRESS ));
@@ -714,6 +715,7 @@ per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu]; } } +#endif cpu_data = __per_cpu_start + __per_cpu_offset[smp_processor_id ()];#else /* !CONFIG_SMP */ cpu_data = __phys_per_cpu_start;
arch/ia64/mm/discontig.c +132 -164
403 lines not on this page · raw message
arch/ia64/mm/init.c +85 -86
248 lines not on this page · raw message
drivers/acpi/Kconfig +1 -1
@@ -133,7 +133,7 @@ config ACPI_NUMA bool "NUMA support" if NUMA && (IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY && !X86_64) - default y if IA64 && IA64_SGI_SN + default y if IA64_GENERIC || IA64_SGI_SN2 config ACPI_ASUS tristate "ASUS/Medion Laptop Extras"
include/asm-ia64/mmzone.h +22 -122
179 lines not on this page · raw message
include/asm-ia64/nodedata.h +9 -30
@@ -13,7 +13,7 @@#ifndef _ASM_IA64_NODEDATA_H#define _ASM_IA64_NODEDATA_H - +#include <asm/percpu.h> #include <asm/mmzone.h> /*
@@ -22,15 +22,17 @@struct pglist_data ;struct ia64_node_data { -short active_cpu_count;short node; +short active_cpu_count; +/* +* The fields are read-only (after boot). They contain pointers to various structures +* located on other nodes. Ths data is replicated on each node in order to reduce +* off-node references. +*/ struct pglist_data *pg_data_ptrs[NR_NODES ]; -struct page *bank_mem_map_base[NR_BANKS ];struct ia64_node_data *node_data_ptrs[NR_NODES ]; -short node_id_map[NR_BANKS ]; }; -/* * Return a pointer to the node_data structure for the executing cpu. */
@@ -40,7 +42,8 @@/* * Return a pointer to the node_data structure for the specified node. */ -#define node_data (node) (local_node_data->node_data_ptrs[node]) +#define node_data (node) (local_node_data->node_data_ptrs[node]) +#define NODE_DATA (nid) (local_node_data->pg_data_ptrs[nid])/* * Get a pointer to the node_id/node_data for the current cpu.
@@ -48,29 +51,5 @@*/ extern int boot_get_local_nodeid (void );extern struct ia64_node_data *get_node_data_ptr (void ); - -/* -* Given a node id, return a pointer to the pg_data_t for the node. -* The following 2 macros are similar. -* -* NODE_DATA - should be used in all code not related to system -* initialization. It uses pernode data structures to minimize -* offnode memory references. However, these structure are not -* present during boot. This macro can be used once cpu_init -* completes. -* -* BOOT_NODE_DATA -* - should be used during system initialization -* prior to freeing __initdata. It does not depend on the percpu -* area being present. -* -* NOTE: The names of these macros are misleading but are difficult to change -* since they are used in generic linux & on other architecures. -*/ -#define NODE_DATA (nid) (local_node_data->pg_data_ptrs[nid]) -#define BOOT_NODE_DATA (nid) boot_get_pg_data_ptr((long)(nid)) - -struct pglist_data ; -extern struct pglist_data *__init boot_get_pg_data_ptr (long );#endif /* _ASM_IA64_NODEDATA_H */
include/asm-ia64/numa.h +15 -1
@@ -15,13 +15,21 @@#ifdef CONFIG_DISCONTIGMEM # include <asm/mmzone.h> -# define NR_MEMBLKS (NR_BANKS)#else # define NR_NODES (8)# define NR_MEMBLKS (NR_NODES * 8)#endif #include <linux/cache.h> +#include <linux/threads.h> +#include <linux/smp.h> + +#define NODEMASK_WORDCOUNT ((NR_NODES+(BITS_PER_LONG-1))/BITS_PER_LONG) + +#define NODE_MASK_NONE { [0 ... ((NR_NODES+BITS_PER_LONG-1)/BITS_PER_LONG)-1] = 0 } + +typedef unsigned long nodemask_t [NODEMASK_WORDCOUNT ]; + extern volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned; extern volatile unsigned long node_to_cpu_mask[NR_NODES] __cacheline_aligned;
@@ -63,6 +71,12 @@extern int paddr_to_nid (unsigned long paddr);#define local_nodeid (cpu_to_node_map[smp_processor_id()]) + +#else /* !CONFIG_NUMA */ + +#define node_distance (from,to) 10 +#define paddr_to_nid (x) 0 +#define local_nodeid 0#endif /* CONFIG_NUMA */
include/asm-ia64/page.h +19 -11
@@ -93,18 +93,26 @@#define virt_addr_valid (kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) -#ifndef CONFIG_DISCONTIGMEM -# ifdef CONFIG_VIRTUAL_MEM_MAP -extern int ia64_pfn_valid (unsigned long pfn); -# define pfn_valid (pfn) (((pfn) < max_mapnr) && ia64_pfn_valid(pfn)) -# else -# define pfn_valid (pfn) ((pfn) < max_mapnr) -# endif -#define virt_to_page (kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) -#define page_to_pfn (page) ((unsigned long) (page - mem_map)) -#define pfn_to_page (pfn) (mem_map + (pfn)) -#define page_to_phys (page) (page_to_pfn(page) << PAGE_SHIFT) +#ifdef CONFIG_VIRTUAL_MEM_MAP +extern int ia64_pfn_valid (unsigned long pfn); +#else +#define ia64_pfn_valid (pfn) (1) +#endif + +extern unsigned long max_low_pfn; +#define pfn_valid (pfn) (((pfn) < max_low_pfn) && ia64_pfn_valid(pfn)) + +#if defined(CONFIG_VIRTUAL_MEM_MAP ) && !defined(CONFIG_DISCONTIGMEM ) +#define vmem_map mem_map +#else +extern struct page *vmem_map;#endif + +#define pfn_to_page (pfn) (vmem_map + (pfn)) +#define page_to_pfn (page) ((unsigned long) (page - vmem_map)) + +#define virt_to_page (kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)) +#define page_to_phys (page) (page_to_pfn(page) << PAGE_SHIFT) typedef union ia64_va { struct {
include/asm-ia64/pgtable.h +0 -1
@@ -174,7 +174,6 @@return (addr & (local_cpu_data->unimpl_pa_mask)) =0 ; } -#ifndef CONFIG_DISCONTIGMEM /* * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel * memory. For the return value to be meaningful, ADDR must be >@@ -190,7 +189,6 @@
*/
#define kern_addr_valid(addr) (1)
-#endif
/*
* Now come the defines and routines to manage and access the three-level
@@ -241,10 +239,8 @@
#define pte_none(pte) (!pte_val(pte))
#define pte_present(pte) (pte_val(pte) & (_PAGE_P | _PAGE_PROTNONE))
#define pte_clear(pte) (pte_val(*(pte)) = 0UL)
-#ifndef CONFIG_DISCONTIGMEM
/* pte_page() returns the "struct page *" corresponding to the PTE: */
#define pte_page(pte) virt_to_page(((pte_val(pte) & _PFN_MASK) + PAGE_OFFSET))
-#endif
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_bad(pmd) (!ia64_phys_addr_valid(pmd_val(pmd)))
@@ -416,6 +412,7 @@
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
extern void paging_init (void);
+extern int filter_rsvd_memory(unsigned long start, unsigned long end, void *arg);
/*
* Note: The macros below rely on the fact that MAX_SWAPFILES_SHIFT <= number of
include/asm-ia64/processor.h +2 -0
@@ -185,6 +185,8 @@#endif #ifdef CONFIG_NUMA struct ia64_node_data *node_data; +struct cpuinfo_ia64 *cpu_data[NR_CPUS ]; +int nodeid;#endif };
mm/bootmem.c +24 -8
@@ -48,8 +48,24 @@bootmem_data_t *bdata = pgdat->bdata;unsigned long mapsize = ((end - start)+7 )/8 ; - pgdat->pgdat_next = pgdat_list; - pgdat_list = pgdat; + +/* +* sort pgdat_list so that the lowest one comes first, +* which makes alloc_bootmem_low_pages work as desired. +*/ +if (!pgdat_list || pgdat_list->node_start_pfn > pgdat->node_start_pfn) { + pgdat->pgdat_next = pgdat_list; + pgdat_list = pgdat; + }else { +pg_data_t *tmp = pgdat_list; +while (tmp->pgdat_next) { +if (tmp->pgdat_next->node_start_pfn > pgdat->node_start_pfn) +break ; + tmp = tmp->pgdat_next; + } + pgdat->pgdat_next = tmp->pgdat_next; + tmp->pgdat_next = pgdat; + } mapsize = (mapsize + (sizeof (long ) -1UL )) & ~(sizeof (long ) -1UL ); bdata->node_bootmem_map =phys_to_virt (mapstart <<PAGE_SHIFT );
@@ -251,7 +267,7 @@static unsigned long __init free_all_bootmem_core (pg_data_t *pgdat) { -struct page *page = pgdat->node_mem_map; +struct page *page;bootmem_data_t *bdata = pgdat->bdata;unsigned long i, count, total =0 ;unsigned long idx;
@@ -260,23 +276,23 @@if (!bdata->node_bootmem_map)BUG (); count =0 ; + page =virt_to_page (phys_to_virt (bdata->node_boot_start)); idx = bdata->node_low_pfn - (bdata->node_boot_start >>PAGE_SHIFT ); map = bdata->node_bootmem_map;for (i =0 ; i < idx; ) {unsigned long v = ~map[i /BITS_PER_LONG ];if (v) {unsigned long m; -for (m =1 ; m && i < idx; m<<=1 , page++, i++) { +for (m =1 ; m && i < idx; m<<=1 , i++) {if (v & m) { count++; -ClearPageReserved (page); -set_page_count (page,1 ); -__free_page (page); +ClearPageReserved (page+i); +set_page_count (page+i,1 ); +__free_page (page+i); } } }else { i+=BITS_PER_LONG ; - page +=BITS_PER_LONG ; } } total += count;
Review line 217
Quoted 11 lines · Jesse Barnes
(quoted diff) +2
-2@@ -210,8 +210,8 @@ system with an A0 or A1 stepping CPU. config NUMA - bool "Enable NUMA support" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 - default y if IA64_SGI_SN2 + bool + default y if IA64_SGI_SN2 || IA64_GENERIC help Say Y to compile the kernel to support NUMA (Non-Uniform Memory Access). This option is for configuring high-end multiprocessor
If you're removing the question, you can remove the helptext too.
Review line 241
Quoted 10 lines
(quoted diff) +1
-2@@ -235,8 +235,7 @@ config DISCONTIGMEM bool - depends on IA64_SGI_SN2 || (IA64_GENERIC || IA64_DIG || IA64_HP_ZX1) && NUMA - default y + default y if IA64_SGI_SN2 || IA64_GENERIC help Say Y to support efficient handling of discontiguous physical memory, for architectures which are either NUMA (Non-Uniform Memory Access)
This one already shouldn't have helptext ;-)
Quoted 2 lines
- * on a BANKSIZE boundary. Multiple banks per node is not supported.
+ * on a GRANULE boundary. Multiple banks per node is not supported.
Multiple banks *are* not supported ;-) The feature of multiple banks *is* not supported.
Review line 31
Quoted 12 lines
(quoted diff) +6
-1@@ -22,15 +22,17 @@ struct pglist_data; struct ia64_node_data { - short active_cpu_count; short node; + short active_cpu_count; + /* + * The fields are read-only (after boot). They contain pointers to various structures + * located on other nodes. Ths data is replicated on each node in order to reduce + * off-node references. + */
Can you wrap comments at 80 columns? It makes them much easier to read.
Signature · 3 lines
"It's not Hollywood. War is real, war is primarily not about defeat or victory, it is about death. I've seen thousands and thousands of dead bodies. Do you think I want to have an academic debate on this subject?" -- Robert Fisk
Thanks for looking at it. Here's another one that fixes that stuff up.
Quoted 22 lines · Matthew Wilcox
Review
Quoted 4 lines
(quoted diff) +1
-0+ default y if IA64_SGI_SN2 || IA64_GENERIC help Say Y to compile the kernel to support NUMA (Non-Uniform Memory Access). This option is for configuring high-end multiprocessorIf you're removing the question, you can remove the helptext too.
Review
Quoted 4 lines
(quoted diff) +1
-0+ default y if IA64_SGI_SN2 || IA64_GENERIC help Say Y to support efficient handling of discontiguous physical memory, for architectures which are either NUMA (Non-Uniform Memory Access)This one already shouldn't have helptext ;-)
Quoted 2 lines
- * on a BANKSIZE boundary. Multiple banks per node is not supported.
+ * on a GRANULE boundary. Multiple banks per node is not supported.Multiple banks *are* not supported ;-) The feature of multiple banks *is* not supported.
Quoted 2 lines
(quoted diff) +0
-0@@ -22,15 +22,17 @@
Quoted 12 lines
Review line 31
Quoted 10 lines
(quoted diff) +6
-1struct pglist_data; struct ia64_node_data { - short active_cpu_count; short node; + short active_cpu_count; + /* + * The fields are read-only (after boot). They contain pointers to various structures + * located on other nodes. Ths data is replicated on each node in order to reduce + * off-node references. + */Can you wrap comments at 80 columns? It makes them much easier to read.
I prefer it that way too, but David likes 100 columns, AFAICT. :) Fixed anyway.
Thanks,
Jesse
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.1396 -> 1.1398
# include/asm-ia64/page.h 1.19 -> 1.20
# arch/ia64/kernel/setup.c 1.53 -> 1.54
# include/asm-ia64/pgtable.h 1.28 -> 1.29
# mm/bootmem.c 1.18 -> 1.19
# include/asm-ia64/numa.h 1.5 -> 1.6
# include/asm-ia64/processor.h 1.48 -> 1.49
# arch/ia64/mm/init.c 1.46 -> 1.47
# include/asm-ia64/nodedata.h 1.3 -> 1.5
# arch/ia64/mm/discontig.c 1.4 -> 1.6
# arch/ia64/Kconfig 1.38 -> 1.40
# drivers/acpi/Kconfig 1.12 -> 1.13
# include/asm-ia64/mmzone.h 1.4 -> 1.5
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/07/16 [email protected] 1.1397
# discontig update # -------------------------------------------- # 03/07/16 [email protected] 1.1398 # more discontig stuff # -------------------------------------------- # diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Wed Jul 16 12:50:02 2003 +++ b/arch/ia64/Kconfig Wed Jul 16 12:50:02 2003 @@ -210,12 +210,8 @@ system with an A0 or A1 stepping CPU.
config NUMA
- bool "Enable NUMA support" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
- default y if IA64_SGI_SN2
- help
- Say Y to compile the kernel to support NUMA (Non-Uniform Memory - Access). This option is for configuring high-end multiprocessor - server systems. If in doubt, say N.
+ bool
+ default y if IA64_SGI_SN2 || IA64_GENERIC
choice
prompt "Maximum Memory per NUMA Node" if NUMA && IA64_DIG
@@ -235,18 +231,11 @@
config DISCONTIGMEM
bool
- depends on IA64_SGI_SN2 || (IA64_GENERIC || IA64_DIG || IA64_HP_ZX1) && NUMA
- default y
- help
- Say Y to support efficient handling of discontiguous physical memory, - for architectures which are either NUMA (Non-Uniform Memory Access) - or have huge holes in the physical address space for other reasons. - See <file:Documentation/vm/numa> for more.
+ default y if IA64_SGI_SN2 || IA64_GENERIC
config VIRTUAL_MEM_MAP
bool "Enable Virtual Mem Map"
- depends on !NUMA
- default y if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
+ default y if !IA64_HP_SIM
help
Say Y to compile the kernel with support for a virtual mem map. This is an alternate method of supporting large holes in the
@@ -259,8 +248,8 @@
are unsure, say Y.
config IA64_MCA
- bool "Enable IA-64 Machine Check Abort" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
- default y if IA64_SGI_SN2
+ bool "Enable IA-64 Machine Check Abort"
+ default y if !IA64_HP_SIM
help
Say Y here to enable machine check support for IA-64. If you're unsure, answer Y.
@@ -292,43 +281,12 @@
depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 || IA64_SGI_SN2 default y
-config IA64_SGI_SN_DEBUG
- bool "Enable extra debugging code"
- depends on IA64_SGI_SN2
- help
- Turns on extra debugging code in the SGI SN (Scalable NUMA) platform - for IA-64. Unless you are debugging problems on an SGI SN IA-64 box, - say N.
-
config IA64_SGI_SN_SIM
bool "Enable SGI Medusa Simulator Support"
depends on IA64_SGI_SN2
help
If you are compiling a kernel that will run under SGI's IA-64 simulator (Medusa) then say Y, otherwise say N.
-
-config IA64_SGI_AUTOTEST
- bool "Enable autotest (llsc). Option to run cache test instead of booting"
- depends on IA64_SGI_SN2
- help
- Build a kernel used for hardware validation. If you include the - keyword "autotest" on the boot command line, the kernel does NOT boot. - Instead, it starts all cpus and runs cache coherency tests instead.
-
- If unsure, say N.
-
-config SERIAL_SGI_L1_PROTOCOL
- bool "Enable protocol mode for the L1 console"
- depends on IA64_SGI_SN2
- help
- Uses protocol mode instead of raw mode for the level 1 console on the - SGI SN (Scalable NUMA) platform for IA-64. If you are compiling for - an SGI SN box then Y is the recommended value, otherwise say N.
-
-config PERCPU_IRQ
- bool
- depends on IA64_SGI_SN2
- default y
# On IA-64, we always want an ELF /proc/kcore.
config KCORE_ELF
arch/ia64/kernel/setup.c +15 -13
@@ -138,7 +138,7 @@ call_pernode_memory (unsigned long start, unsigned long end, void *arg) {unsigned long rs, re; -void (*func)(unsigned long ,unsigned long ,int ,int ); +void (*func)(unsigned long ,unsigned long ,int );int i; start =PAGE_ALIGN (start);
@@ -149,22 +149,21 @@ func = arg;if (!num_memblks) { -/* -* This machine doesn't have SRAT, so call func with -* nid=0, bank=0. -*/ +/* No SRAT table, to assume one node (node 0) */ if (start < end) - (*func)(start, end - start,0 ,0 ); + (*func)(start, end,0 );return ; }for (i =0 ; i < num_memblks; i++) { - rs =max (start, node_memblk[i].start_paddr); - re =min (end, node_memblk[i].start_paddr+node_memblk[i].size); + rs =max (__pa (start), node_memblk[i].start_paddr); + re =min (__pa (end), node_memblk[i].start_paddr+node_memblk[i].size);if (rs < re) - (*func)(rs, re-rs, node_memblk[i].nid, - node_memblk[i].bank); + (*func)((unsigned long )__va (rs), (unsigned long )__va (re), node_memblk[i].nid); + +if ((unsigned long )__va (re) = end) +break ; } }
@@ -180,7 +179,7 @@ filter_rsvd_memory (unsigned long start, unsigned long end, void *arg) {unsigned long range_start, range_end, prev_start; -void (*func)(unsigned long ,unsigned long ); +void (*func)(unsigned long ,unsigned long ,int );int i;#if IGNORE_PFN0
@@ -202,9 +201,9 @@ if (range_start < range_end)#ifdef CONFIG_DISCONTIGMEM -call_pernode_memory (__pa (range_start),__pa (range_end), func); +call_pernode_memory (range_start, range_end, func);#else - (*func)(__pa (range_start), range_end - range_start); + (*func)(range_start, range_end,0 );#endif /* nothing more available in this segment */
@@ -703,6 +702,8 @@* get_free_pages() cannot be used before cpu_init() done. BSP allocates * "NR_CPUS" pages for all CPUs to avoid that AP calls get_zeroed_page(). */ +#ifndef CONFIG_DISCONTIGMEM +/* for discontig machines, we do this in discontig.c */ if (smp_processor_id () =0 ) { cpu_data =__alloc_bootmem (PERCPU_PAGE_SIZE *NR_CPUS ,PERCPU_PAGE_SIZE ,__pa (MAX_DMA_ADDRESS ));
@@ -714,6 +715,7 @@ per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu]; } } +#endif cpu_data = __per_cpu_start + __per_cpu_offset[smp_processor_id ()];#else /* !CONFIG_SMP */ cpu_data = __phys_per_cpu_start;
arch/ia64/mm/discontig.c +132 -164
403 lines not on this page · raw message
arch/ia64/mm/init.c +85 -86
248 lines not on this page · raw message
drivers/acpi/Kconfig +1 -1
@@ -133,7 +133,7 @@ config ACPI_NUMA bool "NUMA support" if NUMA && (IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY && !X86_64) - default y if IA64 && IA64_SGI_SN + default y if IA64_GENERIC || IA64_SGI_SN2 config ACPI_ASUS tristate "ASUS/Medion Laptop Extras"
include/asm-ia64/mmzone.h +22 -122
179 lines not on this page · raw message
include/asm-ia64/nodedata.h +9 -30
@@ -13,7 +13,7 @@#ifndef _ASM_IA64_NODEDATA_H#define _ASM_IA64_NODEDATA_H - +#include <asm/percpu.h> #include <asm/mmzone.h> /*
@@ -22,15 +22,17 @@struct pglist_data ;struct ia64_node_data { -short active_cpu_count;short node; +short active_cpu_count; +/* +* The fields are read-only (after boot). They contain pointers +* to various structures located on other nodes. Ths data is +* replicated on each node in order to reduce off-node references. +*/ struct pglist_data *pg_data_ptrs[NR_NODES ]; -struct page *bank_mem_map_base[NR_BANKS ];struct ia64_node_data *node_data_ptrs[NR_NODES ]; -short node_id_map[NR_BANKS ]; }; -/* * Return a pointer to the node_data structure for the executing cpu. */
@@ -40,7 +42,8 @@/* * Return a pointer to the node_data structure for the specified node. */ -#define node_data (node) (local_node_data->node_data_ptrs[node]) +#define node_data (node) (local_node_data->node_data_ptrs[node]) +#define NODE_DATA (nid) (local_node_data->pg_data_ptrs[nid])/* * Get a pointer to the node_id/node_data for the current cpu.
@@ -48,29 +51,5 @@*/ extern int boot_get_local_nodeid (void );extern struct ia64_node_data *get_node_data_ptr (void ); - -/* -* Given a node id, return a pointer to the pg_data_t for the node. -* The following 2 macros are similar. -* -* NODE_DATA - should be used in all code not related to system -* initialization. It uses pernode data structures to minimize -* offnode memory references. However, these structure are not -* present during boot. This macro can be used once cpu_init -* completes. -* -* BOOT_NODE_DATA -* - should be used during system initialization -* prior to freeing __initdata. It does not depend on the percpu -* area being present. -* -* NOTE: The names of these macros are misleading but are difficult to change -* since they are used in generic linux & on other architecures. -*/ -#define NODE_DATA (nid) (local_node_data->pg_data_ptrs[nid]) -#define BOOT_NODE_DATA (nid) boot_get_pg_data_ptr((long)(nid)) - -struct pglist_data ; -extern struct pglist_data *__init boot_get_pg_data_ptr (long );#endif /* _ASM_IA64_NODEDATA_H */
include/asm-ia64/numa.h +15 -1
@@ -15,13 +15,21 @@#ifdef CONFIG_DISCONTIGMEM # include <asm/mmzone.h> -# define NR_MEMBLKS (NR_BANKS)#else # define NR_NODES (8)# define NR_MEMBLKS (NR_NODES * 8)#endif #include <linux/cache.h> +#include <linux/threads.h> +#include <linux/smp.h> + +#define NODEMASK_WORDCOUNT ((NR_NODES+(BITS_PER_LONG-1))/BITS_PER_LONG) + +#define NODE_MASK_NONE { [0 ... ((NR_NODES+BITS_PER_LONG-1)/BITS_PER_LONG)-1] = 0 } + +typedef unsigned long nodemask_t [NODEMASK_WORDCOUNT ]; + extern volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned; extern volatile unsigned long node_to_cpu_mask[NR_NODES] __cacheline_aligned;
@@ -63,6 +71,12 @@extern int paddr_to_nid (unsigned long paddr);#define local_nodeid (cpu_to_node_map[smp_processor_id()]) + +#else /* !CONFIG_NUMA */ + +#define node_distance (from,to) 10 +#define paddr_to_nid (x) 0 +#define local_nodeid 0#endif /* CONFIG_NUMA */
include/asm-ia64/page.h +19 -11
@@ -93,18 +93,26 @@#define virt_addr_valid (kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) -#ifndef CONFIG_DISCONTIGMEM -# ifdef CONFIG_VIRTUAL_MEM_MAP -extern int ia64_pfn_valid (unsigned long pfn); -# define pfn_valid (pfn) (((pfn) < max_mapnr) && ia64_pfn_valid(pfn)) -# else -# define pfn_valid (pfn) ((pfn) < max_mapnr) -# endif -#define virt_to_page (kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) -#define page_to_pfn (page) ((unsigned long) (page - mem_map)) -#define pfn_to_page (pfn) (mem_map + (pfn)) -#define page_to_phys (page) (page_to_pfn(page) << PAGE_SHIFT) +#ifdef CONFIG_VIRTUAL_MEM_MAP +extern int ia64_pfn_valid (unsigned long pfn); +#else +#define ia64_pfn_valid (pfn) (1) +#endif + +extern unsigned long max_low_pfn; +#define pfn_valid (pfn) (((pfn) < max_low_pfn) && ia64_pfn_valid(pfn)) + +#if defined(CONFIG_VIRTUAL_MEM_MAP ) && !defined(CONFIG_DISCONTIGMEM ) +#define vmem_map mem_map +#else +extern struct page *vmem_map;#endif + +#define pfn_to_page (pfn) (vmem_map + (pfn)) +#define page_to_pfn (page) ((unsigned long) (page - vmem_map)) + +#define virt_to_page (kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)) +#define page_to_phys (page) (page_to_pfn(page) << PAGE_SHIFT) typedef union ia64_va { struct {
include/asm-ia64/pgtable.h +0 -1
@@ -174,7 +174,6 @@return (addr & (local_cpu_data->unimpl_pa_mask)) =0 ; } -#ifndef CONFIG_DISCONTIGMEM /* * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel * memory. For the return value to be meaningful, ADDR must be >@@ -190,7 +189,6 @@
*/
#define kern_addr_valid(addr) (1)
-#endif
/*
* Now come the defines and routines to manage and access the three-level
@@ -241,10 +239,8 @@
#define pte_none(pte) (!pte_val(pte))
#define pte_present(pte) (pte_val(pte) & (_PAGE_P | _PAGE_PROTNONE))
#define pte_clear(pte) (pte_val(*(pte)) = 0UL)
-#ifndef CONFIG_DISCONTIGMEM
/* pte_page() returns the "struct page *" corresponding to the PTE: */
#define pte_page(pte) virt_to_page(((pte_val(pte) & _PFN_MASK) + PAGE_OFFSET))
-#endif
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_bad(pmd) (!ia64_phys_addr_valid(pmd_val(pmd)))
@@ -416,6 +412,7 @@
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
extern void paging_init (void);
+extern int filter_rsvd_memory(unsigned long start, unsigned long end, void *arg);
/*
* Note: The macros below rely on the fact that MAX_SWAPFILES_SHIFT <= number of
include/asm-ia64/processor.h +2 -0
@@ -185,6 +185,8 @@#endif #ifdef CONFIG_NUMA struct ia64_node_data *node_data; +struct cpuinfo_ia64 *cpu_data[NR_CPUS ]; +int nodeid;#endif };
mm/bootmem.c +24 -8
@@ -48,8 +48,24 @@bootmem_data_t *bdata = pgdat->bdata;unsigned long mapsize = ((end - start)+7 )/8 ; - pgdat->pgdat_next = pgdat_list; - pgdat_list = pgdat; + +/* +* sort pgdat_list so that the lowest one comes first, +* which makes alloc_bootmem_low_pages work as desired. +*/ +if (!pgdat_list || pgdat_list->node_start_pfn > pgdat->node_start_pfn) { + pgdat->pgdat_next = pgdat_list; + pgdat_list = pgdat; + }else { +pg_data_t *tmp = pgdat_list; +while (tmp->pgdat_next) { +if (tmp->pgdat_next->node_start_pfn > pgdat->node_start_pfn) +break ; + tmp = tmp->pgdat_next; + } + pgdat->pgdat_next = tmp->pgdat_next; + tmp->pgdat_next = pgdat; + } mapsize = (mapsize + (sizeof (long ) -1UL )) & ~(sizeof (long ) -1UL ); bdata->node_bootmem_map =phys_to_virt (mapstart <<PAGE_SHIFT );
@@ -251,7 +267,7 @@static unsigned long __init free_all_bootmem_core (pg_data_t *pgdat) { -struct page *page = pgdat->node_mem_map; +struct page *page;bootmem_data_t *bdata = pgdat->bdata;unsigned long i, count, total =0 ;unsigned long idx;
@@ -260,23 +276,23 @@if (!bdata->node_bootmem_map)BUG (); count =0 ; + page =virt_to_page (phys_to_virt (bdata->node_boot_start)); idx = bdata->node_low_pfn - (bdata->node_boot_start >>PAGE_SHIFT ); map = bdata->node_bootmem_map;for (i =0 ; i < idx; ) {unsigned long v = ~map[i /BITS_PER_LONG ];if (v) {unsigned long m; -for (m =1 ; m && i < idx; m<<=1 , page++, i++) { +for (m =1 ; m && i < idx; m<<=1 , i++) {if (v & m) { count++; -ClearPageReserved (page); -set_page_count (page,1 ); -__free_page (page); +ClearPageReserved (page+i); +set_page_count (page+i,1 ); +__free_page (page+i); } } }else { i+=BITS_PER_LONG ; - page +=BITS_PER_LONG ; } } total += count;
Quoted 4 lines · Matthew Wilcox
Quoted 3 lines · Jesse Barnes
(quoted diff) +0
-0@@ -210,8 +210,8 @@ system with an A0 or A1 stepping CPU.
Quoted 8 lines
Review line 217
Quoted 8 lines
(quoted diff) +2
-2config NUMA - bool "Enable NUMA support" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 - default y if IA64_SGI_SN2 + bool + default y if IA64_SGI_SN2 || IA64_GENERIC help Say Y to compile the kernel to support NUMA (Non-Uniform Memory Access). This option is for configuring high-end multiprocessor
There are other NUMA machines around which are not from SGI and are IA64_DIG. You excluded them on purpose? I hope not...
Quoted 4 lines
If you're removing the question, you can remove the helptext too.
Quoted 2 lines
(quoted diff) +0
-0@@ -235,8 +235,7 @@
Quoted 8 lines
Review
Quoted 8 lines
(quoted diff) +0
-1config DISCONTIGMEM bool - depends on IA64_SGI_SN2 || (IA64_GENERIC || IA64_DIG || IA64_HP_ZX1) &&NUMA - default y
(quoted diff) +1
-0+ default y if IA64_SGI_SN2 || IA64_GENERIC help Say Y to support efficient handling of discontiguous physical memory, for architectures which are either NUMA (Non-Uniform Memory Access)
Same comment as above. NEC TX7 is an IA64_DIG platform.
Erich
Quoted 21 lines · Erich Focht
Quoted 4 lines · Matthew Wilcox
Quoted 3 lines · Jesse Barnes
(quoted diff) +0
-0@@ -210,8 +210,8 @@ system with an A0 or A1 stepping CPU.Quoted 8 lines
Review line 217
Quoted 8 lines
(quoted diff) +2
-2config NUMA - bool "Enable NUMA support" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 - default y if IA64_SGI_SN2 + bool + default y if IA64_SGI_SN2 || IA64_GENERIC help Say Y to compile the kernel to support NUMA (Non-Uniform Memory Access). This option is for configuring high-end multiprocessorThere are other NUMA machines around which are not from SGI and are
IA64_DIG. You excluded them on purpose? I hope not...Quoted 4 lines
If you're removing the question, you can remove the helptext too.
Quoted 2 lines
(quoted diff) +0
-0@@ -235,8 +235,7 @@
Quoted 10 lines
Quoted 8 lines
Review
Quoted 8 lines
(quoted diff) +0
-1config DISCONTIGMEM bool - depends on IA64_SGI_SN2 || (IA64_GENERIC || IA64_DIG || IA64_HP_ZX1) &&NUMA - default y
(quoted diff) +1
-0+ default y if IA64_SGI_SN2 || IA64_GENERIC help Say Y to support efficient handling of discontiguous physical memory, for architectures which are either NUMA (Non-Uniform Memory Access)Same comment as above. NEC TX7 is an
IA64_DIGplatform.
Oops, sorry. Here's another one. How does it look?
Thanks,
Jesse
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.1397 -> 1.1398
# include/asm-ia64/page.h 1.19 -> 1.20
# arch/ia64/kernel/setup.c 1.53 -> 1.54
# include/asm-ia64/pgtable.h 1.28 -> 1.29
# mm/bootmem.c 1.18 -> 1.19
# include/asm-ia64/numa.h 1.5 -> 1.6
# include/asm-ia64/processor.h 1.48 -> 1.49
# arch/ia64/mm/init.c 1.46 -> 1.47
# include/asm-ia64/nodedata.h 1.3 -> 1.4
# arch/ia64/mm/discontig.c 1.4 -> 1.5
# arch/ia64/Kconfig 1.38 -> 1.39
# drivers/acpi/Kconfig 1.12 -> 1.13
# include/asm-ia64/mmzone.h 1.4 -> 1.5
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/07/16 [email protected] 1.1398
# latest discontig # -------------------------------------------- # diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Wed Jul 16 15:36:33 2003 +++ b/arch/ia64/Kconfig Wed Jul 16 15:36:33 2003 @@ -211,7 +211,7 @@
config NUMA
bool "Enable NUMA support" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
- default y if IA64_SGI_SN2
+ default y if IA64_SGI_SN2 || IA64_GENERIC
help
Say Y to compile the kernel to support NUMA (Non-Uniform Memory Access). This option is for configuring high-end multiprocessor
@@ -234,9 +234,8 @@
endchoice
config DISCONTIGMEM
- bool
- depends on IA64_SGI_SN2 || (IA64_GENERIC || IA64_DIG || IA64_HP_ZX1) && NUMA
- default y
+ bool "Discontiguous memory support" if IA64_DIG
+ default y if IA64_SGI_SN2 || IA64_GENERIC
help
Say Y to support efficient handling of discontiguous physical memory, for architectures which are either NUMA (Non-Uniform Memory Access)
@@ -245,8 +244,7 @@
config VIRTUAL_MEM_MAP
bool "Enable Virtual Mem Map"
- depends on !NUMA
- default y if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
+ default y if !IA64_HP_SIM
help
Say Y to compile the kernel with support for a virtual mem map. This is an alternate method of supporting large holes in the
@@ -259,8 +257,8 @@
are unsure, say Y.
config IA64_MCA
- bool "Enable IA-64 Machine Check Abort" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
- default y if IA64_SGI_SN2
+ bool "Enable IA-64 Machine Check Abort"
+ default y if !IA64_HP_SIM
help
Say Y here to enable machine check support for IA-64. If you're unsure, answer Y.
@@ -292,43 +290,12 @@
depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 || IA64_SGI_SN2 default y
-config IA64_SGI_SN_DEBUG
- bool "Enable extra debugging code"
- depends on IA64_SGI_SN2
- help
- Turns on extra debugging code in the SGI SN (Scalable NUMA) platform - for IA-64. Unless you are debugging problems on an SGI SN IA-64 box, - say N.
-
config IA64_SGI_SN_SIM
bool "Enable SGI Medusa Simulator Support"
depends on IA64_SGI_SN2
help
If you are compiling a kernel that will run under SGI's IA-64 simulator (Medusa) then say Y, otherwise say N.
-
-config IA64_SGI_AUTOTEST
- bool "Enable autotest (llsc). Option to run cache test instead of booting"
- depends on IA64_SGI_SN2
- help
- Build a kernel used for hardware validation. If you include the - keyword "autotest" on the boot command line, the kernel does NOT boot. - Instead, it starts all cpus and runs cache coherency tests instead.
-
- If unsure, say N.
-
-config SERIAL_SGI_L1_PROTOCOL
- bool "Enable protocol mode for the L1 console"
- depends on IA64_SGI_SN2
- help
- Uses protocol mode instead of raw mode for the level 1 console on the - SGI SN (Scalable NUMA) platform for IA-64. If you are compiling for - an SGI SN box then Y is the recommended value, otherwise say N.
-
-config PERCPU_IRQ
- bool
- depends on IA64_SGI_SN2
- default y
# On IA-64, we always want an ELF /proc/kcore.
config KCORE_ELF
arch/ia64/kernel/setup.c +15 -13
@@ -138,7 +138,7 @@ call_pernode_memory (unsigned long start, unsigned long end, void *arg) {unsigned long rs, re; -void (*func)(unsigned long ,unsigned long ,int ,int ); +void (*func)(unsigned long ,unsigned long ,int );int i; start =PAGE_ALIGN (start);
@@ -149,22 +149,21 @@ func = arg;if (!num_memblks) { -/* -* This machine doesn't have SRAT, so call func with -* nid=0, bank=0. -*/ +/* No SRAT table, to assume one node (node 0) */ if (start < end) - (*func)(start, end - start,0 ,0 ); + (*func)(start, end,0 );return ; }for (i =0 ; i < num_memblks; i++) { - rs =max (start, node_memblk[i].start_paddr); - re =min (end, node_memblk[i].start_paddr+node_memblk[i].size); + rs =max (__pa (start), node_memblk[i].start_paddr); + re =min (__pa (end), node_memblk[i].start_paddr+node_memblk[i].size);if (rs < re) - (*func)(rs, re-rs, node_memblk[i].nid, - node_memblk[i].bank); + (*func)((unsigned long )__va (rs), (unsigned long )__va (re), node_memblk[i].nid); + +if ((unsigned long )__va (re) = end) +break ; } }
@@ -180,7 +179,7 @@ filter_rsvd_memory (unsigned long start, unsigned long end, void *arg) {unsigned long range_start, range_end, prev_start; -void (*func)(unsigned long ,unsigned long ); +void (*func)(unsigned long ,unsigned long ,int );int i;#if IGNORE_PFN0
@@ -202,9 +201,9 @@ if (range_start < range_end)#ifdef CONFIG_DISCONTIGMEM -call_pernode_memory (__pa (range_start),__pa (range_end), func); +call_pernode_memory (range_start, range_end, func);#else - (*func)(__pa (range_start), range_end - range_start); + (*func)(range_start, range_end,0 );#endif /* nothing more available in this segment */
@@ -703,6 +702,8 @@* get_free_pages() cannot be used before cpu_init() done. BSP allocates * "NR_CPUS" pages for all CPUs to avoid that AP calls get_zeroed_page(). */ +#ifndef CONFIG_DISCONTIGMEM +/* for discontig machines, we do this in discontig.c */ if (smp_processor_id () =0 ) { cpu_data =__alloc_bootmem (PERCPU_PAGE_SIZE *NR_CPUS ,PERCPU_PAGE_SIZE ,__pa (MAX_DMA_ADDRESS ));
@@ -714,6 +715,7 @@ per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu]; } } +#endif cpu_data = __per_cpu_start + __per_cpu_offset[smp_processor_id ()];#else /* !CONFIG_SMP */ cpu_data = __phys_per_cpu_start;
arch/ia64/mm/discontig.c +132 -164
403 lines not on this page · raw message
arch/ia64/mm/init.c +85 -86
248 lines not on this page · raw message
drivers/acpi/Kconfig +1 -1
@@ -133,7 +133,7 @@ config ACPI_NUMA bool "NUMA support" if NUMA && (IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY && !X86_64) - default y if IA64 && IA64_SGI_SN + default y if IA64_GENERIC || IA64_SGI_SN2 config ACPI_ASUS tristate "ASUS/Medion Laptop Extras"
include/asm-ia64/mmzone.h +22 -122
179 lines not on this page · raw message
include/asm-ia64/nodedata.h +9 -30
@@ -13,7 +13,7 @@#ifndef _ASM_IA64_NODEDATA_H#define _ASM_IA64_NODEDATA_H - +#include <asm/percpu.h> #include <asm/mmzone.h> /*
@@ -22,15 +22,17 @@struct pglist_data ;struct ia64_node_data { -short active_cpu_count;short node; +short active_cpu_count; +/* +* The fields are read-only (after boot). They contain pointers +* to various structures located on other nodes. Ths data is +* replicated on each node in order to reduce off-node references. +*/ struct pglist_data *pg_data_ptrs[NR_NODES ]; -struct page *bank_mem_map_base[NR_BANKS ];struct ia64_node_data *node_data_ptrs[NR_NODES ]; -short node_id_map[NR_BANKS ]; }; -/* * Return a pointer to the node_data structure for the executing cpu. */
@@ -40,7 +42,8 @@/* * Return a pointer to the node_data structure for the specified node. */ -#define node_data (node) (local_node_data->node_data_ptrs[node]) +#define node_data (node) (local_node_data->node_data_ptrs[node]) +#define NODE_DATA (nid) (local_node_data->pg_data_ptrs[nid])/* * Get a pointer to the node_id/node_data for the current cpu.
@@ -48,29 +51,5 @@*/ extern int boot_get_local_nodeid (void );extern struct ia64_node_data *get_node_data_ptr (void ); - -/* -* Given a node id, return a pointer to the pg_data_t for the node. -* The following 2 macros are similar. -* -* NODE_DATA - should be used in all code not related to system -* initialization. It uses pernode data structures to minimize -* offnode memory references. However, these structure are not -* present during boot. This macro can be used once cpu_init -* completes. -* -* BOOT_NODE_DATA -* - should be used during system initialization -* prior to freeing __initdata. It does not depend on the percpu -* area being present. -* -* NOTE: The names of these macros are misleading but are difficult to change -* since they are used in generic linux & on other architecures. -*/ -#define NODE_DATA (nid) (local_node_data->pg_data_ptrs[nid]) -#define BOOT_NODE_DATA (nid) boot_get_pg_data_ptr((long)(nid)) - -struct pglist_data ; -extern struct pglist_data *__init boot_get_pg_data_ptr (long );#endif /* _ASM_IA64_NODEDATA_H */
include/asm-ia64/numa.h +15 -1
@@ -15,13 +15,21 @@#ifdef CONFIG_DISCONTIGMEM # include <asm/mmzone.h> -# define NR_MEMBLKS (NR_BANKS)#else # define NR_NODES (8)# define NR_MEMBLKS (NR_NODES * 8)#endif #include <linux/cache.h> +#include <linux/threads.h> +#include <linux/smp.h> + +#define NODEMASK_WORDCOUNT ((NR_NODES+(BITS_PER_LONG-1))/BITS_PER_LONG) + +#define NODE_MASK_NONE { [0 ... ((NR_NODES+BITS_PER_LONG-1)/BITS_PER_LONG)-1] = 0 } + +typedef unsigned long nodemask_t [NODEMASK_WORDCOUNT ]; + extern volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned; extern volatile unsigned long node_to_cpu_mask[NR_NODES] __cacheline_aligned;
@@ -63,6 +71,12 @@extern int paddr_to_nid (unsigned long paddr);#define local_nodeid (cpu_to_node_map[smp_processor_id()]) + +#else /* !CONFIG_NUMA */ + +#define node_distance (from,to) 10 +#define paddr_to_nid (x) 0 +#define local_nodeid 0#endif /* CONFIG_NUMA */
include/asm-ia64/page.h +19 -11
@@ -93,18 +93,26 @@#define virt_addr_valid (kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) -#ifndef CONFIG_DISCONTIGMEM -# ifdef CONFIG_VIRTUAL_MEM_MAP -extern int ia64_pfn_valid (unsigned long pfn); -# define pfn_valid (pfn) (((pfn) < max_mapnr) && ia64_pfn_valid(pfn)) -# else -# define pfn_valid (pfn) ((pfn) < max_mapnr) -# endif -#define virt_to_page (kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) -#define page_to_pfn (page) ((unsigned long) (page - mem_map)) -#define pfn_to_page (pfn) (mem_map + (pfn)) -#define page_to_phys (page) (page_to_pfn(page) << PAGE_SHIFT) +#ifdef CONFIG_VIRTUAL_MEM_MAP +extern int ia64_pfn_valid (unsigned long pfn); +#else +#define ia64_pfn_valid (pfn) (1) +#endif + +extern unsigned long max_low_pfn; +#define pfn_valid (pfn) (((pfn) < max_low_pfn) && ia64_pfn_valid(pfn)) + +#if defined(CONFIG_VIRTUAL_MEM_MAP ) && !defined(CONFIG_DISCONTIGMEM ) +#define vmem_map mem_map +#else +extern struct page *vmem_map;#endif + +#define pfn_to_page (pfn) (vmem_map + (pfn)) +#define page_to_pfn (page) ((unsigned long) (page - vmem_map)) + +#define virt_to_page (kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)) +#define page_to_phys (page) (page_to_pfn(page) << PAGE_SHIFT) typedef union ia64_va { struct {
include/asm-ia64/pgtable.h +0 -1
@@ -174,7 +174,6 @@return (addr & (local_cpu_data->unimpl_pa_mask)) =0 ; } -#ifndef CONFIG_DISCONTIGMEM /* * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel * memory. For the return value to be meaningful, ADDR must be >@@ -190,7 +189,6 @@
*/
#define kern_addr_valid(addr) (1)
-#endif
/*
* Now come the defines and routines to manage and access the three-level
@@ -241,10 +239,8 @@
#define pte_none(pte) (!pte_val(pte))
#define pte_present(pte) (pte_val(pte) & (_PAGE_P | _PAGE_PROTNONE))
#define pte_clear(pte) (pte_val(*(pte)) = 0UL)
-#ifndef CONFIG_DISCONTIGMEM
/* pte_page() returns the "struct page *" corresponding to the PTE: */
#define pte_page(pte) virt_to_page(((pte_val(pte) & _PFN_MASK) + PAGE_OFFSET))
-#endif
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_bad(pmd) (!ia64_phys_addr_valid(pmd_val(pmd)))
@@ -416,6 +412,7 @@
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
extern void paging_init (void);
+extern int filter_rsvd_memory(unsigned long start, unsigned long end, void *arg);
/*
* Note: The macros below rely on the fact that MAX_SWAPFILES_SHIFT <= number of
include/asm-ia64/processor.h +2 -0
@@ -185,6 +185,8 @@#endif #ifdef CONFIG_NUMA struct ia64_node_data *node_data; +struct cpuinfo_ia64 *cpu_data[NR_CPUS ]; +int nodeid;#endif };
mm/bootmem.c +24 -8
@@ -48,8 +48,24 @@bootmem_data_t *bdata = pgdat->bdata;unsigned long mapsize = ((end - start)+7 )/8 ; - pgdat->pgdat_next = pgdat_list; - pgdat_list = pgdat; + +/* +* sort pgdat_list so that the lowest one comes first, +* which makes alloc_bootmem_low_pages work as desired. +*/ +if (!pgdat_list || pgdat_list->node_start_pfn > pgdat->node_start_pfn) { + pgdat->pgdat_next = pgdat_list; + pgdat_list = pgdat; + }else { +pg_data_t *tmp = pgdat_list; +while (tmp->pgdat_next) { +if (tmp->pgdat_next->node_start_pfn > pgdat->node_start_pfn) +break ; + tmp = tmp->pgdat_next; + } + pgdat->pgdat_next = tmp->pgdat_next; + tmp->pgdat_next = pgdat; + } mapsize = (mapsize + (sizeof (long ) -1UL )) & ~(sizeof (long ) -1UL ); bdata->node_bootmem_map =phys_to_virt (mapstart <<PAGE_SHIFT );
@@ -251,7 +267,7 @@static unsigned long __init free_all_bootmem_core (pg_data_t *pgdat) { -struct page *page = pgdat->node_mem_map; +struct page *page;bootmem_data_t *bdata = pgdat->bdata;unsigned long i, count, total =0 ;unsigned long idx;
@@ -260,23 +276,23 @@if (!bdata->node_bootmem_map)BUG (); count =0 ; + page =virt_to_page (phys_to_virt (bdata->node_boot_start)); idx = bdata->node_low_pfn - (bdata->node_boot_start >>PAGE_SHIFT ); map = bdata->node_bootmem_map;for (i =0 ; i < idx; ) {unsigned long v = ~map[i /BITS_PER_LONG ];if (v) {unsigned long m; -for (m =1 ; m && i < idx; m<<=1 , page++, i++) { +for (m =1 ; m && i < idx; m<<=1 , i++) {if (v & m) { count++; -ClearPageReserved (page); -set_page_count (page,1 ); -__free_page (page); +ClearPageReserved (page+i); +set_page_count (page+i,1 ); +__free_page (page+i); } } }else { i+=BITS_PER_LONG ; - page +=BITS_PER_LONG ; } } total += count;
Quoted 3 lines
Quoted 1 line
Same comment as above. NEC TX7 is an
IA64_DIGplatform.Oops, sorry. Here's another one. How does it look?
...
arch/ia64/Kconfig line 234
Quoted 13 lines
arch/ia64/Kconfig +1
-1@@ -211,7 +211,7 @@ config NUMA bool "Enable NUMA support" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 - default y if IA64_SGI_SN2 + default y if IA64_SGI_SN2 || IA64_GENERIC help Say Y to compile the kernel to support NUMA (Non-Uniform Memory Access). This option is for configuring high-end multiprocessor@@ -234,9 +234,8 @@ endchoice
OK. Thanks.
arch/ia64/Kconfig
Quoted 11 lines
arch/ia64/Kconfig +0
-2config DISCONTIGMEM - bool - depends on IA64_SGI_SN2 || (IA64_GENERIC || IA64_DIG || IA64_HP_ZX1) &&NUMA - default y
arch/ia64/Kconfig +2
-0+ bool "Discontiguous memory support" if IA64_DIG + default y if IA64_SGI_SN2 || IA64_GENERIC help Say Y to support efficient handling of discontiguous physical memory, for architectures which are either NUMA (Non-Uniform Memory Access)@@ -245,8 +244,7 @@
Maybe that should better be
bool "Discontiguous memory support" if (IA64_DIG && NUMA)
Discontigmem alone doesn't make sense, yet, I think...
Regards,
Erich
Quoted 4 lines · Erich Focht
Maybe that should better be
bool "Discontiguous memory support" if (IA64_DIG && NUMA)Discontigmem alone doesn't make sense, yet, I think...
Not for ia64 I guess, unless we make zx1 use discontig as well. Patch appended.
Thanks,
Jesse
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.1397 -> 1.1399
# include/asm-ia64/page.h 1.19 -> 1.20
# arch/ia64/kernel/setup.c 1.53 -> 1.54
# include/asm-ia64/pgtable.h 1.28 -> 1.29
# mm/bootmem.c 1.18 -> 1.19
# include/asm-ia64/numa.h 1.5 -> 1.6
# include/asm-ia64/processor.h 1.48 -> 1.49
# arch/ia64/mm/init.c 1.46 -> 1.47
# include/asm-ia64/nodedata.h 1.3 -> 1.4
# arch/ia64/mm/discontig.c 1.4 -> 1.5
# arch/ia64/Kconfig 1.38 -> 1.40
# drivers/acpi/Kconfig 1.12 -> 1.13
# include/asm-ia64/mmzone.h 1.4 -> 1.5
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/07/16 [email protected] 1.1398
# latest discontig # -------------------------------------------- # 03/07/17 [email protected] 1.1399 # another discontig patch # -------------------------------------------- # diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Thu Jul 17 16:59:05 2003 +++ b/arch/ia64/Kconfig Thu Jul 17 16:59:05 2003 @@ -211,7 +211,7 @@
config NUMA
bool "Enable NUMA support" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
- default y if IA64_SGI_SN2
+ default y if IA64_SGI_SN2 || IA64_GENERIC
help
Say Y to compile the kernel to support NUMA (Non-Uniform Memory Access). This option is for configuring high-end multiprocessor
@@ -234,9 +234,8 @@
endchoice
config DISCONTIGMEM
- bool
- depends on IA64_SGI_SN2 || (IA64_GENERIC || IA64_DIG || IA64_HP_ZX1) && NUMA
- default y
+ bool "Discontiguous memory support" if (IA64_DIG && NUMA)
+ default y if IA64_SGI_SN2 || IA64_GENERIC
help
Say Y to support efficient handling of discontiguous physical memory, for architectures which are either NUMA (Non-Uniform Memory Access)
@@ -245,8 +244,7 @@
config VIRTUAL_MEM_MAP
bool "Enable Virtual Mem Map"
- depends on !NUMA
- default y if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
+ default y if !IA64_HP_SIM
help
Say Y to compile the kernel with support for a virtual mem map. This is an alternate method of supporting large holes in the
@@ -259,8 +257,8 @@
are unsure, say Y.
config IA64_MCA
- bool "Enable IA-64 Machine Check Abort" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
- default y if IA64_SGI_SN2
+ bool "Enable IA-64 Machine Check Abort"
+ default y if !IA64_HP_SIM
help
Say Y here to enable machine check support for IA-64. If you're unsure, answer Y.
@@ -292,43 +290,12 @@
depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 || IA64_SGI_SN2 default y
-config IA64_SGI_SN_DEBUG
- bool "Enable extra debugging code"
- depends on IA64_SGI_SN2
- help
- Turns on extra debugging code in the SGI SN (Scalable NUMA) platform - for IA-64. Unless you are debugging problems on an SGI SN IA-64 box, - say N.
-
config IA64_SGI_SN_SIM
bool "Enable SGI Medusa Simulator Support"
depends on IA64_SGI_SN2
help
If you are compiling a kernel that will run under SGI's IA-64 simulator (Medusa) then say Y, otherwise say N.
-
-config IA64_SGI_AUTOTEST
- bool "Enable autotest (llsc). Option to run cache test instead of booting"
- depends on IA64_SGI_SN2
- help
- Build a kernel used for hardware validation. If you include the - keyword "autotest" on the boot command line, the kernel does NOT boot. - Instead, it starts all cpus and runs cache coherency tests instead.
-
- If unsure, say N.
-
-config SERIAL_SGI_L1_PROTOCOL
- bool "Enable protocol mode for the L1 console"
- depends on IA64_SGI_SN2
- help
- Uses protocol mode instead of raw mode for the level 1 console on the - SGI SN (Scalable NUMA) platform for IA-64. If you are compiling for - an SGI SN box then Y is the recommended value, otherwise say N.
-
-config PERCPU_IRQ
- bool
- depends on IA64_SGI_SN2
- default y
# On IA-64, we always want an ELF /proc/kcore.
config KCORE_ELF
arch/ia64/kernel/setup.c +15 -13
@@ -138,7 +138,7 @@ call_pernode_memory (unsigned long start, unsigned long end, void *arg) {unsigned long rs, re; -void (*func)(unsigned long ,unsigned long ,int ,int ); +void (*func)(unsigned long ,unsigned long ,int );int i; start =PAGE_ALIGN (start);
@@ -149,22 +149,21 @@ func = arg;if (!num_memblks) { -/* -* This machine doesn't have SRAT, so call func with -* nid=0, bank=0. -*/ +/* No SRAT table, to assume one node (node 0) */ if (start < end) - (*func)(start, end - start,0 ,0 ); + (*func)(start, end,0 );return ; }for (i =0 ; i < num_memblks; i++) { - rs =max (start, node_memblk[i].start_paddr); - re =min (end, node_memblk[i].start_paddr+node_memblk[i].size); + rs =max (__pa (start), node_memblk[i].start_paddr); + re =min (__pa (end), node_memblk[i].start_paddr+node_memblk[i].size);if (rs < re) - (*func)(rs, re-rs, node_memblk[i].nid, - node_memblk[i].bank); + (*func)((unsigned long )__va (rs), (unsigned long )__va (re), node_memblk[i].nid); + +if ((unsigned long )__va (re) = end) +break ; } }
@@ -180,7 +179,7 @@ filter_rsvd_memory (unsigned long start, unsigned long end, void *arg) {unsigned long range_start, range_end, prev_start; -void (*func)(unsigned long ,unsigned long ); +void (*func)(unsigned long ,unsigned long ,int );int i;#if IGNORE_PFN0
@@ -202,9 +201,9 @@ if (range_start < range_end)#ifdef CONFIG_DISCONTIGMEM -call_pernode_memory (__pa (range_start),__pa (range_end), func); +call_pernode_memory (range_start, range_end, func);#else - (*func)(__pa (range_start), range_end - range_start); + (*func)(range_start, range_end,0 );#endif /* nothing more available in this segment */
@@ -703,6 +702,8 @@* get_free_pages() cannot be used before cpu_init() done. BSP allocates * "NR_CPUS" pages for all CPUs to avoid that AP calls get_zeroed_page(). */ +#ifndef CONFIG_DISCONTIGMEM +/* for discontig machines, we do this in discontig.c */ if (smp_processor_id () =0 ) { cpu_data =__alloc_bootmem (PERCPU_PAGE_SIZE *NR_CPUS ,PERCPU_PAGE_SIZE ,__pa (MAX_DMA_ADDRESS ));
@@ -714,6 +715,7 @@ per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu]; } } +#endif cpu_data = __per_cpu_start + __per_cpu_offset[smp_processor_id ()];#else /* !CONFIG_SMP */ cpu_data = __phys_per_cpu_start;
arch/ia64/mm/discontig.c +132 -164
403 lines not on this page · raw message
arch/ia64/mm/init.c +85 -86
248 lines not on this page · raw message
drivers/acpi/Kconfig +1 -1
@@ -133,7 +133,7 @@ config ACPI_NUMA bool "NUMA support" if NUMA && (IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY && !X86_64) - default y if IA64 && IA64_SGI_SN + default y if IA64_GENERIC || IA64_SGI_SN2 config ACPI_ASUS tristate "ASUS/Medion Laptop Extras"
include/asm-ia64/mmzone.h +22 -122
179 lines not on this page · raw message
include/asm-ia64/nodedata.h +9 -30
@@ -13,7 +13,7 @@#ifndef _ASM_IA64_NODEDATA_H#define _ASM_IA64_NODEDATA_H - +#include <asm/percpu.h> #include <asm/mmzone.h> /*
@@ -22,15 +22,17 @@struct pglist_data ;struct ia64_node_data { -short active_cpu_count;short node; +short active_cpu_count; +/* +* The fields are read-only (after boot). They contain pointers +* to various structures located on other nodes. Ths data is +* replicated on each node in order to reduce off-node references. +*/ struct pglist_data *pg_data_ptrs[NR_NODES ]; -struct page *bank_mem_map_base[NR_BANKS ];struct ia64_node_data *node_data_ptrs[NR_NODES ]; -short node_id_map[NR_BANKS ]; }; -/* * Return a pointer to the node_data structure for the executing cpu. */
@@ -40,7 +42,8 @@/* * Return a pointer to the node_data structure for the specified node. */ -#define node_data (node) (local_node_data->node_data_ptrs[node]) +#define node_data (node) (local_node_data->node_data_ptrs[node]) +#define NODE_DATA (nid) (local_node_data->pg_data_ptrs[nid])/* * Get a pointer to the node_id/node_data for the current cpu.
@@ -48,29 +51,5 @@*/ extern int boot_get_local_nodeid (void );extern struct ia64_node_data *get_node_data_ptr (void ); - -/* -* Given a node id, return a pointer to the pg_data_t for the node. -* The following 2 macros are similar. -* -* NODE_DATA - should be used in all code not related to system -* initialization. It uses pernode data structures to minimize -* offnode memory references. However, these structure are not -* present during boot. This macro can be used once cpu_init -* completes. -* -* BOOT_NODE_DATA -* - should be used during system initialization -* prior to freeing __initdata. It does not depend on the percpu -* area being present. -* -* NOTE: The names of these macros are misleading but are difficult to change -* since they are used in generic linux & on other architecures. -*/ -#define NODE_DATA (nid) (local_node_data->pg_data_ptrs[nid]) -#define BOOT_NODE_DATA (nid) boot_get_pg_data_ptr((long)(nid)) - -struct pglist_data ; -extern struct pglist_data *__init boot_get_pg_data_ptr (long );#endif /* _ASM_IA64_NODEDATA_H */
include/asm-ia64/numa.h +15 -1
@@ -15,13 +15,21 @@#ifdef CONFIG_DISCONTIGMEM # include <asm/mmzone.h> -# define NR_MEMBLKS (NR_BANKS)#else # define NR_NODES (8)# define NR_MEMBLKS (NR_NODES * 8)#endif #include <linux/cache.h> +#include <linux/threads.h> +#include <linux/smp.h> + +#define NODEMASK_WORDCOUNT ((NR_NODES+(BITS_PER_LONG-1))/BITS_PER_LONG) + +#define NODE_MASK_NONE { [0 ... ((NR_NODES+BITS_PER_LONG-1)/BITS_PER_LONG)-1] = 0 } + +typedef unsigned long nodemask_t [NODEMASK_WORDCOUNT ]; + extern volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned; extern volatile unsigned long node_to_cpu_mask[NR_NODES] __cacheline_aligned;
@@ -63,6 +71,12 @@extern int paddr_to_nid (unsigned long paddr);#define local_nodeid (cpu_to_node_map[smp_processor_id()]) + +#else /* !CONFIG_NUMA */ + +#define node_distance (from,to) 10 +#define paddr_to_nid (x) 0 +#define local_nodeid 0#endif /* CONFIG_NUMA */
include/asm-ia64/page.h +19 -11
@@ -93,18 +93,26 @@#define virt_addr_valid (kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) -#ifndef CONFIG_DISCONTIGMEM -# ifdef CONFIG_VIRTUAL_MEM_MAP -extern int ia64_pfn_valid (unsigned long pfn); -# define pfn_valid (pfn) (((pfn) < max_mapnr) && ia64_pfn_valid(pfn)) -# else -# define pfn_valid (pfn) ((pfn) < max_mapnr) -# endif -#define virt_to_page (kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) -#define page_to_pfn (page) ((unsigned long) (page - mem_map)) -#define pfn_to_page (pfn) (mem_map + (pfn)) -#define page_to_phys (page) (page_to_pfn(page) << PAGE_SHIFT) +#ifdef CONFIG_VIRTUAL_MEM_MAP +extern int ia64_pfn_valid (unsigned long pfn); +#else +#define ia64_pfn_valid (pfn) (1) +#endif + +extern unsigned long max_low_pfn; +#define pfn_valid (pfn) (((pfn) < max_low_pfn) && ia64_pfn_valid(pfn)) + +#if defined(CONFIG_VIRTUAL_MEM_MAP ) && !defined(CONFIG_DISCONTIGMEM ) +#define vmem_map mem_map +#else +extern struct page *vmem_map;#endif + +#define pfn_to_page (pfn) (vmem_map + (pfn)) +#define page_to_pfn (page) ((unsigned long) (page - vmem_map)) + +#define virt_to_page (kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)) +#define page_to_phys (page) (page_to_pfn(page) << PAGE_SHIFT) typedef union ia64_va { struct {
include/asm-ia64/pgtable.h +0 -1
@@ -174,7 +174,6 @@return (addr & (local_cpu_data->unimpl_pa_mask)) =0 ; } -#ifndef CONFIG_DISCONTIGMEM /* * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel * memory. For the return value to be meaningful, ADDR must be >@@ -190,7 +189,6 @@
*/
#define kern_addr_valid(addr) (1)
-#endif
/*
* Now come the defines and routines to manage and access the three-level
@@ -241,10 +239,8 @@
#define pte_none(pte) (!pte_val(pte))
#define pte_present(pte) (pte_val(pte) & (_PAGE_P | _PAGE_PROTNONE))
#define pte_clear(pte) (pte_val(*(pte)) = 0UL)
-#ifndef CONFIG_DISCONTIGMEM
/* pte_page() returns the "struct page *" corresponding to the PTE: */
#define pte_page(pte) virt_to_page(((pte_val(pte) & _PFN_MASK) + PAGE_OFFSET))
-#endif
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_bad(pmd) (!ia64_phys_addr_valid(pmd_val(pmd)))
@@ -416,6 +412,7 @@
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
extern void paging_init (void);
+extern int filter_rsvd_memory(unsigned long start, unsigned long end, void *arg);
/*
* Note: The macros below rely on the fact that MAX_SWAPFILES_SHIFT <= number of
include/asm-ia64/processor.h +2 -0
@@ -185,6 +185,8 @@#endif #ifdef CONFIG_NUMA struct ia64_node_data *node_data; +struct cpuinfo_ia64 *cpu_data[NR_CPUS ]; +int nodeid;#endif };
mm/bootmem.c +24 -8
@@ -48,8 +48,24 @@bootmem_data_t *bdata = pgdat->bdata;unsigned long mapsize = ((end - start)+7 )/8 ; - pgdat->pgdat_next = pgdat_list; - pgdat_list = pgdat; + +/* +* sort pgdat_list so that the lowest one comes first, +* which makes alloc_bootmem_low_pages work as desired. +*/ +if (!pgdat_list || pgdat_list->node_start_pfn > pgdat->node_start_pfn) { + pgdat->pgdat_next = pgdat_list; + pgdat_list = pgdat; + }else { +pg_data_t *tmp = pgdat_list; +while (tmp->pgdat_next) { +if (tmp->pgdat_next->node_start_pfn > pgdat->node_start_pfn) +break ; + tmp = tmp->pgdat_next; + } + pgdat->pgdat_next = tmp->pgdat_next; + tmp->pgdat_next = pgdat; + } mapsize = (mapsize + (sizeof (long ) -1UL )) & ~(sizeof (long ) -1UL ); bdata->node_bootmem_map =phys_to_virt (mapstart <<PAGE_SHIFT );
@@ -251,7 +267,7 @@static unsigned long __init free_all_bootmem_core (pg_data_t *pgdat) { -struct page *page = pgdat->node_mem_map; +struct page *page;bootmem_data_t *bdata = pgdat->bdata;unsigned long i, count, total =0 ;unsigned long idx;
@@ -260,23 +276,23 @@if (!bdata->node_bootmem_map)BUG (); count =0 ; + page =virt_to_page (phys_to_virt (bdata->node_boot_start)); idx = bdata->node_low_pfn - (bdata->node_boot_start >>PAGE_SHIFT ); map = bdata->node_bootmem_map;for (i =0 ; i < idx; ) {unsigned long v = ~map[i /BITS_PER_LONG ];if (v) {unsigned long m; -for (m =1 ; m && i < idx; m<<=1 , page++, i++) { +for (m =1 ; m && i < idx; m<<=1 , i++) {if (v & m) { count++; -ClearPageReserved (page); -set_page_count (page,1 ); -__free_page (page); +ClearPageReserved (page+i); +set_page_count (page+i,1 ); +__free_page (page+i); } } }else { i+=BITS_PER_LONG ; - page +=BITS_PER_LONG ; } } total += count;
Looks good, applies cleanly on top of 2.6.0-test1 + ia64 but doesn't boot on TX7 :-( Dies right after the elilo output lines... Maybe Tak (CC'd) finds some time to have a look?
Regards,
Erich
Quoted 11 lines · Jesse Barnes
Quoted 4 lines · Erich Focht
Maybe that should better be
bool "Discontiguous memory support" if (IA64_DIG && NUMA)Discontigmem alone doesn't make sense, yet, I think...
Not for ia64 I guess, unless we make zx1 use discontig as well. Patch appended.
Thanks,
Jesse
From: Erich Focht <[email protected]>
Subject: Re: [Discontig-devel] [PATCH] another discontig patch
Date: Fri, 18 Jul 2003 18:15:44 +0200
Message-ID: <[email protected]>
Quoted 3 lines
Looks good, applies cleanly on top of 2.6.0-test1 + ia64 but doesn't boot on TX7 :-( Dies right after the elilo output lines... Maybe Tak (CC'd) finds some time to have a look?
I'll attend OLS this week so I think I can't have time to test it. I'll look into it next week.
---
1st Computer Software Division, NEC Corporation Takayoshi Kochi <[email protected]/[email protected]>