Mercurial > illumos > illumos-gate
changeset 12901:7977d17e3193
6894195 race condition between ident_alloc() and ident_release()
6904790 More races in ldi. Bug 6894195 does not give the full picture.
author | Suhasini Peddada <Suhasini.Peddada@Sun.COM> |
---|---|
date | Thu, 22 Jul 2010 12:31:36 -0700 |
parents | 8c8b525b1ad6 |
children | 16985853e3aa |
files | usr/src/uts/common/os/driver_lyr.c |
diffstat | 1 files changed, 10 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/os/driver_lyr.c Thu Jul 22 10:05:16 2010 +0100 +++ b/usr/src/uts/common/os/driver_lyr.c Thu Jul 22 12:31:36 2010 -0700 @@ -213,7 +213,7 @@ static struct ldi_ident * ident_alloc(char *mod_name, dev_info_t *dip, dev_t dev, major_t major) { - struct ldi_ident *lip, **lipp; + struct ldi_ident *lip, **lipp, *retlip; modid_t modid; uint_t index; @@ -235,9 +235,10 @@ /* we found an ident in the hash */ ASSERT(strcmp((*lipp)->li_modname, mod_name) == 0); (*lipp)->li_ref++; + retlip = *lipp; mutex_exit(&ldi_ident_hash_lock[index]); kmem_free(lip, sizeof (struct ldi_ident)); - return (*lipp); + return (retlip); } /* initialize the new ident */ @@ -331,20 +332,20 @@ static struct ldi_handle * handle_find(vnode_t *vp, struct ldi_ident *ident) { - struct ldi_handle **lhpp; + struct ldi_handle **lhpp, *retlhp; int index = LH_HASH(vp); mutex_enter(&ldi_handle_hash_lock[index]); lhpp = handle_find_ref_nolock(vp, ident); + retlhp = *lhpp; mutex_exit(&ldi_handle_hash_lock[index]); - ASSERT(lhpp != NULL); - return (*lhpp); + return (retlhp); } static struct ldi_handle * handle_alloc(vnode_t *vp, struct ldi_ident *ident) { - struct ldi_handle *lhp, **lhpp; + struct ldi_handle *lhp, **lhpp, *retlhp; uint_t index; ASSERT((vp != NULL) && (ident != NULL)); @@ -360,16 +361,17 @@ if (*lhpp != NULL) { /* we found a handle in the hash */ (*lhpp)->lh_ref++; + retlhp = *lhpp; mutex_exit(&ldi_handle_hash_lock[index]); LDI_ALLOCFREE((CE_WARN, "ldi handle alloc: dup " "lh=0x%p, ident=0x%p, vp=0x%p, drv=%s, minor=0x%x", - (void *)*lhpp, (void *)ident, (void *)vp, + (void *)retlhp, (void *)ident, (void *)vp, mod_major_to_name(getmajor(vp->v_rdev)), getminor(vp->v_rdev))); kmem_free(lhp, sizeof (struct ldi_handle)); - return (*lhpp); + return (retlhp); } /* initialize the new handle */