Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/uvm Make the uvm_voaddr structure more compact, only occ...



details:   https://anonhg.NetBSD.org/src/rev/015c0ac62ca6
branches:  trunk
changeset: 932498:015c0ac62ca6
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Sat May 09 15:13:19 2020 +0000

description:
Make the uvm_voaddr structure more compact, only occupying 2 pointers
worth of space, by encoding the type in the lower bits of the object
pointer.

diffstat:

 sys/uvm/uvm_extern.h |  14 ++-------
 sys/uvm/uvm_map.c    |  74 ++++++++++++++++++++++++++++++++++-----------------
 2 files changed, 52 insertions(+), 36 deletions(-)

diffs (175 lines):

diff -r db9260ac845d -r 015c0ac62ca6 sys/uvm/uvm_extern.h
--- a/sys/uvm/uvm_extern.h      Sat May 09 13:16:41 2020 +0000
+++ b/sys/uvm/uvm_extern.h      Sat May 09 15:13:19 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_extern.h,v 1.225 2020/04/27 02:47:26 rin Exp $     */
+/*     $NetBSD: uvm_extern.h,v 1.226 2020/05/09 15:13:19 thorpej Exp $ */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -613,8 +613,7 @@
  *
  *     This structure encapsulates UVM's unique virtual object address
  *     for an individual byte inside a pageable page. Pageable pages can
- *     be owned by either a uvm_object (UVM_VOADDR_TYPE_OBJECT) or a
- *     vm_anon (UVM_VOADDR_TYPE_ANON).
+ *     be owned by either a uvm_object or a vm_anon.
  *
  *     In each case, the byte offset into the owning object
  *     (uvm_object or vm_anon) is included in the ID, so that
@@ -631,14 +630,7 @@
  *     use.
  */
 struct uvm_voaddr {
-       enum {
-               UVM_VOADDR_TYPE_OBJECT = 1,
-               UVM_VOADDR_TYPE_ANON = 2,
-       } type;
-       union {
-               struct uvm_object *uobj;
-               struct vm_anon *anon;
-       };
+       uintptr_t object;
        voff_t offset;
 };
 
diff -r db9260ac845d -r 015c0ac62ca6 sys/uvm/uvm_map.c
--- a/sys/uvm/uvm_map.c Sat May 09 13:16:41 2020 +0000
+++ b/sys/uvm/uvm_map.c Sat May 09 15:13:19 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_map.c,v 1.382 2020/04/30 04:18:07 thorpej Exp $    */
+/*     $NetBSD: uvm_map.c,v 1.383 2020/05/09 15:13:19 thorpej Exp $    */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.382 2020/04/30 04:18:07 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.383 2020/05/09 15:13:19 thorpej Exp $");
 
 #include "opt_ddb.h"
 #include "opt_pax.h"
@@ -4781,6 +4781,31 @@
        }
 }
 
