From nobody Wed Oct 07 06:24:40 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 4j034n3xLyz6vN7j for ; Wed, 07 Oct 2026 06:24:41 +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 4j034m5WmPz3NFn for ; Wed, 07 Oct 2026 06:24:40 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791354280; 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=6O9N5XqM2q+8HayMZYecXsoLAuwSepgQ9okh03JpqB0=; b=f6jeTO8baZTDbFJtdCtMf4jjlRLcYeRcl7Vv/jZjFsb3CVMaU1HrOU8FO18xXejaVZgKuL PkH0Ng7oADIU6hpWIjAydjgzm3USNvQ6v2/sBOI/Hm0WOCV0JXirENgFnbOhCzOR9EF9D0 UmG0v2Scs6yNBRb820OfFwvVrjyevmrw/I4eRE82JdeijzmVN/XOirHdcbt62xnvDRsz8b hCRMFl6kO5j24izaZAsFI9NhBSrpox0BszNe4i8J92TJGys8OEaX+FVtF57Z2WW6I/Odpl 19b7Q4D5gojwx2QYqORsGIhtzdLKo4y/FPAljRy0+ziBk42lFygoG7/r4nKr/Q== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1791354280; b=mvKY1ttjIuJ4OhsvaHb+I/r6yoO6Zgd9lAT0K78pxrPFPcZpTqL7CoUWVfSFyq6lqUbzf4 VbDNss0b6Aq6pllSMWI6pzcnpk4stERLtvVPZ57hqdfaQYdZuKEHwWvxirF71VJEPBd1mb +IZrtMon6pI1hqrhQpu8/uaCvK311USf+LE8eqPaAEa+76d1Xy+YsqVOwAroPZj9W5lUBn gXStJbIoE90M+7GEeo08rtE+LW8/zc95Pad/5jOCt3jFohmIvlCZEobaUY19moxSXI01u6 p8+D09LU8Vr8m5JqKFxPfIVLagbRWSgx/8KWx1n6z7s2u9S1lksIc9Ubpyb3lw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791354280; 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=6O9N5XqM2q+8HayMZYecXsoLAuwSepgQ9okh03JpqB0=; b=HVE60a1tXeYiOhxO6wDjWFV2W0tz5uG4CjY8AnRIl7LiNaA74l8KkxfaJxhPLXGZcbHmaK c1WNrYU/HipaE7OiM300SJ9GE1Cerig4peh1A6Sf1IfeINbu3ca6CP0rZZ91qU0DZ4mIVr I5kjSVk4BrhTG3L5s7vSQ0r/gTEAIsdE4jDQ/OV+YY/7emJ4BxUTxHGXAhqlEDF4EFukB6 yK/geZ3jDB1jLGWNgk/VWBswdgP31BWMcdKDzUYMz30v9SzsILpXzKCpzwkFRsLqsPCV0P Z+c2YxmJJwRJLz3+j3XNW5UgW0gVKFQoXiexMYSoUsS3/4UeM37oQDkD1axyxA== 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 4j034m4bQszj5f for ; Wed, 07 Oct 2026 06:24:40 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 403fd by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 07 Oct 2026 06:24:40 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Christos Margiolis Subject: git: 2cb963ee8d15 - stable/15 - 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/stable/15 X-Git-Reftype: branch X-Git-Commit: 2cb963ee8d157a688892c944aa0567bfd35322b7 Auto-Submitted: auto-generated Date: Wed, 07 Oct 2026 06:24:40 +0000 Message-Id: <6ac5e5a8.403fd.4a1dff52@gitrepo.freebsd.org> The branch stable/15 has been updated by christos: URL: https://cgit.FreeBSD.org/src/commit/?id=2cb963ee8d157a688892c944aa0567bfd35322b7 commit 2cb963ee8d157a688892c944aa0567bfd35322b7 Author: Christos Margiolis AuthorDate: 2026-09-30 09:50:41 +0000 Commit: Christos Margiolis CommitDate: 2026-10-07 06:23:32 +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 (cherry picked from commit d38ef1aca969f9a79572958c06bc4a4e03f053c2) --- 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) {