Messages in this thread Patch in this message | | | Date | Wed, 20 Oct 1999 20:07:47 +0200 (CEST) | From | Ingo Molnar <> | Subject | [patch] highmem-2.3.23-D3 |
| |
the previous patch had a silly bug, this one works instead. highmem-2.3.23-D3:
- fixes PG_DMA handling
- allocates boot-time pages above MAX_DMA_ADDRESS, if possible.
-- mingo --- linux/mm/bootmem.c.orig2 Wed Oct 20 09:20:39 1999 +++ linux/mm/bootmem.c Wed Oct 20 10:56:40 1999 @@ -16,6 +16,7 @@ #include <linux/interrupt.h> #include <linux/init.h> #include <linux/bootmem.h> +#include <asm/dma.h> /* * Pointer to a bitmap - the bits represent all physical memory pages @@ -24,9 +25,10 @@ * Access to this subsystem has to be serialized externally. (this is * true for the boot process anyway) */ -static void * bootmem_map = NULL; unsigned long max_low_pfn; +static void * bootmem_map = NULL; + /* * Called once to set up the allocator itself. */ @@ -107,20 +109,32 @@ /* * alignment has to be a power of 2 value. */ -void * __init __alloc_bootmem (unsigned long size, unsigned long align) +void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal) { int area = 0; unsigned long i, start = 0, reserved; void *ret; unsigned long offset, remaining_size; - unsigned long areasize; + unsigned long areasize, preferred; if (!bootmem_map) BUG(); if (!size) BUG(); + /* + * We try to allocate bootmem pages above 'goal' + * first, then we try to allocate lower pages. + */ + if (goal) { + preferred = goal >> PAGE_SHIFT; + if (preferred >= max_low_pfn) + preferred = 0; + } else + preferred = 0; + areasize = (size+PAGE_SIZE-1)/PAGE_SIZE; - for (i = 0; i < max_low_pfn; i++) { +restart_scan: + for (i = preferred; i < max_low_pfn; i++) { reserved = test_bit(i, bootmem_map); if (!reserved) { if (!area) { @@ -134,6 +148,10 @@ start = -1; } } + if (preferred) { + preferred = 0; + goto restart_scan; + } BUG(); found: if (start >= max_low_pfn) @@ -186,7 +204,6 @@ if (!bootmem_map) BUG(); - printk("freeing all bootmem().\n"); page = mem_map; count = 0; for (i = 0; i < max_low_pfn; i++, page++) { @@ -194,6 +211,8 @@ count++; ClearPageReserved(page); set_page_count(page, 1); + if (i >= (__pa(MAX_DMA_ADDRESS) >> PAGE_SHIFT)) + clear_bit(PG_DMA, page); __free_page(page); } } --- linux/include/linux/bootmem.h.orig2 Wed Oct 20 10:14:45 1999 +++ linux/include/linux/bootmem.h Wed Oct 20 10:57:11 1999 @@ -3,6 +3,7 @@ #include <linux/config.h> #include <asm/pgtable.h> +#include <asm/dma.h> /* * simple boot-time physical memory area allocator. @@ -13,9 +14,13 @@ extern unsigned long __init init_bootmem (unsigned long addr, unsigned long memend); extern void __init reserve_bootmem (unsigned long addr, unsigned long size); extern void __init free_bootmem (unsigned long addr, unsigned long size); -extern void * __init __alloc_bootmem (unsigned long size, unsigned long align); -#define alloc_bootmem(x) __alloc_bootmem((x), SMP_CACHE_BYTES) -#define alloc_bootmem_pages(x) __alloc_bootmem((x), PAGE_SIZE) +extern void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal); +#define alloc_bootmem(x) \ + __alloc_bootmem((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) +#define alloc_bootmem_pages(x) \ + __alloc_bootmem((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) +#define alloc_bootmem_low_pages(x) \ + __alloc_bootmem((x), PAGE_SIZE, 0) extern unsigned long __init free_all_bootmem (void); #endif /* _LINUX_BOOTMEM_H */ --- linux/arch/i386/mm/init.c.orig2 Wed Oct 20 10:48:49 1999 +++ linux/arch/i386/mm/init.c Wed Oct 20 10:49:22 1999 @@ -286,7 +286,7 @@ for (; (i < PTRS_PER_PGD) && (vaddr <= end); pgd++, i++) { vaddr = i*PGDIR_SIZE; #if CONFIG_X86_PAE - pmd = (pmd_t *) alloc_bootmem_pages(PAGE_SIZE); + pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); memset((void*)pmd, 0, PAGE_SIZE); pgd_val(*pgd) = __pa(pmd) + 0x1; #else @@ -311,7 +311,7 @@ continue; } - pte = (pte_t *) alloc_bootmem_pages(PAGE_SIZE); + pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); memset((void*)pte, 0, PAGE_SIZE); pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte); @@ -340,7 +340,7 @@ for ( ; (i < PTRS_PER_PGD) && vaddr; pgd++, i++) { #if CONFIG_X86_PAE if (pgd_none(*pgd)) { - pmd = (pmd_t *) alloc_bootmem_pages(PAGE_SIZE); + pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); memset((void*)pmd, 0, PAGE_SIZE); pgd_val(*pgd) = __pa(pmd) + 0x1; if (pmd != pmd_offset(pgd, vaddr)) @@ -352,7 +352,7 @@ #endif for (; (j < PTRS_PER_PMD) && vaddr; pmd++, j++) { if (pmd_none(*pmd)) { - pte = (pte_t *) alloc_bootmem_pages(PAGE_SIZE); + pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); memset((void*)pte, 0, PAGE_SIZE); pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte); if (pte != pte_offset(pmd, 0)) --- linux/arch/i386/kernel/smpboot.c.orig2 Wed Oct 20 10:16:47 1999 +++ linux/arch/i386/kernel/smpboot.c Wed Oct 20 10:16:57 1999 @@ -633,7 +633,7 @@ */ void __init smp_alloc_memory(void) { - trampoline_base = (void *) alloc_bootmem_pages(PAGE_SIZE); + trampoline_base = (void *) alloc_bootmem_low_pages(PAGE_SIZE); /* * Has to be in very low memory so we can execute * real-mode AP code.
| |