Print this page
5297 mptsas refhash replacement on reset can cause hang
*** 1325,1334 ****
--- 1325,1340 ----
mutex_exit(&mpt->m_mutex);
mptsas_log(mpt, CE_WARN, "mptsas chip initialization failed");
goto fail;
}
+ mpt->m_targets = refhash_create(MPTSAS_TARGET_BUCKET_COUNT,
+ mptsas_target_addr_hash, mptsas_target_addr_cmp,
+ mptsas_target_free, sizeof (mptsas_target_t),
+ offsetof(mptsas_target_t, m_link),
+ offsetof(mptsas_target_t, m_addr), KM_SLEEP);
+
/*
* Fill in the phy_info structure and get the base WWID
*/
if (mptsas_get_manufacture_page5(mpt) == DDI_FAILURE) {
mptsas_log(mpt, CE_WARN,
*** 12711,12726 ****
if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) {
mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed");
goto fail;
}
- mpt->m_targets = refhash_create(MPTSAS_TARGET_BUCKET_COUNT,
- mptsas_target_addr_hash, mptsas_target_addr_cmp,
- mptsas_target_free, sizeof (mptsas_target_t),
- offsetof(mptsas_target_t, m_link),
- offsetof(mptsas_target_t, m_addr), KM_SLEEP);
-
if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) {
goto fail;
}
/*
* Allocate request message frames, reply free queue, reply descriptor
--- 12717,12726 ----
*** 14311,14328 ****
* 2. invalid all the entries in hash table
* m_devhdl = 0xffff and m_deviceinfo = 0
* 3. call sas_device_page/expander_page to update hash table
*/
mptsas_update_phymask(mpt);
/*
! * Invalid the existing entries
! *
! * XXX - It seems like we should just delete everything here. We are
! * holding the lock and are about to refresh all the targets in both
! * hashes anyway. Given the path we're in, what outstanding async
! * event could possibly be trying to reference one of these things
! * without taking the lock, and how would that be useful anyway?
*/
for (tp = refhash_first(mpt->m_targets); tp != NULL;
tp = refhash_next(mpt->m_targets, tp)) {
tp->m_devhdl = MPTSAS_INVALID_DEVHDL;
tp->m_deviceinfo = 0;
--- 14311,14328 ----
* 2. invalid all the entries in hash table
* m_devhdl = 0xffff and m_deviceinfo = 0
* 3. call sas_device_page/expander_page to update hash table
*/
mptsas_update_phymask(mpt);
+
/*
! * Remove all the devhdls for existing entries but leave their
! * addresses alone. In update_hashtab() below, we'll find all
! * targets that are still present and reassociate them with
! * their potentially new devhdls. Leaving the targets around in
! * this fashion allows them to be used on the tx waitq even
! * while IOC reset it occurring.
*/
for (tp = refhash_first(mpt->m_targets); tp != NULL;
tp = refhash_next(mpt->m_targets, tp)) {
tp->m_devhdl = MPTSAS_INVALID_DEVHDL;
tp->m_deviceinfo = 0;