tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: uvm objects with physical address constraints
Date: Tue, 20 May 2014 13:54:44 -0700
From: Matt Thomas <matt%3am-software.com@localhost>
Wrong approach. These should be on dedicated vm freelists instead.
Look at how mips64 has first512m, first4g, etc. You could have
first4g, first64g, first1t. Then you can use UVM_PGA_STRAT_ONLY.
How about the attached patch to add uao_set_pgfl(uao, freelist)
instead?
Index: sys/uvm/uvm_aobj.c
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_aobj.c,v
retrieving revision 1.120
diff -p -u -r1.120 uvm_aobj.c
--- sys/uvm/uvm_aobj.c 25 Oct 2013 20:22:55 -0000 1.120
+++ sys/uvm/uvm_aobj.c 20 May 2014 23:10:32 -0000
@@ -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 +909,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 +1004,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: sys/uvm/uvm_extern.h
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_extern.h,v
retrieving revision 1.189
diff -p -u -r1.189 uvm_extern.h
--- sys/uvm/uvm_extern.h 21 Feb 2014 22:08:07 -0000 1.189
+++ sys/uvm/uvm_extern.h 20 May 2014 23:10:32 -0000
@@ -539,6 +540,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 *);
Home |
Main Index |
Thread Index |
Old Index