From nobody Wed Oct 28 20:35:46 2026 X-Original-To: dev-commits-src-branches@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 4jFJz64YKVz6x5xq for ; Wed, 28 Oct 2026 20:35:46 +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) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 4jFJz622dyz4RBy for ; Wed, 28 Oct 2026 20:35:46 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793219746; 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=LLvx4l3u9XzdmW+BA7dUjCtXXrElkNwUnOk5qh1F3I0=; b=kEocmgR9gEMzcPoxUm9ZIasB4YZsTQ3YTtn7y02vlbGgiRP6rh6MUK9w92YKcCu+PFbwoF CBSSvvkY6qQRly37XN3DRi/BixPiPAXHQtQzQLNbA1KDwC0Mjn94ve0jcO38Yl3xuh9h7X Q99GdnC5SM3opE54gxVXr8XbIR/xnbVnOCjQm7pzY0Fu9fF+2RIKuqL1ajgyQVXTFt+1b9 rU49i6jpthG1qzwcvXf0cfp1O4hz8d8taCFJ40bbG5C3k9lj+SYy/0Vb4Lvc9jGT7t0Ymj hj/heV97PGWsuF3IVERhTKh8AVXQstVBOZbMEvn/d1+xPohDfrWowD8RSRdNhw== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1793219746; b=bl3JP3O7XW+IZczWKIw7/om386abSHfONnooqFZFcJlCICwP7Eni3EFU0Byz5ZJfg6zSAi QTioKI5B9K/5k8FuMp3QTwnKvuZoEGVWQgH9T5fdx/3G20UWLEAw3LXiKXDgVLYg9rl+fH 1MA6dkFqfDF/4Qx3iLGle/kPfkK3rMuFKkilWXU9y++TvXb11lFKDaUbFuBDFnhSRqtvXY QbgbDdMePKcOWmh4w13xLTg//DCHEJTwENlp/GTOAJX9bd5qNG7ecB7dgS1dD3779v/KJv Jhtrtyxa6b6xzEbt829gdWrEyTWARYpX07d2v3xDTY3NxGqonuchzZPXjUgR/w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793219746; 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=LLvx4l3u9XzdmW+BA7dUjCtXXrElkNwUnOk5qh1F3I0=; b=Y0LbxTuCWZxOn+PebnrKzMHgssb26hBy/Bz92qgGj16txqgMBnkhFyHBDB3cwAAhJwCvJY 3vdgKe6g8ZIdndunkDHmLTeAW56UP/QKdaEIAYoLWT8dk+WIJTRAJJe2DkM+5Bj4ZitZUp sajT1FraX0YdBKi5A1YC12XIURumLK7Qd98ufWHXM/GzWMXlSlsFB1a34kqHiyhZzuZ8yj a3+yWW6IIbY8qfPAhgMJf1VJ55Sk4Npyn95SfZqovIIOB/4QBJc5tdVkuthvlfqMseSrnb tLriOta6xaKKX/Sk4WtXThFmy4JGdzWbORaKztWijYyB+snTFPIBzvZiuepf/A== 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 4jFJz61jKSz1MhR for ; Wed, 28 Oct 2026 20:35:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1d8dc by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 28 Oct 2026 20:35:46 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: R. Christian McDonald Subject: git: 9de6e514aa81 - stable/15 - callout: do not retry a try-lock callout sooner than a tick List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org List-Id: Commits to the stable branches of the FreeBSD src repository 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/stable/15 X-Git-Reftype: branch X-Git-Commit: 9de6e514aa8100a0df25a85d0d6f3df2008f2ec4 Auto-Submitted: auto-generated Date: Wed, 28 Oct 2026 20:35:46 +0000 Message-Id: <6ae25ca2.1d8dc.1854cebc@gitrepo.freebsd.org> The branch stable/15 has been updated by rcm: URL: https://cgit.FreeBSD.org/src/commit/?id=9de6e514aa8100a0df25a85d0d6f3df2008f2ec4 commit 9de6e514aa8100a0df25a85d0d6f3df2008f2ec4 Author: R. Christian McDonald AuthorDate: 2026-10-03 23:55:32 +0000 Commit: R. Christian McDonald CommitDate: 2026-10-28 20:34:07 +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 (cherry picked from commit f12b76524d7bbf3d6c1a890834b6f8d018704ef0) --- 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; }