changeset 10421:ce48b48df490

6859388 stmf kstats leak IO completion events during target reset 6868449 STMF kstat memory leak. 6869489 Unable to import a zvol after a zvol name change
author tim szeto <Tim.Szeto@Sun.COM>
date Mon, 31 Aug 2009 16:51:40 -0600
parents 263180af0fee
children d943e7451c42
files usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c usr/src/uts/common/io/comstar/stmf/stmf.c usr/src/uts/common/io/comstar/stmf/stmf_impl.h
diffstat 3 files changed, 44 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c	Mon Aug 31 16:44:41 2009 -0600
+++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c	Mon Aug 31 16:51:40 2009 -0600
@@ -1818,30 +1818,6 @@
 		goto sim_err_out;
 	}
 
-	if (sl->sl_flags & SL_ZFS_META) {
-		/* Verify that its the right zfs node and not some clone */
-		int same_zvol;
-		char *zvol_name = sbd_get_zvol_name(sl);
-
-		if ((sli->sli_flags & (SLI_ZFS_META |
-		    SLI_META_FNAME_VALID)) == 0) {
-			*err_ret = SBD_RET_NO_META;
-			ret = EIO;
-			kmem_free(zvol_name, strlen(zvol_name) + 1);
-			goto sim_err_out;
-		}
-		if (strcmp(zvol_name, (char *)sli_buf_copy +
-		    sli->sli_meta_fname_offset) != 0)
-			same_zvol = 0;
-		else
-			same_zvol = 1;
-		kmem_free(zvol_name, strlen(zvol_name) + 1);
-		if (!same_zvol) {
-			*err_ret = SBD_ZVOL_META_NAME_MISMATCH;
-			ret = EINVAL;
-			goto sim_err_out;
-		}
-	}
 	sl->sl_lu_size = sli->sli_lu_size;
 	sl->sl_data_blocksize_shift = sli->sli_data_blocksize_shift;
 	bcopy(sli->sli_device_id, sl->sl_device_id, 20);
