lkml.org 
[lkml]   [1999]   [Oct]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
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.
\
 
 \ /
  Last update: 2005-03-22 13:54    [W:0.027 / U:1.920 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site