Changeset View
Changeset View
Standalone View
Standalone View
head/sys/vm/swap_pager.c
Show First 20 Lines • Show All 401 Lines • ▼ Show 20 Lines | |||||
static int nswap_hiwat = 512; /* in pages, swap_pager_almost_full warn */ | static int nswap_hiwat = 512; /* in pages, swap_pager_almost_full warn */ | ||||
SYSCTL_INT(_vm, OID_AUTO, dmmax, CTLFLAG_RD, &nsw_cluster_max, 0, | SYSCTL_INT(_vm, OID_AUTO, dmmax, CTLFLAG_RD, &nsw_cluster_max, 0, | ||||
"Maximum size of a swap block in pages"); | "Maximum size of a swap block in pages"); | ||||
static void swp_sizecheck(void); | static void swp_sizecheck(void); | ||||
static void swp_pager_async_iodone(struct buf *bp); | static void swp_pager_async_iodone(struct buf *bp); | ||||
static bool swp_pager_swblk_empty(struct swblk *sb, int start, int limit); | static bool swp_pager_swblk_empty(struct swblk *sb, int start, int limit); | ||||
static void swp_pager_free_empty_swblk(vm_object_t, struct swblk *sb); | |||||
static int swapongeom(struct vnode *); | static int swapongeom(struct vnode *); | ||||
static int swaponvp(struct thread *, struct vnode *, u_long); | static int swaponvp(struct thread *, struct vnode *, u_long); | ||||
static int swapoff_one(struct swdevt *sp, struct ucred *cred); | static int swapoff_one(struct swdevt *sp, struct ucred *cred); | ||||
/* | /* | ||||
* Swap bitmap functions | * Swap bitmap functions | ||||
*/ | */ | ||||
static void swp_pager_freeswapspace(daddr_t blk, daddr_t npages); | static void swp_pager_freeswapspace(daddr_t blk, daddr_t npages); | ||||
▲ Show 20 Lines • Show All 1,449 Lines • ▼ Show 20 Lines | swp_pager_swblk_empty(struct swblk *sb, int start, int limit) | ||||
MPASS(0 <= start && start <= limit && limit <= SWAP_META_PAGES); | MPASS(0 <= start && start <= limit && limit <= SWAP_META_PAGES); | ||||
for (i = start; i < limit; i++) { | for (i = start; i < limit; i++) { | ||||
if (sb->d[i] != SWAPBLK_NONE) | if (sb->d[i] != SWAPBLK_NONE) | ||||
return (false); | return (false); | ||||
} | } | ||||
return (true); | return (true); | ||||
} | } | ||||
/* | /* | ||||
* SWP_PAGER_FREE_EMPTY_SWBLK() - frees if a block is free | |||||
* | |||||
* Nothing is done if the block is still in use. | |||||
*/ | |||||
static void | |||||
swp_pager_free_empty_swblk(vm_object_t object, struct swblk *sb) | |||||
{ | |||||
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); | |||||
} | |||||
} | |||||
/* | |||||
* SWP_PAGER_META_BUILD() - add swap block to swap meta data for object | * SWP_PAGER_META_BUILD() - add swap block to swap meta data for object | ||||
* | * | ||||
* We first convert the object to a swap object if it is a default | * We first convert the object to a swap object if it is a default | ||||
* object. | * object. | ||||
* | * | ||||
* The specified swapblk is added to the object's swap metadata. If | * The specified swapblk is added to the object's swap metadata. If | ||||
* the swapblk is not valid, it is freed instead. Any previously | * the swapblk is not valid, it is freed instead. Any previously | ||||
* assigned swapblk is returned. | * assigned swapblk is returned. | ||||
▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | allocated: | ||||
/* Return prior contents of metadata. */ | /* Return prior contents of metadata. */ | ||||
prev_swapblk = sb->d[modpi]; | prev_swapblk = sb->d[modpi]; | ||||
/* Enter block into metadata. */ | /* Enter block into metadata. */ | ||||
sb->d[modpi] = swapblk; | sb->d[modpi] = swapblk; | ||||
/* | /* | ||||
* Free the swblk if we end up with the empty page run. | * Free the swblk if we end up with the empty page run. | ||||
*/ | */ | ||||
if (swapblk == SWAPBLK_NONE && | if (swapblk == SWAPBLK_NONE) | ||||
swp_pager_swblk_empty(sb, 0, SWAP_META_PAGES)) { | swp_pager_free_empty_swblk(object, sb); | ||||
SWAP_PCTRIE_REMOVE(&object->un_pager.swp.swp_blks, rdpi); | |||||
uma_zfree(swblk_zone, sb); | |||||
} | |||||
return (prev_swapblk); | return (prev_swapblk); | ||||
} | } | ||||
/* | /* | ||||
* SWP_PAGER_META_TRANSFER() - free a range of blocks in the srcobject's swap | * SWP_PAGER_META_TRANSFER() - free a range of blocks in the srcobject's swap | ||||
* metadata, or transfer it into dstobject. | * metadata, or transfer it into dstobject. | ||||
* | * | ||||
* This routine will free swap metadata structures as they are cleaned | * This routine will free swap metadata structures as they are cleaned | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | sb = SWAP_PCTRIE_LOOKUP(&object->un_pager.swp.swp_blks, | ||||
rounddown(pindex, SWAP_META_PAGES)); | rounddown(pindex, SWAP_META_PAGES)); | ||||
if (sb == NULL) | if (sb == NULL) | ||||
return (SWAPBLK_NONE); | return (SWAPBLK_NONE); | ||||
r1 = sb->d[pindex % SWAP_META_PAGES]; | r1 = sb->d[pindex % SWAP_META_PAGES]; | ||||
if (r1 == SWAPBLK_NONE) | if (r1 == SWAPBLK_NONE) | ||||
return (SWAPBLK_NONE); | return (SWAPBLK_NONE); | ||||
if ((flags & SWM_POP) != 0) { | if ((flags & SWM_POP) != 0) { | ||||
sb->d[pindex % SWAP_META_PAGES] = SWAPBLK_NONE; | sb->d[pindex % SWAP_META_PAGES] = SWAPBLK_NONE; | ||||
if (swp_pager_swblk_empty(sb, 0, SWAP_META_PAGES)) { | swp_pager_free_empty_swblk(object, sb); | ||||
SWAP_PCTRIE_REMOVE(&object->un_pager.swp.swp_blks, | |||||
rounddown(pindex, SWAP_META_PAGES)); | |||||
uma_zfree(swblk_zone, sb); | |||||
} | |||||
} | } | ||||
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. | ||||
* 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 | ||||
▲ Show 20 Lines • Show All 882 Lines • Show Last 20 Lines |