Index: head/sys/vm/swap_pager.c =================================================================== --- head/sys/vm/swap_pager.c +++ head/sys/vm/swap_pager.c @@ -1650,6 +1650,31 @@ return (nswapdev); } +static void +swp_pager_force_dirty(vm_page_t m) +{ + + vm_page_dirty(m); +#ifdef INVARIANTS + vm_page_lock(m); + if (!vm_page_wired(m) && m->queue == PQ_NONE) + panic("page %p is neither wired nor queued", m); + vm_page_unlock(m); +#endif + vm_page_xunbusy(m); +} + +static void +swp_pager_force_launder(vm_page_t m) +{ + + vm_page_dirty(m); + vm_page_lock(m); + vm_page_launder(m); + vm_page_unlock(m); + vm_page_xunbusy(m); +} + /* * SWP_PAGER_FORCE_PAGEIN() - force a swap block to be paged in * @@ -1667,7 +1692,7 @@ * 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 void swp_pager_force_pagein(vm_object_t object, vm_pindex_t pindex) { vm_page_t m; @@ -1676,14 +1701,7 @@ 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 (!vm_page_wired(m) && m->queue == PQ_NONE) - panic("page %p is neither wired nor queued", m); - vm_page_unlock(m); -#endif - vm_page_xunbusy(m); + swp_pager_force_dirty(m); vm_pager_page_unswapped(m); return; } @@ -1691,15 +1709,36 @@ 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); + swp_pager_force_launder(m); vm_pager_page_unswapped(m); } /* + * swap_pager_swapoff_object: + * + * Page in all of the pages that have been paged out for an object + * from a given swap device. + */ +static void +swap_pager_swapoff_object(struct swdevt *sp, vm_object_t object) +{ + struct swblk *sb; + vm_pindex_t pi; + int i; + + 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, sb->p + i); + } + } +} + +/* * swap_pager_swapoff: * * Page in all of the pages that have been paged out to the @@ -1712,10 +1751,8 @@ static void swap_pager_swapoff(struct swdevt *sp) { - struct swblk *sb; vm_object_t object; - vm_pindex_t pi; - int i, retries; + int retries; sx_assert(&swdev_syscall_lock, SA_XLOCKED); @@ -1745,17 +1782,7 @@ if (object->type != OBJT_SWAP) goto next_obj; - 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, - sb->p + i); - } - } + swap_pager_swapoff_object(sp, object); next_obj: VM_OBJECT_WUNLOCK(object); mtx_lock(&vm_object_list_mtx);