ia64/linux-2.6.18-xen.hg

annotate mm/page_io.c @ 452:c7ed6fe5dca0

kexec: dont initialise regions in reserve_memory()

There is no need to initialise efi_memmap_res and boot_param_res in
reserve_memory() for the initial xen domain as it is done in
machine_kexec_setup_resources() using values from the kexec hypercall.

Signed-off-by: Simon Horman <horms@verge.net.au>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Feb 28 10:55:18 2008 +0000 (2008-02-28)
parents 831230e53067
children cad6f60f0506
rev   line source
ian@0 1 /*
ian@0 2 * linux/mm/page_io.c
ian@0 3 *
ian@0 4 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
ian@0 5 *
ian@0 6 * Swap reorganised 29.12.95,
ian@0 7 * Asynchronous swapping added 30.12.95. Stephen Tweedie
ian@0 8 * Removed race in async swapping. 14.4.1996. Bruno Haible
ian@0 9 * Add swap of shared pages through the page cache. 20.2.1998. Stephen Tweedie
ian@0 10 * Always use brw_page, life becomes simpler. 12 May 1998 Eric Biederman
ian@0 11 */
ian@0 12
ian@0 13 #include <linux/mm.h>
ian@0 14 #include <linux/kernel_stat.h>
ian@0 15 #include <linux/pagemap.h>
ian@0 16 #include <linux/swap.h>
ian@0 17 #include <linux/bio.h>
ian@0 18 #include <linux/swapops.h>
ian@0 19 #include <linux/writeback.h>
ian@0 20 #include <asm/pgtable.h>
ian@0 21
ian@0 22 static struct bio *get_swap_bio(gfp_t gfp_flags, pgoff_t index,
ian@0 23 struct page *page, bio_end_io_t end_io)
ian@0 24 {
ian@0 25 struct bio *bio;
ian@0 26
ian@0 27 bio = bio_alloc(gfp_flags, 1);
ian@0 28 if (bio) {
ian@0 29 struct swap_info_struct *sis;
ian@0 30 swp_entry_t entry = { .val = index, };
ian@0 31
ian@0 32 sis = get_swap_info_struct(swp_type(entry));
ian@0 33 bio->bi_sector = map_swap_page(sis, swp_offset(entry)) *
ian@0 34 (PAGE_SIZE >> 9);
ian@0 35 bio->bi_bdev = sis->bdev;
ian@0 36 bio->bi_io_vec[0].bv_page = page;
ian@0 37 bio->bi_io_vec[0].bv_len = PAGE_SIZE;
ian@0 38 bio->bi_io_vec[0].bv_offset = 0;
ian@0 39 bio->bi_vcnt = 1;
ian@0 40 bio->bi_idx = 0;
ian@0 41 bio->bi_size = PAGE_SIZE;
ian@0 42 bio->bi_end_io = end_io;
ian@0 43 }
ian@0 44 return bio;
ian@0 45 }
ian@0 46
ian@0 47 static int end_swap_bio_write(struct bio *bio, unsigned int bytes_done, int err)
ian@0 48 {
ian@0 49 const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
ian@0 50 struct page *page = bio->bi_io_vec[0].bv_page;
ian@0 51
ian@0 52 if (bio->bi_size)
ian@0 53 return 1;
ian@0 54
ian@0 55 if (!uptodate)
ian@0 56 SetPageError(page);
ian@0 57 end_page_writeback(page);
ian@0 58 bio_put(bio);
ian@0 59 return 0;
ian@0 60 }
ian@0 61
ian@0 62 static int end_swap_bio_read(struct bio *bio, unsigned int bytes_done, int err)
ian@0 63 {
ian@0 64 const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
ian@0 65 struct page *page = bio->bi_io_vec[0].bv_page;
ian@0 66
ian@0 67 if (bio->bi_size)
ian@0 68 return 1;
ian@0 69
ian@0 70 if (!uptodate) {
ian@0 71 SetPageError(page);
ian@0 72 ClearPageUptodate(page);
ian@0 73 } else {
ian@0 74 SetPageUptodate(page);
ian@0 75 }
ian@0 76 unlock_page(page);
ian@0 77 bio_put(bio);
ian@0 78 return 0;
ian@0 79 }
ian@0 80
ian@0 81 /*
ian@0 82 * We may have stale swap cache pages in memory: notice
ian@0 83 * them here and get rid of the unnecessary final write.
ian@0 84 */
ian@0 85 int swap_writepage(struct page *page, struct writeback_control *wbc)
ian@0 86 {
ian@0 87 struct bio *bio;
ian@0 88 int ret = 0, rw = WRITE;
ian@0 89
ian@0 90 if (remove_exclusive_swap_page(page)) {
ian@0 91 unlock_page(page);
ian@0 92 goto out;
ian@0 93 }
ian@0 94 bio = get_swap_bio(GFP_NOIO, page_private(page), page,
ian@0 95 end_swap_bio_write);
ian@0 96 if (bio == NULL) {
ian@0 97 set_page_dirty(page);
ian@0 98 unlock_page(page);
ian@0 99 ret = -ENOMEM;
ian@0 100 goto out;
ian@0 101 }
ian@0 102 if (wbc->sync_mode == WB_SYNC_ALL)
ian@0 103 rw |= (1 << BIO_RW_SYNC);
ian@0 104 count_vm_event(PSWPOUT);
ian@0 105 set_page_writeback(page);
ian@0 106 unlock_page(page);
ian@0 107 submit_bio(rw, bio);
ian@0 108 out:
ian@0 109 return ret;
ian@0 110 }
ian@0 111
ian@0 112 int swap_readpage(struct file *file, struct page *page)
ian@0 113 {
ian@0 114 struct bio *bio;
ian@0 115 int ret = 0;
ian@0 116
ian@0 117 BUG_ON(!PageLocked(page));
ian@0 118 ClearPageUptodate(page);
ian@0 119 bio = get_swap_bio(GFP_KERNEL, page_private(page), page,
ian@0 120 end_swap_bio_read);
ian@0 121 if (bio == NULL) {
ian@0 122 unlock_page(page);
ian@0 123 ret = -ENOMEM;
ian@0 124 goto out;
ian@0 125 }
ian@0 126 count_vm_event(PSWPIN);
ian@0 127 submit_bio(READ, bio);
ian@0 128 out:
ian@0 129 return ret;
ian@0 130 }
ian@0 131
ian@0 132 #ifdef CONFIG_SOFTWARE_SUSPEND
ian@0 133 /*
ian@0 134 * A scruffy utility function to read or write an arbitrary swap page
ian@0 135 * and wait on the I/O. The caller must have a ref on the page.
ian@0 136 *
ian@0 137 * We use end_swap_bio_read() even for writes, because it happens to do what
ian@0 138 * we want.
ian@0 139 */
ian@0 140 int rw_swap_page_sync(int rw, swp_entry_t entry, struct page *page)
ian@0 141 {
ian@0 142 struct bio *bio;
ian@0 143 int ret = 0;
ian@0 144
ian@0 145 lock_page(page);
ian@0 146
ian@0 147 bio = get_swap_bio(GFP_KERNEL, entry.val, page, end_swap_bio_read);
ian@0 148 if (bio == NULL) {
ian@0 149 unlock_page(page);
ian@0 150 ret = -ENOMEM;
ian@0 151 goto out;
ian@0 152 }
ian@0 153
ian@0 154 submit_bio(rw | (1 << BIO_RW_SYNC), bio);
ian@0 155 wait_on_page_locked(page);
ian@0 156
ian@0 157 if (!PageUptodate(page) || PageError(page))
ian@0 158 ret = -EIO;
ian@0 159 out:
ian@0 160 return ret;
ian@0 161 }
ian@0 162 #endif