diff options
author | David Howells <dhowells@redhat.com> | 2005-01-04 05:15:26 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-01-04 05:15:26 -0800 |
commit | 2954850ea90ffb25c0acff03398af95fbde3d034 (patch) | |
tree | e3fa62f5754b9d550e8b393e8d0e16ee1a620960 /mm | |
parent | de796c9af8ac2598eb501ec05d117d7f7822c221 (diff) | |
download | history-2954850ea90ffb25c0acff03398af95fbde3d034.tar.gz |
[PATCH] VM routine fixes
The attached patch fixes a number of problems in the VM routines:
(1) Some inline funcs don't compile if CONFIG_MMU is not set.
(2) swapper_pml4 needn't exist if CONFIG_MMU is not set.
(3) __free_pages_ok() doesn't counter set_page_refs() different behaviour if
CONFIG_MMU is not set.
(4) swsusp.c invokes TLB flushing functions without including the header file
that declares them.
CONFIG_SHMEM semantics:
- If MMU: Always enabled if !EMBEDDED
- If MMU && EMBEDDED: configurable
- If !MMU: disabled
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/Makefile | 4 | ||||
-rw-r--r-- | mm/bootmem.c | 10 | ||||
-rw-r--r-- | mm/internal.h | 13 | ||||
-rw-r--r-- | mm/page_alloc.c | 13 | ||||
-rw-r--r-- | mm/tiny-shmem.c | 2 |
5 files changed, 34 insertions, 8 deletions
diff --git a/mm/Makefile b/mm/Makefile index 7cea59b58bccf4..4fb15e11539578 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -5,10 +5,10 @@ mmu-y := nommu.o mmu-$(CONFIG_MMU) := fremap.o highmem.o madvise.o memory.o mincore.o \ mlock.o mmap.o mprotect.o mremap.o msync.o rmap.o \ - vmalloc.o + vmalloc.o prio_tree.o obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \ - page_alloc.o page-writeback.o pdflush.o prio_tree.o \ + page_alloc.o page-writeback.o pdflush.o \ readahead.o slab.o swap.o truncate.o vmscan.o \ $(mmu-y) diff --git a/mm/bootmem.c b/mm/bootmem.c index 5e2dce496fb01e..260e703850d827 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -19,6 +19,7 @@ #include <linux/module.h> #include <asm/dma.h> #include <asm/io.h> +#include "internal.h" /* * Access to this subsystem has to be serialized externally. (this is @@ -275,17 +276,18 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat) for (i = 0; i < idx; ) { unsigned long v = ~map[i / BITS_PER_LONG]; if (gofast && v == ~0UL) { - int j; + int j, order; count += BITS_PER_LONG; __ClearPageReserved(page); - set_page_count(page, 1); + order = ffs(BITS_PER_LONG) - 1; + set_page_refs(page, order); for (j = 1; j < BITS_PER_LONG; j++) { if (j + 16 < BITS_PER_LONG) prefetchw(page + j + 16); __ClearPageReserved(page + j); } - __free_pages(page, ffs(BITS_PER_LONG)-1); + __free_pages(page, order); i += BITS_PER_LONG; page += BITS_PER_LONG; } else if (v) { @@ -294,7 +296,7 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat) if (v & m) { count++; __ClearPageReserved(page); - set_page_count(page, 1); + set_page_refs(page, 0); __free_page(page); } } diff --git a/mm/internal.h b/mm/internal.h new file mode 100644 index 00000000000000..6bf134e8fb3d4c --- /dev/null +++ b/mm/internal.h @@ -0,0 +1,13 @@ +/* internal.h: mm/ internal definitions + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +/* page_alloc.c */ +extern void set_page_refs(struct page *page, int order); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 5c0b0f827c58bd..4fb4da2dd5e28e 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -35,6 +35,7 @@ #include <linux/vmalloc.h> #include <asm/tlbflush.h> +#include "internal.h" nodemask_t node_online_map = NODE_MASK_NONE; nodemask_t node_possible_map = NODE_MASK_ALL; @@ -284,6 +285,13 @@ void __free_pages_ok(struct page *page, unsigned int order) arch_free_page(page, order); mod_page_state(pgfree, 1 << order); + +#ifndef CONFIG_MMU + if (order > 0) + for (i = 1 ; i < (1 << order) ; ++i) + __put_page(page + i); +#endif + for (i = 0 ; i < (1 << order) ; ++i) free_pages_check(__FUNCTION__, page + i); list_add(&page->lru, &list); @@ -326,7 +334,7 @@ expand(struct zone *zone, struct page *page, return page; } -static inline void set_page_refs(struct page *page, int order) +void set_page_refs(struct page *page, int order) { #ifdef CONFIG_MMU set_page_count(page, 1); @@ -336,9 +344,10 @@ static inline void set_page_refs(struct page *page, int order) /* * We need to reference all the pages for this order, otherwise if * anyone accesses one of the pages with (get/put) it will be freed. + * - eg: access_process_vm() */ for (i = 0; i < (1 << order); i++) - set_page_count(page+i, 1); + set_page_count(page + i, 1); #endif /* CONFIG_MMU */ } diff --git a/mm/tiny-shmem.c b/mm/tiny-shmem.c index c13a2161bca286..83f5ff1746724d 100644 --- a/mm/tiny-shmem.c +++ b/mm/tiny-shmem.c @@ -112,7 +112,9 @@ int shmem_zero_setup(struct vm_area_struct *vma) if (vma->vm_file) fput(vma->vm_file); vma->vm_file = file; +#ifdef CONFIG_MMU vma->vm_ops = &generic_file_vm_ops; +#endif return 0; } |