git: c301c5841f9f - main - pctrie: unlock node store in remove
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 19 Feb 2025 09:16:35 UTC
The branch main has been updated by dougm:
URL: https://cgit.FreeBSD.org/src/commit/?id=c301c5841f9f5ca3a53a68019115b23ae0ef64a8
commit c301c5841f9f5ca3a53a68019115b23ae0ef64a8
Author: Doug Moore <dougm@FreeBSD.org>
AuthorDate: 2025-02-19 09:15:30 +0000
Commit: Doug Moore <dougm@FreeBSD.org>
CommitDate: 2025-02-19 09:15:30 +0000
pctrie: unlock node store in remove
In pctrie_remove(), if the removal of an item leaves an internal node
with one child, then there are two calls to pctrie_node_store(). Only
the second of these two needs to be stored with PCTRIE_LOCKED
synchronization. Eliminate pointless synchronization for the first
node_store in that case.
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D49033
---
sys/kern/subr_pctrie.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/sys/kern/subr_pctrie.c b/sys/kern/subr_pctrie.c
index a17c386a6e24..03cf3e1e5990 100644
--- a/sys/kern/subr_pctrie.c
+++ b/sys/kern/subr_pctrie.c
@@ -834,13 +834,14 @@ static void
pctrie_remove(struct pctrie *ptree, struct pctrie_node *node, uint64_t index,
struct pctrie_node **freenode)
{
+ smr_pctnode_t *parentp;
struct pctrie_node *child;
int slot;
*freenode = NULL;
+ parentp = pctrie_child(ptree, node, index);
if (node == NULL) {
- pctrie_node_store(pctrie_root(ptree),
- PCTRIE_NULL, PCTRIE_LOCKED);
+ pctrie_node_store(parentp, PCTRIE_NULL, PCTRIE_LOCKED);
return;
}
slot = pctrie_slot(node, index);
@@ -848,20 +849,22 @@ pctrie_remove(struct pctrie *ptree, struct pctrie_node *node, uint64_t index,
("%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))
+ if (!powerof2(node->pn_popmap)) {
+ pctrie_node_store(parentp, PCTRIE_NULL, PCTRIE_LOCKED);
return;
+ }
+ pctrie_node_store(parentp, PCTRIE_NULL, PCTRIE_UNSERIALIZED);
KASSERT(node->pn_popmap != 0, ("%s: bad popmap all zeroes", __func__));
slot = ffs(node->pn_popmap) - 1;
+ *freenode = node;
child = pctrie_node_load(&node->pn_child[slot], NULL, PCTRIE_LOCKED);
KASSERT(child != PCTRIE_NULL,
("%s: bad popmap slot %d in node %p", __func__, slot, node));
- *freenode = node;
node = pctrie_parent(node);
if (!pctrie_isleaf(child))
pctrie_setparent(child, node);
- pctrie_node_store(pctrie_child(ptree, node, index), child,
- PCTRIE_LOCKED);
+ parentp = pctrie_child(ptree, node, index);
+ pctrie_node_store(parentp, child, PCTRIE_LOCKED);
}
/*