Mercurial > illumos > illumos-gate
changeset 12569:06d420824c4b
6532936 rare deadlock between multiple threads between fp_nexus_enum_tq and devfs
author | Jakub Jermar <Jakub.Jermar@Sun.COM> |
---|---|
date | Mon, 07 Jun 2010 13:16:48 +0200 |
parents | 0f6ea478c2c7 |
children | 4be1b7cb5db7 |
files | usr/src/uts/common/fs/devfs/devfs_subr.c |
diffstat | 1 files changed, 14 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/devfs/devfs_subr.c Mon Jun 07 01:47:20 2010 -0600 +++ b/usr/src/uts/common/fs/devfs/devfs_subr.c Mon Jun 07 13:16:48 2010 +0200 @@ -936,7 +936,11 @@ 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 @@ *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); }