Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 9 May 2023 16:48:54 GMT
From:      "Jonathan T. Looney" <jtl@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 8a16fb47303e - main - locks: fix two potential overflows in the lock delay code
Message-ID:  <202305091648.349GmsOs046288@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by jtl:

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

commit 8a16fb47303ef4bfc773b52a920e0b223f8e9c20
Author:     Jonathan T. Looney <jtl@FreeBSD.org>
AuthorDate: 2023-05-09 16:20:49 +0000
Commit:     Jonathan T. Looney <jtl@FreeBSD.org>
CommitDate: 2023-05-09 16:20:49 +0000

    locks: fix two potential overflows in the lock delay code
    
    With large numbers of CPUs, the calculation of the maximum lock delay
    could overflow, leading to an unexpectedly low delay. In fact, the
    maximum delay would calculate to 0 on systems with between 128 and
    255 cores (inclusive). Also, when calculating the new delay in
    lock_delay(), the delay would overflow if the old delay was >= 32,768.
    
    This commit fixes these two overflows. It also updates the maximum
    delay from 32,678 to SHRT_MAX.
    
    Reviewed by:    gallatin, jhb, mjg
    Fixes:  6b8dd26e7c5f ("locks: convert delay times to u_short")
    MFC after:      2 weeks
    Sponsored by:   Netflix
    Differential Revision:  https://reviews.freebsd.org/D39372
---
 sys/kern/subr_lock.c | 8 +++-----
 sys/sys/lock.h       | 2 +-
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/sys/kern/subr_lock.c b/sys/kern/subr_lock.c
index 1061ed5f5d03..05ce8b73b086 100644
--- a/sys/kern/subr_lock.c
+++ b/sys/kern/subr_lock.c
@@ -121,14 +121,14 @@ void
 lock_delay(struct lock_delay_arg *la)
 {
 	struct lock_delay_config *lc = la->config;
-	u_short i;
+	u_int i;
 
 	for (i = la->delay; i > 0; i--)
 		cpu_spinwait();
 	la->spin_cnt += la->delay;
 
 	la->delay <<= 1;
-	if (__predict_false(la->delay > lc->max))
+	if (__predict_false(la->delay > (u_int)lc->max))
 		la->delay = lc->max;
 }
 
@@ -148,9 +148,7 @@ lock_delay_default_init(struct lock_delay_config *lc)
 {
 
 	lc->base = 1;
-	lc->max = lock_roundup_2(mp_ncpus) * 256;
-	if (lc->max > 32678)
-		lc->max = 32678;
+	lc->max = min(lock_roundup_2(mp_ncpus) * 256, SHRT_MAX);
 }
 
 struct lock_delay_config __read_frequently locks_delay;
diff --git a/sys/sys/lock.h b/sys/sys/lock.h
index 4031f20946c0..ce66a8ffebba 100644
--- a/sys/sys/lock.h
+++ b/sys/sys/lock.h
@@ -182,7 +182,7 @@ extern u_short locks_delay_loops;
 
 struct lock_delay_arg {
 	struct lock_delay_config *config;
-	u_short delay;
+	u_int delay;
 	u_int spin_cnt;
 };
 



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