+#define        UVM_VOADDR_TYPE_MASK    0x3UL
+#define        UVM_VOADDR_TYPE_UOBJ    0x1UL
+#define        UVM_VOADDR_TYPE_ANON    0x2UL
+#define        UVM_VOADDR_OBJECT_MASK  ~UVM_VOADDR_TYPE_MASK
+
+#define        UVM_VOADDR_GET_TYPE(voa)                                        \
+       ((voa)->object & UVM_VOADDR_TYPE_MASK)
+#define        UVM_VOADDR_GET_OBJECT(voa)                                      \
+       ((voa)->object & UVM_VOADDR_OBJECT_MASK)
+#define        UVM_VOADDR_SET_OBJECT(voa, obj, type)                           \
+do {                                                                   \
+       KASSERT(((uintptr_t)(obj) & UVM_VOADDR_TYPE_MASK) == 0);        \
+       (voa)->object = ((uintptr_t)(obj)) | (type);                    \
+} while (/*CONSTCOND*/0)
+
+#define        UVM_VOADDR_GET_UOBJ(voa)                                        \
+       ((struct uvm_object *)UVM_VOADDR_GET_OBJECT(voa))
+#define        UVM_VOADDR_SET_UOBJ(voa, uobj)                                  \
+       UVM_VOADDR_SET_OBJECT(voa, uobj, UVM_VOADDR_TYPE_UOBJ)
+
+#define        UVM_VOADDR_GET_ANON(voa)                                        \
+       ((struct vm_anon *)UVM_VOADDR_GET_OBJECT(voa))
+#define        UVM_VOADDR_SET_ANON(voa, anon)                                  \
+       UVM_VOADDR_SET_OBJECT(voa, anon, UVM_VOADDR_TYPE_ANON)
+
 /*
  * uvm_voaddr_acquire: returns the virtual object address corresponding
  * to the specified virtual address.
@@ -4936,8 +4961,7 @@
                        anon->an_ref++;
                        rw_obj_hold(anon->an_lock);
                        KASSERT(anon->an_ref != 0);
-                       voaddr->type = UVM_VOADDR_TYPE_ANON;
-                       voaddr->anon = anon;
+                       UVM_VOADDR_SET_ANON(voaddr, anon);
                        voaddr->offset = va & PAGE_MASK;
                        result = true;
                }
@@ -4950,8 +4974,7 @@
 
                KASSERT(uobj != NULL);
                (*uobj->pgops->pgo_reference)(uobj);
-               voaddr->type = UVM_VOADDR_TYPE_OBJECT;
-               voaddr->uobj = uobj;
+               UVM_VOADDR_SET_UOBJ(voaddr, uobj);
                voaddr->offset = entry->offset + (va - entry->start);
                result = true;
        }
@@ -4961,7 +4984,9 @@
        if (result) {
                UVMHIST_LOG(maphist,
                    "<- done OK (type=%jd,owner=#%jx,offset=%jx)",
-                   voaddr->type, (uintptr_t)voaddr->uobj, voaddr->offset, 0);
+                   UVM_VOADDR_GET_TYPE(voaddr),
+                   UVM_VOADDR_GET_OBJECT(voaddr),
+                   voaddr->offset, 0);
        } else {
                UVMHIST_LOG(maphist,"<- done (failed)",0,0,0,0);
        }
@@ -4977,9 +5002,9 @@
 uvm_voaddr_release(struct uvm_voaddr * const voaddr)
 {
 
-       switch (voaddr->type) {
-       case UVM_VOADDR_TYPE_OBJECT: {
-               struct uvm_object * const uobj = voaddr->uobj;
+       switch (UVM_VOADDR_GET_TYPE(voaddr)) {
+       case UVM_VOADDR_TYPE_UOBJ: {
+               struct uvm_object * const uobj = UVM_VOADDR_GET_UOBJ(voaddr);
 
                KASSERT(uobj != NULL);
                KASSERT(uobj->pgops->pgo_detach != NULL);
@@ -4987,7 +5012,7 @@
                break;
            }
        case UVM_VOADDR_TYPE_ANON: {
-               struct vm_anon * const anon = voaddr->anon;
+               struct vm_anon * const anon = UVM_VOADDR_GET_ANON(voaddr);
                krwlock_t *lock;
 
                KASSERT(anon != NULL);
@@ -5015,23 +5040,22 @@
 uvm_voaddr_compare(const struct uvm_voaddr * const voaddr1,
     const struct uvm_voaddr * const voaddr2)
 {
-
-       KASSERT(voaddr1->type == UVM_VOADDR_TYPE_OBJECT ||
-               voaddr1->type == UVM_VOADDR_TYPE_ANON);
-
-       KASSERT(voaddr2->type == UVM_VOADDR_TYPE_OBJECT ||
-               voaddr2->type == UVM_VOADDR_TYPE_ANON);
-
-       if (voaddr1->type < voaddr2->type)
+       const uintptr_t type1 = UVM_VOADDR_GET_TYPE(voaddr1);
+       const uintptr_t type2 = UVM_VOADDR_GET_TYPE(voaddr2);
+
+       KASSERT(type1 == UVM_VOADDR_TYPE_UOBJ ||
+               type1 == UVM_VOADDR_TYPE_ANON);
+
+       KASSERT(type2 == UVM_VOADDR_TYPE_UOBJ ||
+               type2 == UVM_VOADDR_TYPE_ANON);
+
+       if (type1 < type2)
                return -1;
-       if (voaddr1->type > voaddr2->type)
+       if (type1 > type2)
                return 1;
 
-       /* These fields are unioned together. */
-       CTASSERT(offsetof(struct uvm_voaddr, uobj) ==
-                offsetof(struct uvm_voaddr, anon));
-       const uintptr_t addr1 = (uintptr_t)voaddr1->uobj;
-       const uintptr_t addr2 = (uintptr_t)voaddr2->uobj;
+       const uintptr_t addr1 = UVM_VOADDR_GET_OBJECT(voaddr1);
+       const uintptr_t addr2 = UVM_VOADDR_GET_OBJECT(voaddr2);
 
        if (addr1 < addr2)
                return -1;



Home | Main Index | Thread Index | Old Index