From: "Martin J. Bligh" <fletch@aracnet.com>
To: Andrew Morton <akpm@zip.com.au>
Cc: linux-mm mailing list <linux-mm@kvack.org>
Subject: Cleanup of free_area_init code
Date: Sat, 07 Sep 2002 22:08:30 -0700 [thread overview]
Message-ID: <185352292.1031436510@[10.10.2.3]> (raw)
[-- Attachment #1: Type: text/plain, Size: 1515 bytes --]
This patch cleans up free_area_init stuff, and undefines mem_map
and max_mapnr for discontigmem, where they were horrible kludges
anyway ... we just use the lmem_maps instead, which makes much
more sense. It also kills pgdat->node_start_mapnr, which is tarred
with the same brush.
It breaks free_area_init_core into a couple of sections, pulls
the allocation of the lmem_map back into the next higher function,
and passes more things via the pgdat. But that's not very interesting,
the objective was to kill mem_map for discontigmem, which seems to
attract bugs like flypaper. This brings any misuses to obvious
compile-time errors rather than wierd oopses, which I can't help
but feel is a good thing.
It does break other discontigmem architectures, but in a very
obvious way (they won't compile) and it's easy to fix. I think
that's a small price to pay ... ;-) At some point soon I will
follow up with a patch to remove free_area_init_node for the
contig mem case, or at the very least rename it to something
more sensible, like __free_area_init.
Christoph has grander plans to kill mem_map more extensively
in addition to the attatched, but I've heard nobody disagree
that it should die for the discontigmem case at least.
Oh, and I renamed mem_map in drivers/pcmcia/sa1100 to
pc_mem_map because my tiny little brain (and cscope) find
it confusing like that.
Tested on 16-way NUMA-Q with discontigmem + NUMA support
and on a standard PC (well, boots and appears functional).
On top of 2.5.33-mm4
M.
[-- Attachment #2: 32-free_area_init --]
[-- Type: application/octet-stream, Size: 26552 bytes --]
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/arch/alpha/mm/numa.c 32-free_area_init/arch/alpha/mm/numa.c
--- 0-numafixes/arch/alpha/mm/numa.c Fri Sep 6 22:40:46 2002
+++ 32-free_area_init/arch/alpha/mm/numa.c Fri Sep 6 23:03:19 2002
@@ -286,7 +286,6 @@
for (nid = 0; nid < numnodes; nid++) {
unsigned long start_pfn = plat_node_bdata[nid].node_boot_start >> PAGE_SHIFT;
unsigned long end_pfn = plat_node_bdata[nid].node_low_pfn;
- unsigned long lmax_mapnr;
if (dma_local_pfn >= end_pfn - start_pfn)
zones_size[ZONE_DMA] = end_pfn - start_pfn;
@@ -295,11 +294,6 @@
zones_size[ZONE_NORMAL] = (end_pfn - start_pfn) - dma_local_pfn;
}
free_area_init_node(nid, NODE_DATA(nid), NULL, zones_size, start_pfn, NULL);
- lmax_mapnr = PLAT_NODE_DATA_STARTNR(nid) + PLAT_NODE_DATA_SIZE(nid);
- if (lmax_mapnr > max_mapnr) {
- max_mapnr = lmax_mapnr;
- DBGDCONT("Grow max_mapnr to %ld\n", max_mapnr);
- }
}
/* Initialize the kernel's ZERO_PGE. */
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/arch/i386/kernel/cpu/amd.c 32-free_area_init/arch/i386/kernel/cpu/amd.c
--- 0-numafixes/arch/i386/kernel/cpu/amd.c Sat Aug 31 15:05:34 2002
+++ 32-free_area_init/arch/i386/kernel/cpu/amd.c Fri Sep 6 23:03:19 2002
@@ -25,7 +25,7 @@
static void __init init_amd(struct cpuinfo_x86 *c)
{
u32 l, h;
- int mbytes = max_mapnr >> (20-PAGE_SHIFT);
+ int mbytes = num_physpages >> (20-PAGE_SHIFT);
int r;
/*
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/arch/i386/kernel/i386_ksyms.c 32-free_area_init/arch/i386/kernel/i386_ksyms.c
--- 0-numafixes/arch/i386/kernel/i386_ksyms.c Sat Aug 31 15:05:03 2002
+++ 32-free_area_init/arch/i386/kernel/i386_ksyms.c Fri Sep 6 23:13:32 2002
@@ -58,7 +58,11 @@
EXPORT_SYMBOL(EISA_bus);
#endif
EXPORT_SYMBOL(MCA_bus);
-#ifdef CONFIG_MULTIQUAD
+#ifdef CONFIG_DISCONTIGMEM
+EXPORT_SYMBOL(node_data);
+EXPORT_SYMBOL(pfn_to_nid);
+#endif
+#ifdef CONFIG_X86_NUMAQ
EXPORT_SYMBOL(xquad_portio);
#endif
EXPORT_SYMBOL(__verify_write);
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/arch/i386/kernel/numaq.c 32-free_area_init/arch/i386/kernel/numaq.c
--- 0-numafixes/arch/i386/kernel/numaq.c Fri Sep 6 22:40:47 2002
+++ 32-free_area_init/arch/i386/kernel/numaq.c Fri Sep 6 23:03:19 2002
@@ -82,27 +82,19 @@
*/
int physnode_map[MAX_ELEMENTS] = { [0 ... (MAX_ELEMENTS - 1)] = -1};
-#define MB_TO_ELEMENT(x) (x >> ELEMENT_REPRESENTS)
-#define PA_TO_MB(pa) (pa >> 20) /* assumption: a physical address is in bytes */
+#define PFN_TO_ELEMENT(pfn) (pfn / PAGES_PER_ELEMENT)
+#define PA_TO_ELEMENT(pa) (PFN_TO_ELEMENT(pa >> PAGE_SHIFT))
-int pa_to_nid(u64 pa)
+int pfn_to_nid(unsigned long pfn)
{
- int nid;
-
- nid = physnode_map[MB_TO_ELEMENT(PA_TO_MB(pa))];
+ int nid = physnode_map[PFN_TO_ELEMENT(pfn)];
- /* the physical address passed in is not in the map for the system */
if (nid == -1)
- BUG();
+ BUG(); /* address is not present */
return nid;
}
-int pfn_to_nid(unsigned long pfn)
-{
- return pa_to_nid(((u64)pfn) << PAGE_SHIFT);
-}
-
/*
* for each node mark the regions
* TOPOFMEM = hi_shrd_mem_start + hi_shrd_mem_size
@@ -132,7 +124,7 @@
topofmem = eq->hi_shrd_mem_start + eq->hi_shrd_mem_size;
while (cur < topofmem) {
physnode_map[cur >> 8] = nid;
- cur += (ELEMENT_REPRESENTS - 1);
+ cur ++;
}
}
}
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/arch/i386/mm/discontig.c 32-free_area_init/arch/i386/mm/discontig.c
--- 0-numafixes/arch/i386/mm/discontig.c Fri Sep 6 22:40:47 2002
+++ 32-free_area_init/arch/i386/mm/discontig.c Fri Sep 6 23:03:19 2002
@@ -275,20 +275,9 @@
void __init set_max_mapnr_init(void)
{
#ifdef CONFIG_HIGHMEM
- unsigned long lmax_mapnr;
- int nid;
-
- highmem_start_page = mem_map + NODE_DATA(0)->node_zones[ZONE_HIGHMEM].zone_start_mapnr;
+ highmem_start_page = NODE_DATA(0)->node_zones[ZONE_HIGHMEM].zone_mem_map;
num_physpages = highend_pfn;
-
- for (nid = 0; nid < numnodes; nid++) {
- lmax_mapnr = node_startnr(nid) + node_size(nid);
- if (lmax_mapnr > max_mapnr) {
- max_mapnr = lmax_mapnr;
- }
- }
-
#else
- max_mapnr = num_physpages = max_low_pfn;
+ num_physpages = max_low_pfn;
#endif
}
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/arch/i386/mm/init.c 32-free_area_init/arch/i386/mm/init.c
--- 0-numafixes/arch/i386/mm/init.c Fri Sep 6 22:40:47 2002
+++ 32-free_area_init/arch/i386/mm/init.c Fri Sep 6 23:03:19 2002
@@ -440,8 +440,10 @@
int tmp;
int bad_ppro;
+#ifndef CONFIG_DISCONTIGMEM
if (!mem_map)
BUG();
+#endif
bad_ppro = ppro_with_ram_bug();
@@ -471,7 +473,7 @@
printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
- max_mapnr << (PAGE_SHIFT-10),
+ num_physpages << (PAGE_SHIFT-10),
codesize >> 10,
reservedpages << (PAGE_SHIFT-10),
datasize >> 10,
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/arch/i386/mm/pgtable.c 32-free_area_init/arch/i386/mm/pgtable.c
--- 0-numafixes/arch/i386/mm/pgtable.c Fri Sep 6 22:40:47 2002
+++ 32-free_area_init/arch/i386/mm/pgtable.c Fri Sep 6 23:03:19 2002
@@ -22,26 +22,29 @@
void show_mem(void)
{
- int pfn, total = 0, reserved = 0;
+ int total = 0, reserved = 0;
int shared = 0, cached = 0;
int highmem = 0;
struct page *page;
+ pg_data_t *pgdat;
+ unsigned long i;
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
- pfn = max_mapnr;
- while (pfn-- > 0) {
- page = pfn_to_page(pfn);
- total++;
- if (PageHighMem(page))
- highmem++;
- if (PageReserved(page))
- reserved++;
- else if (PageSwapCache(page))
- cached++;
- else if (page_count(page))
- shared += page_count(page) - 1;
+ for_each_pgdat(pgdat) {
+ for (i = 0; i < pgdat->node_size; ++i) {
+ page = pgdat->node_mem_map + i;
+ total++;
+ if (PageHighMem(page))
+ highmem++;
+ if (PageReserved(page))
+ reserved++;
+ else if (PageSwapCache(page))
+ cached++;
+ else if (page_count(page))
+ shared += page_count(page) - 1;
+ }
}
printk("%d pages of RAM\n", total);
printk("%d pages of HIGHMEM\n",highmem);
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/arch/mips64/sgi-ip27/ip27-memory.c 32-free_area_init/arch/mips64/sgi-ip27/ip27-memory.c
--- 0-numafixes/arch/mips64/sgi-ip27/ip27-memory.c Fri Sep 6 22:40:47 2002
+++ 32-free_area_init/arch/mips64/sgi-ip27/ip27-memory.c Fri Sep 6 23:03:19 2002
@@ -254,10 +254,6 @@
zones_size[ZONE_DMA] = end_pfn + 1 - start_pfn;
free_area_init_node(node, NODE_DATA(node), 0, zones_size,
start_pfn, 0);
- if ((PLAT_NODE_DATA_STARTNR(node) +
- PLAT_NODE_DATA_SIZE(node)) > pagenr)
- pagenr = PLAT_NODE_DATA_STARTNR(node) +
- PLAT_NODE_DATA_SIZE(node);
}
}
@@ -271,7 +267,6 @@
unsigned long codesize, datasize, initsize;
int slot, numslots;
struct page *pg, *pslot;
- pfn_t pgnr;
num_physpages = numpages; /* memory already sized by szmem */
max_mapnr = pagenr; /* already found during paging_init */
@@ -293,7 +288,6 @@
* We need to manually do the other slots.
*/
pg = NODE_DATA(nid)->node_mem_map + slot_getsize(nid, 0);
- pgnr = PLAT_NODE_DATA_STARTNR(nid) + slot_getsize(nid, 0);
numslots = node_getlastslot(nid);
for (slot = 1; slot <= numslots; slot++) {
pslot = NODE_DATA(nid)->node_mem_map +
@@ -304,7 +298,7 @@
* free up the pages that hold the memmap entries.
*/
while (pg < pslot) {
- pg++; pgnr++;
+ pg++;
}
/*
@@ -312,8 +306,8 @@
*/
pslot += slot_getsize(nid, slot);
while (pg < pslot) {
- if (!page_is_ram(pgnr))
- continue;
+ /* if (!page_is_ram(pgnr)) continue; */
+ /* commented out until page_is_ram works */
ClearPageReserved(pg);
atomic_set(&pg->count, 1);
__free_page(pg);
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/drivers/pcmcia/sa1100.h 32-free_area_init/drivers/pcmcia/sa1100.h
--- 0-numafixes/drivers/pcmcia/sa1100.h Sat Aug 31 15:05:27 2002
+++ 32-free_area_init/drivers/pcmcia/sa1100.h Fri Sep 6 23:03:19 2002
@@ -160,7 +160,7 @@
*/
socket_state_t cs_state;
pccard_io_map io_map[MAX_IO_WIN];
- pccard_mem_map mem_map[MAX_WIN];
+ pccard_mem_map pc_mem_map[MAX_WIN];
void (*handler)(void *, unsigned int);
void *handler_info;
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/drivers/pcmcia/sa1100_generic.c 32-free_area_init/drivers/pcmcia/sa1100_generic.c
--- 0-numafixes/drivers/pcmcia/sa1100_generic.c Sat Aug 31 15:05:28 2002
+++ 32-free_area_init/drivers/pcmcia/sa1100_generic.c Fri Sep 6 23:03:19 2002
@@ -686,7 +686,7 @@
DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
if (map->map < MAX_WIN) {
- *map = skt->mem_map[map->map];
+ *map = skt->pc_mem_map[map->map];
ret = 0;
}
@@ -754,7 +754,7 @@
map->sys_stop += start;
map->sys_start = start;
- skt->mem_map[map->map] = *map;
+ skt->pc_mem_map[map->map] = *map;
return 0;
} /* sa1100_pcmcia_set_mem_map() */
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/include/asm-alpha/mmzone.h 32-free_area_init/include/asm-alpha/mmzone.h
--- 0-numafixes/include/asm-alpha/mmzone.h Fri Sep 6 22:40:50 2002
+++ 32-free_area_init/include/asm-alpha/mmzone.h Fri Sep 6 23:03:19 2002
@@ -46,8 +46,6 @@
#define PHYSADDR_TO_NID(pa) ALPHA_PA_TO_NID(pa)
#define PLAT_NODE_DATA(n) (plat_node_data[(n)])
-#define PLAT_NODE_DATA_STARTNR(n) \
- (PLAT_NODE_DATA(n)->gendata.node_start_mapnr)
#define PLAT_NODE_DATA_SIZE(n) (PLAT_NODE_DATA(n)->gendata.node_size)
#if 1
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/include/asm-i386/mmzone.h 32-free_area_init/include/asm-i386/mmzone.h
--- 0-numafixes/include/asm-i386/mmzone.h Fri Sep 6 22:40:51 2002
+++ 32-free_area_init/include/asm-i386/mmzone.h Fri Sep 6 23:03:19 2002
@@ -11,7 +11,6 @@
#ifdef CONFIG_X86_NUMAQ
#include <asm/numaq.h>
#else
-#define pa_to_nid(pa) (0)
#define pfn_to_nid(pfn) (0)
#ifdef CONFIG_NUMA
#define _cpu_to_node(cpu) 0
@@ -44,7 +43,6 @@
#define alloc_bootmem_low_pages_node(ignore, x) \
__alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0)
-#define node_startnr(nid) (node_data[nid]->node_start_mapnr)
#define node_size(nid) (node_data[nid]->node_size)
#define node_localnr(pfn, nid) ((pfn) - node_data[nid]->node_start_pfn)
@@ -55,7 +53,7 @@
/*
* Given a kernel address, find the home node of the underlying memory.
*/
-#define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr))
+#define kvaddr_to_nid(kaddr) pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT)
/*
* Return a pointer to the node data for node n.
@@ -64,6 +62,8 @@
#define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map)
#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
+#define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \
+ NODE_DATA(nid)->node_size)
#define local_mapnr(kvaddr) \
( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) )
@@ -74,5 +74,13 @@
#define pfn_to_page(pfn) (node_mem_map(pfn_to_nid(pfn)) + node_localnr(pfn, pfn_to_nid(pfn)))
#define page_to_pfn(page) ((page - page_zone(page)->zone_mem_map) + page_zone(page)->zone_start_pfn)
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+/*
+ * pfn_valid should be made as fast as possible, and the current definition
+ * is valid for machines that are NUMA, but still contiguous, which is what
+ * is currently supported. A more generalised, but slower definition would
+ * be something like this - mbligh:
+ * ( pfn_to_pgdat(pfn) && (pfn < node_end_pfn(pfn_to_nid(pfn))) )
+ */
+#define pfn_valid(pfn) (pfn < num_physpages)
#endif /* CONFIG_DISCONTIGMEM */
#endif /* _ASM_MMZONE_H_ */
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/include/asm-i386/numaq.h 32-free_area_init/include/asm-i386/numaq.h
--- 0-numafixes/include/asm-i386/numaq.h Fri Sep 6 22:40:51 2002
+++ 32-free_area_init/include/asm-i386/numaq.h Fri Sep 6 23:03:19 2002
@@ -32,17 +32,18 @@
/*
* for now assume that 64Gb is max amount of RAM for whole system
- * 64Gb * 1024Mb/Gb = 65536 Mb
- * 65536 Mb / 256Mb = 256
+ * 64Gb / 4096bytes/page = 16777216 pages
*/
+#define MAX_NR_PAGES 16777216
#define MAX_ELEMENTS 256
-#define ELEMENT_REPRESENTS 8 /* 256 Mb */
+#define PAGES_PER_ELEMENT (16777216/256)
+#define pfn_to_pgdat(pfn) NODE_DATA(pfn_to_nid(pfn))
+#define PHYSADDR_TO_NID(pa) pfn_to_nid(pa >> PAGE_SHIFT)
#define MAX_NUMNODES 8
#ifdef CONFIG_NUMA
#define _cpu_to_node(cpu) (cpu_to_logical_apicid(cpu) >> 4)
#endif /* CONFIG_NUMA */
-extern int pa_to_nid(u64);
extern int pfn_to_nid(unsigned long);
extern void get_memcfg_numaq(void);
#define get_memcfg_numa() get_memcfg_numaq()
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/include/asm-i386/page.h 32-free_area_init/include/asm-i386/page.h
--- 0-numafixes/include/asm-i386/page.h Fri Sep 6 22:40:51 2002
+++ 32-free_area_init/include/asm-i386/page.h Fri Sep 6 23:03:19 2002
@@ -145,10 +145,10 @@
#ifndef CONFIG_DISCONTIGMEM
#define pfn_to_page(pfn) (mem_map + (pfn))
#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
+#define pfn_valid(pfn) ((pfn) < max_mapnr)
#endif /* !CONFIG_DISCONTIGMEM */
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-#define pfn_valid(pfn) ((pfn) < max_mapnr)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/include/asm-mips64/mmzone.h 32-free_area_init/include/asm-mips64/mmzone.h
--- 0-numafixes/include/asm-mips64/mmzone.h Fri Sep 6 22:40:51 2002
+++ 32-free_area_init/include/asm-mips64/mmzone.h Fri Sep 6 23:03:19 2002
@@ -24,7 +24,6 @@
#define PHYSADDR_TO_NID(pa) NASID_TO_COMPACT_NODEID(NASID_GET(pa))
#define PLAT_NODE_DATA(n) (plat_node_data[n])
-#define PLAT_NODE_DATA_STARTNR(n) (PLAT_NODE_DATA(n)->gendata.node_start_mapnr)
#define PLAT_NODE_DATA_SIZE(n) (PLAT_NODE_DATA(n)->gendata.node_size)
#define PLAT_NODE_DATA_LOCALNR(p, n) \
(((p) >> PAGE_SHIFT) - PLAT_NODE_DATA(n)->gendata.node_start_pfn)
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/include/asm-mips64/pgtable.h 32-free_area_init/include/asm-mips64/pgtable.h
--- 0-numafixes/include/asm-mips64/pgtable.h Fri Sep 6 22:40:51 2002
+++ 32-free_area_init/include/asm-mips64/pgtable.h Fri Sep 6 23:03:19 2002
@@ -373,10 +373,10 @@
#ifndef CONFIG_DISCONTIGMEM
#define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT)))
#else
-#define mips64_pte_pagenr(x) \
- (PLAT_NODE_DATA_STARTNR(PHYSADDR_TO_NID(pte_val(x))) + \
- PLAT_NODE_DATA_LOCALNR(pte_val(x), PHYSADDR_TO_NID(pte_val(x))))
-#define pte_page(x) (mem_map+mips64_pte_pagenr(x))
+
+#define pte_page(x) ( NODE_MEM_MAP(PHYSADDR_TO_NID(pte_val(x))) +
+ PLAT_NODE_DATA_LOCALNR(pte_val(x), PHYSADDR_TO_NID(pte_val(x))) )
+
#endif
/*
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/include/asm-ppc64/mmzone.h 32-free_area_init/include/asm-ppc64/mmzone.h
--- 0-numafixes/include/asm-ppc64/mmzone.h Fri Sep 6 22:40:51 2002
+++ 32-free_area_init/include/asm-ppc64/mmzone.h Fri Sep 6 23:03:19 2002
@@ -27,8 +27,6 @@
#define PHYSADDR_TO_NID(pa) ((pa) >> MEMORY_ZONE_BITS)
#define PLAT_NODE_DATA(n) (&plat_node_data[(n)])
-#define PLAT_NODE_DATA_STARTNR(n) \
- (PLAT_NODE_DATA(n)->gendata.node_start_mapnr)
#define PLAT_NODE_DATA_SIZE(n) (PLAT_NODE_DATA(n)->gendata.node_size)
#define PLAT_NODE_DATA_LOCALNR(p, n) \
(((p) >> PAGE_SHIFT) - PLAT_NODE_DATA(n)->gendata.node_start_pfn)
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/include/linux/mm.h 32-free_area_init/include/linux/mm.h
--- 0-numafixes/include/linux/mm.h Fri Sep 6 22:40:51 2002
+++ 32-free_area_init/include/linux/mm.h Fri Sep 6 23:03:19 2002
@@ -15,7 +15,10 @@
#include <linux/rbtree.h>
#include <linux/fs.h>
+#ifndef CONFIG_DISCONTIGMEM /* Don't use mapnrs, do it properly */
extern unsigned long max_mapnr;
+#endif
+
extern unsigned long num_physpages;
extern void * high_memory;
extern int page_cluster;
@@ -335,8 +338,10 @@
#define VM_FAULT_MINOR 1
#define VM_FAULT_MAJOR 2
-/* The array of struct pages */
+#ifndef CONFIG_DISCONTIGMEM
+/* The array of struct pages - for discontigmem use pgdat->lmem_map */
extern struct page *mem_map;
+#endif
extern void show_free_areas(void);
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/include/linux/mmzone.h 32-free_area_init/include/linux/mmzone.h
--- 0-numafixes/include/linux/mmzone.h Fri Sep 6 22:40:51 2002
+++ 32-free_area_init/include/linux/mmzone.h Fri Sep 6 23:21:51 2002
@@ -112,7 +112,6 @@
struct page *zone_mem_map;
/* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */
unsigned long zone_start_pfn;
- unsigned long zone_start_mapnr;
/*
* rarely used fields:
@@ -163,7 +162,6 @@
unsigned long *valid_addr_bitmap;
struct bootmem_data *bdata;
unsigned long node_start_pfn;
- unsigned long node_start_mapnr;
unsigned long node_size;
int node_id;
struct pglist_data *pgdat_next;
@@ -187,9 +185,10 @@
* prototypes for the discontig memory code.
*/
struct page;
-void free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
- unsigned long *zones_size, unsigned long paddr, unsigned long *zholes_size,
- struct page *pmap);
+extern void calculate_totalpages (pg_data_t *pgdat, unsigned long *zones_size,
+ unsigned long *zholes_size);
+extern void free_area_init_core(pg_data_t *pgdat, unsigned long *zones_size,
+ unsigned long *zholes_size);
void get_zone_counts(unsigned long *active, unsigned long *inactive);
extern pg_data_t contig_page_data;
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/kernel/ksyms.c 32-free_area_init/kernel/ksyms.c
--- 0-numafixes/kernel/ksyms.c Fri Sep 6 22:40:51 2002
+++ 32-free_area_init/kernel/ksyms.c Fri Sep 6 23:03:19 2002
@@ -114,9 +114,11 @@
EXPORT_SYMBOL(vmap);
EXPORT_SYMBOL(vunmap);
EXPORT_SYMBOL(vmalloc_to_page);
-EXPORT_SYMBOL(mem_map);
EXPORT_SYMBOL(remap_page_range);
+#ifndef CONFIG_DISCONTIGMEM
+EXPORT_SYMBOL(mem_map);
EXPORT_SYMBOL(max_mapnr);
+#endif
EXPORT_SYMBOL(high_memory);
EXPORT_SYMBOL(vmtruncate);
EXPORT_SYMBOL(find_vma);
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/kernel/suspend.c 32-free_area_init/kernel/suspend.c
--- 0-numafixes/kernel/suspend.c Fri Sep 6 22:40:51 2002
+++ 32-free_area_init/kernel/suspend.c Fri Sep 6 23:03:19 2002
@@ -470,10 +470,12 @@
int nr_copy_pages = 0;
int pfn;
struct page *page;
-
+
+#ifndef CONFIG_DISCONTIGMEM
if (max_mapnr != num_physpages)
panic("mapnr is not expected");
- for (pfn = 0; pfn < max_mapnr; pfn++) {
+#endif
+ for (pfn = 0; pfn < num_physpages; pfn++) {
page = pfn_to_page(pfn);
if (PageHighMem(page))
panic("Swsusp not supported on highmem boxes. Send 1GB of RAM to <pavel@ucw.cz> and try again ;-).");
@@ -513,19 +515,20 @@
static void free_suspend_pagedir(unsigned long this_pagedir)
{
- struct page *page = mem_map;
- int i;
+ struct page *page;
+ int pfn;
unsigned long this_pagedir_end = this_pagedir +
(PAGE_SIZE << pagedir_order);
- for(i=0; i < num_physpages; i++, page++) {
+ for(pfn = 0; pfn < num_physpages; pfn++) {
+ page = pfn_to_page(pfn);
if (!TestClearPageNosave(page))
continue;
- if (ADDRESS(i) >= this_pagedir && ADDRESS(i) < this_pagedir_end)
+ if (ADDRESS(pfn) >= this_pagedir && ADDRESS(pfn) < this_pagedir_end)
continue; /* old pagedir gets freed in one */
- free_page(ADDRESS(i));
+ free_page(ADDRESS(pfn));
}
free_pages(this_pagedir, pagedir_order);
}
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/mm/memory.c 32-free_area_init/mm/memory.c
--- 0-numafixes/mm/memory.c Fri Sep 6 22:40:52 2002
+++ 32-free_area_init/mm/memory.c Fri Sep 6 23:03:19 2002
@@ -53,7 +53,12 @@
#include <linux/swapops.h>
+#ifndef CONFIG_DISCONTIGMEM
+/* use the per-pgdat data instead for discontigmem - mbligh */
unsigned long max_mapnr;
+struct page *mem_map;
+#endif
+
unsigned long num_physpages;
void * high_memory;
struct page *highmem_start_page;
@@ -71,8 +76,6 @@
}
copy_user_highpage(to, from, address);
}
-
-struct page *mem_map;
/*
* Note: this doesn't free the actual pages themselves. That
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/mm/numa.c 32-free_area_init/mm/numa.c
--- 0-numafixes/mm/numa.c Fri Sep 6 22:40:52 2002
+++ 32-free_area_init/mm/numa.c Fri Sep 6 23:03:19 2002
@@ -22,11 +22,21 @@
* Should be invoked with paramters (0, 0, unsigned long *[], start_paddr).
*/
void __init free_area_init_node(int nid, pg_data_t *pgdat, struct page *pmap,
- unsigned long *zones_size, unsigned long zone_start_pfn,
+ unsigned long *zones_size, unsigned long node_start_pfn,
unsigned long *zholes_size)
{
- free_area_init_core(0, &contig_page_data, &mem_map, zones_size,
- zone_start_pfn, zholes_size, pmap);
+ unsigned long size;
+
+ contig_page_data.node_id = 0;
+ contig_page_data.node_start_pfn = node_start_pfn;
+ calculate_totalpages (&contig_page_data, zones_size, zholes_size);
+ if (pmap == (struct page *)0) {
+ size = (pgdat->node_size + 1) * sizeof(struct page);
+ pmap = (struct page *) alloc_bootmem_node(pgdat, size);
+ }
+ contig_page_data.node_mem_map = pmap;
+ free_area_init_core(&contig_page_data, zones_size, zholes_size);
+ mem_map = contig_page_data.node_mem_map;
}
#endif /* !CONFIG_DISCONTIGMEM */
@@ -48,22 +58,26 @@
* Nodes can be initialized parallely, in no particular order.
*/
void __init free_area_init_node(int nid, pg_data_t *pgdat, struct page *pmap,
- unsigned long *zones_size, unsigned long zone_start_pfn,
+ unsigned long *zones_size, unsigned long node_start_pfn,
unsigned long *zholes_size)
{
- int i, size = 0;
- struct page *discard;
-
- if (mem_map == NULL)
- mem_map = (struct page *)PAGE_OFFSET;
+ int i;
+ unsigned long size;
- free_area_init_core(nid, pgdat, &discard, zones_size, zone_start_pfn,
- zholes_size, pmap);
pgdat->node_id = nid;
+ pgdat->node_start_pfn = node_start_pfn;
+ calculate_totalpages (pgdat, zones_size, zholes_size);
+ if (pmap == (struct page *)0) {
+ size = (pgdat->node_size + 1) * sizeof(struct page);
+ pmap = (struct page *) alloc_bootmem_node(pgdat, size);
+ }
+ pgdat->node_mem_map = pmap;
+ free_area_init_core(pgdat, zones_size, zholes_size);
/*
* Get space for the valid bitmap.
*/
+ size = 0;
for (i = 0; i < MAX_NR_ZONES; i++)
size += zones_size[i];
size = LONG_ALIGN((size + 7) >> 3);
diff -urN -X /home/mbligh/.diff.exclude 0-numafixes/mm/page_alloc.c 32-free_area_init/mm/page_alloc.c
--- 0-numafixes/mm/page_alloc.c Fri Sep 6 22:40:52 2002
+++ 32-free_area_init/mm/page_alloc.c Fri Sep 6 23:28:41 2002
@@ -724,6 +724,23 @@
}
}
+void __init calculate_totalpages (pg_data_t *pgdat, unsigned long *zones_size,
+ unsigned long *zholes_size)
+{
+ unsigned long realtotalpages, totalpages = 0;
+ int i;
+
+ for (i = 0; i < MAX_NR_ZONES; i++)
+ totalpages += zones_size[i];
+ pgdat->node_size = totalpages;
+
+ realtotalpages = totalpages;
+ if (zholes_size)
+ for (i = 0; i < MAX_NR_ZONES; i++)
+ realtotalpages -= zholes_size[i];
+ printk("On node %d totalpages: %lu\n", pgdat->node_id, realtotalpages);
+}
+
/*
* Helper functions to size the waitqueue hash table.
* Essentially these want to choose hash table sizes sufficiently
@@ -774,46 +791,18 @@
* - mark all memory queues empty
* - clear the memory bitmaps
*/
-void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
- unsigned long *zones_size, unsigned long zone_start_pfn,
- unsigned long *zholes_size, struct page *lmem_map)
+void __init free_area_init_core(pg_data_t *pgdat,
+ unsigned long *zones_size, unsigned long *zholes_size)
{
unsigned long i, j;
- unsigned long map_size;
- unsigned long totalpages, offset, realtotalpages;
+ unsigned long local_offset;
const unsigned long zone_required_alignment = 1UL << (MAX_ORDER-1);
+ int nid = pgdat->node_id;
+ struct page *lmem_map = pgdat->node_mem_map;
+ unsigned long zone_start_pfn = pgdat->node_start_pfn;
- totalpages = 0;
- for (i = 0; i < MAX_NR_ZONES; i++)
- totalpages += zones_size[i];
-
- realtotalpages = totalpages;
- if (zholes_size)
- for (i = 0; i < MAX_NR_ZONES; i++)
- realtotalpages -= zholes_size[i];
-
- printk("On node %d totalpages: %lu\n", nid, realtotalpages);
-
- /*
- * Some architectures (with lots of mem and discontinous memory
- * maps) have to search for a good mem_map area:
- * For discontigmem, the conceptual mem map array starts from
- * PAGE_OFFSET, we need to align the actual array onto a mem map
- * boundary, so that MAP_NR works.
- */
- map_size = (totalpages + 1)*sizeof(struct page);
- if (lmem_map == (struct page *)0) {
- lmem_map = (struct page *) alloc_bootmem_node(pgdat, map_size);
- lmem_map = (struct page *)(PAGE_OFFSET +
- MAP_ALIGN((unsigned long)lmem_map - PAGE_OFFSET));
- }
- *gmap = pgdat->node_mem_map = lmem_map;
- pgdat->node_size = totalpages;
- pgdat->node_start_pfn = zone_start_pfn;
- pgdat->node_start_mapnr = (lmem_map - mem_map);
pgdat->nr_zones = 0;
-
- offset = lmem_map - mem_map;
+ local_offset = 0; /* offset within lmem_map */
for (j = 0; j < MAX_NR_ZONES; j++) {
struct zone *zone = pgdat->node_zones + j;
unsigned long mask;
@@ -865,8 +854,7 @@
zone->pages_low = mask*2;
zone->pages_high = mask*3;
- zone->zone_mem_map = mem_map + offset;
- zone->zone_start_mapnr = offset;
+ zone->zone_mem_map = lmem_map + local_offset;
zone->zone_start_pfn = zone_start_pfn;
if ((zone_start_pfn) & (zone_required_alignment-1))
@@ -878,7 +866,7 @@
* done. Non-atomic initialization, single-pass.
*/
for (i = 0; i < size; i++) {
- struct page *page = mem_map + offset + i;
+ struct page *page = lmem_map + local_offset + i;
set_page_zone(page, nid * MAX_NR_ZONES + j);
set_page_count(page, 0);
SetPageReserved(page);
@@ -892,7 +880,7 @@
zone_start_pfn++;
}
- offset += size;
+ local_offset += size;
for (i = 0; ; i++) {
unsigned long bitmap_size;
@@ -934,10 +922,13 @@
build_zonelists(pgdat);
}
+#ifndef CONFIG_DISCONTIGMEM
void __init free_area_init(unsigned long *zones_size)
{
- free_area_init_core(0, &contig_page_data, &mem_map, zones_size, 0, 0, 0);
+ free_area_init_node(0, &contig_page_data, NULL, zones_size, 0, NULL);
+ mem_map = contig_page_data.node_mem_map;
}
+#endif
static int __init setup_mem_frac(char *str)
{
reply other threads:[~2002-09-08 5:08 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='185352292.1031436510@[10.10.2.3]' \
--to=fletch@aracnet.com \
--cc=akpm@zip.com.au \
--cc=linux-mm@kvack.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox