From nobody Sun Sep 13 07:41:06 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 4hjKw23n1Fz6rxKY for ; Sun, 13 Sep 2026 07:41:06 +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 4hjKw22C95z3JQm for ; Sun, 13 Sep 2026 07:41:06 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1789285266; 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=98OVN4DawKGjlPSCbJG54CtaSmMXSE+DVwYPSwIwZN0=; b=dibeAaiZhK91JnoGlpM4vEv41ebB7G7USkY43G1sabp3q40edWQvBgTjbtI6RZUMuCJMYH 93s78H9Ic742Z+4lG+rh69jCQCze328qV5y6t6St4fxFqBiCXj4nRqNfe56sQXWsIKFFeS U6o9/VKnS77rksKWGDA8w+X5NqJcm9lPDBqj8D//GRQsUCUPkXEZSeNozQBbScsDbxha7X s63AReCQp22Wew767mTMPxjTod37ErBnyMK+yEhq7zr4YFHe0oJN5nU+OOxVSKSJCsv7LD gzD9b2gfYG2rCvCauQb0hOkt573LEFpMQh4WYYiu9kT2/K4k46RHKhkYLe2ilg== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1789285266; b=ebt6hmeHy8KyycRJqLuq1UQa2lLHxwDA85L3//2hWSieKiRlE/f2mZyfjJz3pUh6y0Rt3A +YgP/Esf9/VWIaanv6+aCudcydR0ngbfUY32Y4c6krC2cMEsYG0ze95PsW6LeWFZwUyKVe d7QmXPKsa9uasRMRx8uoro5vv1lSSNHd4nSUJekQVa6+1e5JFA5SuuZTNeSw/mTsaZqnlV UgceSF0p2UGFeNY7CF7HpGB29zD5JgcgW8FgyZifCg4CJ+Hm6qSN6pYgi5UQL/16EK2iSj TxV7576o90ZnHAYta5xKPAsWv7klIeMFvs9B6alRZ8S9XSqZTdObOjMhVH3gqA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1789285266; 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=98OVN4DawKGjlPSCbJG54CtaSmMXSE+DVwYPSwIwZN0=; b=GUa73/kgNwrhtFrO3lcKIk5aEMsZ4OU1QYAh7+s3zZoMwhiezA4g7hnYAGObswW3k48KCW WFbwD/qN6miHx++sEHgYqNUEND+RE/7O/Mk1rouMvs+JPljzG+kPHhfRXP0K0vT8wpZ9JZ mTQdgj+mMEZzemJmrjYpWVaoBqetorzReZAVEBgyo2iDmkGDN6np05eal070Qi0DgrwOKy QcZkjVR11CNDi7n4OBUiJofYRcV3liY3tMvcZdqz/uXvSTZ/FvckNJVKuG+8IdF2Y7OnFs 8WzTlDAaVENiZsLeAuPKM9l7RLHYUT4IMEx798d+Hk7uTXIzCGL1yjp1ZCUpeA== 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 4hjKw20T5VzZJj for ; Sun, 13 Sep 2026 07:41:06 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1d07e by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 13 Sep 2026 07:41:06 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Ryan Fahy From: Vladimir Kondratyev Subject: git: 79e290d96786 - main - linuxkpi: Fix cancel_delayed_work_sync() return value 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: wulf X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 79e290d967862bef1adcf39f0bfcf1b4993a8202 Auto-Submitted: auto-generated Date: Sun, 13 Sep 2026 07:41:06 +0000 Message-Id: <6aa65392.1d07e.4a9dc3@gitrepo.freebsd.org> The branch main has been updated by wulf: URL: https://cgit.FreeBSD.org/src/commit/?id=79e290d967862bef1adcf39f0bfcf1b4993a8202 commit 79e290d967862bef1adcf39f0bfcf1b4993a8202 Author: Ryan Fahy AuthorDate: 2026-09-13 07:39:48 +0000 Commit: Vladimir Kondratyev CommitDate: 2026-09-13 07:39:48 +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 --- 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 02dfb35d9fd0..bf4c82767621 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); }