Page MenuHomeFreeBSD

D28592.diff
No OneTemporary

D28592.diff

Index: sys/vm/vm_fault.c
===================================================================
--- sys/vm/vm_fault.c
+++ sys/vm/vm_fault.c
@@ -81,6 +81,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/counter.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mman.h>
@@ -162,12 +163,30 @@
"Number of page allocation attempts in page fault handler before it "
"triggers OOM handling");
+static SYSCTL_NODE(_vm_stats, OID_AUTO, fault, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
+ "VM fault statistics");
+
static int vm_pfault_oom_wait = 10;
SYSCTL_INT(_vm, OID_AUTO, pfault_oom_wait, CTLFLAG_RWTUN,
&vm_pfault_oom_wait, 0,
"Number of seconds to wait for free pages before retrying "
"the page fault handler");
+static COUNTER_U64_DEFINE_EARLY(vmpfw_shared_read);
+SYSCTL_COUNTER_U64(_vm_stats_fault, OID_AUTO, vmpfw_shared_read,
+ CTLFLAG_RD, &vmpfw_shared_read,
+ "Number of waits on valid+sbusy pages caused by read faults");
+
+static COUNTER_U64_DEFINE_EARLY(vmpfw_shared_cow);
+SYSCTL_COUNTER_U64(_vm_stats_fault, OID_AUTO, vmpfw_shared_cow,
+ CTLFLAG_RD, &vmpfw_shared_cow,
+ "Number of waits on valid+sbusy pages caused by CoW faults");
+
+static COUNTER_U64_DEFINE_EARLY(vmpfw_exclusive);
+SYSCTL_COUNTER_U64(_vm_stats_fault, OID_AUTO, vmpfw_exclusive,
+ CTLFLAG_RD, &vmpfw_exclusive,
+ "Number of waits on invalid/xbusy pages");
+
static inline void
fault_page_release(vm_page_t *mp)
{
@@ -1223,11 +1242,11 @@
* and we could end up trying to pagein and pageout the same page
* simultaneously.
*
- * We can theoretically allow the busy case on a read fault if the page
- * is marked valid, but since such pages are typically already pmap'd,
- * putting that special case in might be more effort then it is worth.
- * We cannot under any circumstances mess around with a shared busied
- * page except, perhaps, to pmap it.
+ * We can theoretically allow the busy case on a read fault or a CoW
+ * fault if the page is marked valid, but since such pages are typically
+ * already pmap'd, putting that special case in might be more effort than
+ * it is worth. We cannot under any circumstances mess around with a
+ * shared busied page except, perhaps, to pmap it.
*/
static void
vm_fault_busy_sleep(struct faultstate *fs)
@@ -1244,9 +1263,25 @@
}
vm_object_pip_wakeup(fs->object);
unlock_map(fs);
- if (fs->m == vm_page_lookup(fs->object, fs->pindex))
+ if (fs->m == vm_page_lookup(fs->object, fs->pindex)) {
+ /*
+ * Provide statistics on waits that we issue for shared
+ * and valid pages that could potentially be avoided,
+ * in comparison to the expected common case of waits
+ * that cannot be avoided.
+ */
+ if (vm_page_all_valid(fs->m) && vm_page_sbusied(fs->m)) {
+ if ((fs->fault_type &
+ (VM_PROT_COPY | VM_PROT_WRITE)) == 0)
+ counter_u64_add(vmpfw_shared_read, 1);
+ else if (fs->object != fs->first_object)
+ counter_u64_add(vmpfw_shared_cow, 1);
+ else
+ counter_u64_add(vmpfw_exclusive, 1);
+ } else
+ counter_u64_add(vmpfw_exclusive, 1);
vm_page_busy_sleep(fs->m, "vmpfw", false);
- else
+ } else
VM_OBJECT_WUNLOCK(fs->object);
VM_CNT_INC(v_intrans);
vm_object_deallocate(fs->first_object);

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 22, 8:18 AM (18 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31964291
Default Alt Text
D28592.diff (3 KB)

Event Timeline