uvm_anon.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /* $OpenBSD: uvm_anon.c,v 1.43 2014/12/23 04:56:47 tedu Exp $ */
  2. /* $NetBSD: uvm_anon.c,v 1.10 2000/11/25 06:27:59 chs Exp $ */
  3. /*
  4. * Copyright (c) 1997 Charles D. Cranor and Washington University.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  18. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  19. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  20. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  21. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  25. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. /*
  28. * uvm_anon.c: uvm anon ops
  29. */
  30. #include <sys/param.h>
  31. #include <sys/systm.h>
  32. #include <sys/malloc.h>
  33. #include <sys/pool.h>
  34. #include <sys/kernel.h>
  35. #include <sys/atomic.h>
  36. #include <uvm/uvm.h>
  37. #include <uvm/uvm_swap.h>
  38. struct pool uvm_anon_pool;
  39. /*
  40. * allocate anons
  41. */
  42. void
  43. uvm_anon_init(void)
  44. {
  45. pool_init(&uvm_anon_pool, sizeof(struct vm_anon), 0, 0,
  46. PR_WAITOK, "anonpl", NULL);
  47. pool_sethiwat(&uvm_anon_pool, uvmexp.free / 16);
  48. }
  49. /*
  50. * allocate an anon
  51. */
  52. struct vm_anon *
  53. uvm_analloc(void)
  54. {
  55. struct vm_anon *anon;
  56. anon = pool_get(&uvm_anon_pool, PR_NOWAIT);
  57. if (anon) {
  58. anon->an_ref = 1;
  59. anon->an_page = NULL;
  60. anon->an_swslot = 0;
  61. }
  62. return(anon);
  63. }
  64. /*
  65. * uvm_anfree: free a single anon structure
  66. *
  67. * => caller must remove anon from its amap before calling (if it was in
  68. * an amap).
  69. * => we may lock the pageq's.
  70. */
  71. void
  72. uvm_anfree(struct vm_anon *anon)
  73. {
  74. struct vm_page *pg;
  75. /* get page */
  76. pg = anon->an_page;
  77. /*
  78. * if there is a resident page and it is loaned, then anon may not
  79. * own it. call out to uvm_anon_lockpage() to ensure the real owner
  80. * of the page has been identified and locked.
  81. */
  82. if (pg && pg->loan_count)
  83. pg = uvm_anon_lockloanpg(anon);
  84. /*
  85. * if we have a resident page, we must dispose of it before freeing
  86. * the anon.
  87. */
  88. if (pg) {
  89. /*
  90. * if the page is owned by a uobject, then we must
  91. * kill the loan on the page rather than free it.
  92. */
  93. if (pg->uobject) {
  94. uvm_lock_pageq();
  95. KASSERT(pg->loan_count > 0);
  96. pg->loan_count--;
  97. pg->uanon = NULL;
  98. uvm_unlock_pageq();
  99. } else {
  100. /*
  101. * page has no uobject, so we must be the owner of it.
  102. *
  103. * if page is busy then we just mark it as released
  104. * (who ever has it busy must check for this when they
  105. * wake up). if the page is not busy then we can
  106. * free it now.
  107. */
  108. if ((pg->pg_flags & PG_BUSY) != 0) {
  109. /* tell them to dump it when done */
  110. atomic_setbits_int(&pg->pg_flags, PG_RELEASED);
  111. return;
  112. }
  113. pmap_page_protect(pg, PROT_NONE);
  114. uvm_lock_pageq(); /* lock out pagedaemon */
  115. uvm_pagefree(pg); /* bye bye */
  116. uvm_unlock_pageq(); /* free the daemon */
  117. }
  118. }
  119. if (pg == NULL && anon->an_swslot != 0) {
  120. /* this page is no longer only in swap. */
  121. KASSERT(uvmexp.swpgonly > 0);
  122. uvmexp.swpgonly--;
  123. }
  124. /* free any swap resources. */
  125. uvm_anon_dropswap(anon);
  126. /*
  127. * now that we've stripped the data areas from the anon, free the anon
  128. * itself!
  129. */
  130. KASSERT(anon->an_page == NULL);
  131. KASSERT(anon->an_swslot == 0);
  132. pool_put(&uvm_anon_pool, anon);
  133. }
  134. /*
  135. * uvm_anon_dropswap: release any swap resources from this anon.
  136. */
  137. void
  138. uvm_anon_dropswap(struct vm_anon *anon)
  139. {
  140. if (anon->an_swslot == 0)
  141. return;
  142. uvm_swap_free(anon->an_swslot, 1);
  143. anon->an_swslot = 0;
  144. }
  145. /*
  146. * uvm_anon_lockloanpg: given a locked anon, lock its resident page
  147. *
  148. * => on return:
  149. * if there is a resident page:
  150. * if it is ownerless, we take over as owner
  151. * we return the resident page (it can change during
  152. * this function)
  153. * => note that the only time an anon has an ownerless resident page
  154. * is if the page was loaned from a uvm_object and the uvm_object
  155. * disowned it
  156. * => this only needs to be called when you want to do an operation
  157. * on an anon's resident page and that page has a non-zero loan
  158. * count.
  159. */
  160. struct vm_page *
  161. uvm_anon_lockloanpg(struct vm_anon *anon)
  162. {
  163. struct vm_page *pg;
  164. /*
  165. * loop while we have a resident page that has a non-zero loan count.
  166. * if we successfully get our lock, we will "break" the loop.
  167. * note that the test for pg->loan_count is not protected -- this
  168. * may produce false positive results. note that a false positive
  169. * result may cause us to do more work than we need to, but it will
  170. * not produce an incorrect result.
  171. */
  172. while (((pg = anon->an_page) != NULL) && pg->loan_count != 0) {
  173. /*
  174. * if page is un-owned [i.e. the object dropped its ownership],
  175. * then we can take over as owner!
  176. */
  177. if (pg->uobject == NULL && (pg->pg_flags & PQ_ANON) == 0) {
  178. uvm_lock_pageq();
  179. atomic_setbits_int(&pg->pg_flags, PQ_ANON);
  180. pg->loan_count--; /* ... and drop our loan */
  181. uvm_unlock_pageq();
  182. }
  183. break;
  184. }
  185. return(pg);
  186. }
  187. /*
  188. * fetch an anon's page.
  189. *
  190. * => returns TRUE if pagein was aborted due to lack of memory.
  191. */
  192. boolean_t
  193. uvm_anon_pagein(struct vm_anon *anon)
  194. {
  195. struct vm_page *pg;
  196. struct uvm_object *uobj;
  197. int rv;
  198. rv = uvmfault_anonget(NULL, NULL, anon);
  199. switch (rv) {
  200. case VM_PAGER_OK:
  201. break;
  202. case VM_PAGER_ERROR:
  203. case VM_PAGER_REFAULT:
  204. /*
  205. * nothing more to do on errors.
  206. * VM_PAGER_REFAULT can only mean that the anon was freed,
  207. * so again there's nothing to do.
  208. */
  209. return FALSE;
  210. default:
  211. #ifdef DIAGNOSTIC
  212. panic("anon_pagein: uvmfault_anonget -> %d", rv);
  213. #else
  214. return FALSE;
  215. #endif
  216. }
  217. /*
  218. * ok, we've got the page now.
  219. * mark it as dirty, clear its swslot and un-busy it.
  220. */
  221. pg = anon->an_page;
  222. uobj = pg->uobject;
  223. uvm_swap_free(anon->an_swslot, 1);
  224. anon->an_swslot = 0;
  225. atomic_clearbits_int(&pg->pg_flags, PG_CLEAN);
  226. /* deactivate the page (to put it on a page queue) */
  227. pmap_clear_reference(pg);
  228. pmap_page_protect(pg, PROT_NONE);
  229. uvm_lock_pageq();
  230. uvm_pagedeactivate(pg);
  231. uvm_unlock_pageq();
  232. return FALSE;
  233. }