Page MenuHomeFreeBSD

D22548.id64857.diff
No OneTemporary

D22548.id64857.diff

Index: sys/fs/devfs/devfs_devs.c
===================================================================
--- sys/fs/devfs/devfs_devs.c
+++ sys/fs/devfs/devfs_devs.c
@@ -144,6 +144,7 @@
LIST_INIT(&cdev->si_children);
vfs_timestamp(&ts);
cdev->si_atime = cdev->si_mtime = cdev->si_ctime = ts;
+ mtx_init(&cdev->si_threadlock, "devthrd", NULL, MTX_DEF);
return (cdev);
}
@@ -180,6 +181,7 @@
devfs_free_cdp_inode(cdp->cdp_inode);
if (cdp->cdp_maxdirent > 0)
free(cdp->cdp_dirents, M_DEVFS2);
+ mtx_destroy(&cdev->si_threadlock);
free(cdp, M_CDEVP);
}
Index: sys/kern/kern_conf.c
===================================================================
--- sys/kern/kern_conf.c
+++ sys/kern/kern_conf.c
@@ -186,7 +186,7 @@
*ref = 0;
return (dev->si_devsw);
}
- dev_lock();
+ mtx_lock(&dev->si_threadlock);
csw = dev->si_devsw;
if (csw != NULL) {
cdp = cdev2priv(dev);
@@ -195,7 +195,7 @@
else
csw = NULL;
}
- dev_unlock();
+ mtx_unlock(&dev->si_threadlock);
if (csw != NULL)
*ref = 1;
return (csw);
@@ -223,19 +223,21 @@
}
csw = NULL;
- dev_lock();
+ VI_LOCK(vp);
dev = vp->v_rdev;
if (dev == NULL) {
- dev_unlock();
+ VI_UNLOCK(vp);
return (NULL);
}
+ mtx_lock(&dev->si_threadlock);
cdp = cdev2priv(dev);
if ((cdp->cdp_flags & CDP_SCHED_DTR) == 0) {
csw = dev->si_devsw;
if (csw != NULL)
atomic_add_long(&dev->si_threadcount, 1);
}
- dev_unlock();
+ mtx_unlock(&dev->si_threadlock);
+ VI_UNLOCK(vp);
if (csw != NULL) {
*devp = dev;
*ref = 1;
@@ -1133,20 +1135,26 @@
dev->si_flags &= ~SI_CLONELIST;
}
+ mtx_lock(&dev->si_threadlock);
csw = dev->si_devsw;
dev->si_devsw = NULL; /* already NULL for SI_ALIAS */
while (csw != NULL && csw->d_purge != NULL && dev->si_threadcount) {
csw->d_purge(dev);
+ mtx_unlock(&dev->si_threadlock);
msleep(csw, &devmtx, PRIBIO, "devprg", hz/10);
+ mtx_lock(&dev->si_threadlock);
if (dev->si_threadcount)
printf("Still %lu threads in %s\n",
dev->si_threadcount, devtoname(dev));
}
while (dev->si_threadcount != 0) {
/* Use unique dummy wait ident */
+ mtx_unlock(&dev->si_threadlock);
msleep(&csw, &devmtx, PRIBIO, "devdrn", hz / 10);
+ mtx_lock(&dev->si_threadlock);
}
+ mtx_unlock(&dev->si_threadlock);
dev_unlock();
if ((cdp->cdp_flags & CDP_UNREF_DTR) == 0) {
/* avoid out of order notify events */
Index: sys/kern/subr_witness.c
===================================================================
--- sys/kern/subr_witness.c
+++ sys/kern/subr_witness.c
@@ -601,6 +601,7 @@
{ "vm map (system)", &lock_class_mtx_sleep },
{ "vnode interlock", &lock_class_mtx_sleep },
{ "cdev", &lock_class_mtx_sleep },
+ { "devthrd", &lock_class_mtx_sleep },
{ NULL, NULL },
/*
* VM
Index: sys/sys/conf.h
===================================================================
--- sys/sys/conf.h
+++ sys/sys/conf.h
@@ -48,6 +48,9 @@
#include <sys/queue.h>
#endif
+#include <sys/_lock.h>
+#include <sys/_mutex.h>
+
struct snapdata;
struct devfs_dirent;
struct cdevsw;
@@ -84,6 +87,7 @@
struct cdevsw *si_devsw;
int si_iosize_max; /* maximum I/O size (for physio &al) */
u_long si_usecount;
+ struct mtx si_threadlock; /* protects si_devsw association */
u_long si_threadcount;
union {
struct snapdata *__sid_snapdata;
@@ -167,7 +171,8 @@
#define D_VERSION_02 0x28042009 /* Add d_mmap_single */
#define D_VERSION_03 0x17122009 /* d_mmap takes memattr,vm_ooffset_t */
#define D_VERSION_04 0x5c48c353 /* SPECNAMELEN bumped to MAXNAMLEN */
-#define D_VERSION D_VERSION_04
+#define D_VERSION_05 0x5ddc0b6c /* per-dev lock to protect si_devsw */
+#define D_VERSION D_VERSION_05
/*
* Flags used for internal housekeeping

File Metadata

Mime Type
text/plain
Expires
Fri, Aug 28, 2:37 AM (10 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37429914
Default Alt Text
D22548.id64857.diff (3 KB)

Event Timeline