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