The branch main has been updated by kib:

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

commit e59b940dcb45b887974aeae8d8f86665aed2c913
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2022-04-20 22:14:37 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2022-04-27 23:27:34 +0000

    unr(9): allow to avoid internal locking
    
    Reviewed by:    markj
    Tested by:      pho
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D35014
---
 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 043f347ac0d6..98637c4f4838 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -498,6 +498,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);

Reply via email to