Commit 2954850e authored by David Howells's avatar David Howells Committed by Linus Torvalds

[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: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent de796c9a
...@@ -316,8 +316,9 @@ config CC_OPTIMIZE_FOR_SIZE ...@@ -316,8 +316,9 @@ config CC_OPTIMIZE_FOR_SIZE
If unsure, say N. If unsure, say N.
config SHMEM config SHMEM
bool "Use full shmem filesystem" if EMBEDDED
default y default y
bool "Use full shmem filesystem" if EMBEDDED && MMU depends on MMU
help help
The shmem is an internal filesystem used to manage shared memory. The shmem is an internal filesystem used to manage shared memory.
It is backed by swap and manages resource limits. It is also exported It is backed by swap and manages resource limits. It is also exported
......
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <asm/io.h> #include <asm/io.h>
#include "power.h" #include "power.h"
......
...@@ -765,6 +765,7 @@ static ctl_table vm_table[] = { ...@@ -765,6 +765,7 @@ static ctl_table vm_table[] = {
.strategy = &sysctl_intvec, .strategy = &sysctl_intvec,
.extra1 = &zero, .extra1 = &zero,
}, },
#ifdef CONFIG_MMU
{ {
.ctl_name = VM_MAX_MAP_COUNT, .ctl_name = VM_MAX_MAP_COUNT,
.procname = "max_map_count", .procname = "max_map_count",
...@@ -773,6 +774,7 @@ static ctl_table vm_table[] = { ...@@ -773,6 +774,7 @@ static ctl_table vm_table[] = {
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec .proc_handler = &proc_dointvec
}, },
#endif
{ {
.ctl_name = VM_LAPTOP_MODE, .ctl_name = VM_LAPTOP_MODE,
.procname = "laptop_mode", .procname = "laptop_mode",
...@@ -914,6 +916,7 @@ static ctl_table fs_table[] = { ...@@ -914,6 +916,7 @@ static ctl_table fs_table[] = {
.proc_handler = &proc_dointvec, .proc_handler = &proc_dointvec,
}, },
#endif #endif
#ifdef CONFIG_MMU
{ {
.ctl_name = FS_LEASE_TIME, .ctl_name = FS_LEASE_TIME,
.procname = "lease-break-time", .procname = "lease-break-time",
...@@ -938,6 +941,7 @@ static ctl_table fs_table[] = { ...@@ -938,6 +941,7 @@ static ctl_table fs_table[] = {
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec, .proc_handler = &proc_dointvec,
}, },
#endif
{ .ctl_name = 0 } { .ctl_name = 0 }
}; };
......
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
mmu-y := nommu.o mmu-y := nommu.o
mmu-$(CONFIG_MMU) := fremap.o highmem.o madvise.o memory.o mincore.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 \ 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 \ 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 \ readahead.o slab.o swap.o truncate.o vmscan.o \
$(mmu-y) $(mmu-y)
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <asm/dma.h> #include <asm/dma.h>
#include <asm/io.h> #include <asm/io.h>
#include "internal.h"
/* /*
* Access to this subsystem has to be serialized externally. (this is * 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) ...@@ -275,17 +276,18 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
for (i = 0; i < idx; ) { for (i = 0; i < idx; ) {
unsigned long v = ~map[i / BITS_PER_LONG]; unsigned long v = ~map[i / BITS_PER_LONG];
if (gofast && v == ~0UL) { if (gofast && v == ~0UL) {
int j; int j, order;
count += BITS_PER_LONG; count += BITS_PER_LONG;
__ClearPageReserved(page); __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++) { for (j = 1; j < BITS_PER_LONG; j++) {
if (j + 16 < BITS_PER_LONG) if (j + 16 < BITS_PER_LONG)
prefetchw(page + j + 16); prefetchw(page + j + 16);
__ClearPageReserved(page + j); __ClearPageReserved(page + j);
} }
__free_pages(page, ffs(BITS_PER_LONG)-1); __free_pages(page, order);
i += BITS_PER_LONG; i += BITS_PER_LONG;
page += BITS_PER_LONG; page += BITS_PER_LONG;
} else if (v) { } else if (v) {
...@@ -294,7 +296,7 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat) ...@@ -294,7 +296,7 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
if (v & m) { if (v & m) {
count++; count++;
__ClearPageReserved(page); __ClearPageReserved(page);
set_page_count(page, 1); set_page_refs(page, 0);
__free_page(page); __free_page(page);
} }
} }
......
/* 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);
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include "internal.h"
nodemask_t node_online_map = NODE_MASK_NONE; nodemask_t node_online_map = NODE_MASK_NONE;
nodemask_t node_possible_map = NODE_MASK_ALL; nodemask_t node_possible_map = NODE_MASK_ALL;
...@@ -284,6 +285,13 @@ void __free_pages_ok(struct page *page, unsigned int order) ...@@ -284,6 +285,13 @@ void __free_pages_ok(struct page *page, unsigned int order)
arch_free_page(page, order); arch_free_page(page, order);
mod_page_state(pgfree, 1 << 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) for (i = 0 ; i < (1 << order) ; ++i)
free_pages_check(__FUNCTION__, page + i); free_pages_check(__FUNCTION__, page + i);
list_add(&page->lru, &list); list_add(&page->lru, &list);
...@@ -326,7 +334,7 @@ expand(struct zone *zone, struct page *page, ...@@ -326,7 +334,7 @@ expand(struct zone *zone, struct page *page,
return 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 #ifdef CONFIG_MMU
set_page_count(page, 1); set_page_count(page, 1);
...@@ -336,9 +344,10 @@ static inline void set_page_refs(struct page *page, int order) ...@@ -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 * 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. * anyone accesses one of the pages with (get/put) it will be freed.
* - eg: access_process_vm()
*/ */
for (i = 0; i < (1 << order); i++) for (i = 0; i < (1 << order); i++)
set_page_count(page+i, 1); set_page_count(page + i, 1);
#endif /* CONFIG_MMU */ #endif /* CONFIG_MMU */
} }
......
...@@ -112,7 +112,9 @@ int shmem_zero_setup(struct vm_area_struct *vma) ...@@ -112,7 +112,9 @@ int shmem_zero_setup(struct vm_area_struct *vma)
if (vma->vm_file) if (vma->vm_file)
fput(vma->vm_file); fput(vma->vm_file);
vma->vm_file = file; vma->vm_file = file;
#ifdef CONFIG_MMU
vma->vm_ops = &generic_file_vm_ops; vma->vm_ops = &generic_file_vm_ops;
#endif
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment