Page MenuHomeFreeBSD

D22280.id64066.diff
No OneTemporary

D22280.id64066.diff

Index: sys/vm/swap_pager.c
===================================================================
--- sys/vm/swap_pager.c
+++ sys/vm/swap_pager.c
@@ -321,8 +321,6 @@
#endif
}
-#define SWM_POP 0x01 /* pop out */
-
static int swap_pager_full = 2; /* swap space exhaustion (task killing) */
static int swap_pager_almost_full = 1; /* swap space exhaustion (w/hysteresis)*/
static struct mtx swbuf_mtx; /* to sync nsw_wcount_async */
@@ -423,7 +421,8 @@
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_all(vm_object_t);
-static daddr_t swp_pager_meta_ctl(vm_object_t, vm_pindex_t, int);
+static daddr_t swp_pager_meta_lookup(vm_object_t, vm_pindex_t);
+static daddr_t swp_pager_meta_remove(vm_object_t, vm_pindex_t);
static void
swp_pager_init_freerange(daddr_t *start, daddr_t *num)
@@ -956,8 +955,10 @@
swap_pager_copy(vm_object_t srcobject, vm_object_t dstobject,
vm_pindex_t offset, int destroysource)
{
+ struct swblk *sb;
vm_pindex_t i;
daddr_t dstaddr, n_free, s_free, srcaddr;
+ int limit, start;
VM_OBJECT_ASSERT_WLOCKED(srcobject);
VM_OBJECT_ASSERT_WLOCKED(dstobject);
@@ -985,11 +986,39 @@
* Transfer source to destination.
*/
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)
+ for (i = 0; i < dstobject->size; i++) {
+ /*
+ * Find the next source block and remove it.
+ */
+ sb = SWAP_PCTRIE_LOOKUP_GE(&srcobject->un_pager.swp.swp_blks,
+ rounddown(i + offset, SWAP_META_PAGES));
+ if (sb == NULL || sb->p >= dstobject->size + offset)
+ break;
+ limit = dstobject->size + offset - sb->p < SWAP_META_PAGES ?
+ dstobject->size + offset - sb->p : SWAP_META_PAGES;
+ for (start = i + offset > sb->p ? i + offset - sb->p : 0;
+ start < limit; start++) {
+ if (sb->d[start] != SWAPBLK_NONE) {
+ i = sb->p + start - offset;
+ break;
+ }
+ }
+ if (start == limit) {
+ i = sb->p + start - offset - 1;
continue;
- dstaddr = swp_pager_meta_ctl(dstobject, i, 0);
+ }
+ srcaddr = sb->d[start];
+ sb->d[start] = SWAPBLK_NONE;
+ if (swp_pager_swblk_empty(sb, 0, SWAP_META_PAGES)) {
+ SWAP_PCTRIE_REMOVE(&srcobject->un_pager.swp.swp_blks,
+ rounddown(i + offset, SWAP_META_PAGES));
+ uma_zfree(swblk_zone, sb);
+ }
+
+ /*
+ * Find the matching destination block, if any.
+ */
+ dstaddr = swp_pager_meta_lookup(dstobject, i);
if (dstaddr != SWAPBLK_NONE) {
/*
* Destination has valid swapblk or it is represented
@@ -1057,7 +1086,7 @@
/*
* do we have good backing store at the requested index ?
*/
- blk0 = swp_pager_meta_ctl(object, pindex, 0);
+ blk0 = swp_pager_meta_lookup(object, pindex);
if (blk0 == SWAPBLK_NONE) {
if (before)
*before = 0;
@@ -1073,7 +1102,7 @@
for (i = 1; i < SWB_NPAGES; i++) {
if (i > pindex)
break;
- blk = swp_pager_meta_ctl(object, pindex - i, 0);
+ blk = swp_pager_meta_lookup(object, pindex - i);
if (blk != blk0 - i)
break;
}
@@ -1085,7 +1114,7 @@
*/
if (after != NULL) {
for (i = 1; i < SWB_NPAGES; i++) {
- blk = swp_pager_meta_ctl(object, pindex + i, 0);
+ blk = swp_pager_meta_lookup(object, pindex + i);
if (blk != blk0 + i)
break;
}
@@ -1118,7 +1147,7 @@
{
daddr_t srcaddr;
- srcaddr = swp_pager_meta_ctl(m->object, m->pindex, SWM_POP);
+ srcaddr = swp_pager_meta_remove(m->object, m->pindex);
if (srcaddr != SWAPBLK_NONE)
swp_pager_freeswapspace(srcaddr, 1);
}
@@ -1214,7 +1243,7 @@
vm_object_pip_add(object, count);
pindex = bm->pindex;
- blk = swp_pager_meta_ctl(object, pindex, 0);
+ blk = swp_pager_meta_lookup(object, pindex);
KASSERT(blk != SWAPBLK_NONE,
("no swap blocking containing %p(%jx)", object, (uintmax_t)pindex));
@@ -2085,28 +2114,55 @@
}
/*
- * SWP_PAGER_METACTL() - misc control of swap meta data.
+ * SWP_PAGER_META_LOOKUP() - look up swap meta data.
*
- * This routine is capable of looking up, or removing swapblk
- * assignments in the swap meta data. It returns the swapblk being
- * looked-up, popped, or SWAPBLK_NONE if the block was invalid.
+ * Look up swapblk assignments in the swap meta data. Returns the swapblk
+ * for (pindex = 0; (sb = being looked-up, or SWAPBLK_NONE if the block
+ * was invalid.
*
* When acting on a busy resident page and paging is in progress, we
* have to wait until paging is complete but otherwise can act on the
* busy page.
+ */
+static daddr_t
+swp_pager_meta_lookup(vm_object_t object, vm_pindex_t pindex)
+{
+ struct swblk *sb;
+
+ VM_OBJECT_ASSERT_LOCKED(object);
+
+ /*
+ * The meta data only exists if the object is OBJT_SWAP
+ * and even then might not be allocated yet.
+ */
+ if (object->type != OBJT_SWAP)
+ return (SWAPBLK_NONE);
+
+ sb = SWAP_PCTRIE_LOOKUP(&object->un_pager.swp.swp_blks,
+ rounddown(pindex, SWAP_META_PAGES));
+ if (sb == NULL)
+ return (SWAPBLK_NONE);
+ return (sb->d[pindex % SWAP_META_PAGES]);
+}
+
+/*
+ * SWP_PAGER_META_REMOVE() - remove swap meta data.
*
- * SWM_POP remove from meta data but do not free it
+ * This routine is capable of removing swapblk assignments in the swap
+ * for (pindex = 0; (sb = meta data. It returns the swapblk being
+ * removed, or SWAPBLK_NONE if the block was invalid.
+ *
+ * When acting on a busy resident page and paging is in progress, we
+ * have to wait until paging is complete but otherwise can act on the
+ * busy page.
*/
static daddr_t
-swp_pager_meta_ctl(vm_object_t object, vm_pindex_t pindex, int flags)
+swp_pager_meta_remove(vm_object_t object, vm_pindex_t pindex)
{
struct swblk *sb;
daddr_t r1;
- if ((flags & SWM_POP) != 0)
- VM_OBJECT_ASSERT_WLOCKED(object);
- else
- VM_OBJECT_ASSERT_LOCKED(object);
+ VM_OBJECT_ASSERT_WLOCKED(object);
/*
* The meta data only exists if the object is OBJT_SWAP
@@ -2122,13 +2178,11 @@
r1 = sb->d[pindex % SWAP_META_PAGES];
if (r1 == SWAPBLK_NONE)
return (SWAPBLK_NONE);
- if ((flags & SWM_POP) != 0) {
- sb->d[pindex % SWAP_META_PAGES] = SWAPBLK_NONE;
- if (swp_pager_swblk_empty(sb, 0, SWAP_META_PAGES)) {
- SWAP_PCTRIE_REMOVE(&object->un_pager.swp.swp_blks,
- rounddown(pindex, SWAP_META_PAGES));
- uma_zfree(swblk_zone, sb);
- }
+ sb->d[pindex % SWAP_META_PAGES] = SWAPBLK_NONE;
+ if (swp_pager_swblk_empty(sb, 0, SWAP_META_PAGES)) {
+ SWAP_PCTRIE_REMOVE(&object->un_pager.swp.swp_blks,
+ rounddown(pindex, SWAP_META_PAGES));
+ uma_zfree(swblk_zone, sb);
}
return (r1);
}

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 4, 5:08 PM (15 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29235905
Default Alt Text
D22280.id64066.diff (6 KB)

Event Timeline