--- old/usr/src/uts/common/io/comstar/stmf/lun_map.c	Mon Aug  5 17:27:36 2019
+++ new/usr/src/uts/common/io/comstar/stmf/lun_map.c	Mon Aug  5 17:27:36 2019
@@ -47,8 +47,9 @@
 void stmf_add_lus_to_session_per_vemap(stmf_i_local_port_t *ilport,
 		stmf_i_scsi_session_t *iss, stmf_lun_map_t *vemap);
 stmf_id_data_t *stmf_lookup_group_for_host(uint8_t *ident, uint16_t ident_size);
-stmf_status_t stmf_add_ent_to_map(stmf_lun_map_t *sm, void *ent, uint8_t *lun);
-stmf_status_t stmf_remove_ent_from_map(stmf_lun_map_t *sm, uint8_t *lun);
+static stmf_status_t stmf_add_ent_to_map(stmf_lun_map_t *sm, void *ent,
+    uint8_t *lun);
+static stmf_status_t stmf_remove_ent_from_map(stmf_lun_map_t *sm, uint8_t *lun);
 uint16_t stmf_get_next_free_lun(stmf_lun_map_t *sm, uint8_t *lun);
 stmf_status_t stmf_add_tg(uint8_t *tg_name, uint16_t tg_name_size,
 		int allow_special, uint32_t *err_detail);
@@ -179,6 +180,7 @@
 
 /*
  * Create luns map for session based on the view
+ * iss_lockp is held
  */
 stmf_status_t
 stmf_session_create_lun_map(stmf_i_local_port_t *ilport,
@@ -236,52 +238,8 @@
 }
 
 /*
- * destroy lun map for session
- */
-/* ARGSUSED */
-stmf_status_t
-stmf_session_destroy_lun_map(stmf_i_local_port_t *ilport,
-		stmf_i_scsi_session_t *iss)
-{
-	stmf_lun_map_t *sm;
-	stmf_i_lu_t *ilu;
-	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
-	 */
-	sm = iss->iss_sm;
-	iss->iss_sm = NULL;
-	iss->iss_hg = NULL;
-	if (sm->lm_nentries) {
-		for (n = 0; n < sm->lm_nentries; n++) {
-			if ((ent = (stmf_lun_map_ent_t *)sm->lm_plus[n])
-			    != NULL) {
-				if (ent->ent_itl_datap) {
-					stmf_do_itl_dereg(ent->ent_lu,
-					    ent->ent_itl_datap,
-					    STMF_ITL_REASON_IT_NEXUS_LOSS);
-				}
-				ilu = (stmf_i_lu_t *)
-				    ent->ent_lu->lu_stmf_private;
-				atomic_dec_32(&ilu->ilu_ref_cnt);
-				kmem_free(sm->lm_plus[n],
-				    sizeof (stmf_lun_map_ent_t));
-			}
-		}
-		kmem_free(sm->lm_plus,
-		    sizeof (stmf_lun_map_ent_t *) * sm->lm_nentries);
-	}
-
-	kmem_free(sm, sizeof (*sm));
-	return (STMF_SUCCESS);
-}
-
-/*
  * Expects the session lock to be held.
+ * iss_lockp is held
  */
 stmf_xfer_data_t *
 stmf_session_prepare_report_lun_data(stmf_lun_map_t *sm)
@@ -390,8 +348,9 @@
 }
 /*
  * add lu to a session, stmf_lock is already held
+ * iss_lockp/ilport_lock already held
  */
-stmf_status_t
+static stmf_status_t
 stmf_add_lu_to_session(stmf_i_local_port_t *ilport,
 		stmf_i_scsi_session_t	*iss,
 		stmf_lu_t *lu,
@@ -434,13 +393,11 @@
 
 /*
  * remvoe lu from a session, stmf_lock is already held
+ * iss_lockp held
  */
-/* ARGSUSED */
-stmf_status_t
-stmf_remove_lu_from_session(stmf_i_local_port_t *ilport,
-		stmf_i_scsi_session_t *iss,
-		stmf_lu_t *lu,
-		uint8_t *lu_nbr)
+static void
+stmf_remove_lu_from_session(stmf_i_scsi_session_t *iss,
+    stmf_lu_t *lu, uint8_t *lu_nbr)
 {
 	stmf_status_t ret;
 	stmf_i_lu_t *ilu;
@@ -451,7 +408,10 @@
 
 	ASSERT(mutex_owned(&stmf_state.stmf_lock));
 	lun_map_ent = stmf_get_ent_from_map(sm, luNbr);
-	ASSERT(lun_map_ent && lun_map_ent->ent_lu == lu);
+	ASSERT(lun_map_ent->ent_lu == lu);
+	if (lun_map_ent == NULL) {
+		return;
+	}
 
 	ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
 
@@ -464,7 +424,6 @@
 		    STMF_ITL_REASON_USER_REQUEST);
 	}
 	kmem_free((void *)lun_map_ent, sizeof (stmf_lun_map_ent_t));
