Page MenuHomeFreeBSD

D13424.id36389.diff
No OneTemporary

D13424.id36389.diff

Index: sys/vm/vm_page.c
===================================================================
--- sys/vm/vm_page.c
+++ sys/vm/vm_page.c
@@ -2661,15 +2661,9 @@
msleep(&vm_pageout_pages_needed, &vm_page_queue_free_mtx,
PDROP | PSWP, "VMWait", 0);
} else {
- if (__predict_false(pageproc == NULL))
+ if (pageproc == NULL)
panic("vm_wait in early boot");
- if (!vm_pageout_wanted) {
- vm_pageout_wanted = true;
- wakeup(&vm_pageout_wanted);
- }
- vm_pages_needed = true;
- msleep(&vm_cnt.v_free_count, &vm_page_queue_free_mtx, PDROP | PVM,
- "vmwait", 0);
+ pagedaemon_wait(PVM, "vmwait");
}
}
@@ -2699,7 +2693,6 @@
atomic_add_int(&vm_pageout_deficit,
max((u_int)req >> VM_ALLOC_COUNT_SHIFT, 1));
- pagedaemon_wakeup();
if (req & (VM_ALLOC_WAITOK | VM_ALLOC_WAITFAIL)) {
if (object != NULL)
VM_OBJECT_WUNLOCK(object);
@@ -2708,8 +2701,10 @@
VM_OBJECT_WLOCK(object);
if (req & VM_ALLOC_WAITOK)
return (EAGAIN);
- } else
+ } else {
mtx_unlock(&vm_page_queue_free_mtx);
+ pagedaemon_wakeup();
+ }
return (0);
}
@@ -2728,13 +2723,7 @@
{
mtx_lock(&vm_page_queue_free_mtx);
- if (!vm_pageout_wanted) {
- vm_pageout_wanted = true;
- wakeup(&vm_pageout_wanted);
- }
- vm_pages_needed = true;
- msleep(&vm_cnt.v_free_count, &vm_page_queue_free_mtx, PDROP | PUSER,
- "pfault", 0);
+ pagedaemon_wait(PUSER, "pfault");
}
struct vm_pagequeue *
Index: sys/vm/vm_pageout.h
===================================================================
--- sys/vm/vm_pageout.h
+++ sys/vm/vm_pageout.h
@@ -96,6 +96,7 @@
* Signal pageout-daemon and wait for it.
*/
+extern void pagedaemon_wait(int pri, const char *wmesg);
extern void pagedaemon_wakeup(void);
#define VM_WAIT vm_wait()
#define VM_WAITPFAULT vm_waitpfault()
Index: sys/vm/vm_pageout.c
===================================================================
--- sys/vm/vm_pageout.c
+++ sys/vm/vm_pageout.c
@@ -1791,8 +1791,15 @@
* other threads to alleviate the free page shortage. The
* thread will, nonetheless, wait until another page is freed
* or this wakeup is performed.
+ *
+ * If waiters are still asleep, we need to continue scanning.
*/
- if (vm_pages_needed && !vm_page_count_min()) {
+ if (vm_pages_needed) {
+ if (vm_page_count_min()) {
+ mtx_unlock(&vm_page_queue_free_mtx);
+ pass++;
+ goto scan;
+ }
vm_pages_needed = false;
wakeup(&vm_cnt.v_free_count);
}
@@ -1837,6 +1844,7 @@
pass = 0;
}
+scan:
target_met = vm_pageout_scan(domain, pass);
}
}
@@ -1936,17 +1944,39 @@
}
/*
- * Unless the free page queue lock is held by the caller, this function
- * should be regarded as advisory. Specifically, the caller should
- * not msleep() on &vm_cnt.v_free_count following this function unless
- * the free page queue lock is held until the msleep() is performed.
+ * Perform an advisory wakeup of the page daemon.
*/
void
pagedaemon_wakeup(void)
{
+ mtx_assert(&vm_page_queue_free_mtx, MA_NOTOWNED);
+
if (!vm_pageout_wanted && curthread->td_proc != pageproc) {
vm_pageout_wanted = true;
wakeup(&vm_pageout_wanted);
}
}
+
+/*
+ * Wake up the page daemon and wait for it to reclaim free pages.
+ *
+ * This function returns with the free queues mutex unlocked.
+ */
+void
+pagedaemon_wait(int pri, const char *wmesg)
+{
+
+ MPASS(curthread->td_proc != pageproc);
+ mtx_assert(&vm_page_queue_free_mtx, MA_OWNED);
+
+ /*
+ * vm_pageout_wanted may have been set by an advisory wakeup, but if the
+ * page daemon is running on a CPU, the wakeup will have been lost.
+ */
+ if (!vm_pageout_wanted || !vm_pages_needed)
+ wakeup(&vm_pageout_wanted);
+ vm_pageout_wanted = vm_pages_needed = true;
+ msleep(&vm_cnt.v_free_count, &vm_page_queue_free_mtx, PDROP | pri,
+ wmesg, 0);
+}

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 9, 8:13 AM (18 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28556767
Default Alt Text
D13424.id36389.diff (3 KB)

Event Timeline