Introduce mutex for ratecheck(9) and ppsratecheck(9). A global
authorbluhm <bluhm@openbsd.org>
Wed, 4 May 2022 21:24:33 +0000 (21:24 +0000)
committerbluhm <bluhm@openbsd.org>
Wed, 4 May 2022 21:24:33 +0000 (21:24 +0000)
mutex with spl high for all function calls is used for now.  It
protects the lasttime and curpps parameter.  This solution is MP
safe for the usual use case, allows progress, and can be optimized
later.  Remove a useless #if 1 while there.
OK claudio@

sys/kern/kern_malloc.c
sys/kern/kern_time.c

index 6d704d8..583f82c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_malloc.c,v 1.146 2021/05/16 15:10:20 deraadt Exp $       */
+/*     $OpenBSD: kern_malloc.c,v 1.147 2022/05/04 21:24:33 bluhm Exp $ */
 /*     $NetBSD: kern_malloc.c,v 1.15.4.2 1996/06/13 17:10:56 cgd Exp $ */
 
 /*
@@ -188,7 +188,6 @@ malloc(size_t size, int type, int flags)
        if (size > 65535 * PAGE_SIZE) {
                if (flags & M_CANFAIL) {
 #ifndef SMALL_KERNEL
-                       /* XXX lock */
                        if (ratecheck(&malloc_lasterr, &malloc_errintvl))
                                printf("malloc(): allocation too large, "
                                    "type = %d, size = %lu\n", type, size);
index 7c87984..385d47b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_time.c,v 1.154 2021/06/18 15:59:14 cheloha Exp $ */
+/*     $OpenBSD: kern_time.c,v 1.155 2022/05/04 21:24:33 bluhm Exp $   */
 /*     $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $      */
 
 /*
@@ -782,11 +782,13 @@ itimerdecr(struct itimerspec *itp, long nsec)
 int
 ratecheck(struct timeval *lasttime, const struct timeval *mininterval)
 {
+       static struct mutex mtx = MUTEX_INITIALIZER(IPL_HIGH);
        struct timeval tv, delta;
        int rv = 0;
 
        getmicrouptime(&tv);
 
+       mtx_enter(&mtx);
        timersub(&tv, lasttime, &delta);
 
        /*
@@ -798,6 +800,7 @@ ratecheck(struct timeval *lasttime, const struct timeval *mininterval)
                *lasttime = tv;
                rv = 1;
        }
+       mtx_leave(&mtx);
 
        return (rv);
 }
@@ -808,11 +811,13 @@ ratecheck(struct timeval *lasttime, const struct timeval *mininterval)
 int
 ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps)
 {
+       static struct mutex mtx = MUTEX_INITIALIZER(IPL_HIGH);
        struct timeval tv, delta;
        int rv;
 
        microuptime(&tv);
 
+       mtx_enter(&mtx);
        timersub(&tv, lasttime, &delta);
 
        /*
@@ -837,20 +842,11 @@ ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps)
        else
                rv = 0;
 
-#if 1 /*DIAGNOSTIC?*/
        /* be careful about wrap-around */
        if (*curpps + 1 > *curpps)
                *curpps = *curpps + 1;
-#else
-       /*
-        * assume that there's not too many calls to this function.
-        * not sure if the assumption holds, as it depends on *caller's*
-        * behavior, not the behavior of this function.
-        * IMHO it is wrong to make assumption on the caller's behavior,
-        * so the above #if is #if 1, not #ifdef DIAGNOSTIC.
-        */
-       *curpps = *curpps + 1;
-#endif
+
+       mtx_leave(&mtx);
 
        return (rv);
 }