Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/swap_pager.c
Show First 20 Lines • Show All 418 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Metadata functions | * Metadata functions | ||||
*/ | */ | ||||
static daddr_t swp_pager_meta_build(vm_object_t, vm_pindex_t, daddr_t); | static daddr_t swp_pager_meta_build(vm_object_t, vm_pindex_t, daddr_t); | ||||
static void swp_pager_meta_free(vm_object_t, vm_pindex_t, vm_pindex_t); | static void swp_pager_meta_free(vm_object_t, vm_pindex_t, vm_pindex_t); | ||||
static void swp_pager_meta_free_all(vm_object_t); | static void swp_pager_meta_free_all(vm_object_t); | ||||
static daddr_t swp_pager_meta_ctl(vm_object_t, vm_pindex_t, int); | static daddr_t swp_pager_meta_ctl(vm_object_t, vm_pindex_t, int); | ||||
static vm_pindex_t swp_pager_meta_find_least(vm_object_t, vm_pindex_t, | |||||
daddr_t*); | |||||
static void | static void | ||||
swp_pager_init_freerange(daddr_t *start, daddr_t *num) | swp_pager_init_freerange(daddr_t *start, daddr_t *num) | ||||
{ | { | ||||
*start = SWAPBLK_NONE; | *start = SWAPBLK_NONE; | ||||
*num = 0; | *num = 0; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 545 Lines • ▼ Show 20 Lines | if (destroysource && srcobject->handle != NULL) { | ||||
VM_OBJECT_WLOCK(srcobject); | VM_OBJECT_WLOCK(srcobject); | ||||
vm_object_pip_wakeup(srcobject); | vm_object_pip_wakeup(srcobject); | ||||
} | } | ||||
/* | /* | ||||
* Transfer source to destination. | * Transfer source to destination. | ||||
*/ | */ | ||||
swp_pager_init_freerange(&s_free, &n_free); | swp_pager_init_freerange(&s_free, &n_free); | ||||
for (i = 0; i < dstobject->size; ++i) { | |||||
srcaddr = swp_pager_meta_ctl(srcobject, i + offset, SWM_POP); | /* | ||||
if (srcaddr == SWAPBLK_NONE) | * Search srcobject pindex of corresponding dstobject between 0 and | ||||
continue; | * dstobject->size to transfer. | ||||
*/ | |||||
for (i = 0; (i = swp_pager_meta_find_least(srcobject, i + offset, | |||||
&srcaddr) - offset) < dstobject->size; ++i) { | |||||
dstaddr = swp_pager_meta_ctl(dstobject, i, 0); | dstaddr = swp_pager_meta_ctl(dstobject, i, 0); | ||||
if (dstaddr != SWAPBLK_NONE) { | if (dstaddr != SWAPBLK_NONE) { | ||||
/* | /* | ||||
* Destination has valid swapblk or it is represented | * Destination has valid swapblk or it is represented | ||||
* by a resident page. We destroy the source block. | * by a resident page. We destroy the source block. | ||||
*/ | */ | ||||
swp_pager_update_freerange(&s_free, &n_free, srcaddr); | swp_pager_update_freerange(&s_free, &n_free, srcaddr); | ||||
continue; | continue; | ||||
▲ Show 20 Lines • Show All 1,131 Lines • ▼ Show 20 Lines | if ((flags & SWM_POP) != 0) { | ||||
} | } | ||||
} | } | ||||
return (r1); | return (r1); | ||||
} | } | ||||
/* | /* | ||||
* Returns the least page index which is greater than or equal to the | * Returns the least page index which is greater than or equal to the | ||||
* parameter pindex and for which there is a swap block allocated. | * parameter pindex and for which there is a swap block allocated. | ||||
* If removal argument is passed, the swpblk is removed. | |||||
* Returns object's size if the object's type is not swap or if there | * Returns object's size if the object's type is not swap or if there | ||||
* are no allocated swap blocks for the object after the requested | * are no allocated swap blocks for the object after the requested | ||||
* pindex. | * pindex. | ||||
*/ | */ | ||||
vm_pindex_t | vm_pindex_t | ||||
swap_pager_find_least(vm_object_t object, vm_pindex_t pindex) | swp_pager_meta_find_least(vm_object_t object, vm_pindex_t pindex, | ||||
daddr_t *removal) | |||||
{ | { | ||||
struct swblk *sb; | struct swblk *sb; | ||||
int i; | int i; | ||||
if (removal) | |||||
VM_OBJECT_ASSERT_WLOCKED(object); | |||||
else | |||||
VM_OBJECT_ASSERT_LOCKED(object); | VM_OBJECT_ASSERT_LOCKED(object); | ||||
if (object->type != OBJT_SWAP) | if (object->type != OBJT_SWAP) | ||||
return (object->size); | return (object->size); | ||||
sb = SWAP_PCTRIE_LOOKUP_GE(&object->un_pager.swp.swp_blks, | sb = SWAP_PCTRIE_LOOKUP_GE(&object->un_pager.swp.swp_blks, | ||||
rounddown(pindex, SWAP_META_PAGES)); | rounddown(pindex, SWAP_META_PAGES)); | ||||
if (sb == NULL) | if (sb == NULL) | ||||
return (object->size); | return (object->size); | ||||
if (sb->p < pindex) { | if (sb->p < pindex) { | ||||
for (i = pindex % SWAP_META_PAGES; i < SWAP_META_PAGES; i++) { | for (i = pindex % SWAP_META_PAGES; i < SWAP_META_PAGES; i++) | ||||
if (sb->d[i] != SWAPBLK_NONE) | if (sb->d[i] != SWAPBLK_NONE) | ||||
return (sb->p + i); | goto found; | ||||
} | |||||
sb = SWAP_PCTRIE_LOOKUP_GE(&object->un_pager.swp.swp_blks, | sb = SWAP_PCTRIE_LOOKUP_GE(&object->un_pager.swp.swp_blks, | ||||
roundup(pindex, SWAP_META_PAGES)); | roundup(pindex, SWAP_META_PAGES)); | ||||
if (sb == NULL) | if (sb == NULL) | ||||
return (object->size); | return (object->size); | ||||
} | } | ||||
for (i = 0; i < SWAP_META_PAGES; i++) { | for (i = 0; i < SWAP_META_PAGES; i++) | ||||
if (sb->d[i] != SWAPBLK_NONE) | if (sb->d[i] != SWAPBLK_NONE) | ||||
return (sb->p + i); | goto found; | ||||
} | |||||
/* | /* | ||||
* We get here if a swblk is present in the trie but it | * We get here if a swblk is present in the trie but it | ||||
* doesn't map any blocks. | * doesn't map any blocks. | ||||
*/ | */ | ||||
MPASS(0); | MPASS(0); | ||||
return (object->size); | return (object->size); | ||||
found: | |||||
if (removal) { | |||||
*removal = sb->d[i]; | |||||
sb->d[i] = SWAPBLK_NONE; | |||||
if (swp_pager_swblk_empty(sb, 0, SWAP_META_PAGES)) { | |||||
SWAP_PCTRIE_REMOVE(&object->un_pager.swp.swp_blks, | |||||
sb->p); | |||||
uma_zfree(swblk_zone, sb); | |||||
} | |||||
} | |||||
return (sb->p + i); | |||||
} | |||||
/* | |||||
* Returns the least page index which is greater than or equal to the | |||||
* parameter pindex and for which there is a swap block allocated. | |||||
* Returns object's size if the object's type is not swap or if there | |||||
* are no allocated swap blocks for the object after the requested | |||||
* pindex. | |||||
*/ | |||||
vm_pindex_t | |||||
swap_pager_find_least(vm_object_t object, vm_pindex_t pindex) | |||||
{ | |||||
return swp_pager_meta_find_least(object, pindex, NULL); | |||||
} | } | ||||
/* | /* | ||||
* System call swapon(name) enables swapping on device name, | * System call swapon(name) enables swapping on device name, | ||||
* which must be in the swdevsw. Return EBUSY | * which must be in the swdevsw. Return EBUSY | ||||
* if already swapping on this device. | * if already swapping on this device. | ||||
*/ | */ | ||||
#ifndef _SYS_SYSPROTO_H_ | #ifndef _SYS_SYSPROTO_H_ | ||||
▲ Show 20 Lines • Show All 836 Lines • Show Last 20 Lines |