swap_state.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/mm/swap_state.c
  3.  *
  4.  *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  5.  *  Swap reorganised 29.12.95, Stephen Tweedie
  6.  *
  7.  *  Rewritten to use page cache, (C) 1998 Stephen Tweedie
  8.  */
  9. #include <linux/mm.h>
  10. #include <linux/kernel_stat.h>
  11. #include <linux/swap.h>
  12. #include <linux/swapctl.h>
  13. #include <linux/init.h>
  14. #include <linux/pagemap.h>
  15. #include <linux/smp_lock.h>
  16. #include <asm/pgtable.h>
  17. /*
  18.  * We may have stale swap cache pages in memory: notice
  19.  * them here and get rid of the unnecessary final write.
  20.  */
  21. static int swap_writepage(struct page *page)
  22. {
  23. if (remove_exclusive_swap_page(page)) {
  24. UnlockPage(page);
  25. return 0;
  26. }
  27. rw_swap_page(WRITE, page);
  28. return 0;
  29. }
  30. static struct address_space_operations swap_aops = {
  31. writepage: swap_writepage,
  32. sync_page: block_sync_page,
  33. };
  34. struct address_space swapper_space = {
  35. LIST_HEAD_INIT(swapper_space.clean_pages),
  36. LIST_HEAD_INIT(swapper_space.dirty_pages),
  37. LIST_HEAD_INIT(swapper_space.locked_pages),
  38. 0, /* nrpages */
  39. &swap_aops,
  40. };
  41. #ifdef SWAP_CACHE_INFO
  42. #define INC_CACHE_INFO(x) (swap_cache_info.x++)
  43. static struct {
  44. unsigned long add_total;
  45. unsigned long del_total;
  46. unsigned long find_success;
  47. unsigned long find_total;
  48. unsigned long noent_race;
  49. unsigned long exist_race;
  50. } swap_cache_info;
  51. void show_swap_cache_info(void)
  52. {
  53. printk("Swap cache: add %lu, delete %lu, find %lu/%lu, race %lu+%lun",
  54. swap_cache_info.add_total, swap_cache_info.del_total,
  55. swap_cache_info.find_success, swap_cache_info.find_total,
  56. swap_cache_info.noent_race, swap_cache_info.exist_race);
  57. }
  58. #else
  59. #define INC_CACHE_INFO(x) do { } while (0)
  60. #endif
  61. int add_to_swap_cache(struct page *page, swp_entry_t entry)
  62. {
  63. if (page->mapping)
  64. BUG();
  65. if (!swap_duplicate(entry)) {
  66. INC_CACHE_INFO(noent_race);
  67. return -ENOENT;
  68. }
  69. if (add_to_page_cache_unique(page, &swapper_space, entry.val,
  70. page_hash(&swapper_space, entry.val)) != 0) {
  71. swap_free(entry);
  72. INC_CACHE_INFO(exist_race);
  73. return -EEXIST;
  74. }
  75. if (!PageLocked(page))
  76. BUG();
  77. if (!PageSwapCache(page))
  78. BUG();
  79. INC_CACHE_INFO(add_total);
  80. return 0;
  81. }
  82. /*
  83.  * This must be called only on pages that have
  84.  * been verified to be in the swap cache.
  85.  */
  86. void __delete_from_swap_cache(struct page *page)
  87. {
  88. if (!PageLocked(page))
  89. BUG();
  90. if (!PageSwapCache(page))
  91. BUG();
  92. ClearPageDirty(page);
  93. __remove_inode_page(page);
  94. INC_CACHE_INFO(del_total);
  95. }
  96. /*
  97.  * This must be called only on pages that have
  98.  * been verified to be in the swap cache and locked.
  99.  * It will never put the page into the free list,
  100.  * the caller has a reference on the page.
  101.  */
  102. void delete_from_swap_cache(struct page *page)
  103. {
  104. swp_entry_t entry;
  105. if (!PageLocked(page))
  106. BUG();
  107. block_flushpage(page, 0);
  108. entry.val = page->index;
  109. spin_lock(&pagecache_lock);
  110. __delete_from_swap_cache(page);
  111. spin_unlock(&pagecache_lock);
  112. swap_free(entry);
  113. page_cache_release(page);
  114. }
  115. /* 
  116.  * Perform a free_page(), also freeing any swap cache associated with
  117.  * this page if it is the last user of the page. Can not do a lock_page,
  118.  * as we are holding the page_table_lock spinlock.
  119.  */
  120. void free_page_and_swap_cache(struct page *page)
  121. {
  122. /* 
  123.  * If we are the only user, then try to free up the swap cache. 
  124.  * 
  125.  * Its ok to check for PageSwapCache without the page lock
  126.  * here because we are going to recheck again inside 
  127.  * exclusive_swap_page() _with_ the lock. 
  128.  *  - Marcelo
  129.  */
  130. if (PageSwapCache(page) && !TryLockPage(page)) {
  131. remove_exclusive_swap_page(page);
  132. UnlockPage(page);
  133. }
  134. page_cache_release(page);
  135. }
  136. /*
  137.  * Lookup a swap entry in the swap cache. A found page will be returned
  138.  * unlocked and with its refcount incremented - we rely on the kernel
  139.  * lock getting page table operations atomic even if we drop the page
  140.  * lock before returning.
  141.  */
  142. struct page * lookup_swap_cache(swp_entry_t entry)
  143. {
  144. struct page *found;
  145. found = find_get_page(&swapper_space, entry.val);
  146. /*
  147.  * Unsafe to assert PageSwapCache and mapping on page found:
  148.  * if SMP nothing prevents swapoff from deleting this page from
  149.  * the swap cache at this moment.  find_lock_page would prevent
  150.  * that, but no need to change: we _have_ got the right page.
  151.  */
  152. INC_CACHE_INFO(find_total);
  153. if (found)
  154. INC_CACHE_INFO(find_success);
  155. return found;
  156. }
  157. /* 
  158.  * Locate a page of swap in physical memory, reserving swap cache space
  159.  * and reading the disk if it is not already cached.
  160.  * A failure return means that either the page allocation failed or that
  161.  * the swap entry is no longer in use.
  162.  */
  163. struct page * read_swap_cache_async(swp_entry_t entry)
  164. {
  165. struct page *found_page, *new_page = NULL;
  166. int err;
  167. do {
  168. /*
  169.  * First check the swap cache.  Since this is normally
  170.  * called after lookup_swap_cache() failed, re-calling
  171.  * that would confuse statistics: use find_get_page()
  172.  * directly.
  173.  */
  174. found_page = find_get_page(&swapper_space, entry.val);
  175. if (found_page)
  176. break;
  177. /*
  178.  * Get a new page to read into from swap.
  179.  */
  180. if (!new_page) {
  181. new_page = alloc_page(GFP_HIGHUSER);
  182. if (!new_page)
  183. break; /* Out of memory */
  184. }
  185. /*
  186.  * Associate the page with swap entry in the swap cache.
  187.  * May fail (-ENOENT) if swap entry has been freed since
  188.  * our caller observed it.  May fail (-EEXIST) if there
  189.  * is already a page associated with this entry in the
  190.  * swap cache: added by a racing read_swap_cache_async,
  191.  * or by try_to_swap_out (or shmem_writepage) re-using
  192.  * the just freed swap entry for an existing page.
  193.  */
  194. err = add_to_swap_cache(new_page, entry);
  195. if (!err) {
  196. /*
  197.  * Initiate read into locked page and return.
  198.  */
  199. rw_swap_page(READ, new_page);
  200. return new_page;
  201. }
  202. } while (err != -ENOENT);
  203. if (new_page)
  204. page_cache_release(new_page);
  205. return found_page;
  206. }