From 9f7872370e4da0965db7ac1e93c957c5aa3f4dbd Mon Sep 17 00:00:00 2001 From: Jakub Jermar Date: Mon, 7 Jun 2010 13:16:48 +0200 Subject: 6532936 rare deadlock between multiple threads between fp_nexus_enum_tq and devfs --- usr/src/uts/common/fs/devfs/devfs_subr.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'usr/src') diff --git a/usr/src/uts/common/fs/devfs/devfs_subr.c b/usr/src/uts/common/fs/devfs/devfs_subr.c index 8273bced8e..3407d31a3a 100644 --- a/usr/src/uts/common/fs/devfs/devfs_subr.c +++ b/usr/src/uts/common/fs/devfs/devfs_subr.c @@ -936,7 +936,11 @@ dv_find(struct dv_node *ddv, char *nm, struct vnode **vpp, struct pathname *pnp, dcmn_err3(("dv_find %s\n", nm)); - rw_enter(&ddv->dv_contents, RW_READER); + if (!rw_tryenter(&ddv->dv_contents, RW_READER)) { + if (tsd_get(devfs_clean_key)) + return (EBUSY); + rw_enter(&ddv->dv_contents, RW_READER); + } start: if (DV_STALE(ddv)) { rw_exit(&ddv->dv_contents); @@ -1241,10 +1245,16 @@ found: *vpp = vp; notfound: - rw_enter(&ddv->dv_contents, RW_WRITER); - if (was_busy) + if (was_busy) { + /* + * Non-zero was_busy tells us that we are not in the + * devfs_clean() path which in turn means that we can afford + * to take the contents lock unconditionally. + */ + rw_enter(&ddv->dv_contents, RW_WRITER); ddv->dv_busy--; - rw_exit(&ddv->dv_contents); + rw_exit(&ddv->dv_contents); + } return (rv); } -- cgit v1.2.3