1 /* $NetBSD: uvm_anon.c,v 1.50 2008/01/02 11:49:15 ad Exp $ */
5 * Copyright (c) 1997 Charles D. Cranor and Washington University.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Charles D. Cranor and
19 * Washington University.
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 * uvm_anon.c: uvm anon ops
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: uvm_anon.c,v 1.50 2008/01/02 11:49:15 ad Exp $");
42 #include "opt_uvmhist.h"
44 #include <sys/param.h>
45 #include <sys/systm.h>
47 #include <sys/malloc.h>
49 #include <sys/kernel.h>
52 #include <uvm/uvm_swap.h>
53 #include <uvm/uvm_pdpolicy.h>
55 static struct pool_cache uvm_anon_cache
;
57 static int uvm_anon_ctor(void *, void *, int);
58 static void uvm_anon_dtor(void *, void *);
67 pool_cache_bootstrap(&uvm_anon_cache
, sizeof(struct vm_anon
), 0, 0,
68 PR_LARGECACHE
, "anonpl", NULL
, IPL_NONE
, uvm_anon_ctor
,
73 uvm_anon_ctor(void *arg
, void *object
, int flags
)
75 struct vm_anon
*anon
= object
;
78 mutex_init(&anon
->an_lock
, MUTEX_DEFAULT
, IPL_NONE
);
82 #endif /* defined(VMSWAP) */
88 uvm_anon_dtor(void *arg
, void *object
)
90 struct vm_anon
*anon
= object
;
92 mutex_destroy(&anon
->an_lock
);
98 * => new anon is returned locked!
103 struct vm_anon
*anon
;
105 anon
= pool_cache_get(&uvm_anon_cache
, PR_NOWAIT
);
107 KASSERT(anon
->an_ref
== 0);
108 KASSERT(anon
->an_page
== NULL
);
110 KASSERT(anon
->an_swslot
== 0);
111 #endif /* defined(VMSWAP) */
113 mutex_enter(&anon
->an_lock
);
119 * uvm_anfree: free a single anon structure
121 * => caller must remove anon from its amap before calling (if it was in
123 * => anon must be unlocked and have a zero reference count.
124 * => we may lock the pageq's.
128 uvm_anfree(struct vm_anon
*anon
)
131 UVMHIST_FUNC("uvm_anfree"); UVMHIST_CALLED(maphist
);
132 UVMHIST_LOG(maphist
,"(anon=0x%x)", anon
, 0,0,0);
134 KASSERT(anon
->an_ref
== 0);
135 KASSERT(!mutex_owned(&anon
->an_lock
));
144 * if there is a resident page and it is loaned, then anon may not
145 * own it. call out to uvm_anon_lockpage() to ensure the real owner
146 * of the page has been identified and locked.
149 if (pg
&& pg
->loan_count
) {
150 mutex_enter(&anon
->an_lock
);
151 pg
= uvm_anon_lockloanpg(anon
);
152 mutex_exit(&anon
->an_lock
);
156 * if we have a resident page, we must dispose of it before freeing
163 * if the page is owned by a uobject (now locked), then we must
164 * kill the loan on the page rather than free it.
168 mutex_enter(&uvm_pageqlock
);
169 KASSERT(pg
->loan_count
> 0);
172 mutex_exit(&uvm_pageqlock
);
173 mutex_exit(&pg
->uobject
->vmobjlock
);
177 * page has no uobject, so we must be the owner of it.
180 KASSERT((pg
->flags
& PG_RELEASED
) == 0);
181 mutex_enter(&anon
->an_lock
);
182 pmap_page_protect(pg
, VM_PROT_NONE
);
185 * if the page is busy, mark it as PG_RELEASED
186 * so that uvm_anon_release will release it later.
189 if (pg
->flags
& PG_BUSY
) {
190 pg
->flags
|= PG_RELEASED
;
191 mutex_exit(&anon
->an_lock
);
194 mutex_enter(&uvm_pageqlock
);
196 mutex_exit(&uvm_pageqlock
);
197 mutex_exit(&anon
->an_lock
);
198 UVMHIST_LOG(maphist
, "anon 0x%x, page 0x%x: "
199 "freed now!", anon
, pg
, 0, 0);
203 if (pg
== NULL
&& anon
->an_swslot
> 0) {
204 /* this page is no longer only in swap. */
205 mutex_enter(&uvm_swap_data_lock
);
206 KASSERT(uvmexp
.swpgonly
> 0);
208 mutex_exit(&uvm_swap_data_lock
);
210 #endif /* defined(VMSWAP) */
213 * free any swap resources.
216 uvm_anon_dropswap(anon
);
219 * give a page replacement hint.
222 uvmpdpol_anfree(anon
);
225 * now that we've stripped the data areas from the anon,
226 * free the anon itself.
229 KASSERT(anon
->an_page
== NULL
);
231 KASSERT(anon
->an_swslot
== 0);
232 #endif /* defined(VMSWAP) */
234 pool_cache_put(&uvm_anon_cache
, anon
);
235 UVMHIST_LOG(maphist
,"<- done!",0,0,0,0);
241 * uvm_anon_dropswap: release any swap resources from this anon.
243 * => anon must be locked or have a reference count of 0.
246 uvm_anon_dropswap(struct vm_anon
*anon
)
248 UVMHIST_FUNC("uvm_anon_dropswap"); UVMHIST_CALLED(maphist
);
250 if (anon
->an_swslot
== 0)
253 UVMHIST_LOG(maphist
,"freeing swap for anon %p, paged to swslot 0x%x",
254 anon
, anon
->an_swslot
, 0, 0);
255 uvm_swap_free(anon
->an_swslot
, 1);
259 #endif /* defined(VMSWAP) */
262 * uvm_anon_lockloanpg: given a locked anon, lock its resident page
264 * => anon is locked by caller
265 * => on return: anon is locked
266 * if there is a resident page:
267 * if it has a uobject, it is locked by us
268 * if it is ownerless, we take over as owner
269 * we return the resident page (it can change during
271 * => note that the only time an anon has an ownerless resident page
272 * is if the page was loaned from a uvm_object and the uvm_object
274 * => this only needs to be called when you want to do an operation
275 * on an anon's resident page and that page has a non-zero loan
279 uvm_anon_lockloanpg(struct vm_anon
*anon
)
284 KASSERT(mutex_owned(&anon
->an_lock
));
287 * loop while we have a resident page that has a non-zero loan count.
288 * if we successfully get our lock, we will "break" the loop.
289 * note that the test for pg->loan_count is not protected -- this
290 * may produce false positive results. note that a false positive
291 * result may cause us to do more work than we need to, but it will
292 * not produce an incorrect result.
295 while (((pg
= anon
->an_page
) != NULL
) && pg
->loan_count
!= 0) {
298 * quickly check to see if the page has an object before
299 * bothering to lock the page queues. this may also produce
300 * a false positive result, but that's ok because we do a real
305 mutex_enter(&uvm_pageqlock
);
308 mutex_tryenter(&pg
->uobject
->vmobjlock
);
310 /* object disowned before we got PQ lock */
313 mutex_exit(&uvm_pageqlock
);
316 * if we didn't get a lock (try lock failed), then we
317 * toggle our anon lock and try again
321 mutex_exit(&anon
->an_lock
);
324 * someone locking the object has a chance to
327 /* XXX Better than yielding but inadequate. */
328 kpause("livelock", false, 1, NULL
);
330 mutex_enter(&anon
->an_lock
);
336 * if page is un-owned [i.e. the object dropped its ownership],
337 * then we can take over as owner!
340 if (pg
->uobject
== NULL
&& (pg
->pqflags
& PQ_ANON
) == 0) {
341 mutex_enter(&uvm_pageqlock
);
342 pg
->pqflags
|= PQ_ANON
;
344 mutex_exit(&uvm_pageqlock
);
354 * fetch an anon's page.
356 * => anon must be locked, and is unlocked upon return.
357 * => returns true if pagein was aborted due to lack of memory.
361 uvm_anon_pagein(struct vm_anon
*anon
)
364 struct uvm_object
*uobj
;
368 KASSERT(mutex_owned(&anon
->an_lock
));
370 rv
= uvmfault_anonget(NULL
, NULL
, anon
);
373 * if rv == 0, anon is still locked, else anon
385 * nothing more to do on errors.
386 * ERESTART can only mean that the anon was freed,
387 * so again there's nothing to do.
397 * ok, we've got the page now.
398 * mark it as dirty, clear its swslot and un-busy it.
403 if (anon
->an_swslot
> 0)
404 uvm_swap_free(anon
->an_swslot
, 1);
406 pg
->flags
&= ~(PG_CLEAN
);
409 * deactivate the page (to put it on a page queue)
412 mutex_enter(&uvm_pageqlock
);
413 if (pg
->wire_count
== 0)
414 uvm_pagedeactivate(pg
);
415 mutex_exit(&uvm_pageqlock
);
417 if (pg
->flags
& PG_WANTED
) {
419 pg
->flags
&= ~(PG_WANTED
);
423 * unlock the anon and we're done.
426 mutex_exit(&anon
->an_lock
);
428 mutex_exit(&uobj
->vmobjlock
);
433 #endif /* defined(VMSWAP) */
436 * uvm_anon_release: release an anon and its page.
438 * => caller must lock the anon.
442 uvm_anon_release(struct vm_anon
*anon
)
444 struct vm_page
*pg
= anon
->an_page
;
446 KASSERT(mutex_owned(&anon
->an_lock
));
448 KASSERT((pg
->flags
& PG_RELEASED
) != 0);
449 KASSERT((pg
->flags
& PG_BUSY
) != 0);
450 KASSERT(pg
->uobject
== NULL
);
451 KASSERT(pg
->uanon
== anon
);
452 KASSERT(pg
->loan_count
== 0);
453 KASSERT(anon
->an_ref
== 0);
455 mutex_enter(&uvm_pageqlock
);
457 mutex_exit(&uvm_pageqlock
);
458 mutex_exit(&anon
->an_lock
);
460 KASSERT(anon
->an_page
== NULL
);