Mercurial > illumos > illumos-gate
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.