Mercurial > illumos > illumos-gate
changeset 12668:12abda5fe158
6957990 RCC hotplug causes panic - Deadlock: cycle in blocking chain
6962090 bad mutex panic in pmcs_update_phy_pm_props
author | Srikanth Suravajhala <srikanth.suravajhala@oracle.com> |
---|---|
date | Mon, 21 Jun 2010 17:58:51 -0400 |
parents | 62bc4887874f |
children | d6e297b04d5d |
files | usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_scsa.c usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_def.h |
diffstat | 3 files changed, 49 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_scsa.c Mon Jun 21 14:10:34 2010 -0700 +++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_scsa.c Mon Jun 21 17:58:51 2010 -0400 @@ -227,6 +227,8 @@ tgt = pmcs_get_target(iport, tgt_port, B_TRUE); if (tgt == NULL) { + pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "%s: " + "No tgt for tgt_port (%s)", __func__, tgt_port); goto tgt_init_fail; }
--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c Mon Jun 21 14:10:34 2010 -0700 +++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c Mon Jun 21 17:58:51 2010 -0400 @@ -3571,6 +3571,7 @@ */ while (clist) { ctmp = clist->sibling; + clist->target_addr = NULL; kmem_cache_free(pwp->phy_cache, clist); clist = ctmp; } @@ -3661,6 +3662,7 @@ while (clist) { ctmp = clist->sibling; pmcs_unlock_phy(clist); + clist->target_addr = NULL; kmem_cache_free(pwp->phy_cache, clist); clist = ctmp; } @@ -4822,6 +4824,7 @@ pmcs_tag2wp(pmcs_hw_t *pwp, uint32_t htag, boolean_t lock_phy) { pmcwork_t *p; + pmcs_phy_t *phyp; uint32_t idx = PMCS_TAG_INDEX(htag); p = &pwp->work[idx]; @@ -4829,9 +4832,28 @@ mutex_enter(&p->lock); if (p->htag == htag) { if (lock_phy) { - mutex_exit(&p->lock); - mutex_enter(&p->phy->phy_lock); - mutex_enter(&p->lock); + phyp = p->phy; + if (phyp != NULL) { + /* phy lock should be held before work lock */ + mutex_exit(&p->lock); + mutex_enter(&phyp->phy_lock); + mutex_enter(&p->lock); + } + /* + * Check htag again, in case the work got completed + * while we dropped the work lock and got the phy lock + */ + if (p->htag != htag) { + if (phyp != NULL) { + mutex_exit(&p->lock); + mutex_exit(&phyp->phy_lock); + } + pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, NULL, "%s: " + "HTAG (0x%x) found, but work (0x%p) " + "is already complete", __func__, htag, + (void *)p); + return (NULL); + } } return (p); } @@ -7502,6 +7524,7 @@ } if (!IS_ROOT_PHY(tphyp)) { + tphyp->target_addr = NULL; kmem_cache_free(pwp->phy_cache, tphyp); } } @@ -7509,6 +7532,7 @@ mutex_enter(&pwp->dead_phylist_lock); for (tphyp = pwp->dead_phys; tphyp; tphyp = nphyp) { nphyp = tphyp->dead_next; + tphyp->target_addr = NULL; kmem_cache_free(pwp->phy_cache, tphyp); } pwp->dead_phys = NULL; @@ -7528,6 +7552,7 @@ while (phyp) { next_phy = phyp->sibling; ASSERT(!mutex_owned(&phyp->phy_lock)); + phyp->target_addr = NULL; kmem_cache_free(pwp->phy_cache, phyp); phyp = next_phy; } @@ -7554,6 +7579,7 @@ * Go ahead and just copy everything... */ *local = *orig_phy; + local->target_addr = &orig_phy->target; /* * But the following must be set appropriately for this copy @@ -7755,6 +7781,7 @@ mutex_exit(&phyp->target->statlock); } pmcs_unlock_phy(phyp); + phyp->target_addr = NULL; kmem_cache_free(pwp->phy_cache, phyp); } @@ -8042,6 +8069,8 @@ pmcs_update_phy_pm_props(pmcs_phy_t *phyp, uint64_t att_bv, uint64_t tgt_bv, boolean_t prop_add_val) { + pmcs_xscsi_t *tgt; + if (prop_add_val) { /* * If the values are currently 0, then we're setting the @@ -8078,15 +8107,19 @@ } } - if (phyp->target == NULL) { + if ((phyp->target_addr) && (*phyp->target_addr != NULL)) { + tgt = *phyp->target_addr; + } else if (phyp->target != NULL) { + tgt = phyp->target; + } else { return; } - mutex_enter(&phyp->target->statlock); - if (!list_is_empty(&phyp->target->lun_list)) { + mutex_enter(&tgt->statlock); + if (!list_is_empty(&tgt->lun_list)) { pmcs_lun_t *lunp; - lunp = list_head(&phyp->target->lun_list); + lunp = list_head(&tgt->lun_list); while (lunp) { (void) scsi_device_prop_update_string(lunp->sd, SCSI_DEVICE_PROP_PATH, @@ -8096,17 +8129,17 @@ SCSI_DEVICE_PROP_PATH, SCSI_ADDR_PROP_TARGET_PORT_PM, phyp->tgt_port_pm_str); - lunp = list_next(&phyp->target->lun_list, lunp); - } - } else if (phyp->target->smpd) { - (void) smp_device_prop_update_string(phyp->target->smpd, + lunp = list_next(&tgt->lun_list, lunp); + } + } else if (tgt->smpd) { + (void) smp_device_prop_update_string(tgt->smpd, SCSI_ADDR_PROP_ATTACHED_PORT_PM, phyp->att_port_pm_str); - (void) smp_device_prop_update_string(phyp->target->smpd, + (void) smp_device_prop_update_string(tgt->smpd, SCSI_ADDR_PROP_TARGET_PORT_PM, phyp->tgt_port_pm_str); } - mutex_exit(&phyp->target->statlock); + mutex_exit(&tgt->statlock); } /* ARGSUSED */
--- a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_def.h Mon Jun 21 14:10:34 2010 -0700 +++ b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_def.h Mon Jun 21 17:58:51 2010 -0400 @@ -125,6 +125,7 @@ pmcs_iport_t *iport; /* back ptr to the iport handle */ pmcs_iport_t *last_iport; /* last iport this PHY was on */ pmcs_xscsi_t *target; /* back ptr to current target */ + pmcs_xscsi_t **target_addr; /* address of real target pointer */ kstat_t *phy_stats; /* kstats for this phy */ /* * Attached port phy mask and target port phymask. With 16 bytes