diff options
author | Jeff Biseda <jeff.biseda@delphix.com> | 2013-07-07 18:18:37 -0800 |
---|---|---|
committer | Christopher Siden <chris.siden@delphix.com> | 2013-07-07 19:18:37 -0700 |
commit | 09409df0fea2444decd38bc1b87ab7a80d3251e5 (patch) | |
tree | d193088ba6cecd4b0979cf8343143eeb34b70fb0 | |
parent | f99db78fa089c50b0d8fcef75f99d7a7f2e27dda (diff) | |
download | illumos-joyent-09409df0fea2444decd38bc1b87ab7a80d3251e5.tar.gz |
3862 stmf + kstat = kernel panic
3863 stmf_itl_task_start() must check for ilu->ilu_kstat_io is non-null
3864 memory leak in the iSCSI code
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Jeremy Jones <jeremy@delphix.com>
Reviewed by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed by: Dan McDonald <danmcd@nexenta.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Richard Elling <richard.elling@gmail.com>
Approved by: Gordon Ross <gwr@nexenta.com>
-rw-r--r-- | usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c | 11 | ||||
-rw-r--r-- | usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c | 23 | ||||
-rw-r--r-- | usr/src/uts/common/io/comstar/stmf/stmf.c | 534 | ||||
-rw-r--r-- | usr/src/uts/common/io/comstar/stmf/stmf_impl.h | 19 | ||||
-rw-r--r-- | usr/src/uts/common/io/comstar/stmf/stmf_state.h | 2 | ||||
-rw-r--r-- | usr/src/uts/common/sys/lpif.h | 4 | ||||
-rw-r--r-- | usr/src/uts/common/sys/stmf.h | 3 |
7 files changed, 22 insertions, 574 deletions
diff --git a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c index 2556c67e37..6c9c1f1158 100644 --- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c +++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c @@ -22,6 +22,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #include <sys/conf.h> @@ -2997,7 +2998,6 @@ sbd_data_read(sbd_lu_t *sl, struct scsi_task *task, { int ret; long resid; - hrtime_t xfer_start, xfer_done; if ((offset + size) > sl->sl_lu_size) { return (SBD_IO_PAST_EOF); @@ -3016,8 +3016,6 @@ sbd_data_read(sbd_lu_t *sl, struct scsi_task *task, size = store_end; } - xfer_start = gethrtime(); - stmf_lu_xfer_start(task); DTRACE_PROBE5(backing__store__read__start, sbd_lu_t *, sl, uint8_t *, buf, uint64_t, size, uint64_t, offset, scsi_task_t *, task); @@ -3038,8 +3036,6 @@ sbd_data_read(sbd_lu_t *sl, struct scsi_task *task, &resid); rw_exit(&sl->sl_access_state_lock); - xfer_done = gethrtime() - xfer_start; - stmf_lu_xfer_done(task, B_TRUE /* read */, size, xfer_done); DTRACE_PROBE6(backing__store__read__end, sbd_lu_t *, sl, uint8_t *, buf, uint64_t, size, uint64_t, offset, int, ret, scsi_task_t *, task); @@ -3062,7 +3058,6 @@ sbd_data_write(sbd_lu_t *sl, struct scsi_task *task, long resid; sbd_status_t sret = SBD_SUCCESS; int ioflag; - hrtime_t xfer_start, xfer_done; if ((offset + size) > sl->sl_lu_size) { return (SBD_IO_PAST_EOF); @@ -3077,8 +3072,6 @@ sbd_data_write(sbd_lu_t *sl, struct scsi_task *task, ioflag = 0; } - xfer_start = gethrtime(); - stmf_lu_xfer_start(task); DTRACE_PROBE5(backing__store__write__start, sbd_lu_t *, sl, uint8_t *, buf, uint64_t, size, uint64_t, offset, scsi_task_t *, task); @@ -3099,8 +3092,6 @@ sbd_data_write(sbd_lu_t *sl, struct scsi_task *task, &resid); rw_exit(&sl->sl_access_state_lock); - xfer_done = gethrtime() - xfer_start; - stmf_lu_xfer_done(task, B_FALSE /* write */, size, xfer_done); DTRACE_PROBE6(backing__store__write__end, sbd_lu_t *, sl, uint8_t *, buf, uint64_t, size, uint64_t, offset, int, ret, scsi_task_t *, task); diff --git a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c index 3ae1322113..cb6e115fe9 100644 --- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c +++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c @@ -20,8 +20,8 @@ */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #include <sys/conf.h> @@ -218,7 +218,6 @@ sbd_do_sgl_read_xfer(struct scsi_task *task, sbd_cmd_t *scmd, int first_xfer) uint_t nblks; uint64_t blksize = sl->sl_blksize; size_t db_private_sz; - hrtime_t xfer_start, xfer_elapsed; uintptr_t pad; ASSERT(rw_read_held(&sl->sl_access_state_lock)); @@ -334,18 +333,12 @@ sbd_do_sgl_read_xfer(struct scsi_task *task, sbd_cmd_t *scmd, int first_xfer) * Accounting for start of read. * Note there is no buffer address for the probe yet. */ - stmf_lu_xfer_start(task); DTRACE_PROBE5(backing__store__read__start, sbd_lu_t *, sl, uint8_t *, NULL, uint64_t, xfer_len, uint64_t, offset, scsi_task_t *, task); - xfer_start = gethrtime(); ret = sbd_zvol_alloc_read_bufs(sl, dbuf); - xfer_elapsed = gethrtime() - xfer_start; - - stmf_lu_xfer_done(task, B_TRUE /* read */, (uint64_t)xfer_len, - xfer_elapsed); DTRACE_PROBE6(backing__store__read__end, sbd_lu_t *, sl, uint8_t *, NULL, uint64_t, xfer_len, uint64_t, offset, int, ret, scsi_task_t *, task); @@ -607,7 +600,6 @@ sbd_handle_sgl_write_xfer_completion(struct scsi_task *task, sbd_cmd_t *scmd, int scmd_err, scmd_xfer_done; stmf_status_t xfer_status = dbuf->db_xfer_status; uint32_t data_size = dbuf->db_data_size; - hrtime_t xfer_start; ASSERT(zvio); @@ -627,12 +619,9 @@ sbd_handle_sgl_write_xfer_completion(struct scsi_task *task, sbd_cmd_t *scmd, (scmd->flags & SBD_SCSI_CMD_XFER_FAIL) || (xfer_status != STMF_SUCCESS)); - /* start the accounting clock */ - stmf_lu_xfer_start(task); DTRACE_PROBE5(backing__store__write__start, sbd_lu_t *, sl, uint8_t *, NULL, uint64_t, data_size, uint64_t, zvio->zvio_offset, scsi_task_t *, task); - xfer_start = gethrtime(); if (scmd_err) { /* just return the write buffers */ @@ -647,9 +636,6 @@ sbd_handle_sgl_write_xfer_completion(struct scsi_task *task, sbd_cmd_t *scmd, ret = sbd_zvol_rele_write_bufs(sl, dbuf); } - /* finalize accounting */ - stmf_lu_xfer_done(task, B_FALSE /* not read */, data_size, - (gethrtime() - xfer_start)); DTRACE_PROBE6(backing__store__write__end, sbd_lu_t *, sl, uint8_t *, NULL, uint64_t, data_size, uint64_t, zvio->zvio_offset, int, ret, scsi_task_t *, task); @@ -739,7 +725,6 @@ sbd_copy_rdwr(scsi_task_t *task, uint64_t laddr, stmf_data_buf_t *dbuf, struct iovec *iov, *tiov, iov1[8]; uint32_t len, resid; int ret, i, iovcnt, flags; - hrtime_t xfer_start; boolean_t is_read; ASSERT(cmd == SBD_CMD_SCSI_READ || cmd == SBD_CMD_SCSI_WRITE); @@ -777,9 +762,6 @@ sbd_copy_rdwr(scsi_task_t *task, uint64_t laddr, stmf_data_buf_t *dbuf, uio.uio_resid = (uint64_t)len; uio.uio_llimit = RLIM64_INFINITY; - /* start the accounting clock */ - stmf_lu_xfer_start(task); - xfer_start = gethrtime(); if (is_read == B_TRUE) { uio.uio_fmode = FREAD; uio.uio_extflg = UIO_COPY_CACHED; @@ -808,9 +790,6 @@ sbd_copy_rdwr(scsi_task_t *task, uint64_t laddr, stmf_data_buf_t *dbuf, uint8_t *, NULL, uint64_t, len, uint64_t, laddr, int, ret, scsi_task_t *, task); } - /* finalize accounting */ - stmf_lu_xfer_done(task, is_read, (uint64_t)len, - (gethrtime() - xfer_start)); if (iov != &iov1[0]) kmem_free(iov, iovcnt * sizeof (*iov)); diff --git a/usr/src/uts/common/io/comstar/stmf/stmf.c b/usr/src/uts/common/io/comstar/stmf/stmf.c index 2981453cd4..9df2c4e247 100644 --- a/usr/src/uts/common/io/comstar/stmf/stmf.c +++ b/usr/src/uts/common/io/comstar/stmf/stmf.c @@ -175,14 +175,6 @@ static stmf_i_remote_port_t *stmf_irport_lookup_locked( scsi_devid_desc_t *rport_devid); static void stmf_irport_deregister(stmf_i_remote_port_t *irport); -static void stmf_teardown_itl_kstats(stmf_i_itl_kstat_t *ks); -static void stmf_delete_itl_kstat_by_lport(char *); -static void stmf_delete_itl_kstat_by_guid(char *); -static int stmf_itl_kstat_compare(const void*, const void*); -static stmf_i_itl_kstat_t *stmf_itl_kstat_lookup(char *kstat_nm); -static stmf_i_itl_kstat_t *stmf_itl_kstat_create(stmf_itl_data_t *itl, - char *nm, scsi_devid_desc_t *lport, scsi_devid_desc_t *lun); - extern struct mod_ops mod_driverops; /* =====[ Tunables ]===== */ @@ -324,9 +316,6 @@ _init(void) id_space_create("lport-instances", 0, MAX_ILPORT); stmf_state.stmf_irport_inst_space = id_space_create("rport-instances", 0, MAX_IRPORT); - avl_create(&stmf_state.stmf_itl_kstat_list, - stmf_itl_kstat_compare, sizeof (stmf_i_itl_kstat_t), - offsetof(stmf_i_itl_kstat_t, iitl_kstat_ln)); stmf_view_init(); stmf_svc_init(); stmf_dlun_init(); @@ -338,7 +327,6 @@ _fini(void) { int ret; stmf_i_remote_port_t *irport; - stmf_i_itl_kstat_t *ks_itl; void *avl_dest_cookie = NULL; if (stmf_state.stmf_service_running) @@ -379,14 +367,6 @@ _fini(void) id_space_destroy(stmf_state.stmf_ilport_inst_space); id_space_destroy(stmf_state.stmf_irport_inst_space); - avl_dest_cookie = NULL; - while ((ks_itl = avl_destroy_nodes(&stmf_state.stmf_itl_kstat_list, - &avl_dest_cookie)) != NULL) { - stmf_teardown_itl_kstats(ks_itl); - kmem_free(ks_itl, sizeof (ks_itl)); - } - avl_destroy(&stmf_state.stmf_itl_kstat_list); - kmem_free(stmf_trace_buf, stmf_trace_buf_size); mutex_destroy(&trace_buf_lock); mutex_destroy(&stmf_state.stmf_lock); @@ -1604,6 +1584,7 @@ stmf_get_stmf_state(stmf_state_desc_t *std) return (0); } + /* * handles registration message from pppt for a logical unit */ @@ -3209,7 +3190,6 @@ stmf_deregister_lu(stmf_lu_t *lu) kstat_delete(ilu->ilu_kstat_io); mutex_destroy(&ilu->ilu_kstat_lock); } - stmf_delete_itl_kstat_by_guid(ilu->ilu_ascii_hex_guid); cv_destroy(&ilu->ilu_offline_pending_cv); mutex_exit(&stmf_state.stmf_lock); return (STMF_SUCCESS); @@ -3388,7 +3368,6 @@ stmf_deregister_local_port(stmf_local_port_t *lport) kstat_delete(ilport->ilport_kstat_io); mutex_destroy(&ilport->ilport_kstat_lock); } - stmf_delete_itl_kstat_by_lport(ilport->ilport_kstat_tgt_name); mutex_exit(&stmf_state.stmf_lock); return (STMF_SUCCESS); } @@ -3717,320 +3696,6 @@ stmf_session_id_to_issptr(uint64_t session_id, int stay_locked) return (NULL); } -#define MAX_ALIAS 128 - -static int -stmf_itl_kstat_compare(const void *itl_kstat_1, const void *itl_kstat_2) -{ - const stmf_i_itl_kstat_t *kstat_nm1 = itl_kstat_1; - const stmf_i_itl_kstat_t *kstat_nm2 = itl_kstat_2; - int ret; - - ret = strcmp(kstat_nm1->iitl_kstat_nm, kstat_nm2->iitl_kstat_nm); - if (ret < 0) { - return (-1); - } else if (ret > 0) { - return (1); - } - return (0); -} - -static stmf_i_itl_kstat_t * -stmf_itl_kstat_lookup(char *kstat_nm) -{ - stmf_i_itl_kstat_t tmp; - stmf_i_itl_kstat_t *itl_kstat; - - ASSERT(mutex_owned(&stmf_state.stmf_lock)); - (void) strcpy(tmp.iitl_kstat_nm, kstat_nm); - itl_kstat = avl_find(&stmf_state.stmf_itl_kstat_list, &tmp, NULL); - return (itl_kstat); -} - -static void -stmf_delete_itl_kstat_by_lport(char *tgt) -{ - stmf_i_itl_kstat_t *ks_itl, *next; - - ASSERT(mutex_owned(&stmf_state.stmf_lock)); - ks_itl = avl_first(&stmf_state.stmf_itl_kstat_list); - for (; ks_itl != NULL; ks_itl = next) { - next = AVL_NEXT(&stmf_state.stmf_itl_kstat_list, ks_itl); - if (strcmp(ks_itl->iitl_kstat_lport, tgt) == 0) { - stmf_teardown_itl_kstats(ks_itl); - avl_remove(&stmf_state.stmf_itl_kstat_list, ks_itl); - kmem_free(ks_itl, sizeof (stmf_i_itl_kstat_t)); - } - } -} - -static void -stmf_delete_itl_kstat_by_guid(char *guid) -{ - stmf_i_itl_kstat_t *ks_itl, *next; - - ASSERT(mutex_owned(&stmf_state.stmf_lock)); - ks_itl = avl_first(&stmf_state.stmf_itl_kstat_list); - for (; ks_itl != NULL; ks_itl = next) { - next = AVL_NEXT(&stmf_state.stmf_itl_kstat_list, ks_itl); - if (strcmp(ks_itl->iitl_kstat_guid, guid) == 0) { - stmf_teardown_itl_kstats(ks_itl); - avl_remove(&stmf_state.stmf_itl_kstat_list, ks_itl); - kmem_free(ks_itl, sizeof (stmf_i_itl_kstat_t)); - } - } -} - -static stmf_i_itl_kstat_t * -stmf_itl_kstat_create(stmf_itl_data_t *itl, char *nm, - scsi_devid_desc_t *lport, scsi_devid_desc_t *lun) -{ - stmf_i_itl_kstat_t *ks_itl; - int i, len; - - ASSERT(mutex_owned(&stmf_state.stmf_lock)); - if ((ks_itl = stmf_itl_kstat_lookup(nm)) != NULL) - return (ks_itl); - - len = sizeof (stmf_i_itl_kstat_t); - ks_itl = kmem_zalloc(len, KM_NOSLEEP); - if (ks_itl == NULL) - return (NULL); - - (void) strcpy(ks_itl->iitl_kstat_nm, nm); - bcopy(lport->ident, ks_itl->iitl_kstat_lport, lport->ident_length); - ks_itl->iitl_kstat_lport[lport->ident_length] = '\0'; - for (i = 0; i < STMF_GUID_INPUT / 2; i++) { - (void) sprintf(&ks_itl->iitl_kstat_guid[i * 2], "%02x", - lun->ident[i]); - } - ks_itl->iitl_kstat_strbuf = itl->itl_kstat_strbuf; - ks_itl->iitl_kstat_strbuflen = itl->itl_kstat_strbuflen; - ks_itl->iitl_kstat_info = itl->itl_kstat_info; - ks_itl->iitl_kstat_taskq = itl->itl_kstat_taskq; - ks_itl->iitl_kstat_lu_xfer = itl->itl_kstat_lu_xfer; - ks_itl->iitl_kstat_lport_xfer = itl->itl_kstat_lport_xfer; - avl_add(&stmf_state.stmf_itl_kstat_list, ks_itl); - - return (ks_itl); -} - -stmf_status_t -stmf_setup_itl_kstats(stmf_itl_data_t *itl) -{ - char ks_itl_id[32]; - char ks_nm[KSTAT_STRLEN]; - char ks_itl_nm[KSTAT_STRLEN]; - stmf_kstat_itl_info_t *ks_itl; - stmf_scsi_session_t *ss; - stmf_i_scsi_session_t *iss; - stmf_i_local_port_t *ilport; - char *strbuf; - int id, len, i; - char *rport_alias; - char *lport_alias; - char *lu_alias; - stmf_i_itl_kstat_t *tmp_kstat; - - /* - * Allocate enough memory in the ITL to hold the relevant - * identifiers. - * rport and lport identifiers come from the stmf_scsi_session_t. - * ident might not be null terminated. - */ - ss = itl->itl_session->iss_ss; - iss = ss->ss_stmf_private; - ilport = ss->ss_lport->lport_stmf_private; - (void) snprintf(ks_itl_id, 32, "%d.%d.%d", - iss->iss_irport->irport_instance, ilport->ilport_instance, - itl->itl_lun); - - (void) snprintf(ks_itl_nm, KSTAT_STRLEN, "itl_%s", ks_itl_id); - /* - * let's verify this itl_kstat already exist - */ - if ((tmp_kstat = stmf_itl_kstat_lookup(ks_itl_nm)) != NULL) { - itl->itl_kstat_strbuf = tmp_kstat->iitl_kstat_strbuf; - itl->itl_kstat_strbuflen = tmp_kstat->iitl_kstat_strbuflen; - itl->itl_kstat_info = tmp_kstat->iitl_kstat_info; - itl->itl_kstat_taskq = tmp_kstat->iitl_kstat_taskq; - itl->itl_kstat_lu_xfer = tmp_kstat->iitl_kstat_lu_xfer; - itl->itl_kstat_lport_xfer = tmp_kstat->iitl_kstat_lport_xfer; - return (STMF_SUCCESS); - } - - /* New itl_kstat */ - rport_alias = (ss->ss_rport_alias == NULL) ? - "" : ss->ss_rport_alias; - lport_alias = (ss->ss_lport->lport_alias == NULL) ? - "" : ss->ss_lport->lport_alias; - lu_alias = (itl->itl_ilu->ilu_lu->lu_alias == NULL) ? - "" : itl->itl_ilu->ilu_lu->lu_alias; - - itl->itl_kstat_strbuflen = (ss->ss_rport_id->ident_length + 1) + - (strnlen(rport_alias, MAX_ALIAS) + 1) + - (ss->ss_lport->lport_id->ident_length + 1) + - (strnlen(lport_alias, MAX_ALIAS) + 1) + - (STMF_GUID_INPUT + 1) + - (strnlen(lu_alias, MAX_ALIAS) + 1) + - MAX_PROTO_STR_LEN; - itl->itl_kstat_strbuf = kmem_zalloc(itl->itl_kstat_strbuflen, - KM_NOSLEEP); - if (itl->itl_kstat_strbuf == NULL) { - return (STMF_ALLOC_FAILURE); - } - - ks_itl = (stmf_kstat_itl_info_t *)kmem_zalloc(sizeof (*ks_itl), - KM_NOSLEEP); - if (ks_itl == NULL) { - kmem_free(itl->itl_kstat_strbuf, itl->itl_kstat_strbuflen); - return (STMF_ALLOC_FAILURE); - } - - if ((itl->itl_kstat_info = kstat_create(STMF_MODULE_NAME, - 0, ks_itl_nm, "misc", KSTAT_TYPE_NAMED, - sizeof (stmf_kstat_itl_info_t) / sizeof (kstat_named_t), - KSTAT_FLAG_VIRTUAL)) == NULL) { - goto itl_kstat_cleanup; - } - - itl->itl_kstat_info->ks_data_size += itl->itl_kstat_strbuflen; - itl->itl_kstat_info->ks_data = ks_itl; - - kstat_named_init(&ks_itl->i_rport_name, "rport-name", - KSTAT_DATA_STRING); - kstat_named_init(&ks_itl->i_rport_alias, "rport-alias", - KSTAT_DATA_STRING); - kstat_named_init(&ks_itl->i_lport_name, "lport-name", - KSTAT_DATA_STRING); - kstat_named_init(&ks_itl->i_lport_alias, "lport-alias", - KSTAT_DATA_STRING); - kstat_named_init(&ks_itl->i_protocol, "protocol", - KSTAT_DATA_STRING); - kstat_named_init(&ks_itl->i_lu_guid, "lu-guid", - KSTAT_DATA_STRING); - kstat_named_init(&ks_itl->i_lu_alias, "lu-alias", - KSTAT_DATA_STRING); - kstat_named_init(&ks_itl->i_lu_number, "lu-number", - KSTAT_DATA_UINT64); - kstat_named_init(&ks_itl->i_task_waitq_elapsed, "task-waitq-elapsed", - KSTAT_DATA_UINT64); - kstat_named_init(&ks_itl->i_task_read_elapsed, "task-read-elapsed", - KSTAT_DATA_UINT64); - kstat_named_init(&ks_itl->i_task_write_elapsed, "task-write-elapsed", - KSTAT_DATA_UINT64); - kstat_named_init(&ks_itl->i_lu_read_elapsed, "lu-read-elapsed", - KSTAT_DATA_UINT64); - kstat_named_init(&ks_itl->i_lu_write_elapsed, "lu-write-elapsed", - KSTAT_DATA_UINT64); - kstat_named_init(&ks_itl->i_lport_read_elapsed, "lport-read-elapsed", - KSTAT_DATA_UINT64); - kstat_named_init(&ks_itl->i_lport_write_elapsed, "lport-write-elapsed", - KSTAT_DATA_UINT64); - - strbuf = itl->itl_kstat_strbuf; - - /* Rport */ - len = ss->ss_rport_id->ident_length; - bcopy(ss->ss_rport_id->ident, strbuf, len); - strbuf += len; - *strbuf = '\0'; - kstat_named_setstr(&ks_itl->i_rport_name, strbuf - len); - strbuf++; - - len = strnlen(rport_alias, MAX_ALIAS); - (void) strncpy(strbuf, rport_alias, len + 1); - kstat_named_setstr(&ks_itl->i_rport_alias, strbuf); - strbuf += len + 1; - - /* Lport */ - len = ss->ss_lport->lport_id->ident_length; - bcopy(ss->ss_lport->lport_id->ident, strbuf, len); - strbuf += len; - *strbuf = '\0'; - kstat_named_setstr(&ks_itl->i_lport_name, strbuf - len); - strbuf++; - - len = strnlen(lport_alias, MAX_ALIAS); - (void) strncpy(strbuf, lport_alias, len + 1); - kstat_named_setstr(&ks_itl->i_lport_alias, strbuf); - strbuf += len + 1; - - id = (ss->ss_lport->lport_id->protocol_id > PROTOCOL_ANY) ? - PROTOCOL_ANY : ss->ss_lport->lport_id->protocol_id; - kstat_named_setstr(&ks_itl->i_protocol, protocol_ident[id]); - - /* LU */ - for (i = 0; i < STMF_GUID_INPUT / 2; i++) { - (void) sprintf(&strbuf[i * 2], "%02x", - itl->itl_ilu->ilu_lu->lu_id->ident[i]); - } - kstat_named_setstr(&ks_itl->i_lu_guid, strbuf); - strbuf += STMF_GUID_INPUT + 1; - - len = strnlen(lu_alias, MAX_ALIAS); - (void) strncpy(strbuf, lu_alias, len + 1); - kstat_named_setstr(&ks_itl->i_lu_alias, strbuf); - strbuf += len + 1; - - ks_itl->i_lu_number.value.ui64 = itl->itl_lun; - - /* Now create the I/O kstats */ - (void) snprintf(ks_nm, KSTAT_STRLEN, "itl_tasks_%s", ks_itl_id); - if ((itl->itl_kstat_taskq = kstat_create(STMF_MODULE_NAME, 0, - ks_nm, "io", KSTAT_TYPE_IO, 1, 0)) == NULL) { - goto itl_kstat_cleanup; - } - - (void) snprintf(ks_nm, KSTAT_STRLEN, "itl_lu_%s", ks_itl_id); - if ((itl->itl_kstat_lu_xfer = kstat_create(STMF_MODULE_NAME, 0, - ks_nm, "io", KSTAT_TYPE_IO, 1, 0)) == NULL) { - goto itl_kstat_cleanup; - } - - (void) snprintf(ks_nm, KSTAT_STRLEN, "itl_lport_%s", ks_itl_id); - if ((itl->itl_kstat_lport_xfer = kstat_create(STMF_MODULE_NAME, 0, - ks_nm, "io", KSTAT_TYPE_IO, 1, 0)) == NULL) { - goto itl_kstat_cleanup; - } - - /* Install all the kstats */ - kstat_install(itl->itl_kstat_info); - kstat_install(itl->itl_kstat_taskq); - kstat_install(itl->itl_kstat_lu_xfer); - kstat_install(itl->itl_kstat_lport_xfer); - - /* Add new itl_kstat to stmf_itl_kstat_list */ - if (stmf_itl_kstat_create(itl, ks_itl_nm, ss->ss_lport->lport_id, - itl->itl_ilu->ilu_lu->lu_id) != NULL) - return (STMF_SUCCESS); - -itl_kstat_cleanup: - if (itl->itl_kstat_taskq) - kstat_delete(itl->itl_kstat_taskq); - if (itl->itl_kstat_lu_xfer) - kstat_delete(itl->itl_kstat_lu_xfer); - if (itl->itl_kstat_lport_xfer) - kstat_delete(itl->itl_kstat_lport_xfer); - if (itl->itl_kstat_info) - kstat_delete(itl->itl_kstat_info); - kmem_free(ks_itl, sizeof (*ks_itl)); - kmem_free(itl->itl_kstat_strbuf, itl->itl_kstat_strbuflen); - cmn_err(CE_WARN, "STMF: kstat_create itl failed"); - return (STMF_ALLOC_FAILURE); -} - -static void -stmf_teardown_itl_kstats(stmf_i_itl_kstat_t *ks) -{ - kstat_delete(ks->iitl_kstat_lport_xfer); - kstat_delete(ks->iitl_kstat_lu_xfer); - kstat_delete(ks->iitl_kstat_taskq); - kmem_free(ks->iitl_kstat_info->ks_data, sizeof (stmf_kstat_itl_info_t)); - kstat_delete(ks->iitl_kstat_info); - kmem_free(ks->iitl_kstat_strbuf, ks->iitl_kstat_strbuflen); -} - void stmf_release_itl_handle(stmf_lu_t *lu, stmf_itl_data_t *itl) { @@ -4074,9 +3739,6 @@ stmf_register_itl_handle(stmf_lu_t *lu, uint8_t *lun, iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private; } - /* - * Acquire stmf_lock for stmf_itl_kstat_lookup. - */ mutex_enter(&stmf_state.stmf_lock); rw_enter(iss->iss_lockp, RW_WRITER); n = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8)); @@ -4106,13 +3768,6 @@ stmf_register_itl_handle(stmf_lu_t *lu, uint8_t *lun, itl->itl_lun = n; itl->itl_handle = itl_handle; - if (stmf_setup_itl_kstats(itl) != STMF_SUCCESS) { - kmem_free(itl, sizeof (*itl)); - rw_exit(iss->iss_lockp); - mutex_exit(&stmf_state.stmf_lock); - return (STMF_ALLOC_FAILURE); - } - mutex_enter(&ilu->ilu_task_lock); itl->itl_next = ilu->ilu_itl_list; ilu->ilu_itl_list = itl; @@ -4142,10 +3797,6 @@ stmf_do_itl_dereg(stmf_lu_t *lu, stmf_itl_data_t *itl, uint8_t hdlrm_reason) if (atomic_add_32_nv(&itl->itl_counter, -1)) return; - drv_usecwait(10); - if (itl->itl_counter) - return; - stmf_release_itl_handle(lu, itl); } @@ -4216,66 +3867,6 @@ dai_scan_done: } stmf_status_t -stmf_deregister_itl_handle(stmf_lu_t *lu, uint8_t *lun, - stmf_scsi_session_t *ss, uint64_t session_id, void *itl_handle) -{ - stmf_i_scsi_session_t *iss; - stmf_itl_data_t *itl; - stmf_lun_map_ent_t *ent; - stmf_lun_map_t *lm; - int i; - uint16_t n; - - if (ss == NULL) { - if (session_id == STMF_SESSION_ID_NONE) - return (STMF_INVALID_ARG); - iss = stmf_session_id_to_issptr(session_id, 1); - if (iss == NULL) - return (STMF_NOT_FOUND); - } else { - iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private; - rw_enter(iss->iss_lockp, RW_WRITER); - } - lm = iss->iss_sm; - if (lm == NULL) { - rw_exit(iss->iss_lockp); - return (STMF_NOT_FOUND); - } - - if (lun) { - n = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8)); - ent = (stmf_lun_map_ent_t *) - stmf_get_ent_from_map(iss->iss_sm, n); - } else { - if (itl_handle == NULL) { - rw_exit(iss->iss_lockp); - return (STMF_INVALID_ARG); - } - ent = NULL; - for (i = 0; i < lm->lm_nentries; i++) { - if (lm->lm_plus[i] == NULL) - continue; - ent = (stmf_lun_map_ent_t *)lm->lm_plus[i]; - if (ent->ent_itl_datap && - (ent->ent_itl_datap->itl_handle == itl_handle)) { - break; - } - } - } - if ((ent == NULL) || (ent->ent_lu != lu) || - (ent->ent_itl_datap == NULL)) { - rw_exit(iss->iss_lockp); - return (STMF_NOT_FOUND); - } - itl = ent->ent_itl_datap; - ent->ent_itl_datap = NULL; - rw_exit(iss->iss_lockp); - stmf_do_itl_dereg(lu, itl, STMF_ITL_REASON_DEREG_REQUEST); - - return (STMF_SUCCESS); -} - -stmf_status_t stmf_get_itl_handle(stmf_lu_t *lu, uint8_t *lun, stmf_scsi_session_t *ss, uint64_t session_id, void **itl_handle_retp) { @@ -7562,11 +7153,12 @@ stmf_itl_task_start(stmf_i_scsi_task_t *itask) if (itl == NULL || task->task_lu == dlun0) return; ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private; - mutex_enter(ilu->ilu_kstat_io->ks_lock); itask->itask_start_timestamp = gethrtime(); - kstat_waitq_enter(KSTAT_IO_PTR(itl->itl_kstat_taskq)); - stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_enter); - mutex_exit(ilu->ilu_kstat_io->ks_lock); + if (ilu->ilu_kstat_io != NULL) { + mutex_enter(ilu->ilu_kstat_io->ks_lock); + stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_enter); + mutex_exit(ilu->ilu_kstat_io->ks_lock); + } stmf_update_kstat_lport_q(itask->itask_task, kstat_waitq_enter); } @@ -7581,10 +7173,11 @@ stmf_itl_lu_new_task(stmf_i_scsi_task_t *itask) if (itl == NULL || task->task_lu == dlun0) return; ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private; - mutex_enter(ilu->ilu_kstat_io->ks_lock); - kstat_waitq_to_runq(KSTAT_IO_PTR(itl->itl_kstat_taskq)); - stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_to_runq); - mutex_exit(ilu->ilu_kstat_io->ks_lock); + if (ilu->ilu_kstat_io != NULL) { + mutex_enter(ilu->ilu_kstat_io->ks_lock); + stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_to_runq); + mutex_exit(ilu->ilu_kstat_io->ks_lock); + } stmf_update_kstat_lport_q(itask->itask_task, kstat_waitq_to_runq); } @@ -7594,108 +7187,30 @@ stmf_itl_task_done(stmf_i_scsi_task_t *itask) { stmf_itl_data_t *itl = itask->itask_itl_datap; scsi_task_t *task = itask->itask_task; - kstat_io_t *kip; - hrtime_t elapsed_time; - stmf_kstat_itl_info_t *itli; stmf_i_lu_t *ilu; + itask->itask_done_timestamp = gethrtime(); + if (itl == NULL || task->task_lu == dlun0) return; ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private; - mutex_enter(ilu->ilu_kstat_io->ks_lock); - itli = (stmf_kstat_itl_info_t *)KSTAT_NAMED_PTR(itl->itl_kstat_info); - kip = KSTAT_IO_PTR(itl->itl_kstat_taskq); - - itli->i_task_waitq_elapsed.value.ui64 += itask->itask_waitq_time; - - itask->itask_done_timestamp = gethrtime(); - elapsed_time = - itask->itask_done_timestamp - itask->itask_start_timestamp; - - if (task->task_flags & TF_READ_DATA) { - kip->reads++; - kip->nread += itask->itask_read_xfer; - itli->i_task_read_elapsed.value.ui64 += elapsed_time; - itli->i_lu_read_elapsed.value.ui64 += - itask->itask_lu_read_time; - itli->i_lport_read_elapsed.value.ui64 += - itask->itask_lport_read_time; - } + if (ilu->ilu_kstat_io == NULL) + return; - if (task->task_flags & TF_WRITE_DATA) { - kip->writes++; - kip->nwritten += itask->itask_write_xfer; - itli->i_task_write_elapsed.value.ui64 += elapsed_time; - itli->i_lu_write_elapsed.value.ui64 += - itask->itask_lu_write_time; - itli->i_lport_write_elapsed.value.ui64 += - itask->itask_lport_write_time; - } + mutex_enter(ilu->ilu_kstat_io->ks_lock); if (itask->itask_flags & ITASK_KSTAT_IN_RUNQ) { - kstat_runq_exit(kip); stmf_update_kstat_lu_q(task, kstat_runq_exit); mutex_exit(ilu->ilu_kstat_io->ks_lock); stmf_update_kstat_lport_q(task, kstat_runq_exit); } else { - kstat_waitq_exit(kip); stmf_update_kstat_lu_q(task, kstat_waitq_exit); mutex_exit(ilu->ilu_kstat_io->ks_lock); stmf_update_kstat_lport_q(task, kstat_waitq_exit); } } -void -stmf_lu_xfer_start(scsi_task_t *task) -{ - stmf_i_scsi_task_t *itask = task->task_stmf_private; - stmf_itl_data_t *itl = itask->itask_itl_datap; - stmf_i_lu_t *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private; - kstat_io_t *kip; - - if (itl == NULL || task->task_lu == dlun0) - return; - - kip = KSTAT_IO_PTR(itl->itl_kstat_lu_xfer); - mutex_enter(ilu->ilu_kstat_io->ks_lock); - kstat_runq_enter(kip); - mutex_exit(ilu->ilu_kstat_io->ks_lock); -} - -void -stmf_lu_xfer_done(scsi_task_t *task, boolean_t read, uint64_t xfer_bytes, - hrtime_t elapsed_time) -{ - stmf_i_scsi_task_t *itask = task->task_stmf_private; - stmf_itl_data_t *itl = itask->itask_itl_datap; - stmf_i_lu_t *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private; - kstat_io_t *kip; - - if (itl == NULL || task->task_lu == dlun0) - return; - - if (read) { - atomic_add_64((uint64_t *)&itask->itask_lu_read_time, - elapsed_time); - } else { - atomic_add_64((uint64_t *)&itask->itask_lu_write_time, - elapsed_time); - } - - kip = KSTAT_IO_PTR(itl->itl_kstat_lu_xfer); - mutex_enter(ilu->ilu_kstat_io->ks_lock); - kstat_runq_exit(kip); - if (read) { - kip->reads++; - kip->nread += xfer_bytes; - } else { - kip->writes++; - kip->nwritten += xfer_bytes; - } - mutex_exit(ilu->ilu_kstat_io->ks_lock); -} - static void stmf_lport_xfer_start(stmf_i_scsi_task_t *itask, stmf_data_buf_t *dbuf) { @@ -7714,17 +7229,12 @@ static void stmf_lport_xfer_done(stmf_i_scsi_task_t *itask, stmf_data_buf_t *dbuf) { stmf_itl_data_t *itl = itask->itask_itl_datap; - scsi_task_t *task; - stmf_i_local_port_t *ilp; - kstat_io_t *kip; hrtime_t elapsed_time; uint64_t xfer_size; if (itl == NULL) return; - task = (scsi_task_t *)itask->itask_task; - ilp = (stmf_i_local_port_t *)task->task_lport->lport_stmf_private; xfer_size = (dbuf->db_xfer_status == STMF_SUCCESS) ? dbuf->db_data_size : 0; @@ -7744,17 +7254,6 @@ stmf_lport_xfer_done(stmf_i_scsi_task_t *itask, stmf_data_buf_t *dbuf) DTRACE_PROBE3(scsi__xfer__end, scsi_task_t *, itask->itask_task, stmf_data_buf_t *, dbuf, hrtime_t, elapsed_time); - kip = KSTAT_IO_PTR(itl->itl_kstat_lport_xfer); - mutex_enter(ilp->ilport_kstat_io->ks_lock); - if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) { - kip->reads++; - kip->nread += xfer_size; - } else { - kip->writes++; - kip->nwritten += xfer_size; - } - mutex_exit(ilp->ilport_kstat_io->ks_lock); - dbuf->db_xfer_start_timestamp = 0; } @@ -7864,6 +7363,7 @@ stmf_svc(void *arg) req->svc_cmd); } + kmem_free(req, req->svc_req_alloc_size); mutex_enter(&stmf_state.stmf_lock); } diff --git a/usr/src/uts/common/io/comstar/stmf/stmf_impl.h b/usr/src/uts/common/io/comstar/stmf/stmf_impl.h index e5046ec64d..d477224863 100644 --- a/usr/src/uts/common/io/comstar/stmf/stmf_impl.h +++ b/usr/src/uts/common/io/comstar/stmf/stmf_impl.h @@ -166,19 +166,6 @@ typedef struct stmf_i_remote_port { avl_node_t irport_ln; } stmf_i_remote_port_t; -typedef struct stmf_i_itl_kstat { - char iitl_kstat_nm[KSTAT_STRLEN]; - char iitl_kstat_lport[STMF_TGT_NAME_LEN]; - char iitl_kstat_guid[STMF_GUID_INPUT + 1]; - char *iitl_kstat_strbuf; - int iitl_kstat_strbuflen; - kstat_t *iitl_kstat_info; - kstat_t *iitl_kstat_taskq; - kstat_t *iitl_kstat_lu_xfer; - kstat_t *iitl_kstat_lport_xfer; - avl_node_t iitl_kstat_ln; -} stmf_i_itl_kstat_t; - /* * ilport flags */ @@ -327,12 +314,6 @@ typedef struct stmf_itl_data { uint8_t itl_flags; uint8_t itl_hdlrm_reason; uint16_t itl_lun; - char *itl_kstat_strbuf; - int itl_kstat_strbuflen; - kstat_t *itl_kstat_info; - kstat_t *itl_kstat_taskq; - kstat_t *itl_kstat_lu_xfer; - kstat_t *itl_kstat_lport_xfer; void *itl_handle; struct stmf_i_lu *itl_ilu; struct stmf_i_scsi_session *itl_session; diff --git a/usr/src/uts/common/io/comstar/stmf/stmf_state.h b/usr/src/uts/common/io/comstar/stmf/stmf_state.h index e86a8b397c..2d7a81f93d 100644 --- a/usr/src/uts/common/io/comstar/stmf/stmf_state.h +++ b/usr/src/uts/common/io/comstar/stmf/stmf_state.h @@ -23,6 +23,7 @@ */ /* * Copyright 2011, Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #ifndef _STMF_STATE_H #define _STMF_STATE_H @@ -42,7 +43,6 @@ typedef struct stmf_state { id_space_t *stmf_ilport_inst_space; avl_tree_t stmf_irportlist; id_space_t *stmf_irport_inst_space; - avl_tree_t stmf_itl_kstat_list; int stmf_nlps; int stmf_npps; int stmf_nlus; diff --git a/usr/src/uts/common/sys/lpif.h b/usr/src/uts/common/sys/lpif.h index 55ada12ee9..7b04a22f7b 100644 --- a/usr/src/uts/common/sys/lpif.h +++ b/usr/src/uts/common/sys/lpif.h @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #ifndef _LPIF_H #define _LPIF_H @@ -131,9 +132,6 @@ stmf_status_t stmf_deregister_lu(stmf_lu_t *lup); stmf_status_t stmf_set_lu_access(stmf_lu_t *lup, uint8_t access_state); stmf_status_t stmf_proxy_scsi_cmd(scsi_task_t *, stmf_data_buf_t *dbuf); int stmf_is_standby_port(scsi_task_t *); -void stmf_lu_xfer_start(struct scsi_task *task); -void stmf_lu_xfer_done(struct scsi_task *task, boolean_t read, - uint64_t xfer_bytes, hrtime_t elapsed_time); #ifdef __cplusplus } diff --git a/usr/src/uts/common/sys/stmf.h b/usr/src/uts/common/sys/stmf.h index 3a3ead0421..ad95cd0b15 100644 --- a/usr/src/uts/common/sys/stmf.h +++ b/usr/src/uts/common/sys/stmf.h @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #ifndef _STMF_H #define _STMF_H @@ -384,8 +385,6 @@ stmf_status_t stmf_task_poll_lport(scsi_task_t *task, uint32_t timeout); stmf_status_t stmf_ctl(int cmd, void *obj, void *arg); stmf_status_t stmf_register_itl_handle(struct stmf_lu *lu, uint8_t *lun, struct stmf_scsi_session *ss, uint64_t session_id, void *itl_handle); -stmf_status_t stmf_deregister_itl_handle(struct stmf_lu *lu, uint8_t *lun, - struct stmf_scsi_session *ss, uint64_t session_id, void *itl_handle); stmf_status_t stmf_deregister_all_lu_itl_handles(struct stmf_lu *lu); stmf_status_t stmf_get_itl_handle(struct stmf_lu *lu, uint8_t *lun, struct stmf_scsi_session *ss, uint64_t session_id, void **itl_handle_retp); |