diff --git a/sys/uvm/uvm_fault.c b/sys/uvm/uvm_fault.c index 197652e98fd0..096ab7632d36 100644 --- a/sys/uvm/uvm_fault.c +++ b/sys/uvm/uvm_fault.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_fault.c,v 1.152 2010/02/02 05:58:16 uebayasi Exp $ */ +/* $NetBSD: uvm_fault.c,v 1.153 2010/02/02 06:06:02 uebayasi Exp $ */ /* * @@ -39,7 +39,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.152 2010/02/02 05:58:16 uebayasi Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.153 2010/02/02 06:06:02 uebayasi Exp $"); #include "opt_uvmhist.h" @@ -1461,11 +1461,6 @@ uvm_fault_upper( return uvm_fault_upper1(ufi, flt, uobj, anon); } -static int -uvm_fault_upper_loan_break( - struct uvm_faultinfo *ufi, struct uvm_faultctx *flt, - struct vm_anon *anon, struct uvm_object **ruobj); - static int uvm_fault_upper_loan( struct uvm_faultinfo *ufi, struct uvm_faultctx *flt, @@ -1499,7 +1494,7 @@ uvm_fault_upper_loan( /* >1 case is already ok */ if (anon->an_ref == 1) { - error = uvm_fault_upper_loan_break(ufi, flt, anon, ruobj); + error = uvm_loanbreak_anon(anon, ruobj); if (error != 0) { uvmfault_unlockall(ufi, amap, *ruobj, anon); uvm_wait("flt_noram2"); @@ -1510,67 +1505,6 @@ uvm_fault_upper_loan( return error; } -/* XXXUEBS consider to move this elsewhere */ -static int -uvm_fault_upper_loan_break( - struct uvm_faultinfo *ufi, struct uvm_faultctx *flt, - struct vm_anon *anon, struct uvm_object **ruobj) -{ - struct vm_page *pg; - - /* get new un-owned replacement page */ - pg = uvm_pagealloc(NULL, 0, NULL, 0); - if (pg == NULL) { - return ENOMEM; - } - - /* - * copy data, kill loan, and drop uobj lock - * (if any) - */ - /* copy old -> new */ - uvm_pagecopy(anon->an_page, pg); - - /* force reload */ - pmap_page_protect(anon->an_page, VM_PROT_NONE); - mutex_enter(&uvm_pageqlock); /* KILL loan */ - - anon->an_page->uanon = NULL; - /* in case we owned */ - anon->an_page->pqflags &= ~PQ_ANON; - - if (*ruobj) { - /* if we were receiver of loan */ - anon->an_page->loan_count--; - } else { - /* - * we were the lender (A->K); need - * to remove the page from pageq's. - */ - uvm_pagedequeue(anon->an_page); - } - - if (*ruobj) { - mutex_exit(&(*ruobj)->vmobjlock); - *ruobj = NULL; - } - - /* install new page in anon */ - anon->an_page = pg; - pg->uanon = anon; - pg->pqflags |= PQ_ANON; - - uvm_pageactivate(pg); - mutex_exit(&uvm_pageqlock); - - pg->flags &= ~(PG_BUSY|PG_FAKE); - UVM_PAGE_OWN(pg, NULL); - - /* done! */ - - return 0; -} - static int uvm_fault_upper1( struct uvm_faultinfo *ufi, struct uvm_faultctx *flt, diff --git a/sys/uvm/uvm_loan.c b/sys/uvm/uvm_loan.c index ceef6b0b8f6b..7858a327f590 100644 --- a/sys/uvm/uvm_loan.c +++ b/sys/uvm/uvm_loan.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_loan.c,v 1.74 2009/12/05 22:34:43 pooka Exp $ */ +/* $NetBSD: uvm_loan.c,v 1.75 2010/02/02 06:06:02 uebayasi Exp $ */ /* * @@ -39,7 +39,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uvm_loan.c,v 1.74 2009/12/05 22:34:43 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_loan.c,v 1.75 2010/02/02 06:06:02 uebayasi Exp $"); #include #include @@ -1182,3 +1182,61 @@ uvm_loanbreak(struct vm_page *uobjpage) return pg; } + +int +uvm_loanbreak_anon(struct vm_anon *anon, struct uvm_object **ruobj) +{ + struct vm_page *pg; + + /* get new un-owned replacement page */ + pg = uvm_pagealloc(NULL, 0, NULL, 0); + if (pg == NULL) { + return ENOMEM; + } + + /* + * copy data, kill loan, and drop uobj lock + * (if any) + */ + /* copy old -> new */ + uvm_pagecopy(anon->an_page, pg); + + /* force reload */ + pmap_page_protect(anon->an_page, VM_PROT_NONE); + mutex_enter(&uvm_pageqlock); /* KILL loan */ + + anon->an_page->uanon = NULL; + /* in case we owned */ + anon->an_page->pqflags &= ~PQ_ANON; + + if (*ruobj) { + /* if we were receiver of loan */ + anon->an_page->loan_count--; + } else { + /* + * we were the lender (A->K); need + * to remove the page from pageq's. + */ + uvm_pagedequeue(anon->an_page); + } + + if (*ruobj) { + mutex_exit(&(*ruobj)->vmobjlock); + *ruobj = NULL; + } + + /* install new page in anon */ + anon->an_page = pg; + pg->uanon = anon; + pg->pqflags |= PQ_ANON; + + uvm_pageactivate(pg); + mutex_exit(&uvm_pageqlock); + + pg->flags &= ~(PG_BUSY|PG_FAKE); + UVM_PAGE_OWN(pg, NULL); + + /* done! */ + + return 0; +} diff --git a/sys/uvm/uvm_loan.h b/sys/uvm/uvm_loan.h index dd2e231013c3..e5a6796fde41 100644 --- a/sys/uvm/uvm_loan.h +++ b/sys/uvm/uvm_loan.h @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_loan.h,v 1.14 2005/12/11 12:25:29 christos Exp $ */ +/* $NetBSD: uvm_loan.h,v 1.15 2010/02/02 06:06:02 uebayasi Exp $ */ /* * @@ -56,6 +56,7 @@ void uvm_unloan(void *, int, int); int uvm_loanuobjpages(struct uvm_object *, voff_t, int, struct vm_page **); struct vm_page *uvm_loanbreak(struct vm_page *); +int uvm_loanbreak_anon(struct vm_anon *, struct uvm_object **); #endif /* _KERNEL */