Index | Thread | Search

From:
Martin Pieuchot <mpi@grenadille.net>
Subject:
Fault upgrade counters
To:
tech@openbsd.org
Date:
Mon, 24 Feb 2025 12:36:34 +0100

Download raw body.

Thread
Diff below adds a new counter to measure lock upgrades, documents it and
unifies the re-lock counters to do only one atomic operation instead of
two.

ok?

Index: sys/uvm/uvm_fault.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_fault.c,v
diff -u -p -r1.163 uvm_fault.c
--- sys/uvm/uvm_fault.c	29 Jan 2025 15:22:33 -0000	1.163
+++ sys/uvm/uvm_fault.c	24 Feb 2025 11:11:00 -0000
@@ -1268,8 +1268,10 @@ uvm_fault_lower_upgrade(struct uvm_fault
 	flt->lower_lock_type = RW_WRITE;
 	if (rw_enter(uobj->vmobjlock, RW_UPGRADE|RW_NOSLEEP)) {
 		uvmfault_unlockall(ufi, amap, uobj);
+		counters_inc(uvmexp_counters, flt_noup);
 		return ERESTART;
 	}
+	counters_inc(uvmexp_counters, flt_up);
 	KASSERT(flt->lower_lock_type == rw_status(uobj->vmobjlock));
 	return 0;
 }
@@ -1910,8 +1912,6 @@ uvmfault_relock(struct uvm_faultinfo *uf
 		return TRUE;
 	}
 
-	counters_inc(uvmexp_counters, flt_relck);
-
 	/*
 	 * relock map.   fail if version mismatch (in which case nothing
 	 * gets locked).
@@ -1919,9 +1919,10 @@ uvmfault_relock(struct uvm_faultinfo *uf
 	vm_map_lock_read(ufi->map);
 	if (ufi->mapv != ufi->map->timestamp) {
 		vm_map_unlock_read(ufi->map);
+		counters_inc(uvmexp_counters, flt_norelck);
 		return FALSE;
 	}
 
-	counters_inc(uvmexp_counters, flt_relckok);
+	counters_inc(uvmexp_counters, flt_relck);
 	return TRUE;		/* got it! */
 }
Index: sys/uvm/uvm_meter.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_meter.c,v
diff -u -p -r1.51 uvm_meter.c
--- sys/uvm/uvm_meter.c	26 Nov 2024 09:51:30 -0000	1.51
+++ sys/uvm/uvm_meter.c	24 Feb 2025 11:20:35 -0000
@@ -267,7 +267,7 @@ uvmexp_read(struct uvmexp *uexp)
 		uexp->fltpgwait = (int)counters[flt_pgwait];
 		uexp->fltpgrele = (int)counters[flt_pgrele];
 		uexp->fltrelck = (int)counters[flt_relck];
-		uexp->fltrelckok = (int)counters[flt_relckok];
+		uexp->fltnorelck = (int)counters[flt_norelck];
 		uexp->fltanget = (int)counters[flt_anget];
 		uexp->fltanretry = (int)counters[flt_anretry];
 		uexp->fltamcopy = (int)counters[flt_amcopy];
@@ -280,6 +280,8 @@ uvmexp_read(struct uvmexp *uexp)
 		uexp->flt_obj = (int)counters[flt_obj];
 		uexp->flt_prcopy = (int)counters[flt_prcopy];
 		uexp->flt_przero = (int)counters[flt_przero];
+		uexp->fltup = (int)counters[flt_up];
+		uexp->fltnoup = (int)counters[flt_noup];
 }
 
 #ifdef DDB
