The branch stable/14 has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=b29fb0b5259cc991d6e51e0de53455701014858e

commit b29fb0b5259cc991d6e51e0de53455701014858e
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2025-10-23 18:37:00 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2025-12-24 00:43:07 +0000

    devfs: make destroy_dev() a release barrier for cdevpriv destructors runs
    
    (cherry picked from commit 4dbe6628179d8e6bf400bfdb4bfa869bdc102a56)
---
 sys/fs/devfs/devfs_int.h   |  1 +
 sys/fs/devfs/devfs_vnops.c | 17 ++++++++++++++---
 sys/kern/kern_conf.c       |  3 +++
 3 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/sys/fs/devfs/devfs_int.h b/sys/fs/devfs/devfs_int.h
index 916297425b53..9fa75c0e90ad 100644
--- a/sys/fs/devfs/devfs_int.h
+++ b/sys/fs/devfs/devfs_int.h
@@ -67,6 +67,7 @@ struct cdev_priv {
        void                    *cdp_dtr_cb_arg;
 
        LIST_HEAD(, cdev_privdata) cdp_fdpriv;
+       u_int                   cdp_fdpriv_dtrc;
 
        struct mtx              cdp_threadlock;
 };
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index 2a4576320286..1ff24b54cbf0 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -202,14 +202,25 @@ devfs_foreach_cdevpriv(struct cdev *dev, int (*cb)(void 
*data, void *arg),
 void
 devfs_destroy_cdevpriv(struct cdev_privdata *p)
 {
+       struct file *fp;
+       struct cdev_priv *cdp;
 
        mtx_assert(&cdevpriv_mtx, MA_OWNED);
-       KASSERT(p->cdpd_fp->f_cdevpriv == p,
-           ("devfs_destoy_cdevpriv %p != %p", p->cdpd_fp->f_cdevpriv, p));
-       p->cdpd_fp->f_cdevpriv = NULL;
+       fp = p->cdpd_fp;
+       KASSERT(fp->f_cdevpriv == p,
+           ("devfs_destoy_cdevpriv %p != %p", fp->f_cdevpriv, p));
+       cdp = cdev2priv((struct cdev *)fp->f_data);
+       cdp->cdp_fdpriv_dtrc++;
+       fp->f_cdevpriv = NULL;
        LIST_REMOVE(p, cdpd_list);
        mtx_unlock(&cdevpriv_mtx);
        (p->cdpd_dtr)(p->cdpd_data);
+       mtx_lock(&cdevpriv_mtx);
+       MPASS(cdp->cdp_fdpriv_dtrc >= 1);
+       cdp->cdp_fdpriv_dtrc--;
+       if (cdp->cdp_fdpriv_dtrc == 0)
+               wakeup(&cdp->cdp_fdpriv_dtrc);
+       mtx_unlock(&cdevpriv_mtx);
        free(p, M_CDEVPDATA);
 }
 
diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c
index db5fe7a6a373..dcc7ebafb13c 100644
--- a/sys/kern/kern_conf.c
+++ b/sys/kern/kern_conf.c
@@ -1164,6 +1164,9 @@ destroy_devl(struct cdev *dev)
                devfs_destroy_cdevpriv(p);
                mtx_lock(&cdevpriv_mtx);
        }
+       while (cdp->cdp_fdpriv_dtrc != 0) {
+               msleep(&cdp->cdp_fdpriv_dtrc, &cdevpriv_mtx, 0, "cdfdpc", 0);
+       }
        mtx_unlock(&cdevpriv_mtx);
        dev_lock();
 

Reply via email to