Module Name:    src
Committed By:   ad
Date:           Sat Sep 23 18:20:20 UTC 2023

Modified Files:
        src/sys/uvm: uvm_page.c uvm_physseg.c

Log Message:
uvm_phys_to_vm_page() turns out to be a fairly central routine due to the
way that some of the pmaps work, so try to optimise it a little.


To generate a diff of this commit:
cvs rdiff -u -r1.253 -r1.254 src/sys/uvm/uvm_page.c
cvs rdiff -u -r1.18 -r1.19 src/sys/uvm/uvm_physseg.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/uvm/uvm_page.c
diff -u src/sys/uvm/uvm_page.c:1.253 src/sys/uvm/uvm_page.c:1.254
--- src/sys/uvm/uvm_page.c:1.253	Mon Jul 17 12:55:37 2023
+++ src/sys/uvm/uvm_page.c	Sat Sep 23 18:20:20 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_page.c,v 1.253 2023/07/17 12:55:37 riastradh Exp $	*/
+/*	$NetBSD: uvm_page.c,v 1.254 2023/09/23 18:20:20 ad Exp $	*/
 
 /*-
  * Copyright (c) 2019, 2020 The NetBSD Foundation, Inc.
@@ -95,7 +95,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.253 2023/07/17 12:55:37 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.254 2023/09/23 18:20:20 ad Exp $");
 
 #include "opt_ddb.h"
 #include "opt_uvm.h"
@@ -671,23 +671,6 @@ uvm_page_physget(paddr_t *paddrp)
 }
 #endif /* PMAP_STEAL_MEMORY */
 
-/*
- * PHYS_TO_VM_PAGE: find vm_page for a PA.   used by MI code to get vm_pages
- * back from an I/O mapping (ugh!).   used in some MD code as well.
- */
-struct vm_page *
-uvm_phys_to_vm_page(paddr_t pa)
-{
-	paddr_t pf = atop(pa);
-	paddr_t	off;
-	uvm_physseg_t	upm;
-
-	upm = uvm_physseg_find(pf, &off);
-	if (upm != UVM_PHYSSEG_TYPE_INVALID)
-		return uvm_physseg_get_pg(upm, off);
-	return(NULL);
-}
-
 paddr_t
 uvm_vm_page_to_phys(const struct vm_page *pg)
 {

Index: src/sys/uvm/uvm_physseg.c
diff -u src/sys/uvm/uvm_physseg.c:1.18 src/sys/uvm/uvm_physseg.c:1.19
--- src/sys/uvm/uvm_physseg.c:1.18	Sun Apr  9 09:00:56 2023
+++ src/sys/uvm/uvm_physseg.c	Sat Sep 23 18:20:20 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_physseg.c,v 1.18 2023/04/09 09:00:56 riastradh Exp $ */
+/* $NetBSD: uvm_physseg.c,v 1.19 2023/09/23 18:20:20 ad Exp $ */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -88,7 +88,9 @@
  */
 struct uvm_physseg {
 	/* used during RB tree lookup for PHYS_TO_VM_PAGE(). */
+#if defined(UVM_HOTPLUG)
 	struct  rb_node rb_node;	/* tree information */
+#endif
 	paddr_t	start;			/* PF# of first page in segment */
 	paddr_t	end;			/* (PF# of last page in segment) + 1 */
 	struct	vm_page *pgs;		/* vm_page structures (from start) */
@@ -561,8 +563,10 @@ uvm_physseg_find(paddr_t pframe, psize_t
 #define		HANDLE_TO_PHYSSEG_NODE(h)	(VM_PHYSMEM_PTR((int)h))
 #define		PHYSSEG_NODE_TO_HANDLE(u)	((int)((vsize_t) (u - vm_physmem) / sizeof(struct uvm_physseg)))
 
-static struct uvm_physseg vm_physmem[VM_PHYSSEG_MAX];	/* XXXCDC: uvm.physmem */
-static int vm_nphysseg = 0;				/* XXXCDC: uvm.nphysseg */
+/* XXXCDC: uvm.physmem */
+static struct uvm_physseg vm_physmem[VM_PHYSSEG_MAX] __read_mostly;
+/* XXXCDC: uvm.nphysseg */
+static int vm_nphysseg __read_mostly = 0;
 #define	vm_nphysmem	vm_nphysseg
 
 void
@@ -851,7 +855,7 @@ static inline int vm_physseg_find_linear
 /*
  * vm_physseg_find: find vm_physseg structure that belongs to a PA
  */
-int
+inline int
 uvm_physseg_find(paddr_t pframe, psize_t *offp)
 {
 
@@ -943,6 +947,40 @@ vm_physseg_find_linear(struct uvm_physse
 #endif
 #endif /* UVM_HOTPLUG */
 
+/*
+ * PHYS_TO_VM_PAGE: find vm_page for a PA.  used by MI code to get vm_pages
+ * back from an I/O mapping (ugh!).  used in some MD code as well.  it can
+ * be prominent in flamegraphs, so optimise it and try to make it easy for
+ * the compiler by including next to the inline lookup routines.
+ */
+struct vm_page *
+uvm_phys_to_vm_page(paddr_t pa)
+{
+#if VM_PHYSSEG_STRAT != VM_PSTRAT_BSEARCH
+	/* 'contig' and linear cases */
+	KASSERT(vm_nphysseg > 0);
+	struct uvm_physseg *ps = &vm_physmem[0];
+	struct uvm_physseg *end = &vm_physmem[vm_nphysseg];
+	paddr_t pframe = atop(pa);
+	do {
+		if (pframe >= ps->start && pframe < ps->end) {
+			return &ps->pgs[pframe - ps->start];
+		}
+	} while (VM_PHYSSEG_MAX > 1 && __predict_false(++ps < end));
+	return NULL;
+#else
+	/* binary search for it */
+	paddr_t pf = atop(pa);
+	paddr_t	off;
+	uvm_physseg_t	upm;
+
+	upm = uvm_physseg_find(pf, &off);
+	if (upm != UVM_PHYSSEG_TYPE_INVALID)
+		return uvm_physseg_get_pg(upm, off);
+	return(NULL);
+#endif
+}
+
 bool
 uvm_physseg_valid_p(uvm_physseg_t upm)
 {
@@ -1047,7 +1085,7 @@ uvm_physseg_get_avail_end(uvm_physseg_t 
 	return HANDLE_TO_PHYSSEG_NODE(upm)->avail_end;
 }
 
-struct vm_page *
+inline struct vm_page *
 uvm_physseg_get_pg(uvm_physseg_t upm, paddr_t idx)
 {
 	KASSERT(uvm_physseg_valid_p(upm));

Reply via email to