Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/kern_conf.c
Show First 20 Lines • Show All 180 Lines • ▼ Show 20 Lines | dev_refthread(struct cdev *dev, int *ref) | ||||
struct cdevsw *csw; | struct cdevsw *csw; | ||||
struct cdev_priv *cdp; | struct cdev_priv *cdp; | ||||
mtx_assert(&devmtx, MA_NOTOWNED); | mtx_assert(&devmtx, MA_NOTOWNED); | ||||
if ((dev->si_flags & SI_ETERNAL) != 0) { | if ((dev->si_flags & SI_ETERNAL) != 0) { | ||||
*ref = 0; | *ref = 0; | ||||
return (dev->si_devsw); | return (dev->si_devsw); | ||||
} | } | ||||
dev_lock(); | cdp = cdev2priv(dev); | ||||
mtx_lock(&cdp->cdp_threadlock); | |||||
csw = dev->si_devsw; | csw = dev->si_devsw; | ||||
if (csw != NULL) { | if (csw != NULL) { | ||||
cdp = cdev2priv(dev); | |||||
if ((cdp->cdp_flags & CDP_SCHED_DTR) == 0) | if ((cdp->cdp_flags & CDP_SCHED_DTR) == 0) | ||||
atomic_add_long(&dev->si_threadcount, 1); | atomic_add_long(&dev->si_threadcount, 1); | ||||
else | else | ||||
csw = NULL; | csw = NULL; | ||||
} | } | ||||
dev_unlock(); | mtx_unlock(&cdp->cdp_threadlock); | ||||
if (csw != NULL) | if (csw != NULL) | ||||
*ref = 1; | *ref = 1; | ||||
return (csw); | return (csw); | ||||
} | } | ||||
struct cdevsw * | struct cdevsw * | ||||
devvn_refthread(struct vnode *vp, struct cdev **devp, int *ref) | devvn_refthread(struct vnode *vp, struct cdev **devp, int *ref) | ||||
{ | { | ||||
Show All 11 Lines | if ((vp->v_vflag & VV_ETERNALDEV) != 0) { | ||||
*ref = 0; | *ref = 0; | ||||
csw = dev->si_devsw; | csw = dev->si_devsw; | ||||
KASSERT(csw != NULL, ("Eternal cdev is destroyed")); | KASSERT(csw != NULL, ("Eternal cdev is destroyed")); | ||||
*devp = dev; | *devp = dev; | ||||
return (csw); | return (csw); | ||||
} | } | ||||
csw = NULL; | csw = NULL; | ||||
dev_lock(); | VI_LOCK(vp); | ||||
dev = vp->v_rdev; | dev = vp->v_rdev; | ||||
if (dev == NULL) { | if (dev == NULL) { | ||||
dev_unlock(); | VI_UNLOCK(vp); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
cdp = cdev2priv(dev); | cdp = cdev2priv(dev); | ||||
mtx_lock(&cdp->cdp_threadlock); | |||||
if ((cdp->cdp_flags & CDP_SCHED_DTR) == 0) { | if ((cdp->cdp_flags & CDP_SCHED_DTR) == 0) { | ||||
csw = dev->si_devsw; | csw = dev->si_devsw; | ||||
if (csw != NULL) | if (csw != NULL) | ||||
atomic_add_long(&dev->si_threadcount, 1); | atomic_add_long(&dev->si_threadcount, 1); | ||||
} | } | ||||
dev_unlock(); | mtx_unlock(&cdp->cdp_threadlock); | ||||
VI_UNLOCK(vp); | |||||
if (csw != NULL) { | if (csw != NULL) { | ||||
*devp = dev; | *devp = dev; | ||||
*ref = 1; | *ref = 1; | ||||
} | } | ||||
return (csw); | return (csw); | ||||
} | } | ||||
void | void | ||||
▲ Show 20 Lines • Show All 884 Lines • ▼ Show 20 Lines | while (!LIST_EMPTY(&dev->si_children)) | ||||
destroy_devl(LIST_FIRST(&dev->si_children)); | destroy_devl(LIST_FIRST(&dev->si_children)); | ||||
/* Remove from clone list */ | /* Remove from clone list */ | ||||
if (dev->si_flags & SI_CLONELIST) { | if (dev->si_flags & SI_CLONELIST) { | ||||
LIST_REMOVE(dev, si_clone); | LIST_REMOVE(dev, si_clone); | ||||
dev->si_flags &= ~SI_CLONELIST; | dev->si_flags &= ~SI_CLONELIST; | ||||
} | } | ||||
mtx_lock(&cdp->cdp_threadlock); | |||||
csw = dev->si_devsw; | csw = dev->si_devsw; | ||||
dev->si_devsw = NULL; /* already NULL for SI_ALIAS */ | dev->si_devsw = NULL; /* already NULL for SI_ALIAS */ | ||||
while (csw != NULL && csw->d_purge != NULL && dev->si_threadcount) { | while (csw != NULL && csw->d_purge != NULL && dev->si_threadcount) { | ||||
csw->d_purge(dev); | csw->d_purge(dev); | ||||
mtx_unlock(&cdp->cdp_threadlock); | |||||
msleep(csw, &devmtx, PRIBIO, "devprg", hz/10); | msleep(csw, &devmtx, PRIBIO, "devprg", hz/10); | ||||
mtx_lock(&cdp->cdp_threadlock); | |||||
if (dev->si_threadcount) | if (dev->si_threadcount) | ||||
printf("Still %lu threads in %s\n", | printf("Still %lu threads in %s\n", | ||||
dev->si_threadcount, devtoname(dev)); | dev->si_threadcount, devtoname(dev)); | ||||
} | } | ||||
while (dev->si_threadcount != 0) { | while (dev->si_threadcount != 0) { | ||||
/* Use unique dummy wait ident */ | /* Use unique dummy wait ident */ | ||||
mtx_unlock(&cdp->cdp_threadlock); | |||||
msleep(&csw, &devmtx, PRIBIO, "devdrn", hz / 10); | msleep(&csw, &devmtx, PRIBIO, "devdrn", hz / 10); | ||||
mtx_lock(&cdp->cdp_threadlock); | |||||
} | } | ||||
mtx_unlock(&cdp->cdp_threadlock); | |||||
dev_unlock(); | dev_unlock(); | ||||
if ((cdp->cdp_flags & CDP_UNREF_DTR) == 0) { | if ((cdp->cdp_flags & CDP_UNREF_DTR) == 0) { | ||||
/* avoid out of order notify events */ | /* avoid out of order notify events */ | ||||
notify_destroy(dev); | notify_destroy(dev); | ||||
} | } | ||||
mtx_lock(&cdevpriv_mtx); | mtx_lock(&cdevpriv_mtx); | ||||
while ((p = LIST_FIRST(&cdp->cdp_fdpriv)) != NULL) { | while ((p = LIST_FIRST(&cdp->cdp_fdpriv)) != NULL) { | ||||
devfs_destroy_cdevpriv(p); | devfs_destroy_cdevpriv(p); | ||||
▲ Show 20 Lines • Show All 413 Lines • Show Last 20 Lines |