--- arch/i386/kernel/setup.c | 0 memhotplug-dave/mm/sparse.c | 118 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 114 insertions(+), 4 deletions(-) diff -puN include/linux/mmzone.h~sparsemem-userspace-debug include/linux/mmzone.h diff -puN mm/sparse.c~sparsemem-userspace-debug mm/sparse.c --- memhotplug/mm/sparse.c~sparsemem-userspace-debug 2005-06-21 17:16:09.000000000 -0700 +++ memhotplug-dave/mm/sparse.c 2005-06-21 17:26:26.000000000 -0700 @@ -1,3 +1,5 @@ +#ifdef __KERNEL__ +#warning KERNEL /* * sparse memory mappings. */ @@ -8,12 +10,93 @@ #include #include +#else + +#include +#define EXPORT_SYMBOL(X) + +#ifndef NULL +#define NULL 0 +#endif +#define EINVAL -1 +#define EEXIST -2 +#define KERN_WARNING +#define __inline inline __attribute__((always_inline)) +#define __init +#define PAGE_SHIFT (12) +#define PAGE_SIZE (1<> PFN_SECTION_SHIFT) +#define section_nr_to_pfn(sec) ((sec) << PFN_SECTION_SHIFT) + + +struct page +{ + char stuff[32]; +}; + +#define __nr_to_section(nr) (&mem_section[(nr)]) +#define __section_nr(sec) (sec - &mem_section[0]) +#define alloc_remap(nid, size) malloc(size) +#define printk printf + +#define __pfn_to_section(pfn) __nr_to_section(pfn_to_section_nr(pfn)) +#define early_pfn_to_nid(nid) 0 + +static unsigned long freed_total = 0; +static void free_bootmem(unsigned long addr, unsigned long size) +{ + freed_total += size; +} +#define valid_section(section) \ + (section->section_mem_map & SECTION_MARKED_PRESENT) +#define valid_section_nr(nr) \ + valid_section(__nr_to_section(nr)) + + +#endif + /* * Permanent SPARSEMEM data: * * 1) mem_section - memory sections, mem_map's for valid memory */ -struct mem_section mem_section[NR_MEM_SECTIONS]; +struct mem_section mem_section[NR_MEM_SECTIONS] +//__attribute__((__aligned__(PAGE_SIZE))) + ; EXPORT_SYMBOL(mem_section); /* Record a memory area against a node. */ @@ -22,8 +105,10 @@ void memory_present(int nid, unsigned lo unsigned long pfn; start &= PAGE_SECTION_MASK; + printf("%s(%d, %08lx, %08lx) %08lx\n", __func__, nid, start, end, PAGES_PER_SECTION); for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) { unsigned long section = pfn_to_section_nr(pfn); + printk("\tsetting section_nr: %ld\n", section); if (!mem_section[section].section_mem_map) mem_section[section].section_mem_map = SECTION_MARKED_PRESENT; } @@ -62,9 +147,12 @@ int vaddr_page_has_sections(void *page_a if (!start_section || !end_section) return 1; - for (sec = start_section; sec < end_section; sec++) { + for (sec = start_section; sec <= end_section; sec++) { if (!section_empty(sec)) { - printk("!section_empty(): nr: %d\n", (sec) - &mem_section[0]); + printf("!sec_empty: %d (%08lx) (%p -> %p)\n", + __section_nr(sec), + sec->section_mem_map, + sec, sec+1); return 1; } } @@ -85,8 +173,9 @@ void all_memory_present(void) printk("mem_section[] range: %p -> %p\n", __nr_to_section(0), __nr_to_section(NR_MEM_SECTIONS)); for (page = begin; page <= end; page += PAGE_SIZE) { - if (vaddr_page_has_sections(page)) + if (vaddr_page_has_sections(page)) { continue; + } printk("all_memory_present() freed page: %p\n", page); free_bootmem(__pa(page), PAGE_SIZE); } @@ -96,6 +185,7 @@ void all_memory_present(void) * Only used by the i386 NUMA architecures, but relatively * generic code. */ +#ifdef __KERNEL__ unsigned long __init node_memmap_size_bytes(int nid, unsigned long start_pfn, unsigned long end_pfn) { @@ -112,6 +202,7 @@ unsigned long __init node_memmap_size_by return nr_pages * sizeof(struct page); } +#endif /* * Subtle, we encode the real pfn into the mem_map such that @@ -146,6 +237,7 @@ static int sparse_init_one_section(struc static struct page *sparse_early_mem_map_alloc(unsigned long pnum) { +#ifdef __KERNEL__ struct page *map; int nid = early_pfn_to_nid(section_nr_to_pfn(pnum)); @@ -161,6 +253,9 @@ static struct page *sparse_early_mem_map printk(KERN_WARNING "%s: allocation failed\n", __FUNCTION__); mem_section[pnum].section_mem_map = 0; return NULL; +#else + return malloc(sizeof(struct page) * PAGES_PER_SECTION); +#endif } /* @@ -198,3 +293,18 @@ int sparse_add_one_section(unsigned long return sparse_init_one_section(ms, pfn_to_section_nr(start_pfn), map); } + +int main(void) +{ + unsigned long long d = sizeof(mem_section); + printk("nr_sections: %ld\n", NR_MEM_SECTIONS); + printk("sizeof: %Ld bytes (%Ld MB)\n", d, d>>20); + printk("addr: %p\n", (&mem_section)); + printk("range: %p -> %p\n", __nr_to_section(0), __nr_to_section(NR_MEM_SECTIONS)); +#define SECTION_SIZE (1<