From nobody Wed Sep 30 09:51:30 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 4hvr0f497Jz6v8bh for ; Wed, 30 Sep 2026 09:51:30 +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 4hvr0f1mPxz3NHX for ; Wed, 30 Sep 2026 09:51:30 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1790761890; 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=C3kTkb1dJSRp7UFWBmuRYgPSrY5eRArmrXSi53urxXQ=; b=eBwT3LO8cGzOjHZhlmaJk8t1iXs9tEb8e2MolFMfdDfFX8MTI0arDO0MeS4tEm30hbU8n3 jzRn5WzhHk6QuxkqVwCFrCU/suSvNEIw8mLT0sAfPSG/awcqr5a/Sjra9PZmYk0IP1CpKI aOcmOXQjO61wL4jRtFubfBIQfnGXDxFjOSr706mu+tbXp2Dt4MEaTPbNd0bfmG4Vcv5gi5 uFRNYPAkuNCIBKSEW78uuI1JwI1UcxbYedJmhyugbV18EugSZeFaB5APxjE67ce0KEGD79 DURJAnGA2QUpRAZK2ewAjVIqdAXut1B4/Dj4D/hJXOs8OS+u5fIyapmf30ZN7g== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1790761890; b=hqGMgL4qpMjJD3djFZPnDeduRSaA3QHpYI1ipM86oDmYnuUzo9vM2A1hckQoZ70QVWFgzn Z75nvr6XWp5uD+wrXKXoOH4g7JvIRGZUikGjF4JQ3ppz1wzyW4VsO/cltZW7od8Zya2VfG RWR+3hnRpZ0VGq3WxeWemCjq5W19mhuXavaAdMLR+WSmyIKuk51BFEbYGPvGab/ot9cYSQ vJR1D1CiqLkCObV9jFPZ6PZfnWNOoV0ZFrPBGQHQ5ozupKJhA2q8aEeC0P2EgdDHuTIPig b+EKLYsY4ZPN/kx/RRYrAJOggjvghwvVSVDppzpw/TF3/hefzbxo8R7C4NM67Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1790761890; 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=C3kTkb1dJSRp7UFWBmuRYgPSrY5eRArmrXSi53urxXQ=; b=MreQ6P69PelzTW/SywaDR4FfbOP5mcE1paDtJliseAv70bf8hm9GJZZdteJCD2ItmbAfHm 1aVb0IvqfQexv+sG7gMO95cTL59TWqX1PEc5G2rB8qZu7hBSdf7BoRPdYMTlvzW5BZ38Rq nIxIvMvKUOvGKwvUvETbFGUieln8DQOjit1a0SWQRkVZkw/9tAzSmZYXXqtlmKJHWSTSBm /XT+5LBDJ6DQkOHhJGJWN/tm++R3cwouuiMsa5vQIeIRlbECegjvVrGg8d+LYJLtttrec1 tuErQUMfZFNF0jOW/r16UlEGrtzfzUp/mgwaXSgCW/HXo0BOkMq+1kjqoehi0Q== 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 4hvr0f0sWtzgsj for ; Wed, 30 Sep 2026 09:51:30 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 35bab by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 30 Sep 2026 09:51:30 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Christos Margiolis Subject: git: d38ef1aca969 - main - cuse: Implement hot-unload 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: christos X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: d38ef1aca969f9a79572958c06bc4a4e03f053c2 Auto-Submitted: auto-generated Date: Wed, 30 Sep 2026 09:51:30 +0000 Message-Id: <6abcdba2.35bab.5f40f1d8@gitrepo.freebsd.org> The branch main has been updated by christos: URL: https://cgit.FreeBSD.org/src/commit/?id=d38ef1aca969f9a79572958c06bc4a4e03f053c2 commit d38ef1aca969f9a79572958c06bc4a4e03f053c2 Author: Christos Margiolis AuthorDate: 2026-09-30 09:50:41 +0000 Commit: Christos Margiolis CommitDate: 2026-09-30 09:50:41 +0000 cuse: Implement hot-unload cuse_kern_uninit() can hang on destroy_dev(), because of threads sleeping in CUSE_IOCTL_GET_COMMAND, so implement d_purge to wake them up before calling destroy_dev(). Also do not allow threads to go back to sleep if the is_closing flag has been set. MFC after: 1 week Sponsored by: The FreeBSD Foundation Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D60022 --- sys/fs/cuse/cuse.c | 92 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 33 deletions(-) diff --git a/sys/fs/cuse/cuse.c b/sys/fs/cuse/cuse.c index 0bd8cc0d5dac..081fe1fe0bad 100644 --- a/sys/fs/cuse/cuse.c +++ b/sys/fs/cuse/cuse.c @@ -209,6 +209,7 @@ static d_read_t cuse_server_read; static d_write_t cuse_server_write; static d_poll_t cuse_server_poll; static d_mmap_single_t cuse_server_mmap_single; +static d_purge_t cuse_server_purge; static struct cdevsw cuse_server_devsw = { .d_version = D_VERSION, @@ -221,6 +222,7 @@ static struct cdevsw cuse_server_devsw = { .d_write = cuse_server_write, .d_poll = cuse_server_poll, .d_mmap_single = cuse_server_mmap_single, + .d_purge = cuse_server_purge, }; static void cuse_client_is_closing(struct cuse_client *); @@ -268,33 +270,6 @@ cuse_cmd_unlock(struct cuse_client_command *pccmd) sx_xunlock(&pccmd->sx); } -static int -cuse_kern_init(void) -{ - TAILQ_INIT(&cuse_server_head); - - mtx_init(&cuse_global_mtx, "cuse-global-mtx", NULL, MTX_DEF); - - cuse_dev = make_dev_credf(MAKEDEV_CHECKNAME, - &cuse_server_devsw, 0, NULL, UID_ROOT, GID_OPERATOR, 0600, "cuse"); - if (cuse_dev == NULL) - return (ENODEV); - - return (0); -} - -static void -cuse_kern_uninit(void) -{ - /* destroy_dev() runs the cdevpriv destructor of every open instance. */ - if (cuse_dev != NULL) - destroy_dev(cuse_dev); - - MPASS(TAILQ_EMPTY(&cuse_server_head)); - - mtx_destroy(&cuse_global_mtx); -} - static int cuse_server_get(struct cuse_server **ppcs) { @@ -667,19 +642,24 @@ cuse_server_unref(struct cuse_server *pcs) { struct cuse_memory *mem; + /* + * Take the global lock before the server lock, to avoid a lock order + * reversal in cuse_kern_uninit(). + */ + cuse_global_lock(); cuse_server_lock(pcs); if (--(pcs->refs) != 0) { cuse_server_unlock(pcs); + cuse_global_unlock(); return; } + TAILQ_REMOVE(&cuse_server_head, pcs, entry); + cuse_global_unlock(); + cuse_server_is_closing(pcs); /* final client wakeup, if any */ cuse_server_wakeup_all_client_locked(pcs); - cuse_global_lock(); - TAILQ_REMOVE(&cuse_server_head, pcs, entry); - cuse_global_unlock(); - /* The cdevpriv destructor destroys the devices before unreffing. */ MPASS(TAILQ_EMPTY(&pcs->hdev)); @@ -1083,10 +1063,10 @@ cuse_server_ioctl(struct cdev *dev, unsigned long cmd, cuse_server_lock(pcs); while ((pccmd = TAILQ_FIRST(&pcs->head)) == NULL) { - error = cv_wait_sig(&pcs->cv, &pcs->mtx); - if (pcs->is_closing) error = ENXIO; + else + error = cv_wait_sig(&pcs->cv, &pcs->mtx); if (error) { cuse_server_unlock(pcs); @@ -1412,6 +1392,25 @@ cuse_server_mmap_single(struct cdev *dev, vm_ooffset_t *offset, return (cuse_common_mmap_single(pcs, offset, size, object)); } +static void +cuse_server_purge(struct cdev *dev __unused) +{ + struct cuse_server *pcs; + + /* + * Wake up the servers sleeping in CUSE_IOCTL_GET_COMMAND, so that + * destroy_dev() can return. + */ + cuse_global_lock(); + TAILQ_FOREACH(pcs, &cuse_server_head, entry) { + cuse_server_lock(pcs); + cuse_server_is_closing(pcs); + cv_broadcast(&pcs->cv); + cuse_server_unlock(pcs); + } + cuse_global_unlock(); +} + /*------------------------------------------------------------------------* * CUSE CLIENT PART *------------------------------------------------------------------------*/ @@ -2026,6 +2025,33 @@ cuse_client_kqfilter(struct cdev *dev, struct knote *kn) return (error); } +static int +cuse_kern_init(void) +{ + TAILQ_INIT(&cuse_server_head); + + mtx_init(&cuse_global_mtx, "cuse-global-mtx", NULL, MTX_DEF); + + cuse_dev = make_dev_credf(MAKEDEV_CHECKNAME, + &cuse_server_devsw, 0, NULL, UID_ROOT, GID_OPERATOR, 0600, "cuse"); + if (cuse_dev == NULL) + return (ENODEV); + + return (0); +} + +static void +cuse_kern_uninit(void) +{ + /* destroy_dev() runs the cdevpriv destructor of every open instance. */ + if (cuse_dev != NULL) + destroy_dev(cuse_dev); + + MPASS(TAILQ_EMPTY(&cuse_server_head)); + + mtx_destroy(&cuse_global_mtx); +} + static int cuse_modevent(module_t mod, int type, void *data) {