bug-hurd
[Top][All Lists]
Advanced

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

[RFC PATCH 1/7] Shrink struct vm_page size


From: Sergey Bugaev
Subject: [RFC PATCH 1/7] Shrink struct vm_page size
Date: Mon, 26 Jun 2023 14:26:50 +0300

struct vm_page is supposed to be a "small structure", but it takes up 96
bytes on x86_64 (to represent a 4k page). By utilizing bitfields and
strategically reordering members to avoid excessive padding, it can be
shrunk to 80 bytes.

- page_lock and unlock_request only need to store a bitmask of
  VM_PROT_READ, VM_PROT_WRITE, and VM_PROT_EXECUTE. Even though the
  special values VM_PROT_NO_CHANGE and VM_PROT_NOTIFY are defined, they
  are not used for the two struct vm_page members.

- type and seg_index both need to store one of the four possible values
  in the range from 0 to 3. Two bits are sufficient for this.

- order needs to store a number from 0 to VM_PAGE_NR_FREE_LISTS (which
  is 11), or a special value VM_PAGE_ORDER_UNLISTED. Four bits are
  sufficient for this.

No functional change.
---
 vm/vm_page.c     |  4 ++--
 vm/vm_page.h     | 18 ++++++++++++------
 vm/vm_resident.c |  2 +-
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/vm/vm_page.c b/vm/vm_page.c
index 50916b74..ce37c8aa 100644
--- a/vm/vm_page.c
+++ b/vm/vm_page.c
@@ -94,7 +94,7 @@ struct vm_page_cpu_pool {
  * Special order value for pages that aren't in a free list. Such pages are
  * either allocated, or part of a free block of pages but not the head page.
  */
-#define VM_PAGE_ORDER_UNLISTED ((unsigned short)-1)
+#define VM_PAGE_ORDER_UNLISTED (VM_PAGE_NR_FREE_LISTS + 1)
 
 /*
  * Doubly-linked list of free blocks.
@@ -1016,7 +1016,7 @@ vm_page_seg_balance_page(struct vm_page_seg *seg,
 
     vm_page_set_type(dest, 0, src->type);
     memcpy(&dest->vm_page_header, &src->vm_page_header,
-           sizeof(*dest) - VM_PAGE_HEADER_SIZE);
+           VM_PAGE_BODY_SIZE);
     vm_page_copy(src, dest);
 
     if (!src->dirty) {
diff --git a/vm/vm_page.h b/vm/vm_page.h
index d457f9a2..b2581d9e 100644
--- a/vm/vm_page.h
+++ b/vm/vm_page.h
@@ -79,9 +79,6 @@
 
 struct vm_page {
        struct list node;               /* page queues or free list (P) */
-       unsigned short type;
-       unsigned short seg_index;
-       unsigned short order;
        void *priv;
 
        /*
@@ -95,7 +92,6 @@ struct vm_page {
 
        /* We use an empty struct as the delimiter.  */
        struct {} vm_page_header;
-#define VM_PAGE_HEADER_SIZE    offsetof(struct vm_page, vm_page_header)
 
        vm_object_t     object;         /* which object am I in (O,P) */
        vm_offset_t     offset;         /* offset into that object (O,P) */
@@ -126,10 +122,20 @@ struct vm_page {
                                         * without having data. (O)
                                         * [See vm_object_overwrite] */
 
-       vm_prot_t       page_lock;      /* Uses prohibited by data manager (O) 
*/
-       vm_prot_t       unlock_request; /* Outstanding unlock request (O) */
+       vm_prot_t       page_lock:3;    /* Uses prohibited by data manager (O) 
*/
+       vm_prot_t       unlock_request:3;       /* Outstanding unlock request 
(O) */
+
+       struct {} vm_page_footer;
+
+       unsigned short type:2;
+       unsigned short seg_index:2;
+       unsigned short order:4;
 };
 
+#define VM_PAGE_BODY_SIZE                                      \
+               (offsetof(struct vm_page, vm_page_footer)       \
+               - offsetof(struct vm_page, vm_page_header))
+
 /*
  *     For debugging, this macro can be defined to perform
  *     some useful check on a page structure.
diff --git a/vm/vm_resident.c b/vm/vm_resident.c
index e0a03bf5..d4777e70 100644
--- a/vm/vm_resident.c
+++ b/vm/vm_resident.c
@@ -746,7 +746,7 @@ boolean_t vm_page_convert(struct vm_page **mp)
 
        memcpy(&real_m->vm_page_header,
               &fict_m->vm_page_header,
-              sizeof(*fict_m) - VM_PAGE_HEADER_SIZE);
+              VM_PAGE_BODY_SIZE);
        real_m->fictitious = FALSE;
 
        vm_page_insert(real_m, object, offset);
-- 
2.41.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]