Changeset View
Changeset View
Standalone View
Standalone View
head/sys/vm/swap_pager.c
Show First 20 Lines • Show All 1,682 Lines • ▼ Show 20 Lines | |||||
* There may be no processes swapped out to the device. | * There may be no processes swapped out to the device. | ||||
* | * | ||||
* This routine may block. | * This routine may block. | ||||
*/ | */ | ||||
static void | static void | ||||
swap_pager_swapoff(struct swdevt *sp) | swap_pager_swapoff(struct swdevt *sp) | ||||
{ | { | ||||
struct swblock *swap; | struct swblock *swap; | ||||
vm_object_t locked_obj, object; | |||||
vm_pindex_t pindex; | |||||
int i, j, retries; | int i, j, retries; | ||||
sx_assert(&swdev_syscall_lock, SA_XLOCKED); | sx_assert(&swdev_syscall_lock, SA_XLOCKED); | ||||
retries = 0; | retries = 0; | ||||
locked_obj = NULL; | |||||
full_rescan: | full_rescan: | ||||
mtx_lock(&swhash_mtx); | mtx_lock(&swhash_mtx); | ||||
for (i = 0; i <= swhash_mask; i++) { /* '<=' is correct here */ | for (i = 0; i <= swhash_mask; i++) { /* '<=' is correct here */ | ||||
restart: | restart: | ||||
for (swap = swhash[i]; swap != NULL; swap = swap->swb_hnext) { | for (swap = swhash[i]; swap != NULL; swap = swap->swb_hnext) { | ||||
vm_object_t object = swap->swb_object; | object = swap->swb_object; | ||||
vm_pindex_t pindex = swap->swb_index; | pindex = swap->swb_index; | ||||
for (j = 0; j < SWAP_META_PAGES; ++j) { | for (j = 0; j < SWAP_META_PAGES; ++j) { | ||||
if (swp_pager_isondev(swap->swb_pages[j], sp)) { | if (!swp_pager_isondev(swap->swb_pages[j], sp)) | ||||
/* avoid deadlock */ | continue; | ||||
if (locked_obj != object) { | |||||
if (locked_obj != NULL) | |||||
VM_OBJECT_WUNLOCK(locked_obj); | |||||
locked_obj = object; | |||||
if (!VM_OBJECT_TRYWLOCK(object)) { | if (!VM_OBJECT_TRYWLOCK(object)) { | ||||
break; | |||||
} else { | |||||
mtx_unlock(&swhash_mtx); | mtx_unlock(&swhash_mtx); | ||||
swp_pager_force_pagein(object, | /* Depends on type-stability. */ | ||||
pindex + j); | VM_OBJECT_WLOCK(object); | ||||
VM_OBJECT_WUNLOCK(object); | |||||
mtx_lock(&swhash_mtx); | mtx_lock(&swhash_mtx); | ||||
goto restart; | goto restart; | ||||
} | } | ||||
} | } | ||||
MPASS(locked_obj == object); | |||||
mtx_unlock(&swhash_mtx); | |||||
swp_pager_force_pagein(object, pindex + j); | |||||
mtx_lock(&swhash_mtx); | |||||
goto restart; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
mtx_unlock(&swhash_mtx); | mtx_unlock(&swhash_mtx); | ||||
if (locked_obj != NULL) { | |||||
VM_OBJECT_WUNLOCK(locked_obj); | |||||
locked_obj = NULL; | |||||
} | |||||
if (sp->sw_used) { | if (sp->sw_used) { | ||||
/* | /* | ||||
* Objects may be locked or paging to the device being | * Objects may be locked or paging to the device being | ||||
* removed, so we will miss their pages and need to | * removed, so we will miss their pages and need to | ||||
* make another pass. We have marked this device as | * make another pass. We have marked this device as | ||||
* SW_CLOSING, so the activity should finish soon. | * SW_CLOSING, so the activity should finish soon. | ||||
*/ | */ | ||||
retries++; | retries++; | ||||
▲ Show 20 Lines • Show All 1,035 Lines • Show Last 20 Lines |