Page MenuHomeFreeBSD

D46629.id143298.diff
No OneTemporary

D46629.id143298.diff

Index: sys/vm/swap_pager.c
===================================================================
--- sys/vm/swap_pager.c
+++ sys/vm/swap_pager.c
@@ -2216,33 +2216,62 @@
start = (sb != NULL && sb->p < pindex) ? pindex - sb->p : 0;
for (; sb != NULL;
sb = swblk_start_limit(srcobject, pindex, last), start = 0) {
- limit = MIN(last - sb->p, SWAP_META_PAGES);
- for (i = start; i < limit; i++) {
+ daddr_t d[SWAP_META_PAGES];
+ int d_mask = 0;
+
+ pindex = sb->p;
+ limit = MIN(last - pindex, SWAP_META_PAGES);
+ for (i = start; i < limit; i++, pindex += SWAP_META_PAGES) {
if (sb->d[i] == SWAPBLK_NONE)
continue;
blk = swp_pager_meta_build(dstobject,
- sb->p + i - offset, sb->d[i], true);
+ pindex + i - offset, sb->d[i], true);
if (blk == sb->d[i]) {
/*
* Destination has no swapblk and is not
- * resident, so transfer source.
+ * resident, so transfer source. But
* swp_pager_meta_build() failed memory
* allocation already, likely to sleep in retry.
*/
- VM_OBJECT_WUNLOCK(srcobject);
- swp_pager_meta_build(dstobject,
- sb->p + i - offset, sb->d[i], false);
- VM_OBJECT_WLOCK(srcobject);
+ d[i] = blk;
+ d_mask |= 1 << i;
} else if (blk != SWAPBLK_NONE)
swp_pager_update_freerange(&range, sb->d[i]);
sb->d[i] = SWAPBLK_NONE;
}
- pindex = sb->p + SWAP_META_PAGES;
if (swp_pager_swblk_empty(sb, 0, start) &&
swp_pager_swblk_empty(sb, limit, SWAP_META_PAGES)) {
swblk_lookup_remove(srcobject, sb);
uma_zfree(swblk_zone, sb);
}
+
+ /*
+ * Try transferring un-transferred blocks again, since it's
+ * likely that just-freed memory will allow success this time,
+ * without releasing the write lock.
+ */
+ while (d_mask != 0) {
+ i = ffs(d_mask) - 1;
+ blk = swp_pager_meta_build(dstobject,
+ pindex + i - offset, d[i], true);
+ if (blk == d[i])
+ break;
+ d_mask ^= 1 << i;
+ }
+ if (d_mask == 0)
+ continue;
+
+ /*
+ * Finish transferring, with the lock released.
+ */
+ VM_OBJECT_WUNLOCK(srcobject);
+ do {
+ i = ffs(d_mask) - 1;
+ swp_pager_meta_build(dstobject,
+ pindex + i - offset, d[i], false);
+ d_mask ^= 1 << i;
+ } while (d_mask != 0);
+ VM_OBJECT_WLOCK(srcobject);
}
swp_pager_freeswapspace(&range);
}

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 29, 9:30 AM (11 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26325156
Default Alt Text
D46629.id143298.diff (2 KB)

Event Timeline