summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_glue.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2010-04-29 09:59:16 +0000
committerkib <kib@FreeBSD.org>2010-04-29 09:59:16 +0000
commit8ec6fa6b8c48d5e5aec45bcce7e5e93e531bb971 (patch)
treebc7608125ec0eeb8ab9d16e522b4199bca370b3e /sys/vm/vm_glue.c
parentb1ef5079faea187e8c41cce0863d90d4d7527cb7 (diff)
downloadFreeBSD-src-8ec6fa6b8c48d5e5aec45bcce7e5e93e531bb971.zip
FreeBSD-src-8ec6fa6b8c48d5e5aec45bcce7e5e93e531bb971.tar.gz
When doing kstack swapin, read as much pages in one run as possible.
Suggested and reviewed by: alc (previous version) Tested by: pho MFC after: 2 weeks
Diffstat (limited to 'sys/vm/vm_glue.c')
-rw-r--r--sys/vm/vm_glue.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index dbd5065d8..4eeaa4d 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -538,23 +538,37 @@ static void
vm_thread_swapin(struct thread *td)
{
vm_object_t ksobj;
- vm_page_t m, ma[KSTACK_MAX_PAGES];
- int i, pages, rv;
+ vm_page_t ma[KSTACK_MAX_PAGES];
+ int i, j, k, pages, rv;
pages = td->td_kstack_pages;
ksobj = td->td_kstack_obj;
VM_OBJECT_LOCK(ksobj);
- for (i = 0; i < pages; i++) {
- m = vm_page_grab(ksobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY |
+ for (i = 0; i < pages; i++)
+ ma[i] = vm_page_grab(ksobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY |
VM_ALLOC_WIRED);
- if (m->valid != VM_PAGE_BITS_ALL) {
- rv = vm_pager_get_pages(ksobj, &m, 1, 0);
+ for (i = 0; i < pages; i++) {
+ if (ma[i]->valid != VM_PAGE_BITS_ALL) {
+ KASSERT(ma[i]->oflags & VPO_BUSY,
+ ("lost busy 1"));
+ vm_object_pip_add(ksobj, 1);
+ for (j = i + 1; j < pages; j++) {
+ KASSERT(ma[j]->valid == VM_PAGE_BITS_ALL ||
+ (ma[j]->oflags & VPO_BUSY),
+ ("lost busy 2"));
+ if (ma[j]->valid == VM_PAGE_BITS_ALL)
+ break;
+ }
+ rv = vm_pager_get_pages(ksobj, ma + i, j - i, 0);
if (rv != VM_PAGER_OK)
- panic("vm_thread_swapin: cannot get kstack for proc: %d", td->td_proc->p_pid);
- m = vm_page_lookup(ksobj, i);
- }
- ma[i] = m;
- vm_page_wakeup(m);
+ panic("vm_thread_swapin: cannot get kstack for proc: %d",
+ td->td_proc->p_pid);
+ vm_object_pip_wakeup(ksobj);
+ for (k = i; k < j; k++)
+ ma[k] = vm_page_lookup(ksobj, k);
+ vm_page_wakeup(ma[i]);
+ } else if (ma[i]->oflags & VPO_BUSY)
+ vm_page_wakeup(ma[i]);
}
VM_OBJECT_UNLOCK(ksobj);
pmap_qenter(td->td_kstack, ma, pages);
OpenPOWER on IntegriCloud