--- a/usr/src/uts/common/io/comstar/stmf/stmf.c	Mon Aug 31 16:44:41 2009 -0600
+++ b/usr/src/uts/common/io/comstar/stmf/stmf.c	Mon Aug 31 16:51:40 2009 -0600
@@ -2333,6 +2333,8 @@
 		return (STMF_BUSY);
 	}
 	if (ilu->ilu_kstat_info) {
+		kmem_free(ilu->ilu_kstat_info->ks_data,
+		    ilu->ilu_kstat_info->ks_data_size);
 		kstat_delete(ilu->ilu_kstat_info);
 	}
 	if (ilu->ilu_kstat_io) {
@@ -2426,6 +2428,8 @@
 		return (STMF_BUSY);
 	}
 	if (ilport->ilport_kstat_info) {
+		kmem_free(ilport->ilport_kstat_info->ks_data,
+		    ilport->ilport_kstat_info->ks_data_size);
 		kstat_delete(ilport->ilport_kstat_info);
 	}
 	if (ilport->ilport_kstat_io) {
@@ -3433,7 +3437,7 @@
 	    (stmf_i_scsi_task_t *)task->task_stmf_private;
 	stmf_worker_t *w = itask->itask_worker;
 	uint32_t new, old;
-	uint8_t update_queue_flags, free_it, queue_it;
+	uint8_t update_queue_flags, free_it, queue_it, kstat_it;
 
 	mutex_enter(&w->worker_lock);
 	do {
@@ -3443,10 +3447,12 @@
 			return;
 		}
 		free_it = 0;
+		kstat_it = 0;
 		if (iof & STMF_IOF_LPORT_DONE) {
 			new &= ~ITASK_KNOWN_TO_TGT_PORT;
 			task->task_completion_status = dbuf->db_xfer_status;
 			free_it = 1;
+			kstat_it = 1;
 		}
 		/*
 		 * If the task is known to LU then queue it. But if
@@ -3471,6 +3477,10 @@
 		}
 	} while (atomic_cas_32(&itask->itask_flags, old, new) != old);
 
+	if (kstat_it) {
+		stmf_update_kstat_lu_q(task, kstat_runq_exit);
+		stmf_update_kstat_lport_q(task, kstat_runq_exit);
+	}
 	if (update_queue_flags) {
 		uint8_t cmd = (dbuf->db_handle << 5) | ITASK_CMD_DATA_XFER_DONE;
 
@@ -3498,8 +3508,6 @@
 		if ((itask->itask_flags & (ITASK_KNOWN_TO_LU |
 		    ITASK_KNOWN_TO_TGT_PORT | ITASK_IN_WORKER_QUEUE |
 		    ITASK_BEING_ABORTED)) == 0) {
-			stmf_update_kstat_lu_q(task, kstat_runq_exit);
-			stmf_update_kstat_lport_q(task, kstat_runq_exit);
 			stmf_task_free(task);
 		}
 	}
@@ -3556,7 +3564,7 @@
 	    (stmf_i_scsi_task_t *)task->task_stmf_private;
 	stmf_worker_t *w = itask->itask_worker;
 	uint32_t new, old;
-	uint8_t free_it, queue_it;
+	uint8_t free_it, queue_it, kstat_it;
 
 	mutex_enter(&w->worker_lock);
 	do {
@@ -3566,9 +3574,11 @@
 			return;
 		}
 		free_it = 0;
+		kstat_it = 0;
 		if (iof & STMF_IOF_LPORT_DONE) {
 			new &= ~ITASK_KNOWN_TO_TGT_PORT;
 			free_it = 1;
+			kstat_it = 1;
 		}
 		/*
 		 * If the task is known to LU then queue it. But if
@@ -3593,8 +3603,10 @@
 	} while (atomic_cas_32(&itask->itask_flags, old, new) != old);
 	task->task_completion_status = s;
 
-	stmf_update_kstat_lu_q(task, kstat_runq_exit);
-	stmf_update_kstat_lport_q(task, kstat_runq_exit);
+	if (kstat_it) {
+		stmf_update_kstat_lu_q(task, kstat_runq_exit);
+		stmf_update_kstat_lport_q(task, kstat_runq_exit);
+	}
 
 	if (queue_it) {
 		ASSERT(itask->itask_ncmds < ITASK_MAX_NCMDS);
@@ -3777,9 +3789,10 @@
 void
 stmf_task_lport_aborted(scsi_task_t *task, stmf_status_t s, uint32_t iof)
 {
-	char			 info[STMF_CHANGE_INFO_LEN];
+	char			info[STMF_CHANGE_INFO_LEN];
 	stmf_i_scsi_task_t	*itask = TASK_TO_ITASK(task);
 	unsigned long long	st;
+	uint32_t		old, new;
 
 	st = s;
 	if ((s != STMF_ABORT_SUCCESS) && (s != STMF_NOT_FOUND)) {
@@ -3792,9 +3805,22 @@
 		    "task=%p, s=%llx, iof=%x", (void *)task, st, iof);
 	} else {
 		/*
-		 * LU abort successfully
+		 * LPORT abort successfully
 		 */
-		atomic_and_32(&itask->itask_flags, ~ITASK_KNOWN_TO_TGT_PORT);
+		do {
+			old = new = itask->itask_flags;
+			if (!(old & ITASK_KNOWN_TO_TGT_PORT))
+				return;
+			new &= ~ITASK_KNOWN_TO_TGT_PORT;
+		} while (atomic_cas_32(&itask->itask_flags, old, new) != old);
+
+		if (!(itask->itask_flags & ITASK_KSTAT_IN_RUNQ)) {
+			stmf_update_kstat_lu_q(task, kstat_waitq_exit);
+			stmf_update_kstat_lport_q(task, kstat_waitq_exit);
+		} else {
+			stmf_update_kstat_lu_q(task, kstat_runq_exit);
+			stmf_update_kstat_lport_q(task, kstat_runq_exit);
+		}
 		return;
 	}
 
@@ -4890,7 +4916,12 @@
 				goto out_itask_flag_loop;
 			} else if ((curcmd & ITASK_CMD_MASK) ==
 			    ITASK_CMD_NEW_TASK) {
-				new = old | ITASK_KNOWN_TO_LU;
+				/*
+				 * set ITASK_KSTAT_IN_RUNQ, this flag
+				 * will not reset until task completed
+				 */
+				new = old | ITASK_KNOWN_TO_LU |
+				    ITASK_KSTAT_IN_RUNQ;
 			} else {
 				goto out_itask_flag_loop;
 			}
@@ -6065,9 +6096,9 @@
 static void
 stmf_abort_task_offline(scsi_task_t *task, int offline_lu, char *info)
 {
-	stmf_state_change_info_t	 change_info;
+	stmf_state_change_info_t	change_info;
 	void				*ctl_private;
-	uint32_t			 ctl_cmd;
+	uint32_t			ctl_cmd;
 	int				msg = 0;
 
 	stmf_trace("FROM STMF", "abort_task_offline called for %s: %s",
--- a/usr/src/uts/common/io/comstar/stmf/stmf_impl.h	Mon Aug 31 16:44:41 2009 -0600
+++ b/usr/src/uts/common/io/comstar/stmf/stmf_impl.h	Mon Aug 31 16:51:40 2009 -0600
@@ -218,6 +218,7 @@
 #define	ITASK_DEFAULT_HANDLING		0x0200
 #define	ITASK_CAUSING_LU_RESET		0x0400
 #define	ITASK_CAUSING_TARGET_RESET	0x0800
+#define	ITASK_KSTAT_IN_RUNQ		0x1000
 
 /*
  * itask cmds.