|
Link Here
|
| 1634 |
* We also attempt to swap in all other pages in the swap block. |
1634 |
* We also attempt to swap in all other pages in the swap block. |
| 1635 |
* However, we only guarantee that the one at the specified index is |
1635 |
* However, we only guarantee that the one at the specified index is |
| 1636 |
* paged in. |
1636 |
* paged in. |
| 1637 |
* |
|
|
| 1638 |
* XXX - The code to page the whole block in doesn't work, so we |
| 1639 |
* revert to the one-by-one behavior for now. Sigh. |
| 1640 |
*/ |
1637 |
*/ |
| 1641 |
static inline void |
1638 |
static void |
| 1642 |
swp_pager_force_pagein(vm_object_t object, vm_pindex_t pindex) |
1639 |
swp_pager_activate_vmpage(vm_object_t object, vm_page_t m) |
| 1643 |
{ |
1640 |
{ |
| 1644 |
vm_page_t m; |
1641 |
vm_object_pip_wakeup(object); |
| 1645 |
|
1642 |
vm_page_dirty(m); |
| 1646 |
vm_object_pip_add(object, 1); |
|
|
| 1647 |
m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL); |
| 1648 |
if (m->valid == VM_PAGE_BITS_ALL) { |
| 1649 |
vm_object_pip_wakeup(object); |
| 1650 |
vm_page_dirty(m); |
| 1651 |
#ifdef INVARIANTS |
1643 |
#ifdef INVARIANTS |
| 1652 |
vm_page_lock(m); |
1644 |
vm_page_lock(m); |
| 1653 |
if (m->wire_count == 0 && m->queue == PQ_NONE) |
1645 |
if (m->wire_count == 0 && m->queue == PQ_NONE) |
| 1654 |
panic("page %p is neither wired nor queued", m); |
1646 |
panic("page %p is neither wired nor queued", m); |
| 1655 |
vm_page_unlock(m); |
1647 |
vm_page_unlock(m); |
| 1656 |
#endif |
1648 |
#endif |
| 1657 |
vm_page_xunbusy(m); |
1649 |
vm_page_xunbusy(m); |
| 1658 |
vm_pager_page_unswapped(m); |
1650 |
vm_pager_page_unswapped(m); |
| 1659 |
return; |
1651 |
} |
| 1660 |
} |
1652 |
static void |
| 1661 |
|
1653 |
swp_pager_launder_vmpage(vm_object_t object, vm_page_t m) |
| 1662 |
if (swap_pager_getpages(object, &m, 1, NULL, NULL) != VM_PAGER_OK) |
1654 |
{ |
| 1663 |
panic("swap_pager_force_pagein: read from swap failed");/*XXX*/ |
|
|
| 1664 |
vm_object_pip_wakeup(object); |
1655 |
vm_object_pip_wakeup(object); |
| 1665 |
vm_page_dirty(m); |
1656 |
vm_page_dirty(m); |
| 1666 |
vm_page_lock(m); |
1657 |
vm_page_lock(m); |
|
Link Here
|
| 1669 |
vm_page_xunbusy(m); |
1660 |
vm_page_xunbusy(m); |
| 1670 |
vm_pager_page_unswapped(m); |
1661 |
vm_pager_page_unswapped(m); |
| 1671 |
} |
1662 |
} |
|
|
1663 |
static int |
| 1664 |
swp_pager_force_pagein(vm_object_t object, vm_pindex_t pindex) |
| 1665 |
{ |
| 1666 |
vm_page_t m[SWB_NPAGES]; |
| 1667 |
int count, i, j, npages, rv; |
| 1672 |
|
1668 |
|
|
|
1669 |
rv = swap_pager_haspage(object, pindex, NULL, &npages); |
| 1670 |
KASSERT(rv == 1, ("%s: missing page %p", __func__, m)); |
| 1671 |
npages += 1; |
| 1672 |
i = vm_page_grab_pages(object, pindex, VM_ALLOC_NORMAL, m, npages); |
| 1673 |
vm_object_pip_add(object, npages); |
| 1674 |
|
| 1675 |
for (i = 0; i < npages;) { |
| 1676 |
if (m[i]->valid == VM_PAGE_BITS_ALL) { |
| 1677 |
swp_pager_activate_vmpage(object, m[i]); |
| 1678 |
i++; |
| 1679 |
continue; |
| 1680 |
} |
| 1681 |
|
| 1682 |
for (j = i + 1; j < npages; j++) |
| 1683 |
if (m[j]->valid == VM_PAGE_BITS_ALL) |
| 1684 |
break; |
| 1685 |
|
| 1686 |
count = j - i; |
| 1687 |
if (swap_pager_getpages(object, &m[i], count, NULL, NULL) != VM_PAGER_OK) |
| 1688 |
panic("swap_pager_force_pagein: read from swap failed");/*XXX*/ |
| 1689 |
for (; i < j; i++) { |
| 1690 |
swp_pager_launder_vmpage(object, m[i]); |
| 1691 |
} |
| 1692 |
} |
| 1693 |
return npages; |
| 1694 |
} |
| 1695 |
|
| 1673 |
/* |
1696 |
/* |
| 1674 |
* swap_pager_swapoff: |
1697 |
* swap_pager_swapoff: |
| 1675 |
* |
1698 |
* |
|
Link Here
|
| 1686 |
struct swblk *sb; |
1711 |
struct swblk *sb; |
| 1687 |
vm_object_t object; |
1712 |
vm_object_t object; |
| 1688 |
vm_pindex_t pi; |
1713 |
vm_pindex_t pi; |
| 1689 |
int i, retries; |
1714 |
int freedpages, i, offset, retries; |
| 1690 |
|
1715 |
|
| 1691 |
sx_assert(&swdev_syscall_lock, SA_XLOCKED); |
1716 |
sx_assert(&swdev_syscall_lock, SA_XLOCKED); |
| 1692 |
|
1717 |
|
|
Link Here
|
| 1716 |
if (object->type != OBJT_SWAP) |
1741 |
if (object->type != OBJT_SWAP) |
| 1717 |
goto next_obj; |
1742 |
goto next_obj; |
| 1718 |
|
1743 |
|
|
|
1744 |
freedpages = offset = 0; |
| 1719 |
for (pi = 0; (sb = SWAP_PCTRIE_LOOKUP_GE( |
1745 |
for (pi = 0; (sb = SWAP_PCTRIE_LOOKUP_GE( |
| 1720 |
&object->un_pager.swp.swp_blks, pi)) != NULL; ) { |
1746 |
&object->un_pager.swp.swp_blks, pi)) != NULL; ) { |
| 1721 |
pi = sb->p + SWAP_META_PAGES; |
1747 |
pi = sb->p + SWAP_META_PAGES; |
| 1722 |
for (i = 0; i < SWAP_META_PAGES; i++) { |
1748 |
if (freedpages > SWAP_META_PAGES) { |
|
|
1749 |
freedpages -= SWAP_META_PAGES; |
| 1750 |
continue; |
| 1751 |
} else if (offset > 0) { |
| 1752 |
i = freedpages; |
| 1753 |
freedpages = 0; |
| 1754 |
} else |
| 1755 |
i = 0; |
| 1756 |
for (; i < SWAP_META_PAGES; i++) { |
| 1723 |
if (sb->d[i] == SWAPBLK_NONE) |
1757 |
if (sb->d[i] == SWAPBLK_NONE) |
| 1724 |
continue; |
1758 |
continue; |
| 1725 |
if (swp_pager_isondev(sb->d[i], sp)) |
1759 |
if (swp_pager_isondev(sb->d[i], sp)) { |
| 1726 |
swp_pager_force_pagein(object, |
1760 |
freedpages = swp_pager_force_pagein(object, |
| 1727 |
sb->p + i); |
1761 |
sb->p + i); |
|
|
1762 |
offset = min(freedpages, SWAP_META_PAGES - i); |
| 1763 |
freedpages -= offset; |
| 1764 |
i += ( offset - 1 ); |
| 1765 |
} |
| 1728 |
} |
1766 |
} |
| 1729 |
} |
1767 |
} |
| 1730 |
next_obj: |
1768 |
next_obj: |