Print this page
NEX-9981 Deadman timer panic from idm_refcnt_wait_ref thread while offlining iSCSI targets
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
NEX-6018 Return of the walking dead idm_refcnt_wait_ref comstar threads
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-3746 Panic seen if iSCSI Initiator sends a SCSI Response packet to target
NEX-3777 COMSTAR iscsi/io test can panic the target running 5.0
NEX-3785 This is on 5.0 release and iSCSI target can panic while running iSCSI mpxio disable test
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
NEX-2359 iSCSI target connection handling is missing refcount audit information
re #10417 rb2398 incorrect handling in iscsit of duplicate PDUs with cmdsn > expsn
re #9966: sysretq doesn't properly handle non-canonical addresses
re #9966: sysretq doesn't properly handle non-canonical addresses
--HG--
branch : stable-4.0
re #9822 - libiscsi test panics COMSTAR
--HG--
branch : stable-4.0
re #9822 - libiscsi test panics COMSTAR
*** 18,29 ****
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
! *
! * Copyright 2014, 2015 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2017, Joyent, Inc. All rights reserved.
*/
#include <sys/cpuvar.h>
#include <sys/types.h>
--- 18,28 ----
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright 2017 Nexenta Systems, Inc.
* Copyright (c) 2017, Joyent, Inc. All rights reserved.
*/
#include <sys/cpuvar.h>
#include <sys/types.h>
*** 562,571 ****
--- 561,571 ----
cleanup:
if (cfg)
it_config_free_cmn(cfg);
if (cfg_pnvlist)
kmem_free(cfg_pnvlist, setcfg.set_cfg_pnvlist_len);
+ if (cfg_nvlist)
nvlist_free(cfg_nvlist);
/*
* Now that the reconfig is complete set our state back to
* enabled.
*** 990,1000 ****
*
* STMF specification is wrong... says to return
* STMF_ABORTED, the code actually looks for
* STMF_ABORT_SUCCESS.
*/
! stmf_task_lport_aborted(itask->it_stmf_task,
STMF_ABORT_SUCCESS, STMF_IOF_LPORT_DONE);
return;
} else {
mutex_exit(&itask->it_mutex);
/*
--- 990,1000 ----
*
* STMF specification is wrong... says to return
* STMF_ABORTED, the code actually looks for
* STMF_ABORT_SUCCESS.
*/
! stmf_task_lport_aborted_unlocked(itask->it_stmf_task,
STMF_ABORT_SUCCESS, STMF_IOF_LPORT_DONE);
return;
} else {
mutex_exit(&itask->it_mutex);
/*
*** 1222,1231 ****
--- 1222,1232 ----
ict->ict_keepalive_ttt = IDM_TASKIDS_MAX; /* Avoid IDM TT range */
ic->ic_handle = ict;
mutex_init(&ict->ict_mutex, NULL, MUTEX_DRIVER, NULL);
mutex_init(&ict->ict_statsn_mutex, NULL, MUTEX_DRIVER, NULL);
idm_refcnt_init(&ict->ict_refcnt, ict);
+ idm_refcnt_init(&ict->ict_dispatch_refcnt, ict);
/*
* Initialize login state machine
*/
if (iscsit_login_sm_init(ict) != IDM_STATUS_SUCCESS) {
*** 1367,1376 ****
--- 1368,1380 ----
}
/*
* Make sure there aren't any PDU's transitioning from the receive
* handler to the dispatch taskq.
*/
+ if (idm_refcnt_is_held(&ict->ict_dispatch_refcnt) < 0) {
+ cmn_err(CE_WARN, "Possible hang in iscsit_conn_lost");
+ }
idm_refcnt_wait_ref(&ict->ict_dispatch_refcnt);
return (IDM_STATUS_SUCCESS);
}
*** 1383,1399 ****
ict->ict_destroyed = B_TRUE;
mutex_exit(&ict->ict_mutex);
/* Generate session state machine event */
if (ict->ict_sess != NULL) {
- /*
- * Session state machine will call iscsit_conn_destroy_done()
- * when it has removed references to this connection.
- */
iscsit_sess_sm_event(ict->ict_sess, SE_CONN_FAIL, ict);
}
idm_refcnt_wait_ref(&ict->ict_refcnt);
/*
* The session state machine does not need to post
* events to IDM any longer, so it is safe to set
* the idm connection reference to NULL
--- 1387,1400 ----
ict->ict_destroyed = B_TRUE;
mutex_exit(&ict->ict_mutex);
/* Generate session state machine event */
if (ict->ict_sess != NULL) {
iscsit_sess_sm_event(ict->ict_sess, SE_CONN_FAIL, ict);
}
+ idm_refcnt_wait_ref(&ict->ict_dispatch_refcnt);
idm_refcnt_wait_ref(&ict->ict_refcnt);
/*
* The session state machine does not need to post
* events to IDM any longer, so it is safe to set
* the idm connection reference to NULL
*** 1405,1414 ****
--- 1406,1416 ----
/* Clean up any text command remnants */
iscsit_text_cmd_fini(ict);
mutex_destroy(&ict->ict_mutex);
+ idm_refcnt_destroy(&ict->ict_dispatch_refcnt);
idm_refcnt_destroy(&ict->ict_refcnt);
kmem_free(ict, sizeof (*ict));
iscsit_global_rele();
*** 1886,1910 ****
mutex_exit(&iscsit_task->it_mutex);
/*
* Call IDM to abort the task. Due to a variety of
* circumstances the task may already be in the process of
* aborting.
- * We'll let IDM worry about rationalizing all that except
- * for one particular instance. If the state of the task
- * is TASK_COMPLETE, we need to indicate to the framework
- * that we are in fact done. This typically happens with
- * framework-initiated task management type requests
- * (e.g. abort task).
*/
! if (idt->idt_state == TASK_COMPLETE) {
! idm_refcnt_wait_ref(&idt->idt_refcnt);
! return (STMF_ABORT_SUCCESS);
! } else {
! idm_task_abort(idt->idt_ic, idt, AT_TASK_MGMT_ABORT);
! return (STMF_SUCCESS);
}
- }
/*NOTREACHED*/
}
/*ARGSUSED*/
--- 1888,1900 ----
mutex_exit(&iscsit_task->it_mutex);
/*
* Call IDM to abort the task. Due to a variety of
* circumstances the task may already be in the process of
* aborting.
*/
! return (idm_task_abort(idt->idt_ic, idt, AT_TASK_MGMT_ABORT));
}
/*NOTREACHED*/
}
/*ARGSUSED*/
*** 1960,1969 ****
--- 1950,1974 ----
iscsit_post_scsi_cmd(ic, rx_pdu);
}
iscsit_process_pdu_in_queue(ict->ict_sess);
}
+ static int
+ iscsit_validate_idm_pdu(idm_pdu_t *rx_pdu)
+ {
+ iscsi_scsi_cmd_hdr_t *iscsi_scsi =
+ (iscsi_scsi_cmd_hdr_t *)rx_pdu->isp_hdr;
+
+ if ((iscsi_scsi->scb[0] == SCMD_READ) ||
+ (iscsi_scsi->scb[0] == SCMD_READ_G1) ||
+ (iscsi_scsi->scb[0] == SCMD_READ_G4)) {
+ if (iscsi_scsi->flags & ISCSI_FLAG_CMD_WRITE)
+ return (IDM_STATUS_FAIL);
+ }
+ return (IDM_STATUS_SUCCESS);
+ }
+
/*
* ISCSI protocol
*/
void
*** 1977,1987 ****
--- 1982,2001 ----
(iscsi_scsi_cmd_hdr_t *)rx_pdu->isp_hdr;
iscsi_addl_hdr_t *ahs_hdr;
uint16_t addl_cdb_len = 0;
ict = ic->ic_handle;
+ if (iscsit_validate_idm_pdu(rx_pdu) != IDM_STATUS_SUCCESS) {
+ /* Finish processing request */
+ iscsit_set_cmdsn(ict, rx_pdu);
+ iscsit_send_direct_scsi_resp(ict, rx_pdu,
+ ISCSI_STATUS_CMD_COMPLETED, STATUS_CHECK);
+ idm_pdu_complete(rx_pdu, IDM_STATUS_PROTOCOL_ERROR);
+ return;
+ }
+
itask = iscsit_task_alloc(ict);
if (itask == NULL) {
/* Finish processing request */
iscsit_set_cmdsn(ict, rx_pdu);