Page MenuHomeFreeBSD

imgact_elf: Optimize pagesizes[] loop
ClosedPublic

Authored by alc on Aug 2 2024, 8:09 PM.
Tags
None
Referenced Files
F102562444: D46215.diff
Thu, Nov 14, 2:42 AM
F102518194: D46215.id141749.diff
Wed, Nov 13, 11:38 AM
Unknown Object (File)
Mon, Nov 11, 3:14 AM
Unknown Object (File)
Thu, Nov 7, 7:32 AM
Unknown Object (File)
Sat, Oct 26, 4:50 PM
Unknown Object (File)
Tue, Oct 15, 6:57 AM
Unknown Object (File)
Oct 9 2024, 10:24 AM
Unknown Object (File)
Oct 9 2024, 10:24 AM
Subscribers

Details

Summary

Except for elements whose value is zero, the elements of pagesizes[] are always sorted in increasing order, so once a loop starting from the end of the array has found a non-zero element, it has found the largest valued element and can stop iterating.

Diff Detail

Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

alc requested review of this revision.Aug 2 2024, 8:09 PM
alc created this revision.

As I wrote this patch, I thought about adding a sanity check on pagesizes[] to the machine-independent layer. Thoughts on this? pmap_init() happens fairly late with only vm_pager_init() coming after it in vm_mem_init(), and that does not seem like a natural place for it.

IMO it could be a function like vm_pagesizes_check() called directly from pmap_init()s?

This revision is now accepted and ready to land.Aug 2 2024, 11:12 PM
This revision was automatically updated to reflect the committed changes.
In D46215#1053727, @kib wrote:

IMO it could be a function like vm_pagesizes_check() called directly from pmap_init()s?

diff --git a/sys/vm/vm_init.c b/sys/vm/vm_init.c
index 0fd13f73a180..4783a7deaf96 100644
--- a/sys/vm/vm_init.c
+++ b/sys/vm/vm_init.c
@@ -100,6 +100,23 @@ long physmem;
 static void vm_mem_init(void *);
 SYSINIT(vm_mem, SI_SUB_VM, SI_ORDER_FIRST, vm_mem_init, NULL);
 
+#ifdef INVARIANTS
+/*
+ * Ensure that pmap_init() correctly initialized pagesizes[].
+ */
+static void
+vm_check_pagesizes(void)
+{
+       int i;
+
+       KASSERT(pagesizes[0] == PAGE_SIZE, ("pagesizes[0] != PAGE_SIZE"));
+       for (i = 1; i < MAXPAGESIZES; i++) {
+               KASSERT(pagesizes[i - 1] < pagesizes[i] || pagesizes[i] == 0,
+                   ("pagesizes[%d] >= pagesizes[%d]", i - 1, i));
+       }
+}
+#endif
+
 /*
  *     vm_mem_init() initializes the virtual memory system.
  *     This is done only by the first cpu up.
@@ -140,6 +157,10 @@ vm_mem_init(void *dummy)
        kmem_init_zero_region();
        pmap_init();
        vm_pager_init();
+
+#ifdef INVARIANTS
+       vm_check_pagesizes();
+#endif
 }
 
 void

If I'm being paranoid, then I don't want to rely on the pmap calling the check function. Do we want this check? I'm on the fence. @markj

In D46215#1053781, @alc wrote:
In D46215#1053727, @kib wrote:

IMO it could be a function like vm_pagesizes_check() called directly from pmap_init()s?

diff --git a/sys/vm/vm_init.c b/sys/vm/vm_init.c
index 0fd13f73a180..4783a7deaf96 100644
--- a/sys/vm/vm_init.c
+++ b/sys/vm/vm_init.c
@@ -100,6 +100,23 @@ long physmem;
 static void vm_mem_init(void *);
 SYSINIT(vm_mem, SI_SUB_VM, SI_ORDER_FIRST, vm_mem_init, NULL);
 
+#ifdef INVARIANTS
+/*
+ * Ensure that pmap_init() correctly initialized pagesizes[].
+ */
+static void
+vm_check_pagesizes(void)
+{
+       int i;
+
+       KASSERT(pagesizes[0] == PAGE_SIZE, ("pagesizes[0] != PAGE_SIZE"));
+       for (i = 1; i < MAXPAGESIZES; i++) {
+               KASSERT(pagesizes[i - 1] < pagesizes[i] || pagesizes[i] == 0,
+                   ("pagesizes[%d] >= pagesizes[%d]", i - 1, i));
+       }
+}
+#endif
+
 /*
  *     vm_mem_init() initializes the virtual memory system.
  *     This is done only by the first cpu up.
@@ -140,6 +157,10 @@ vm_mem_init(void *dummy)
        kmem_init_zero_region();
        pmap_init();
        vm_pager_init();
+
+#ifdef INVARIANTS
+       vm_check_pagesizes();
+#endif
 }
 
 void

If I'm being paranoid, then I don't want to rely on the pmap calling the check function. Do we want this check? I'm on the fence. @markj

I don't feel strongly either. I agree that relying on each pmap to check is a bit unsatisfying.

I can't think of any bugs the check would have caught, but on the other hand it's inobtrusive and might save someone some time someday, or help catch some boot-time memory corruption. I'm for it.

IMO the most value of the check is that it documents our assumptions about pagesizes[]. This improves understanding of other places, and eases potential addition of new arches.