Module Name: src Committed By: riastradh Date: Thu May 22 14:01:46 UTC 2014
Modified Files: src/sys/uvm: uvm_aobj.c uvm_extern.h Log Message: Add uao_set_pgfl to limit a uvm_aobj's pages to a specified freelist. Brought up on tech-kern: https://mail-index.netbsd.org/tech-kern/2014/05/20/msg017095.html To generate a diff of this commit: cvs rdiff -u -r1.120 -r1.121 src/sys/uvm/uvm_aobj.c cvs rdiff -u -r1.189 -r1.190 src/sys/uvm/uvm_extern.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/uvm/uvm_aobj.c diff -u src/sys/uvm/uvm_aobj.c:1.120 src/sys/uvm/uvm_aobj.c:1.121 --- src/sys/uvm/uvm_aobj.c:1.120 Fri Oct 25 20:22:55 2013 +++ src/sys/uvm/uvm_aobj.c Thu May 22 14:01:46 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_aobj.c,v 1.120 2013/10/25 20:22:55 martin Exp $ */ +/* $NetBSD: uvm_aobj.c,v 1.121 2014/05/22 14:01:46 riastradh Exp $ */ /* * Copyright (c) 1998 Chuck Silvers, Charles D. Cranor and @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_aobj.c,v 1.120 2013/10/25 20:22:55 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_aobj.c,v 1.121 2014/05/22 14:01:46 riastradh Exp $"); #include "opt_uvmhist.h" @@ -146,6 +146,7 @@ struct uvm_aobj { struct uao_swhash *u_swhash; u_long u_swhashmask; /* mask for hashtable */ LIST_ENTRY(uvm_aobj) u_list; /* global list of aobjs */ + int u_freelist; /* freelist to allocate pages from */ }; static void uao_free(struct uvm_aobj *); @@ -161,6 +162,8 @@ static bool uao_pagein(struct uvm_aobj * static bool uao_pagein_page(struct uvm_aobj *, int); #endif /* defined(VMSWAP) */ +static struct vm_page *uao_pagealloc(struct uvm_object *, voff_t, int); + /* * aobj_pager * @@ -436,6 +439,12 @@ uao_create(vsize_t size, int flags) } /* + * no freelist by default + */ + + aobj->u_freelist = VM_NFREELIST; + + /* * allocate hash/array if necessary * * note: in the KERNSWAP case no need to worry about locking since @@ -490,6 +499,39 @@ uao_create(vsize_t size, int flags) } /* + * uao_set_pgfl: allocate pages only from the specified freelist. + * + * => must be called before any pages are allocated for the object. + */ + +void +uao_set_pgfl(struct uvm_object *uobj, int freelist) +{ + struct uvm_aobj *aobj = (struct uvm_aobj *)uobj; + + KASSERTMSG((0 <= freelist), "invalid freelist %d", freelist); + KASSERTMSG((freelist < VM_NFREELIST), "invalid freelist %d", freelist); + + aobj->u_freelist = freelist; +} + +/* + * uao_pagealloc: allocate a page for aobj. + */ + +static inline struct vm_page * +uao_pagealloc(struct uvm_object *uobj, voff_t offset, int flags) +{ + struct uvm_aobj *aobj = (struct uvm_aobj *)uobj; + + if (__predict_true(aobj->u_freelist == VM_NFREELIST)) + return uvm_pagealloc(uobj, offset, NULL, flags); + else + return uvm_pagealloc_strat(uobj, offset, NULL, flags, + UVM_PGA_STRAT_ONLY, aobj->u_freelist); +} + +/* * uao_init: set up aobj pager subsystem * * => called at boot time from uvm_pager_init() @@ -864,8 +906,8 @@ uao_get(struct uvm_object *uobj, voff_t if (ptmp == NULL && uao_find_swslot(uobj, current_offset >> PAGE_SHIFT) == 0) { - ptmp = uvm_pagealloc(uobj, current_offset, - NULL, UVM_FLAG_COLORMATCH|UVM_PGA_ZERO); + ptmp = uao_pagealloc(uobj, current_offset, + UVM_FLAG_COLORMATCH|UVM_PGA_ZERO); if (ptmp) { /* new page */ ptmp->flags &= ~(PG_FAKE); @@ -959,8 +1001,7 @@ gotpage: /* not resident? allocate one now (if we can) */ if (ptmp == NULL) { - ptmp = uvm_pagealloc(uobj, current_offset, - NULL, 0); + ptmp = uao_pagealloc(uobj, current_offset, 0); /* out of RAM? */ if (ptmp == NULL) { Index: src/sys/uvm/uvm_extern.h diff -u src/sys/uvm/uvm_extern.h:1.189 src/sys/uvm/uvm_extern.h:1.190 --- src/sys/uvm/uvm_extern.h:1.189 Fri Feb 21 22:08:07 2014 +++ src/sys/uvm/uvm_extern.h Thu May 22 14:01:46 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_extern.h,v 1.189 2014/02/21 22:08:07 skrll Exp $ */ +/* $NetBSD: uvm_extern.h,v 1.190 2014/05/22 14:01:46 riastradh Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -539,6 +539,7 @@ void vunmapbuf(struct buf *, vsize_t); /* uvm_aobj.c */ struct uvm_object *uao_create(vsize_t, int); +void uao_set_pgfl(struct uvm_object *, int); void uao_detach(struct uvm_object *); void uao_reference(struct uvm_object *);