diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 01:05:20 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 01:05:20 +0000 |
commit | 546db14ee74118296f425f3b91634fb767d67290 (patch) | |
tree | 22b613a3da8d4bf663eec5e155af01b87fdf9094 /mm/highmem.c | |
parent | 1e25e41c4f5474e14452094492dbc169b800e4c8 (diff) |
Merge with Linux 2.3.23. The new bootmem stuff has broken various
platforms. At this time I've only verified that IP22 support compiles
and IP27 actually works.
Diffstat (limited to 'mm/highmem.c')
-rw-r--r-- | mm/highmem.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/mm/highmem.c b/mm/highmem.c new file mode 100644 index 000000000..7665393cf --- /dev/null +++ b/mm/highmem.c @@ -0,0 +1,81 @@ +/* + * High memory handling common code and variables. + * + * (C) 1999 Andrea Arcangeli, SuSE GmbH, andrea@suse.de + * Gerhard Wichert, Siemens AG, Gerhard.Wichert@pdb.siemens.de + * + * Redesigned the x86 32-bit VM architecture to deal with + * 64-bit physical space. With current x86 CPUs this + * means up to 64 Gigabytes physical RAM. + * + * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com> + */ + +#include <linux/mm.h> +#include <linux/pagemap.h> +#include <linux/highmem.h> + +unsigned long highmem_mapnr; +unsigned long nr_free_highpages = 0; + +struct page * prepare_highmem_swapout(struct page * page) +{ + unsigned long regular_page; + unsigned long vaddr; + /* + * If this is a highmem page so it can't be swapped out directly + * otherwise the b_data buffer addresses will break + * the lowlevel device drivers. + */ + if (!PageHighMem(page)) + return page; + + regular_page = __get_free_page(GFP_ATOMIC); + if (!regular_page) + return NULL; + + vaddr = kmap(page, KM_READ); + copy_page((void *)regular_page, (void *)vaddr); + kunmap(vaddr, KM_READ); + + /* + * ok, we can just forget about our highmem page since + * we stored its data into the new regular_page. + */ + __free_page(page); + + return mem_map + MAP_NR(regular_page); +} + +struct page * replace_with_highmem(struct page * page) +{ + struct page *highpage; + unsigned long vaddr; + + if (PageHighMem(page) || !nr_free_highpages) + return page; + + highpage = get_free_highpage(GFP_ATOMIC|__GFP_HIGHMEM); + if (!highpage) + return page; + if (!PageHighMem(highpage)) { + __free_page(highpage); + return page; + } + + vaddr = kmap(highpage, KM_WRITE); + copy_page((void *)vaddr, (void *)page_address(page)); + kunmap(vaddr, KM_WRITE); + + /* Preserve the caching of the swap_entry. */ + highpage->offset = page->offset; + highpage->inode = page->inode; + + /* + * We can just forget the old page since + * we stored its data into the new highmem-page. + */ + __free_page(page); + + return highpage; +} |