@@ -314,9 +316,9 @@ uvmexp_print(int (*pr)(const char *, ...
 	(*pr)("    noram=%d, noanon=%d, noamap=%d, pgwait=%d, pgrele=%d\n",
 	    uexp.fltnoram, uexp.fltnoanon, uexp.fltnoamap,
 	    uexp.fltpgwait, uexp.fltpgrele);
-	(*pr)("    ok relocks(total)=%d(%d), anget(retries)=%d(%d), "
-	    "amapcopy=%d\n", uexp.fltrelckok, uexp.fltrelck,
-	    uexp.fltanget, uexp.fltanretry, uexp.fltamcopy);
+	(*pr)("    relocks=%d(%d), upgrades=%d(%d) anget(retries)=%d(%d), "
+	    "amapcopy=%d\n", uexp.fltrelck, uexp.fltnorelck, uexp.fltup,
+	    uexp.fltnoup, uexp.fltanget, uexp.fltanretry, uexp.fltamcopy);
 	(*pr)("    neighbor anon/obj pg=%d/%d, gets(lock/unlock)=%d/%d\n",
 	    uexp.fltnamap, uexp.fltnomap, uexp.fltlget, uexp.fltget);
 	(*pr)("    cases: anon=%d, anoncow=%d, obj=%d, prcopy=%d, przero=%d\n",
Index: sys/uvm/uvmexp.h
===================================================================
RCS file: /cvs/src/sys/uvm/uvmexp.h,v
diff -u -p -r1.16 uvmexp.h
--- sys/uvm/uvmexp.h	25 Nov 2024 13:06:25 -0000	1.16
+++ sys/uvm/uvmexp.h	24 Feb 2025 11:17:58 -0000
@@ -120,8 +120,8 @@ struct uvmexp {
 	int fltnoamap;	/* [p] # of times fault was out of amap chunks */
 	int fltpgwait;	/* [p] # of times fault had to wait on a page */
 	int fltpgrele;	/* [p] # of times fault found a released page */
-	int fltrelck;	/* [p] # of times fault relock called */
-	int fltrelckok;	/* [p] # of times fault relock is a success */
+	int fltrelck;	/* [p] # of times fault relock is a success */
+	int fltnorelck;	/* [p] # of times fault relock failed */
 	int fltanget;	/* [p] # of times fault gets anon page */
 	int fltanretry;	/* [p] # of times fault retrys an anon get */
 	int fltamcopy;	/* [p] # of times fault clears "needs copy" */
@@ -134,6 +134,8 @@ struct uvmexp {
 	int flt_obj;	/* [p] # of times fault is on object page (2a) */
 	int flt_prcopy;	/* [p] # of times fault promotes with copy (2b) */
 	int flt_przero;	/* [p] # of times fault promotes with zerofill (2b) */
+	int fltup;	/* [p] # of times fault upgrade is a success */
+	int fltnoup;	/* [p] # of times fault upgrade failed */
 
 	/* daemon counters */
 	int pdwoke;	/* [F] # of times daemon woke up */
@@ -148,8 +150,7 @@ struct uvmexp {
 	int pdpageouts;	/* number of times daemon started a pageout */
 	int pdpending;	/* number of times daemon got a pending pagout */
 	int pddeact;	/* number of pages daemon deactivates */
-	int unused11;	/* formerly pdreanon */
-	int unused12;	/* formerly pdrevnode */
+
 	int unused13;	/* formerly pdrevtext */
 
 	int fpswtch;	/* FPU context switches */
@@ -178,8 +179,8 @@ enum uvm_exp_counters {
 	flt_noamap,	/* number of times fault was out of amap chunks */
 	flt_pgwait,	/* number of times fault had to wait on a page */
 	flt_pgrele,	/* number of times fault found a released page */
-	flt_relck,	/* number of times fault relock called */
-	flt_relckok,	/* number of times fault relock is a success */
+	flt_relck,	/* number of times fault relock is a success */
+	flt_norelck,	/* number of times fault relock failed */
 	flt_anget,	/* number of times fault gets anon page */
 	flt_anretry,	/* number of times fault retrys an anon get */
 	flt_amcopy,	/* number of times fault clears "needs copy" */
@@ -192,6 +193,8 @@ enum uvm_exp_counters {
 	flt_obj,	/* number of times fault is on object page (2a) */
 	flt_prcopy,	/* number of times fault promotes with copy (2b) */
 	flt_przero,	/* number of times fault promotes with zerofill (2b) */
+	flt_up,		/* number of times fault upgrade is a success */
+	flt_noup,	/* number of times fault upgrade failed */
 
 	exp_ncounters
 };
Index: usr.bin/systat/systat.1
===================================================================
RCS file: /cvs/src/usr.bin/systat/systat.1,v
diff -u -p -r1.124 systat.1
--- usr.bin/systat/systat.1	23 Jan 2025 11:05:26 -0000	1.124
+++ usr.bin/systat/systat.1	24 Feb 2025 11:22:00 -0000
@@ -650,9 +650,13 @@ fault had to wait on a page
 .It fltpgrele
 fault found a released page
 .It fltrelck
-fault relock called
-.It fltrelckok
 fault relock was a success
+.It fltnorelck
+fault relock failed
+.It fltup
+fault upgrade was a success
+.It fltnoup
+fault upgrade failed
 .It fltanget
 fault got anon page
 .It fltanretry
Index: usr.bin/systat/uvm.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/uvm.c,v
diff -u -p -r1.11 uvm.c
--- usr.bin/systat/uvm.c	23 Jan 2025 11:05:26 -0000	1.11
+++ usr.bin/systat/uvm.c	24 Feb 2025 11:32:17 -0000
@@ -78,7 +78,7 @@ struct uvmline uvmline[] = {
 	  &uvmexp.fltrelck, &last_uvmexp.fltrelck, "fltrelck" },
 	{ &uvmexp.zeropages, &last_uvmexp.zeropages, "zeropages",
 	  &uvmexp.pageins, &last_uvmexp.pageins, "pageins",
-	  &uvmexp.fltrelckok, &last_uvmexp.fltrelckok, "fltrelckok" },
+	  &uvmexp.fltnorelck, &last_uvmexp.fltnorelck, "fltnorelck" },
 	{ &uvmexp.percpucaches, &last_uvmexp.percpucaches, "percpucaches",
 	  &uvmexp.pgswapin, &last_uvmexp.pgswapin, "pgswapin",
 	  &uvmexp.fltanget, &last_uvmexp.fltanget, "fltanget" },
@@ -117,10 +117,10 @@ struct uvmline uvmline[] = {
 	  &uvmexp.flt_przero, &last_uvmexp.flt_przero, "flt_przero" },
 	{ &uvmexp.pcpmiss, &last_uvmexp.pcpmiss, "pcpmiss",
 	  &uvmexp.pdswout, &last_uvmexp.pdswout, "pdswout",
-	  NULL, NULL, NULL },
+	  &uvmexp.fltup, &last_uvmexp.fltup, "fltup" },
 	{ NULL, NULL, NULL,
 	  &uvmexp.pdfreed, &last_uvmexp.pdfreed, "pdfreed",
-	  NULL, NULL, NULL },
+	  &uvmexp.fltnoup, &last_uvmexp.fltnoup, "fltnoup" },
 	{ NULL, NULL, NULL,
 	  &uvmexp.pdscans, &last_uvmexp.pdscans, "pdscans",
 	  NULL, NULL, NULL },
Index: usr.bin/systat/vmstat.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/vmstat.c,v
diff -u -p -r1.96 vmstat.c
--- usr.bin/systat/vmstat.c	28 Dec 2022 20:49:05 -0000	1.96
+++ usr.bin/systat/vmstat.c	24 Feb 2025 11:22:08 -0000
@@ -407,7 +407,7 @@ showkre(void)
 	PUTRATE(uvmexp.forks_sharevm, VMSTATROW + 2, VMSTATCOL + 3, 6);
 	PUTRATE(uvmexp.fltpgwait, VMSTATROW + 3, VMSTATCOL + 4, 5);
 	PUTRATE(uvmexp.fltrelck, VMSTATROW + 4, VMSTATCOL + 3, 6);
-	PUTRATE(uvmexp.fltrelckok, VMSTATROW + 5, VMSTATCOL + 3, 6);
+	PUTRATE(uvmexp.fltnorelck, VMSTATROW + 5, VMSTATCOL + 3, 6);
 	PUTRATE(uvmexp.fltnoram, VMSTATROW + 6, VMSTATCOL + 3, 6);
 	PUTRATE(uvmexp.fltamcopy, VMSTATROW + 7, VMSTATCOL + 3, 6);
 	PUTRATE(uvmexp.flt_prcopy, VMSTATROW + 8, VMSTATCOL + 3, 6);