summaryrefslogtreecommitdiffstats
path: root/mm/highmem.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-01-27 01:05:20 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-01-27 01:05:20 +0000
commit546db14ee74118296f425f3b91634fb767d67290 (patch)
tree22b613a3da8d4bf663eec5e155af01b87fdf9094 /mm/highmem.c
parent1e25e41c4f5474e14452094492dbc169b800e4c8 (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.c81
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;
+}