Page MenuHomeFreeBSD

D45627.id140997.diff
No OneTemporary

D45627.id140997.diff

Index: sys/kern/subr_pctrie.c
===================================================================
--- sys/kern/subr_pctrie.c
+++ sys/kern/subr_pctrie.c
@@ -63,7 +63,6 @@
#endif
#define PCTRIE_MASK (PCTRIE_COUNT - 1)
-#define PCTRIE_LIMIT (howmany(sizeof(uint64_t) * NBBY, PCTRIE_WIDTH) - 1)
#if PCTRIE_WIDTH == 3
typedef uint8_t pn_popmap_t;
@@ -738,42 +737,25 @@
}
#endif
-/*
- * Remove the specified index from the tree, and return the value stored at
- * that index. If the index is not present, return NULL.
- */
-uint64_t *
-pctrie_remove_lookup(struct pctrie *ptree, uint64_t index,
- struct pctrie_node **freenode)
+static void
+pctrie_remove(struct pctrie *ptree, uint64_t index, struct pctrie_node *parent,
+ struct pctrie_node *node, struct pctrie_node **freenode)
{
- struct pctrie_node *child, *node, *parent;
- uint64_t *m;
+ struct pctrie_node *child;
int slot;
- *freenode = node = NULL;
- child = pctrie_root_load(ptree, NULL, PCTRIE_LOCKED);
- for (;;) {
- if (pctrie_isleaf(child))
- break;
- parent = node;
- node = child;
- slot = pctrie_slot(node, index);
- child = pctrie_node_load(&node->pn_child[slot], NULL,
- PCTRIE_LOCKED);
- }
- if ((m = pctrie_toval(child)) == NULL || *m != index)
- return (NULL);
if (node == NULL) {
pctrie_root_store(ptree, PCTRIE_NULL, PCTRIE_LOCKED);
- return (m);
+ return;
}
+ slot = pctrie_slot(node, index);
KASSERT((node->pn_popmap & (1 << slot)) != 0,
("%s: bad popmap slot %d in node %p",
__func__, slot, node));
node->pn_popmap ^= 1 << slot;
pctrie_node_store(&node->pn_child[slot], PCTRIE_NULL, PCTRIE_LOCKED);
if (!powerof2(node->pn_popmap))
- return (m);
+ return;
KASSERT(node->pn_popmap != 0, ("%s: bad popmap all zeroes", __func__));
slot = ffs(node->pn_popmap) - 1;
child = pctrie_node_load(&node->pn_child[slot], NULL, PCTRIE_LOCKED);
@@ -795,6 +777,33 @@
*/
pctrie_node_put(node);
*freenode = node;
+}
+
+/*
+ * Remove the specified index from the tree, and return the value stored at
+ * that index. If the index is not present, return NULL.
+ */
+uint64_t *
+pctrie_remove_lookup(struct pctrie *ptree, uint64_t index,
+ struct pctrie_node **freenode)
+{
+ struct pctrie_node *child, *node, *parent;
+ uint64_t *m;
+ int slot;
+
+ parent = (struct pctrie_node *)0xdeadbeef;
+ *freenode = node = NULL;
+ child = pctrie_root_load(ptree, NULL, PCTRIE_LOCKED);
+ while (!pctrie_isleaf(child)) {
+ parent = node;
+ node = child;
+ slot = pctrie_slot(node, index);
+ child = pctrie_node_load(&node->pn_child[slot], NULL,
+ PCTRIE_LOCKED);
+ }
+ if ((m = pctrie_toval(child)) == NULL || *m != index)
+ return (NULL);
+ pctrie_remove(ptree, index, parent, node, freenode);
return (m);
}
@@ -901,6 +910,161 @@
callback, keyoff, arg));
}
+/*
+ * Find first leaf >= index, and fill iter with the path to the parent of that
+ * leaf.
+ */
+static uint64_t *
+pctrie_iter_index(struct pctrie_iter *iter, struct pctrie_node *node,
+ uint64_t index)
+{
+ uint64_t *m;
+ int slot;
+
+ /* Seek a node that matches index. */
+ while (!pctrie_isleaf(node) &&
+ !pctrie_keybarr(node, index, &slot)) {
+ iter->path[iter->top++] = node;
+ KASSERT(iter->top <= nitems(iter->path),
+ ("%s: path overflow in trie %p", __func__, iter->ptree));
+ node = pctrie_node_load(&node->pn_child[slot], NULL,
+ PCTRIE_LOCKED);
+ }
+
+ /*
+ * If no such node was found, and instead this path leads only to nodes
+ * < index, back up to find a subtrie with the least value > index.
+ */
+ if (pctrie_isleaf(node) ?
+ (m = pctrie_toval(node)) == NULL || *m < index :
+ node->pn_owner < index) {
+ /* Climb the path to find a node with a descendant > index. */
+ do {
+ if (iter->top == 0) {
+ MPASS(pctrie_lookup_ge(iter->ptree, index) ==
+ NULL);
+ return (NULL);
+ }
+ node = iter->path[--iter->top];
+ slot = pctrie_slot(node, index) + 1;
+ } while ((node->pn_popmap >> slot) == 0);
+
+ /* Step to the least child with a descendant > index. */
+ slot += ffs(node->pn_popmap >> slot) - 1;
+ iter->top++;
+ node = pctrie_node_load(&node->pn_child[slot], NULL,
+ PCTRIE_LOCKED);
+ }
+ /* Descend to the least leaf of the subtrie. */
+ while (!pctrie_isleaf(node)) {
+ slot = ffs(node->pn_popmap) - 1;
+ iter->path[iter->top++] = node;
+ KASSERT(iter->top <= nitems(iter->path),
+ ("%s: path overflow in trie %p", __func__, iter->ptree));
+ node = pctrie_node_load(&node->pn_child[slot], NULL,
+ PCTRIE_LOCKED);
+ }
+ m = pctrie_toval(node);
+ iter->index = *m;
+ MPASS(pctrie_lookup_ge(iter->ptree, index) == m);
+ return (m);
+}
+
+/*
+ * Find the first leaf with value at least 'step' greater than the previous
+ * leaf.
+ */
+uint64_t *
+pctrie_iter_step(struct pctrie_iter *iter, uint64_t step)
+{
+ struct pctrie_node *node;
+ uint64_t index = iter->index + step;
+ int slot;
+
+ /* Detect step overflow. */
+ if (index < iter->index)
+ return (NULL);
+
+ if (iter->top == 0) {
+ uint64_t *m;
+ node = pctrie_root_load(iter->ptree, NULL, PCTRIE_UNSERIALIZED);
+ if (!pctrie_isleaf(node))
+ /*
+ * If there have been insertions since the last
+ * iteration, the root may not be a leaf; in that case,
+ * put the root on the path.
+ */
+ iter->path[iter->top++] = node;
+ else if ((m = pctrie_toval(node)) != NULL && *m >= index) {
+ /* If the root is the only value in the trie and it is
+ * larger than the current index value, it was promoted
+ * to root via the removal of another, and should be
+ * considered as the last iteration.
+ */
+ iter->index = *m;
+ MPASS(pctrie_lookup_ge(iter->ptree, index) == m);
+ return (m);
+ }
+ }
+
+ /* Climb the path to find a node that matches a prefix of index. */
+ do {
+ if (iter->top == 0)
+ return (NULL);
+ node = iter->path[--iter->top];
+ } while (pctrie_keybarr(node, index, &slot));
+
+ /* Complete the search for index from node. */
+ iter->top++;
+ node = pctrie_node_load(&node->pn_child[slot], NULL, PCTRIE_LOCKED);
+ return (pctrie_iter_index(iter, node, index));
+}
+
+/*
+ * Find first leaf >= index, and initialize iter with the path to the parent of
+ * that leaf.
+ */
+uint64_t *
+pctrie_iter_start(struct pctrie_iter *iter,
+ struct pctrie *ptree, uint64_t index)
+{
+ struct pctrie_node *node = pctrie_root_load(ptree, NULL, PCTRIE_LOCKED);
+
+ iter->ptree = ptree;
+ iter->top = 0;
+ return (pctrie_iter_index(iter, node, index));
+}
+
+/*
+ * Remove from the trie the leaf last chosen by the iterator, and
+ * adjust the path if it's last member is to be freed.
+ */
+uint64_t *
+pctrie_iter_remove(struct pctrie_iter *iter, struct pctrie_node **freenode)
+{
+ struct pctrie_node *child, *node, *parent;
+ uint64_t *m;
+ int slot;
+
+ *freenode = NULL;
+ parent = (iter->top >= 2) ? iter->path[iter->top - 2] : NULL;
+ if (iter->top >= 1) {
+ node = iter->path[iter->top - 1];
+ slot = pctrie_slot(node, iter->index);
+ child = pctrie_node_load(&node->pn_child[slot], NULL,
+ PCTRIE_LOCKED);
+ } else {
+ node = NULL;
+ child = pctrie_root_load(iter->ptree, NULL, PCTRIE_LOCKED);
+ }
+ if ((m = pctrie_toval(child)) == NULL || *m != iter->index)
+ return (NULL);
+ pctrie_remove(iter->ptree, iter->index, parent, node, freenode);
+ if (*freenode != NULL)
+ --iter->top;
+ return (m);
+}
+
/*
* Replace an existing value in the trie with another one.
* Panics if there is not an old value in the trie at the new value's index.
Index: sys/kern/subr_rangeset.c
===================================================================
--- sys/kern/subr_rangeset.c
+++ sys/kern/subr_rangeset.c
@@ -272,8 +272,8 @@
int
rangeset_copy(struct rangeset *dst_rs, struct rangeset *src_rs)
{
+ struct pctrie_iter iter;
struct rs_el *src_r, *dst_r;
- uint64_t cursor;
int error;
MPASS(pctrie_is_empty(&dst_rs->rs_trie));
@@ -281,10 +281,8 @@
MPASS(dst_rs->rs_dup_data == src_rs->rs_dup_data);
error = 0;
- for (cursor = 0;; cursor = src_r->re_start + 1) {
- src_r = RANGESET_PCTRIE_LOOKUP_GE(&src_rs->rs_trie, cursor);
- if (src_r == NULL)
- break;
+ for (src_r = RANGESET_PCTRIE_ITER_START(&iter, &src_rs->rs_trie, 0);
+ src_r != NULL; src_r = RANGESET_PCTRIE_ITER_STEP(&iter, 1)) {
dst_r = dst_rs->rs_dup_data(dst_rs->rs_data_ctx, src_r);
if (dst_r == NULL) {
error = ENOMEM;
@@ -303,13 +301,11 @@
static void
rangeset_check(struct rangeset *rs)
{
+ struct pctrie_iter iter;
struct rs_el *r, *rp;
- uint64_t cursor;
- for (cursor = 0, rp = NULL;; cursor = r->re_start + 1, rp = r) {
- r = RANGESET_PCTRIE_LOOKUP_GE(&rs->rs_trie, cursor);
- if (r == NULL)
- break;
+ for (rp = NULL, r = RANGESET_PCTRIE_ITER_START(&iter, &rs->rs_trie, 0);
+ r != NULL; rp = r, r = RANGESET_PCTRIE_ITER_STEP(&iter, 1)) {
KASSERT(r->re_start < r->re_end,
("invalid interval rs %p elem %p (%#jx, %#jx)",
rs, r, (uintmax_t)r->re_start, (uintmax_t)r->re_end));
@@ -332,9 +328,9 @@
DB_SHOW_COMMAND(rangeset, rangeset_show_fn)
{
+ struct pctrie_iter iter;
struct rangeset *rs;
struct rs_el *r;
- uint64_t cursor;
if (!have_addr) {
db_printf("show rangeset addr\n");
@@ -343,10 +339,8 @@
rs = (struct rangeset *)addr;
db_printf("rangeset %p\n", rs);
- for (cursor = 0;; cursor = r->re_start + 1) {
- r = RANGESET_PCTRIE_LOOKUP_GE(&rs->rs_trie, cursor);
- if (r == NULL)
- break;
+ for (r = RANGESET_PCTRIE_ITER_START(&iter, &rs->rs_trie, 0);
+ r != NULL; r = RANGESET_PCTRIE_ITER_STEP(&iter, 1)) {
db_printf(" el %p start %#jx end %#jx\n",
r, r->re_start, r->re_end);
}
Index: sys/sys/pctrie.h
===================================================================
--- sys/sys/pctrie.h
+++ sys/sys/pctrie.h
@@ -240,6 +240,34 @@
} \
\
static __inline __unused struct type * \
+name##_PCTRIE_ITER_STEP(struct pctrie_iter *iter, uint64_t step) \
+{ \
+ return name##_PCTRIE_VAL2PTR( \
+ pctrie_iter_step(iter, step)); \
+} \
+ \
+static __inline __unused struct type * \
+name##_PCTRIE_ITER_START(struct pctrie_iter *iter, \
+ struct pctrie *ptree, uint64_t index) \
+{ \
+ return name##_PCTRIE_VAL2PTR( \
+ pctrie_iter_start(iter, ptree, index)); \
+} \
+ \
+static __inline __unused void \
+name##_PCTRIE_ITER_REMOVE(struct pctrie_iter *iter) \
+{ \
+ uint64_t *val; \
+ struct pctrie_node *freenode; \
+ \
+ val = pctrie_iter_remove(iter, &freenode); \
+ if (val == NULL) \
+ panic("%s: key not found", __func__); \
+ if (freenode != NULL) \
+ freefn(iter->ptree, freenode); \
+} \
+ \
+static __inline __unused struct type * \
name##_PCTRIE_REPLACE(struct pctrie *ptree, struct type *ptr) \
{ \
\
@@ -295,6 +323,12 @@
pctrie_cb_t callback, int keyoff, void *arg);
struct pctrie_node *pctrie_reclaim_resume_cb(struct pctrie_node **pnode,
pctrie_cb_t callback, int keyoff, void *arg);
+struct pctrie_iter;
+uint64_t *pctrie_iter_step(struct pctrie_iter *iter, uint64_t step);
+uint64_t *pctrie_iter_start(struct pctrie_iter *iter,
+ struct pctrie *ptree, uint64_t index);
+uint64_t *pctrie_iter_remove(struct pctrie_iter *iter,
+ struct pctrie_node **freenode);
uint64_t *pctrie_remove_lookup(struct pctrie *ptree, uint64_t index,
struct pctrie_node **killnode);
uint64_t *pctrie_replace(struct pctrie *ptree, uint64_t *newval);
@@ -343,5 +377,12 @@
#define PCTRIE_COUNT (1 << PCTRIE_WIDTH)
+struct pctrie_iter {
+ struct pctrie_node *path[sizeof(uint64_t) * NBBY / PCTRIE_WIDTH];
+ struct pctrie *ptree;
+ uint64_t index;
+ int top;
+};
+
#endif /* _KERNEL */
#endif /* !_SYS_PCTRIE_H_ */
Index: sys/vm/swap_pager.c
===================================================================
--- sys/vm/swap_pager.c
+++ sys/vm/swap_pager.c
@@ -491,7 +491,7 @@
static void swp_pager_meta_free(vm_object_t, vm_pindex_t, vm_pindex_t,
vm_size_t *);
static void swp_pager_meta_transfer(vm_object_t src, vm_object_t dst,
- vm_pindex_t pindex, vm_pindex_t count, vm_size_t *freed);
+ vm_pindex_t pindex, vm_pindex_t count);
static void swp_pager_meta_free_all(vm_object_t);
static daddr_t swp_pager_meta_lookup(vm_object_t, vm_pindex_t);
@@ -1084,8 +1084,7 @@
/*
* Transfer source to destination.
*/
- swp_pager_meta_transfer(srcobject, dstobject, offset, dstobject->size,
- NULL);
+ swp_pager_meta_transfer(srcobject, dstobject, offset, dstobject->size);
/*
* Free left over swap blocks in source.
@@ -1776,8 +1775,8 @@
u_long
swap_pager_swapped_pages(vm_object_t object)
{
+ struct pctrie_iter iter;
struct swblk *sb;
- vm_pindex_t pi;
u_long res;
int i;
@@ -1786,9 +1785,10 @@
if (pctrie_is_empty(&object->un_pager.swp.swp_blks))
return (0);
- for (res = 0, pi = 0; (sb = SWAP_PCTRIE_LOOKUP_GE(
- &object->un_pager.swp.swp_blks, pi)) != NULL;
- pi = sb->p + SWAP_META_PAGES) {
+ res = 0;
+ for (sb = SWAP_PCTRIE_ITER_START(&iter,
+ &object->un_pager.swp.swp_blks, 0); sb != NULL;
+ sb = SWAP_PCTRIE_ITER_STEP(&iter, SWAP_META_PAGES)) {
for (i = 0; i < SWAP_META_PAGES; i++) {
if (sb->d[i] != SWAPBLK_NONE)
res++;
@@ -1806,6 +1806,7 @@
static void
swap_pager_swapoff_object(struct swdevt *sp, vm_object_t object)
{
+ struct pctrie_iter iter;
struct page_range range;
struct swblk *sb;
vm_page_t m;
@@ -1822,29 +1823,28 @@
i = 0;
swp_pager_init_freerange(&range);
for (;;) {
- if (i == 0 && (object->flags & OBJ_DEAD) != 0) {
- /*
- * Make sure that pending writes finish before
- * returning.
- */
- vm_object_pip_wait(object, "swpoff");
- swp_pager_meta_free_all(object);
- break;
- }
-
- if (i == SWAP_META_PAGES) {
+ if (i == 0) {
+ if ((object->flags & OBJ_DEAD) != 0) {
+ /*
+ * Make sure that pending writes finish before
+ * returning.
+ */
+ vm_object_pip_wait(object, "swpoff");
+ swp_pager_meta_free_all(object);
+ break;
+ }
+ sb = SWAP_PCTRIE_ITER_START(&iter,
+ &object->un_pager.swp.swp_blks, pi);
+ } else if (i == SWAP_META_PAGES) {
pi = sb->p + SWAP_META_PAGES;
if (sb_empty) {
- SWAP_PCTRIE_REMOVE(
- &object->un_pager.swp.swp_blks, sb->p);
+ SWAP_PCTRIE_ITER_REMOVE(&iter);
uma_zfree(swblk_zone, sb);
}
+ sb = SWAP_PCTRIE_ITER_STEP(&iter, SWAP_META_PAGES);
i = 0;
}
-
if (i == 0) {
- sb = SWAP_PCTRIE_LOOKUP_GE(
- &object->un_pager.swp.swp_blks, pi);
if (sb == NULL)
break;
sb_empty = true;
@@ -2142,31 +2142,27 @@
}
/*
- * SWP_PAGER_META_TRANSFER() - free a range of blocks in the srcobject's swap
- * metadata, or transfer it into dstobject.
+ * SWP_PAGER_META_TRANSFER() - transfer a range of blocks in the srcobject's
+ * swap metadata into dstobject.
*
* This routine will free swap metadata structures as they are cleaned
* out.
*/
static void
swp_pager_meta_transfer(vm_object_t srcobject, vm_object_t dstobject,
- vm_pindex_t pindex, vm_pindex_t count, vm_size_t *moved)
+ vm_pindex_t pindex, vm_pindex_t count)
{
struct page_range range;
struct swblk *sb;
daddr_t blk;
- vm_page_t m;
vm_pindex_t offset, last;
- vm_size_t mc;
int i, limit, start;
VM_OBJECT_ASSERT_WLOCKED(srcobject);
- MPASS(moved == NULL || dstobject == NULL);
+ VM_OBJECT_ASSERT_WLOCKED(dstobject);
- mc = 0;
- m = NULL;
if (count == 0 || pctrie_is_empty(&srcobject->un_pager.swp.swp_blks))
- goto out;
+ return;
swp_pager_init_freerange(&range);
offset = pindex;
@@ -2180,13 +2176,11 @@
limit = last - sb->p < SWAP_META_PAGES ? last - sb->p :
SWAP_META_PAGES;
for (i = start; i < limit; i++) {
- blk = sb->d[i];
- if (blk == SWAPBLK_NONE)
+ if (sb->d[i] == SWAPBLK_NONE)
continue;
- if (dstobject == NULL ||
- (blk = swp_pager_meta_build(dstobject,
- sb->p + i - offset, blk, true),
- blk != sb->d[i] && blk != SWAPBLK_NONE))
+ blk = swp_pager_meta_build(dstobject,
+ sb->p + i - offset, sb->d[i], true);
+ if (blk != sb->d[i] && blk != SWAPBLK_NONE)
swp_pager_update_freerange(&range, sb->d[i]);
else if (blk == sb->d[i]) {
/*
@@ -2197,17 +2191,9 @@
*/
VM_OBJECT_WUNLOCK(srcobject);
swp_pager_meta_build(dstobject,
- sb->p + i - offset, blk, false);
+ sb->p + i - offset, sb->d[i], false);
VM_OBJECT_WLOCK(srcobject);
}
- if (moved != NULL) {
- if (m != NULL && m->pindex != pindex + i - 1)
- m = NULL;
- m = m != NULL ? vm_page_next(m) :
- vm_page_lookup(srcobject, pindex + i);
- if (m == NULL || vm_page_none_valid(m))
- mc++;
- }
sb->d[i] = SWAPBLK_NONE;
}
pindex = sb->p + SWAP_META_PAGES;
@@ -2219,9 +2205,6 @@
}
}
swp_pager_freeswapspace(&range);
-out:
- if (moved != NULL)
- *moved = mc;
}
/*
@@ -2238,7 +2221,54 @@
swp_pager_meta_free(vm_object_t object, vm_pindex_t pindex, vm_pindex_t count,
vm_size_t *freed)
{
- swp_pager_meta_transfer(object, NULL, pindex, count, freed);
+ struct pctrie_iter iter;
+ struct page_range range;
+ struct swblk *sb;
+ vm_page_t m;
+ vm_pindex_t last;
+ vm_size_t fc;
+ int i, limit, start;
+
+ VM_OBJECT_ASSERT_WLOCKED(object);
+
+ fc = 0;
+ m = NULL;
+ if (count == 0 || pctrie_is_empty(&object->un_pager.swp.swp_blks))
+ goto out;
+
+ swp_pager_init_freerange(&range);
+ last = pindex + count;
+ for (sb = SWAP_PCTRIE_ITER_START(&iter, &object->un_pager.swp.swp_blks,
+ rounddown(pindex, SWAP_META_PAGES)); sb != NULL && sb->p < last;
+ sb = SWAP_PCTRIE_ITER_STEP(&iter, SWAP_META_PAGES)) {
+ start = pindex > sb->p ? pindex - sb->p : 0;
+ limit = last - sb->p < SWAP_META_PAGES ? last - sb->p :
+ SWAP_META_PAGES;
+ for (i = start; i < limit; i++) {
+ if (sb->d[i] == SWAPBLK_NONE)
+ continue;
+ swp_pager_update_freerange(&range, sb->d[i]);
+ if (freed != NULL) {
+ if (m != NULL && m->pindex != pindex + i - 1)
+ m = NULL;
+ m = m != NULL ? vm_page_next(m) :
+ vm_page_lookup(object, pindex + i);
+ if (m == NULL || vm_page_none_valid(m))
+ fc++;
+ }
+ 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)) {
+ SWAP_PCTRIE_ITER_REMOVE(&iter);
+ uma_zfree(swblk_zone, sb);
+ }
+ }
+ swp_pager_freeswapspace(&range);
+out:
+ if (freed != NULL)
+ *freed = fc;
}
static void
@@ -2314,6 +2344,7 @@
vm_pindex_t
swap_pager_find_least(vm_object_t object, vm_pindex_t pindex)
{
+ struct pctrie_iter iter;
struct swblk *sb;
int i;
@@ -2322,7 +2353,7 @@
if (pctrie_is_empty(&object->un_pager.swp.swp_blks))
return (object->size);
- sb = SWAP_PCTRIE_LOOKUP_GE(&object->un_pager.swp.swp_blks,
+ sb = SWAP_PCTRIE_ITER_START(&iter, &object->un_pager.swp.swp_blks,
rounddown(pindex, SWAP_META_PAGES));
if (sb == NULL)
return (object->size);
@@ -2331,8 +2362,7 @@
if (sb->d[i] != SWAPBLK_NONE)
return (sb->p + i);
}
- sb = SWAP_PCTRIE_LOOKUP_GE(&object->un_pager.swp.swp_blks,
- roundup(pindex, SWAP_META_PAGES));
+ sb = SWAP_PCTRIE_ITER_STEP(&iter, SWAP_META_PAGES);
if (sb == NULL)
return (object->size);
}
@@ -2776,6 +2806,8 @@
long
vmspace_swap_count(struct vmspace *vmspace)
{
+ struct pctrie_iter iter;
+ struct pctrie *ptree;
vm_map_t map;
vm_map_entry_t cur;
vm_object_t object;
@@ -2796,13 +2828,12 @@
VM_OBJECT_RLOCK(object);
if ((object->flags & OBJ_SWAP) == 0)
goto unlock;
+ ptree = &object->un_pager.swp.swp_blks;
pi = OFF_TO_IDX(cur->offset);
e = pi + OFF_TO_IDX(cur->end - cur->start);
- for (;; pi = sb->p + SWAP_META_PAGES) {
- sb = SWAP_PCTRIE_LOOKUP_GE(
- &object->un_pager.swp.swp_blks, pi);
- if (sb == NULL || sb->p >= e)
- break;
+ for (sb = SWAP_PCTRIE_ITER_START(&iter, ptree, pi);
+ sb != NULL && sb->p < e;
+ sb = SWAP_PCTRIE_ITER_STEP(&iter, SWAP_META_PAGES)) {
for (i = 0; i < SWAP_META_PAGES; i++) {
if (sb->p + i < e &&
sb->d[i] != SWAPBLK_NONE)

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 9, 9:47 AM (16 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16550568
Default Alt Text
D45627.id140997.diff (19 KB)

Event Timeline