changeset 11978:bbbc665841e4

6904476 panic in stmf_remove_lu_from_session()
author tim szeto <Tim.Szeto@Sun.COM>
date Tue, 23 Mar 2010 08:57:29 -0600
parents 258a44653869
children e44013b33d33
files usr/src/uts/common/io/comstar/stmf/lun_map.c usr/src/uts/common/io/comstar/stmf/stmf.c
diffstat 2 files changed, 23 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/comstar/stmf/lun_map.c	Tue Mar 23 11:51:39 2010 +0800
+++ b/usr/src/uts/common/io/comstar/stmf/lun_map.c	Tue Mar 23 08:57:29 2010 -0600
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -191,11 +191,8 @@
 	stmf_ver_hg_t	*verhg;
 	stmf_lun_map_t	*ve_map;
 
-	if (iss->iss_sm != NULL)
-		cmn_err(CE_PANIC, "create lun map called with non NULL map");
-	iss->iss_sm = (stmf_lun_map_t *)kmem_zalloc(sizeof (stmf_lun_map_t),
-	    KM_SLEEP);
-	mutex_enter(&stmf_state.stmf_lock);
+	ASSERT(mutex_owned(&stmf_state.stmf_lock));
+
 	tg = ilport->ilport_tg;
 	hg = stmf_lookup_group_for_host(iss->iss_ss->ss_rport_id->ident,
 	    iss->iss_ss->ss_rport_id->ident_length);
@@ -233,7 +230,6 @@
 	}
 	/* not configured, cannot access any luns for now */
 
-	mutex_exit(&stmf_state.stmf_lock);
 	stmf_destroy_ve_map(ve_map);
 
 	return (STMF_SUCCESS);
@@ -252,15 +248,14 @@
 	uint16_t n;
 	stmf_lun_map_ent_t *ent;
 
+	ASSERT(mutex_owned(&stmf_state.stmf_lock));
 	/*
 	 * to avoid conflict with updating session's map,
 	 * which only grab stmf_lock
 	 */
-	mutex_enter(&stmf_state.stmf_lock);
 	sm = iss->iss_sm;
 	iss->iss_sm = NULL;
 	iss->iss_hg = NULL;
-	mutex_exit(&stmf_state.stmf_lock);
 	if (sm->lm_nentries) {
 		for (n = 0; n < sm->lm_nentries; n++) {
 			if ((ent = (stmf_lun_map_ent_t *)sm->lm_plus[n])
--- a/usr/src/uts/common/io/comstar/stmf/stmf.c	Tue Mar 23 11:51:39 2010 +0800
+++ b/usr/src/uts/common/io/comstar/stmf/stmf.c	Tue Mar 23 08:57:29 2010 -0600
@@ -49,6 +49,11 @@
 #include <pppt_ic_if.h>
 #include <stmf_stats.h>
 
+/*
+ * Lock order:
+ * stmf_state_lock --> ilport_lock/iss_lockp --> ilu_task_lock
+ */
+
 static uint64_t stmf_session_counter = 0;
 static uint16_t stmf_rtpid_counter = 0;
 /* start messages at 1 */
@@ -3494,13 +3499,20 @@
 
 	/* sessions use the ilport_lock. No separate lock is required */
 	iss->iss_lockp = &ilport->ilport_lock;
+
+	if (iss->iss_sm != NULL)
+		cmn_err(CE_PANIC, "create lun map called with non NULL map");
+	iss->iss_sm = (stmf_lun_map_t *)kmem_zalloc(sizeof (stmf_lun_map_t),
+	    KM_SLEEP);
+
+	mutex_enter(&stmf_state.stmf_lock);
+	rw_enter(&ilport->ilport_lock, RW_WRITER);
 	(void) stmf_session_create_lun_map(ilport, iss);
-
-	rw_enter(&ilport->ilport_lock, RW_WRITER);
 	ilport->ilport_nsessions++;
 	iss->iss_next = ilport->ilport_ss_list;
 	ilport->ilport_ss_list = iss;
 	rw_exit(&ilport->ilport_lock);
+	mutex_exit(&stmf_state.stmf_lock);
 
 	iss->iss_creation_time = ddi_get_time();
 	ss->ss_session_id = atomic_add_64_nv(&stmf_session_counter, 1);
@@ -3554,8 +3566,6 @@
 		}
 	}
 
-	mutex_exit(&stmf_state.stmf_lock);
-
 	rw_enter(&ilport->ilport_lock, RW_WRITER);
 	for (ppss = &ilport->ilport_ss_list; *ppss != NULL;
 	    ppss = &((*ppss)->iss_next)) {
@@ -3570,10 +3580,11 @@
 		    " session");
 	}
 	ilport->ilport_nsessions--;
-	rw_exit(&ilport->ilport_lock);
 
 	stmf_irport_deregister(iss->iss_irport);
 	(void) stmf_session_destroy_lun_map(ilport, iss);
+	rw_exit(&ilport->ilport_lock);
+	mutex_exit(&stmf_state.stmf_lock);
 }
 
 stmf_i_scsi_session_t *
@@ -6228,8 +6239,6 @@
 		ilu = (stmf_i_lu_t *)(lm_ent->ent_lu->lu_stmf_private);
 		atomic_or_32(&ilu->ilu_flags, ILU_RESET_ACTIVE);
 	}
-	rw_exit(iss->iss_lockp);
-	mutex_exit(&stmf_state.stmf_lock);
 
 	for (i = 0; i < lm->lm_nentries; i++) {
 		if (lm->lm_plus[i] == NULL)
@@ -6239,6 +6248,9 @@
 		    lm_ent->ent_lu);
 	}
 
+	rw_exit(iss->iss_lockp);
+	mutex_exit(&stmf_state.stmf_lock);
+
 	/* Start polling on this task */
 	if (stmf_task_poll_lu(task, ITASK_DEFAULT_POLL_TIMEOUT)
 	    != STMF_SUCCESS) {