git: 3bf38618ee3f - stable/13 - unr(9): allow to avoid internal locking

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 04 May 2022 22:33:25 UTC
The branch stable/13 has been updated by kib:

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

commit 3bf38618ee3ff8068d983f249311f473c864e421
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-04-20 22:14:37 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-05-04 22:33:05 +0000

    unr(9): allow to avoid internal locking
    
    (cherry picked from commit e59b940dcb45b887974aeae8d8f86665aed2c913)
---
 share/man/man9/unr.9 |  5 ++++-
 sys/kern/subr_unit.c | 43 +++++++++++++++++++++++++++++--------------
 sys/sys/systm.h      |  1 +
 3 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/share/man/man9/unr.9 b/share/man/man9/unr.9
index fe1299d40e5d..c2e9b3943829 100644
--- a/share/man/man9/unr.9
+++ b/share/man/man9/unr.9
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd October 4, 2017
+.Dd April 21, 2022
 .Dt UNR 9
 .Os
 .Sh NAME
@@ -72,6 +72,9 @@ If
 is not
 .Dv NULL ,
 it is used for locking when allocating and freeing units.
+If the passed value is the token
+.Va UNR_NO_MTX ,
+then no locking is applied internally.
 Otherwise, internal mutex is used.
 .It Fn clear_unrhdr uh
 Clear all units from the specified unit number allocator entity.
diff --git a/sys/kern/subr_unit.c b/sys/kern/subr_unit.c
index 9ca67bcfe7a2..66314887ac39 100644
--- a/sys/kern/subr_unit.c
+++ b/sys/kern/subr_unit.c
@@ -312,12 +312,15 @@ clean_unrhdrl(struct unrhdr *uh)
 {
 	struct unr *up;
 
-	mtx_assert(uh->mtx, MA_OWNED);
+	if (uh->mtx != NULL)
+		mtx_assert(uh->mtx, MA_OWNED);
 	while ((up = TAILQ_FIRST(&uh->ppfree)) != NULL) {
 		TAILQ_REMOVE(&uh->ppfree, up, list);
-		mtx_unlock(uh->mtx);
+		if (uh->mtx != NULL)
+			mtx_unlock(uh->mtx);
 		Free(up);
-		mtx_lock(uh->mtx);
+		if (uh->mtx != NULL)
+			mtx_lock(uh->mtx);
 	}
 
 }
@@ -326,9 +329,11 @@ void
 clean_unrhdr(struct unrhdr *uh)
 {
 
-	mtx_lock(uh->mtx);
+	if (uh->mtx != NULL)
+		mtx_lock(uh->mtx);
 	clean_unrhdrl(uh);
-	mtx_unlock(uh->mtx);
+	if (uh->mtx != NULL)
+		mtx_unlock(uh->mtx);
 }
 
 void
@@ -337,7 +342,9 @@ init_unrhdr(struct unrhdr *uh, int low, int high, struct mtx *mutex)
 
 	KASSERT(low >= 0 && low <= high,
 	    ("UNR: use error: new_unrhdr(%d, %d)", low, high));
-	if (mutex != NULL)
+	if (mutex == UNR_NO_MTX)
+		uh->mtx = NULL;
+	else if (mutex != NULL)
 		uh->mtx = mutex;
 	else
 		uh->mtx = &unitmtx;
@@ -608,7 +615,8 @@ alloc_unrl(struct unrhdr *uh)
 	u_int x;
 	int y;
 
-	mtx_assert(uh->mtx, MA_OWNED);
+	if (uh->mtx != NULL)
+		mtx_assert(uh->mtx, MA_OWNED);
 	check_unrhdr(uh, __LINE__);
 	x = uh->low + uh->first;
 
@@ -653,10 +661,12 @@ alloc_unr(struct unrhdr *uh)
 {
 	int i;
 
-	mtx_lock(uh->mtx);
+	if (uh->mtx != NULL)
+		mtx_lock(uh->mtx);
 	i = alloc_unrl(uh);
 	clean_unrhdrl(uh);
-	mtx_unlock(uh->mtx);
+	if (uh->mtx != NULL)
+		mtx_unlock(uh->mtx);
 	return (i);
 }
 
@@ -667,7 +677,8 @@ alloc_unr_specificl(struct unrhdr *uh, u_int item, void **p1, void **p2)
 	struct unrb *ub;
 	u_int i, last, tl;
 
-	mtx_assert(uh->mtx, MA_OWNED);
+	if (uh->mtx != NULL)
+		mtx_assert(uh->mtx, MA_OWNED);
 
 	if (item < uh->low + uh->first || item > uh->high)
 		return (-1);
@@ -773,9 +784,11 @@ alloc_unr_specific(struct unrhdr *uh, u_int item)
 	p1 = Malloc(sizeof(struct unr));
 	p2 = Malloc(sizeof(struct unr));
 
-	mtx_lock(uh->mtx);
+	if (uh->mtx != NULL)
+		mtx_lock(uh->mtx);
 	i = alloc_unr_specificl(uh, item, &p1, &p2);
-	mtx_unlock(uh->mtx);
+	if (uh->mtx != NULL)
+		mtx_unlock(uh->mtx);
 
 	if (p1 != NULL)
 		Free(p1);
@@ -906,10 +919,12 @@ free_unr(struct unrhdr *uh, u_int item)
 	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "free_unr");
 	p1 = Malloc(sizeof(struct unr));
 	p2 = Malloc(sizeof(struct unr));
-	mtx_lock(uh->mtx);
+	if (uh->mtx != NULL)
+		mtx_lock(uh->mtx);
 	free_unrl(uh, item, &p1, &p2);
 	clean_unrhdrl(uh);
-	mtx_unlock(uh->mtx);
+	if (uh->mtx != NULL)
+		mtx_unlock(uh->mtx);
 	if (p1 != NULL)
 		Free(p1);
 	if (p2 != NULL)
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index cf13c16f8b4a..e2e4a30275e9 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -477,6 +477,7 @@ int root_mounted(void);
  * Unit number allocation API. (kern/subr_unit.c)
  */
 struct unrhdr;
+#define	UNR_NO_MTX	((void *)(uintptr_t)-1)
 struct unrhdr *new_unrhdr(int low, int high, struct mtx *mutex);
 void init_unrhdr(struct unrhdr *uh, int low, int high, struct mtx *mutex);
 void delete_unrhdr(struct unrhdr *uh);