swap.c
上传用户:meggie1001
上传日期:2010-01-14
资源大小:35986k
文件大小:6k
源码类别:

操作系统开发

开发平台:

C/C++

  1. /*
  2.  *  linux/mm/swap.c
  3.  *
  4.  *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  5.  */
  6. /*
  7.  * This file contains the default values for the opereation of the
  8.  * Linux VM subsystem. Fine-tuning documentation can be found in
  9.  * linux/Documentation/sysctl/vm.txt.
  10.  * Started 18.12.91
  11.  * Swap aging added 23.2.95, Stephen Tweedie.
  12.  * Buffermem limits added 12.3.98, Rik van Riel.
  13.  */
  14. #include <linux/mm.h>
  15. #include <linux/kernel_stat.h>
  16. #include <linux/swapctl.h>
  17. #include <linux/pagemap.h>
  18. #include <linux/init.h>
  19. #include <linux/mm_inline.h>
  20. #include <asm/dma.h>
  21. #include <asm/uaccess.h> /* for copy_to/from_user */
  22. #include <asm/pgtable.h>
  23. /* How many pages do we try to swap or page in/out together? */
  24. int page_cluster;
  25. pager_daemon_t pager_daemon = {
  26. 512, /* base number for calculating the number of tries */
  27. SWAP_CLUSTER_MAX, /* minimum number of tries */
  28. 8, /* do swap I/O in clusters of this size */
  29. };
  30. /**
  31.  * (de)activate_page - move pages from/to active and inactive lists
  32.  * @page: the page we want to move
  33.  *
  34.  * Deactivate_page will move an active page to the right
  35.  * inactive list, while activate_page will move a page back
  36.  * from one of the inactive lists to the active list. If
  37.  * called on a page which is not on any of the lists, the
  38.  * page is left alone.
  39.  */
  40. void deactivate_page_nolock(struct page * page)
  41. {
  42. /*
  43.  * Don't touch it if it's not on the active list.
  44.  * (some pages aren't on any list at all)
  45.  */
  46. ClearPageReferenced(page);
  47. if (PageActiveAnon(page)) {
  48. del_page_from_active_anon_list(page);
  49. add_page_to_inactive_dirty_list(page);
  50. } else if (PageActiveCache(page)) {
  51. del_page_from_active_cache_list(page);
  52. add_page_to_inactive_dirty_list(page);
  53. }
  54. }
  55. void deactivate_page(struct page * page)
  56. {
  57. lru_lock(page_zone(page));
  58. deactivate_page_nolock(page);
  59. lru_unlock(page_zone(page));
  60. }
  61. /**
  62.  * drop_page - like deactivate_page, but try inactive_clean list
  63.  * @page: the page to drop
  64.  *
  65.  * Try to move a page to the inactive_clean list, this succeeds if the
  66.  * page is clean and not in use by anybody. If the page cannot be placed
  67.  * on the inactive_clean list it is placed on the inactive_dirty list
  68.  * instead.
  69.  *
  70.  * Note: this function gets called with the lru lock held.
  71.  */
  72. void drop_page_zone(struct zone_struct *zone, struct page * page)
  73. {
  74. if (!TryLockPage(page)) {
  75. if (page->mapping && page->buffers) {
  76. page_cache_get(page);
  77. lru_unlock(zone);
  78. try_to_release_page(page, GFP_NOIO);
  79. lru_lock(zone);
  80. page_cache_release(page);
  81. }
  82. UnlockPage(page);
  83. }
  84. /* Make sure the page really is reclaimable. */
  85. pte_chain_lock(page);
  86. if (!page->mapping || PageDirty(page) || page->pte.direct ||
  87. page->buffers || page_count(page) > 1)
  88. deactivate_page_nolock(page);
  89. else if (page_count(page) == 1) {
  90. ClearPageReferenced(page);
  91. if (PageActiveAnon(page)) {
  92. del_page_from_active_anon_list(page);
  93. add_page_to_inactive_clean_list(page);
  94. } else if (PageActiveCache(page)) {
  95. del_page_from_active_cache_list(page);
  96. add_page_to_inactive_clean_list(page);
  97. } else if (PageInactiveDirty(page)) {
  98. del_page_from_inactive_dirty_list(page);
  99. add_page_to_inactive_clean_list(page);
  100. } else if (PageInactiveLaundry(page)) {
  101. del_page_from_inactive_laundry_list(page);
  102. add_page_to_inactive_clean_list(page);
  103. }
  104. }
  105. pte_chain_unlock(page);
  106. }
  107. void drop_page(struct page * page)
  108. {
  109. if (!TryLockPage(page)) {
  110. if (page->mapping && page->buffers) {
  111. page_cache_get(page);
  112. lru_unlock(ALL_ZONES);
  113. try_to_release_page(page, GFP_NOIO);
  114. lru_lock(ALL_ZONES);
  115. page_cache_release(page);
  116. }
  117. UnlockPage(page);
  118. }
  119. /* Make sure the page really is reclaimable. */
  120. pte_chain_lock(page);
  121. if (!page->mapping || PageDirty(page) || page->pte.direct ||
  122. page->buffers || page_count(page) > 1)
  123. deactivate_page_nolock(page);
  124. else if (page_count(page) == 1) {
  125. ClearPageReferenced(page);
  126. if (PageActiveAnon(page)) {
  127. del_page_from_active_anon_list(page);
  128. add_page_to_inactive_clean_list(page);
  129. } else if (PageActiveCache(page)) {
  130. del_page_from_active_cache_list(page);
  131. add_page_to_inactive_clean_list(page);
  132. } else if (PageInactiveDirty(page)) {
  133. del_page_from_inactive_dirty_list(page);
  134. add_page_to_inactive_clean_list(page);
  135. } else if (PageInactiveLaundry(page)) {
  136. del_page_from_inactive_laundry_list(page);
  137. add_page_to_inactive_clean_list(page);
  138. }
  139. }
  140. pte_chain_unlock(page);
  141. }
  142. /*
  143.  * Move an inactive page to the active list.
  144.  */
  145. void activate_page_nolock(struct page * page)
  146. {
  147. if (PageInactiveDirty(page)) {
  148. del_page_from_inactive_dirty_list(page);
  149. add_page_to_active_list(page, INITIAL_AGE);
  150. } else if (PageInactiveLaundry(page)) {
  151. del_page_from_inactive_laundry_list(page);
  152. add_page_to_active_list(page, INITIAL_AGE);
  153. } else if (PageInactiveClean(page)) {
  154. del_page_from_inactive_clean_list(page);
  155. add_page_to_active_list(page, INITIAL_AGE);
  156. }
  157. }
  158. void activate_page(struct page * page)
  159. {
  160. lru_lock(page_zone(page));
  161. activate_page_nolock(page);
  162. lru_unlock(page_zone(page));
  163. }
  164. /**
  165.  * lru_cache_add: add a page to the page lists
  166.  * @page: the page to add
  167.  */
  168. void lru_cache_add(struct page * page)
  169. {
  170. if (!PageLRU(page)) {
  171. lru_lock(page_zone(page));
  172. if (!TestandSetPageLRU(page))
  173. add_page_to_active_list(page, INITIAL_AGE);
  174. lru_unlock(page_zone(page));
  175. }
  176. }
  177. /**
  178.  * __lru_cache_del: remove a page from the page lists
  179.  * @page: the page to add
  180.  *
  181.  * This function is for when the caller already holds
  182.  * the lru lock.
  183.  */
  184. void __lru_cache_del(struct page * page)
  185. {
  186. if (PageActiveAnon(page)) {
  187. del_page_from_active_anon_list(page);
  188. } else if (PageActiveCache(page)) {
  189. del_page_from_active_cache_list(page);
  190. } else if (PageInactiveDirty(page)) {
  191. del_page_from_inactive_dirty_list(page);
  192. } else if (PageInactiveLaundry(page)) {
  193. del_page_from_inactive_laundry_list(page);
  194. } else if (PageInactiveClean(page)) {
  195. del_page_from_inactive_clean_list(page);
  196. }
  197. ClearPageLRU(page);
  198. }
  199. /**
  200.  * lru_cache_del: remove a page from the page lists
  201.  * @page: the page to remove
  202.  */
  203. void lru_cache_del(struct page * page)
  204. {
  205. lru_lock(page_zone(page));
  206. __lru_cache_del(page);
  207. lru_unlock(page_zone(page));
  208. }
  209. /*
  210.  * Perform any setup for the swap system
  211.  */
  212. void __init swap_setup(void)
  213. {
  214. unsigned long megs = num_physpages >> (20 - PAGE_SHIFT);
  215. /* Use a smaller cluster for small-memory machines */
  216. if (megs < 16)
  217. page_cluster = 2;
  218. else
  219. page_cluster = 3;
  220. /*
  221.  * Right now other parts of the system means that we
  222.  * _really_ don't want to cluster much more
  223.  */
  224. }