-	return (STMF_SUCCESS);
 }
 
 /*
@@ -519,8 +478,8 @@
 				continue;
 			/* This host belongs to the host group */
 			if (action == 0) { /* to remove */
-				(void) stmf_remove_lu_from_session(ilport, iss,
-				    lu_to_add, ve->ve_lun);
+				stmf_remove_lu_from_session(iss, lu_to_add,
+				    ve->ve_lun);
 				if (ilu_tmp->ilu_ref_cnt == 0) {
 					rw_exit(&ilport->ilport_lock);
 					return;
@@ -549,7 +508,6 @@
 	uint32_t	i;
 
 	ASSERT(mutex_owned(&stmf_state.stmf_lock));
-
 	for (i = 0; i < vemap->lm_nentries; i++) {
 		ve = (stmf_view_entry_t *)vemap->lm_plus[i];
 		if (!ve)
@@ -562,11 +520,13 @@
 		}
 	}
 }
-/* remove luns in view entry map from a session */
+/*
+ * remove luns in view entry map from a session
+ * iss_lockp held
+ */
 void
-stmf_remove_lus_from_session_per_vemap(stmf_i_local_port_t *ilport,
-		stmf_i_scsi_session_t *iss,
-		stmf_lun_map_t *vemap)
+stmf_remove_lus_from_session_per_vemap(stmf_i_scsi_session_t *iss,
+    stmf_lun_map_t *vemap)
 {
 	stmf_lu_t *lu;
 	stmf_i_lu_t *ilu;
@@ -582,8 +542,7 @@
 		ilu = (stmf_i_lu_t *)ve->ve_luid->id_pt_to_object;
 		if (ilu && ilu->ilu_state == STMF_STATE_ONLINE) {
 			lu = ilu->ilu_lu;
-			(void) stmf_remove_lu_from_session(ilport, iss, lu,
-			    ve->ve_lun);
+			stmf_remove_lu_from_session(iss, lu, ve->ve_lun);
 		}
 	}
 }
@@ -710,6 +669,7 @@
  * is successfully added. ve_map is just another representation of the
  * view enrtries in a LU. Duplicating or merging a ve map does not
  * affect any refcnts.
+ * stmf_state.stmf_lock held
  */
 stmf_lun_map_t *
 stmf_duplicate_ve_map(stmf_lun_map_t *src)
@@ -742,6 +702,10 @@
 	kmem_free(dst, sizeof (*dst));
 }
 
+/*
+ * stmf_state.stmf_lock held. Operations are stmf global in nature and
+ * not session level.
+ */
 int
 stmf_merge_ve_map(stmf_lun_map_t *src, stmf_lun_map_t *dst,
 		stmf_lun_map_t **pp_ret_map, stmf_merge_flags_t mf)
@@ -1066,7 +1030,11 @@
 	return (ret);
 }
 
-stmf_status_t
+/*
+ * protected by stmf_state.stmf_lock when working on global lun map.
+ * iss_lockp when working at the session level.
+ */
+static stmf_status_t
 stmf_add_ent_to_map(stmf_lun_map_t *lm, void *ent, uint8_t *lun)
 {
 	uint16_t n;
@@ -1098,7 +1066,11 @@
 }
 
 
-stmf_status_t
+/*
+ * iss_lockp held when working on a session.
+ * stmf_state.stmf_lock is held when working on the global views.
+ */
+static stmf_status_t
 stmf_remove_ent_from_map(stmf_lun_map_t *lm, uint8_t *lun)
 {
 	uint16_t n, i;
@@ -1135,6 +1107,9 @@
 	return (STMF_SUCCESS);
 }
 
+/*
+ * stmf_state.stmf_lock held
+ */
 uint16_t
 stmf_get_next_free_lun(stmf_lun_map_t *sm, uint8_t *lun)
 {
@@ -1158,6 +1133,10 @@
 	return (luNbr);
 }
 
+/*
+ * stmf_state.stmf_lock is held when working on global view map
+ * iss_lockp (RW_WRITER) is held when working on session map.
+ */
 void *
 stmf_get_ent_from_map(stmf_lun_map_t *sm, uint16_t lun_num)
 {
@@ -1492,6 +1471,7 @@
 			stmf_id_data_t *tgid;
 			iss->iss_hg = (void *)id_grp;
 			tgid = ilport->ilport_tg;
+			rw_enter(iss->iss_lockp, RW_WRITER);
 			if (tgid) {
 				vemap = stmf_get_ve_map_per_ids(tgid, id_grp);
 				if (vemap)
@@ -1501,6 +1481,7 @@
 			if (vemap_alltgt)
 				stmf_add_lus_to_session_per_vemap(ilport,
 				    iss, vemap_alltgt);
+			rw_exit(iss->iss_lockp);
 		}
 	}
 
@@ -1577,6 +1558,7 @@
 		    entry_ident, entry_size);
 		if (iss) {
 			stmf_id_data_t *tgid;
+			rw_enter(iss->iss_lockp, RW_WRITER);
 			iss->iss_hg = NULL;
 			tgid = ilport->ilport_tg;
 			if (tgid) {
@@ -1583,11 +1565,12 @@
 				vemap = stmf_get_ve_map_per_ids(tgid, id_grp);
 				if (vemap)
 					stmf_remove_lus_from_session_per_vemap(
-					    ilport, iss, vemap);
+					    iss, vemap);
 			}
 			if (vemap_alltgt)
-				stmf_remove_lus_from_session_per_vemap(ilport,
-				    iss, vemap_alltgt);
+				stmf_remove_lus_from_session_per_vemap(iss,
+				    vemap_alltgt);
+			rw_exit(iss->iss_lockp);
 		}
 	}
 
