Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Feb 2025 09:16:35 GMT
From:      Doug Moore <dougm@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: c301c5841f9f - main - pctrie: unlock node store in remove
Message-ID:  <202502190916.51J9GZqJ063940@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 }
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202502190916.51J9GZqJ063940>