Page MenuHomeFreeBSD

D50389.id155624.diff
No OneTemporary

D50389.id155624.diff

Index: sys/kern/subr_pctrie.c
===================================================================
--- sys/kern/subr_pctrie.c
+++ sys/kern/subr_pctrie.c
@@ -630,16 +630,44 @@
base = (index + i) % PCTRIE_COUNT;
if (base == 0 || parent == NULL || parent->pn_clev != 0)
continue;
- end = MIN(count, i + PCTRIE_COUNT - base);
+
+ /*
+ * For PCTRIE_SMR, compute an upper bound on number of children
+ * of this parent left to examine. For PCTRIE_LOCKED, compute
+ * the number of non-NULL children from base up to the first
+ * NULL child, if any, using the fact that pn_popmap has bits
+ * set for only the non-NULL children.
+ *
+ * The pn_popmap field is accessed only when a lock is held.
+ * To use it for PCTRIE_SMR here would require that we know that
+ * race conditions cannot occur if the tree is modified while
+ * accessed here. Guarantees about the visibility of changes to
+ * child pointers, enforced by synchronization of the writing of
+ * pointers, are not present for the pn_popmap field, so that
+ * the popmap bit for a child page may, for an instant,
+ * misrepresent the nullness of the child page because an
+ * operation modifying the pctrie is in progress.
+ */
+ end = (access == PCTRIE_SMR) ? PCTRIE_COUNT - base :
+ ffs((parent->pn_popmap >> base) + 1) - 1;
+ end = MIN(count, i + end);
while (i < end) {
node = pctrie_node_load(&parent->pn_child[base++],
smr, access);
- if ((val = pctrie_toval(node)) == NULL)
+ val = pctrie_toval(node);
+ if (access == PCTRIE_SMR && val == NULL)
break;
value[i++] = val;
+ KASSERT(val != NULL,
+ ("%s: null child written to range", __func__));
+ }
+ if (access == PCTRIE_SMR) {
+ if (i < end)
+ break;
+ } else {
+ if (base < PCTRIE_COUNT)
+ break;
}
- if (i < end)
- break;
}
if (parent_out != NULL)
*parent_out = parent;

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 9, 8:11 AM (19 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28556518
Default Alt Text
D50389.id155624.diff (1 KB)

Event Timeline