Page MenuHomeFreeBSD

D13484.id57672.diff
No OneTemporary

D13484.id57672.diff

Index: sys/vm/swap_pager.c
===================================================================
--- sys/vm/swap_pager.c
+++ sys/vm/swap_pager.c
@@ -1650,9 +1650,41 @@
return (nswapdev);
}
+static void
+swp_pager_force_dirty(vm_page_t m)
+{
+
+ vm_object_pip_wakeup(m->object);
+ vm_page_dirty(m);
+#ifdef INVARIANTS
+ vm_page_lock(m);
+ if (m->wire_count == 0 && m->queue == PQ_NONE)
+ panic("page %p is neither wired nor queued", m);
+ vm_page_unlock(m);
+#endif
+ vm_page_xunbusy(m);
+ vm_pager_page_unswapped(m);
+}
+
+static void
+swp_pager_force_launder(vm_page_t m)
+{
+
+ vm_object_pip_wakeup(m->object);
+ vm_page_dirty(m);
+ vm_page_lock(m);
+ vm_page_launder(m);
+ vm_page_unlock(m);
+ vm_page_xunbusy(m);
+ vm_pager_page_unswapped(m);
+}
+
/*
* SWP_PAGER_FORCE_PAGEIN() - force a swap block to be paged in
*
+ * Returns the number of pages that are paged in. The maximum number of
+ * pages this function can page in at a time is SWB_NPAGES.
+ *
* This routine dissociates the page at the given index within an object
* from its backing store, paging it in if it does not reside in memory.
* If the page is paged in, it is marked dirty and placed in the laundry
@@ -1663,40 +1695,33 @@
* We also attempt to swap in all other pages in the swap block.
* However, we only guarantee that the one at the specified index is
* paged in.
- *
- * XXX - The code to page the whole block in doesn't work, so we
- * revert to the one-by-one behavior for now. Sigh.
*/
-static inline void
+static int
swp_pager_force_pagein(vm_object_t object, vm_pindex_t pindex)
{
- vm_page_t m;
+ vm_page_t ma[SWB_NPAGES];
+ int i, j, npages;
+ boolean_t rv;
- vm_object_pip_add(object, 1);
- m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL);
- if (m->valid == VM_PAGE_BITS_ALL) {
- vm_object_pip_wakeup(object);
- vm_page_dirty(m);
-#ifdef INVARIANTS
- vm_page_lock(m);
- if (m->wire_count == 0 && m->queue == PQ_NONE)
- panic("page %p is neither wired nor queued", m);
- vm_page_unlock(m);
-#endif
- vm_page_xunbusy(m);
- vm_pager_page_unswapped(m);
- return;
- }
+ rv = swap_pager_haspage(object, pindex, NULL, &npages);
+ KASSERT(rv == true, ("%s: missing page %p", __func__, ma));
+ npages += 1;
+ npages = vm_page_grab_pages(object, pindex, VM_ALLOC_NORMAL, ma, npages);
+ vm_object_pip_add(object, npages);
- if (swap_pager_getpages(object, &m, 1, NULL, NULL) != VM_PAGER_OK)
- panic("swap_pager_force_pagein: read from swap failed");/*XXX*/
- vm_object_pip_wakeup(object);
- vm_page_dirty(m);
- vm_page_lock(m);
- vm_page_launder(m);
- vm_page_unlock(m);
- vm_page_xunbusy(m);
- vm_pager_page_unswapped(m);
+ for (i = j = 0;; i++) {
+ if (i < npages && ma[i]->valid != VM_PAGE_BITS_ALL)
+ continue;
+ if (j < i &&
+ (swap_pager_getpages(object, &ma[j], i - j, NULL, NULL) != VM_PAGER_OK))
+ panic("swp_pager_force_pagein: read from swap failed");
+ while (j < i)
+ swp_pager_force_launder(ma[j++]);
+ if (i == npages)
+ break;
+ swp_pager_force_dirty(ma[j++]);
+ }
+ return (npages);
}
/*
@@ -1715,7 +1740,7 @@
struct swblk *sb;
vm_object_t object;
vm_pindex_t pi;
- int i, retries;
+ int freedpages, i, offset, retries;
sx_assert(&swdev_syscall_lock, SA_XLOCKED);
@@ -1745,15 +1770,27 @@
if (object->type != OBJT_SWAP)
goto next_obj;
+ freedpages = 0;
for (pi = 0; (sb = SWAP_PCTRIE_LOOKUP_GE(
&object->un_pager.swp.swp_blks, pi)) != NULL; ) {
pi = sb->p + SWAP_META_PAGES;
- for (i = 0; i < SWAP_META_PAGES; i++) {
- if (sb->d[i] == SWAPBLK_NONE)
- continue;
- if (swp_pager_isondev(sb->d[i], sp))
- swp_pager_force_pagein(object,
+ /*
+ * Last swp_pager_force_pagein() call already paged-in
+ * this block and thus we skip one.
+ */
+ if (freedpages >= SWAP_META_PAGES) {
+ freedpages -= SWAP_META_PAGES;
+ continue;
+ }
+ for (i = freedpages, freedpages = 0; i < SWAP_META_PAGES;) {
+ if (swp_pager_isondev(sb->d[i], sp)) {
+ freedpages = swp_pager_force_pagein(object,
sb->p + i);
+ offset = min(freedpages, SWAP_META_PAGES - i);
+ freedpages -= offset;
+ i += offset;
+ } else
+ i++;
}
}
next_obj:
Index: sys/vm/vm_swapout.c
===================================================================
--- sys/vm/vm_swapout.c
+++ sys/vm/vm_swapout.c
@@ -570,7 +570,8 @@
{
vm_object_t ksobj;
vm_page_t ma[KSTACK_MAX_PAGES];
- int a, count, i, j, pages, rv;
+ int a, count, i, j, pages;
+ boolean_t rv;
pages = td->td_kstack_pages;
ksobj = td->td_kstack_obj;
@@ -589,7 +590,7 @@
if (ma[j]->valid == VM_PAGE_BITS_ALL)
break;
rv = vm_pager_has_page(ksobj, ma[i]->pindex, NULL, &a);
- KASSERT(rv == 1, ("%s: missing page %p", __func__, ma[i]));
+ KASSERT(rv == true, ("%s: missing page %p", __func__, ma[i]));
count = min(a + 1, j - i);
rv = vm_pager_get_pages(ksobj, ma + i, count, NULL, NULL);
KASSERT(rv == VM_PAGER_OK, ("%s: cannot get kstack for proc %d",

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 17, 10:19 AM (20 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25405012
Default Alt Text
D13484.id57672.diff (4 KB)

Event Timeline