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 *);