From nobody Fri Oct 23 06:20:31 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 4j9tDc0Srdz6wKhx for ; Fri, 23 Oct 2026 06:20: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) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 4j9tDb5xnzz3QKL for ; Fri, 23 Oct 2026 06:20:31 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1792736431; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+E0mbcGWDXJG48jM1rO1jXDKI/I5Wg9aUi7LHLAVKB4=; b=lBlKkD9GcsxyvnEpH/KUYydeP3FpxlrHgBZ7nxpoY3CMNf2pSOqRWli5+Pz+JAE86mNtUH 3/J7FG/fjlDcbAKDT6dzn/1iS/nnrT7ETquX+6bl3MjCeZ5q8Csrl174PmiTlUfAxL9EW1 1GRLCvang1BbHULy/SQ9dNC7IoEnQdkPbf9hVGXeoEWCHpSHoag+2bYKmK5atR3okuSpWM Zc0ueyt4QiZaNEEeGmxWqQ4P59kgnysvJG/qOYC9LdHXiYbKFZxqk3Vl7LsvVs6G34ARmY dWoS9jURjxLwNMVZgMt6q9aznae5nk+Vb9eOj0pwqpcZuUQoP+VXSuWktLHLOg== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1792736431; b=geTMiaMIliU7RB1sJsHVqfB153Y0VbCeY7HGBUxTsqtKagZFU+dpqfIRz5EgHH40P4hJBP tD9KwAtNPiQhdTmGaH3dL18KnxuQp7F2VacXhvOs2IJzeQ4MYY5dP5GJ8mfxV7/H6udDCa 1vgIj/E97WgpzPqK70kL2lewIWXy/NJ786OweDgCglrF6gQP61vpx6S8yRcp1HdPPDRs+i 2Q+15N/dbo0jIxP51MMUQ3Y9k0zsmBK4L+6gKpFNKgDUWbYE9+J5up7S3wM0nkMfq4rgtl BVrrZ6hyo7yfK3kNsb8PhBsgVEAEhh06eFWiDcUexmesJZJv+a+GjodqvM1LUA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1792736431; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+E0mbcGWDXJG48jM1rO1jXDKI/I5Wg9aUi7LHLAVKB4=; b=MLEcZ+M1HJjflODTvYB1luipMmR/sMpIgBW83bRn3JgOAa8B0n8dTgmVD0PMaY1AvJJ2CB D1/RkmZsiYoTXY2lyEZ9guEy7lI+1BtrEMKyG2gNnOjPr5+m5RNWz6IB2RZ2IIvTCgCHnz WeXm22G2kRGDkEWspMeIzHI4yiz0RSuAwqAWjqWIz7nKri0S+gz+4Nu7PvY9J0tKVShcb2 5uqYoqq6ogjme9QpolVnHYOVvRxoHEpydrKOLzDO5GpBVrYfXeOK2dVTAOsBt3rtTGe07S qBKZfnotiqy8iuDBwZkFH+Ofrxe1B2oruFZLIhmHGp1fN8B4kkaq+0z+tY+KjQ== 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 4j9tDb5KjpzGg0 for ; Fri, 23 Oct 2026 06:20:31 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 47e32 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 23 Oct 2026 06:20:31 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Cc: Ryan Fahy From: Vladimir Kondratyev Subject: git: 74ea8dd3fc19 - stable/15 - linuxkpi: Fix cancel_delayed_work_sync() return value 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: wulf X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 74ea8dd3fc1994fe70547f2ac81b68ed754dc484 Auto-Submitted: auto-generated Date: Fri, 23 Oct 2026 06:20:31 +0000 Message-Id: <6adafcaf.47e32.646454ff@gitrepo.freebsd.org> The branch stable/15 has been updated by wulf: URL: https://cgit.FreeBSD.org/src/commit/?id=74ea8dd3fc1994fe70547f2ac81b68ed754dc484 commit 74ea8dd3fc1994fe70547f2ac81b68ed754dc484 Author: Ryan Fahy AuthorDate: 2026-09-13 07:39:48 +0000 Commit: Vladimir Kondratyev CommitDate: 2026-10-23 06:16:01 +0000 linuxkpi: Fix cancel_delayed_work_sync() return value Align behavior between the Linux cancel_delayed_work_sync() function return value and the LinuxKPI equivalent. Linux cancel_delayed_work_sync() returns whether delayed work was pending, even if canceled before executing. This includes the case where the timer fired and work was queued but the callback had not yet started. The LinuxKPI version used the return value from taskqueue_cancel() as the return value of the public facing API, which inverted the behavior of two cases, violating the Linux API contract. Queued work which was removed before running would return false, and work whose callback was already executing would return true. Track the taskqueue pending count separately from the taskqueue_cancel() return value. Use the pending count for the public return value. Use taskqueue_cancel() return value only to decide whether state needs to be re-checked. This fixes behavior in consumers which use the return value of cancel_delayed_work_sync() to distinguish canceled pending work from work that was already running or idle. Signed-off-by: Ryan Fahy Reviewed by: wulf MFC after: 1 month Pull Request: https://github.com/freebsd/freebsd-src/pull/2268 (cherry picked from commit 79e290d967862bef1adcf39f0bfcf1b4993a8202) --- sys/compat/linuxkpi/common/src/linux_work.c | 37 +++++++++++++++++++---------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/sys/compat/linuxkpi/common/src/linux_work.c b/sys/compat/linuxkpi/common/src/linux_work.c index bb25893d9c71..93090f4f26bc 100644 --- a/sys/compat/linuxkpi/common/src/linux_work.c +++ b/sys/compat/linuxkpi/common/src/linux_work.c @@ -507,12 +507,16 @@ linux_cancel_delayed_work(struct delayed_work *dwork) } /* - * This function cancels the given work structure in a synchronous - * fashion. It returns true if the work was successfully - * cancelled. Else the work was already cancelled. + * This function cancels the given delayed work structure in a + * synchronous fashion. It returns true if pending delayed work was + * cancelled. Else the work was not pending. + * + * If the work restarted itself or was busy while being cancelled, + * retry_needed is set to true so the caller can re-check the state. */ static bool -linux_cancel_delayed_work_sync_int(struct delayed_work *dwork) +linux_cancel_delayed_work_sync_int(struct delayed_work *dwork, u_int *pending, + bool *cancelled) { static const uint8_t states[WORK_ST_MAX] __aligned(8) = { [WORK_ST_IDLE] = WORK_ST_IDLE, /* NOP */ @@ -523,7 +527,6 @@ linux_cancel_delayed_work_sync_int(struct delayed_work *dwork) }; struct taskqueue *tq; int ret, state; - bool cancelled; WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "linux_cancel_delayed_work_sync() might sleep"); @@ -536,18 +539,18 @@ linux_cancel_delayed_work_sync_int(struct delayed_work *dwork) return (false); case WORK_ST_TIMER: case WORK_ST_CANCEL: - cancelled = (callout_stop(&dwork->timer.callout) == 1); + *cancelled = (callout_stop(&dwork->timer.callout) == 1); tq = dwork->work.work_queue->taskqueue; - ret = taskqueue_cancel(tq, &dwork->work.work_task, NULL); + ret = taskqueue_cancel(tq, &dwork->work.work_task, pending); mtx_unlock(&dwork->timer.mtx); callout_drain(&dwork->timer.callout); taskqueue_drain(tq, &dwork->work.work_task); - return (cancelled || (ret != 0)); + return (*cancelled || (ret != 0)); default: tq = dwork->work.work_queue->taskqueue; - ret = taskqueue_cancel(tq, &dwork->work.work_task, NULL); + ret = taskqueue_cancel(tq, &dwork->work.work_task, pending); mtx_unlock(&dwork->timer.mtx); if (ret != 0) taskqueue_drain(tq, &dwork->work.work_task); @@ -558,11 +561,19 @@ linux_cancel_delayed_work_sync_int(struct delayed_work *dwork) bool linux_cancel_delayed_work_sync(struct delayed_work *dwork) { - bool res; + u_int pending; + bool cancelled; + bool res = false; + bool ret; + + do { + pending = 0; + cancelled = false; + ret = linux_cancel_delayed_work_sync_int(dwork, &pending, + &cancelled); + res = res || cancelled || pending != 0; + } while (ret); - res = false; - while (linux_cancel_delayed_work_sync_int(dwork)) - res = true; return (res); }