From nobody Sat Oct 03 23:58:27 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hy2fc2WWcz4TkhN for ; Sat, 03 Oct 2026 23:58:32 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hy2fc21tXz4Cjq for ; Sat, 03 Oct 2026 23:58:32 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791071912; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=saKK1C0BkBb9uVHjPWKz1WDmpNW87I4CYRMe564ji5k=; b=fBZS1pWMhCEFX84Y/Vr0bPYU0bp7o8RWV0jHG3lnAPLvuYtXEyJRMlbUXDKDgesVIvukz9 XeGPK35DhqvbNK+k9sHMnGG05o+pfbUE+oy9wS62pvz1snIP1OW+QKTXfY+K3eyZ7BYr+C /KB6VVzHZFWocoZxpf59eFFNufBeAM+PMX6dYgCqLg5Pz41abA29Yzrff/m0wldPy+Uq+z b0yXgk5mpiSeN9d+EDDg6C+o5R12o1lnR6GpNzSalShtg6UgeO2kmiMqkH9U03T0j6vljm VdYJuM+vxlCBP3e9QiS5kZ2c/pvEUeAsU3gc9+O35+Xr0RjYd+kmUMtXjCLK4w== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1791071912; b=hloqwikuvuPe2svaRPqQrjQFIYPcDayuPRgojnZIkfSsTtg1XZjDmPwMA/F9JEvZuwx4Qi 46/ode0OlN3FE7iLYMdmHavU8qba5bN37NhP9W4qmERXS+jgkR/I2cYdQ0dmMEP8u8YBI+ DhY5hkz3gTHDhpRcWFl2It1rCf/kzpkTJB4k5ScXZELy8WRhr6ANF8/HZzVqO3N2H0o5+z TxSKZ10zhMjE9xQiuMAogkXPRi9P6vuPBBmTWrvhFCvsXcsZkFAkVURZD+GTht9lQEl/xS RPlHBJ3yHXIeJNZKBzs416YsYnX6Qi4ynFGKitl8lQxxllunrlprCo7IUsWagQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791071912; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=saKK1C0BkBb9uVHjPWKz1WDmpNW87I4CYRMe564ji5k=; b=lZxEhtmUidMZAFw2FY90ThuPpoR5pSW5a/1jhxqsJgc8XnSKLPs29o1OjKwIWRHIW5g6N7 Ds7V2BfV7Qj2cdNSAJ/PQQkTHM0cO2aohF1gQBbeBLyN6TqG/FnZedZ35IZy6Sb99O6Q8Q xgS0NbyV83tDnirds1T1PAqepwfzlUoytk3+QNKmQv6I9b22fYVwYZaICG4T8SXv3Iby79 hekXZLBwgaN3rJSFUwDWI9F0Ms75aKe8Nv/XctQEtMnB2ytiiI21VEMY2Yo4k/9KrmdmHW vOMyaeypJrYeD+ntIrvGqHeBxtKWY0nf09qZ89h7qzXJJMW/W7mGK0fira1SnQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hy2fc16HBz1P2L for ; Sat, 03 Oct 2026 23:58:32 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 27c56 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 03 Oct 2026 23:58:27 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: R. Christian McDonald Subject: git: f12b76524d7b - main - callout: do not retry a try-lock callout sooner than a tick List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rcm X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: f12b76524d7bbf3d6c1a890834b6f8d018704ef0 Auto-Submitted: auto-generated Date: Sat, 03 Oct 2026 23:58:27 +0000 Message-Id: <6ac196a3.27c56.7b21e4d0@gitrepo.freebsd.org> The branch main has been updated by rcm: URL: https://cgit.FreeBSD.org/src/commit/?id=f12b76524d7bbf3d6c1a890834b6f8d018704ef0 commit f12b76524d7bbf3d6c1a890834b6f8d018704ef0 Author: R. Christian McDonald AuthorDate: 2026-10-03 23:55:32 +0000 Commit: R. Christian McDonald CommitDate: 2026-10-03 23:58:05 +0000 callout: do not retry a try-lock callout sooner than a tick When softclock_call_cc() fails to acquire the lock of a CALLOUT_TRYLOCK callout, it reschedules the callout half its precision after cc_lastscan and halves the precision. Repeated failures shrink the delay toward zero, and once the precision reaches 1 the callout is due immediately: the timer fires again at once and softclock retries the lock in a tight loop for as long as the lock is held. If the lock owner runs on the callout's CPU and no other CPU is idle, the softclock thread preempts it on every attempt, starving the thread it is waiting on. On an 8-CPU arm64 VM, a test module holding the lock saw 760,000 attempts per second, each with its own timer interrupt, and progressed at 38% of its normal rate. On a 4-core amd64 system under loopback TCP load, a netisr thread holding an inpcb lock made no progress for 12 minutes while the TCP timer callout was retried 830,000 times per second. Keep the half-precision retry, but never schedule it less than one tick from now. Base the deadline on sbinuptime() rather than cc_lastscan: cc_lastscan is the time of the last callout_process() scan, which can be a tick or more in the past by the time softclock runs the callout, leaving cc_lastscan + tick_sbt already expired. Floor the precision at a tick as well. With a precision of 1 the retries of many contended callouts cannot share a timer interrupt: the timer is armed for the earliest retry, each interrupt collects only those already due, and every callout_process() call walks all the contended callouts in the callwheel bucket. On the same VM, with 10,000 callouts on one lock, the owner took 5.0 to 5.8 s to finish 1 s of work with a precision of 1 and 1.3 s with the floor, and callout_process() ran about 58,000 times against about 900. A single contended callout is now retried about every two ticks. Reviewed by: kib Fixes: efcb2ec8cb81 ("callout: provide CALLOUT_TRYLOCK flag") MFC after: 2 weeks Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D60246 --- sys/kern/kern_timeout.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c index 1f97e4f813a1..05856921df1d 100644 --- a/sys/kern/kern_timeout.c +++ b/sys/kern/kern_timeout.c @@ -634,6 +634,7 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc, struct lock_class *class; struct lock_object *c_lock; uintptr_t lock_status; + sbintime_t prec; int c_iflags; #ifdef SMP struct callout_cpu *new_cc; @@ -676,10 +677,26 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc, if (c_iflags & CALLOUT_TRYLOCK) { if (__predict_false(class->lc_trylock(c_lock, lock_status) == 0)) { + /* + * Retry after half of the precision, but not + * sooner than a tick from the current time. + * Every failure halves the precision, so the + * retry delay would otherwise shrink to zero. + * Immediate retries can starve a + * lower-priority lock owner on the same CPU, + * preventing it from running to release the + * lock. + * + * Use the current time because cc_lastscan may + * be stale by the time the lock is attempted. + * Keep the precision at least a tick as well, + * so that the retries of many contended + * callouts can share a timer interrupt. + */ cc_exec_curr(cc, direct) = NULL; - callout_cc_add(c, cc, - cc->cc_lastscan + c->c_precision / 2, - qmax(c->c_precision / 2, 1), c_func, c_arg, + prec = qmax(c->c_precision / 2, tick_sbt); + callout_cc_add(c, cc, sbinuptime() + prec, + prec, c_func, c_arg, (direct) ? C_DIRECT_EXEC : 0); return; }