The branch main has been updated by dougm:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=c301c5841f9f5ca3a53a68019115b23ae0ef64a8

commit c301c5841f9f5ca3a53a68019115b23ae0ef64a8
Author:     Doug Moore <do...@freebsd.org>
AuthorDate: 2025-02-19 09:15:30 +0000
Commit:     Doug Moore <do...@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);
 }
 
 /*

Reply via email to