From: Martin Pieuchot Subject: Fault upgrade counters To: tech@openbsd.org Date: Mon, 24 Feb 2025 12:36:34 +0100 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);