mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-17 18:51:27 +00:00
Fixed a bug in the command abortion code. E.g. the following kernel message could be generated when unloading ib_srpt while I/O was ongoing:
------------[ cut here ]------------ WARNING: at /home/bart/software/scst/srpt/src/ib_srpt.c:1063 srpt_reset_ioctx+0x15b/0x170 [ib_srpt]() Hardware name: P5Q DELUXE Modules linked in: [ ... ] Pid: 20709, comm: disk011_4 Tainted: G W 2.6.34-scst #1 Call Trace: [<ffffffff81048dbb>] warn_slowpath_common+0x7b/0xc0 [<ffffffff81048e14>] warn_slowpath_null+0x14/0x20 [<ffffffffa050772b>] srpt_reset_ioctx+0x15b/0x170 [ib_srpt] [<ffffffff81048dcf>] ? warn_slowpath_common+0x8f/0xc0 [<ffffffffa0507773>] srpt_on_free_cmd+0x33/0x60 [ib_srpt] [<ffffffffa0480a0b>] scst_free_cmd+0xab/0x460 [scst] [<ffffffffa046dd38>] scst_finish_cmd+0x178/0x300 [scst] [<ffffffffa0470ed4>] scst_process_active_cmd+0x134/0x640 [scst] [<ffffffffa0471dac>] scst_process_redirect_cmd+0x2bc/0x3f0 [scst] [<ffffffffa047247a>] scst_tgt_cmd_done+0x6a/0x100 [scst] [<ffffffffa0508dec>] srpt_xmit_response+0x11c/0x210 [ib_srpt] [<ffffffffa046b53c>] scst_xmit_response+0x13c/0x560 [scst] [<ffffffffa0470efb>] scst_process_active_cmd+0x15b/0x640 [scst] [<ffffffffa047149d>] scst_do_job_active+0xbd/0x180 [scst] [<ffffffffa0471806>] scst_cmd_thread+0x1c6/0x4b0 [scst] [<ffffffff8103e960>] ? default_wake_function+0x0/0x20 [<ffffffffa0471640>] ? scst_cmd_thread+0x0/0x4b0 [scst] [<ffffffff810683e6>] kthread+0x96/0xa0 [<ffffffff81003d94>] kernel_thread_helper+0x4/0x10 [<ffffffff8103dcb1>] ? finish_task_switch+0x51/0xb0 [<ffffffff81344dac>] ? _raw_spin_unlock_irq+0x1c/0x40 [<ffffffff813458ad>] ? restore_args+0x0/0x30 [<ffffffff81068350>] ? kthread+0x0/0xa0 [<ffffffff81003d90>] ? kernel_thread_helper+0x0/0x10 ---[ end trace 84b1e00ea2ac6651 ]--- git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1812 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1107,21 +1107,21 @@ static void srpt_abort_scst_cmd(struct srpt_ioctx *ioctx,
|
||||
BUG_ON(!ioctx);
|
||||
|
||||
/*
|
||||
* Change the state of the command into SRPT_STATE_DONE, except when
|
||||
* the current state is SRPT_STATE_NEW or SRPT_STATE_NEED_DATA. For
|
||||
* these last two states, change the state into SRPT_STATE_DATA_IN.
|
||||
* Doing so ensures that srpt_xmit_response() will call this function
|
||||
* a second time and will invoke scst_tgt_cmd_done(). Unfortunately it
|
||||
* is not allowed to invoke scst_tgt_cmd_done() for commands that have
|
||||
* one of the states SRPT_STATE_NEW or SRPT_STATE_NEED_DATA
|
||||
* If the command is in a state where the SCST core is waiting for the
|
||||
* ib_srpt driver, change the state to the next state. Changing the
|
||||
* state of the command from SRPT_NEED_DATA to SRPT_STATE_DATA_IN
|
||||
* ensures that srpt_xmit_response() will call this function a second
|
||||
* time.
|
||||
*/
|
||||
state = srpt_test_and_set_cmd_state(ioctx, SRPT_STATE_NEW,
|
||||
state = srpt_test_and_set_cmd_state(ioctx, SRPT_STATE_NEED_DATA,
|
||||
SRPT_STATE_DATA_IN);
|
||||
if (state != SRPT_STATE_NEW) {
|
||||
state = srpt_test_and_set_cmd_state(ioctx, SRPT_STATE_NEED_DATA,
|
||||
SRPT_STATE_DATA_IN);
|
||||
if (state != SRPT_STATE_NEED_DATA)
|
||||
state = srpt_set_cmd_state(ioctx, SRPT_STATE_DONE);
|
||||
if (state != SRPT_STATE_NEED_DATA) {
|
||||
state = srpt_test_and_set_cmd_state(ioctx,
|
||||
SRPT_STATE_CMD_RSP_SENT, SRPT_STATE_DONE);
|
||||
if (state != SRPT_STATE_CMD_RSP_SENT)
|
||||
state = srpt_test_and_set_cmd_state(ioctx,
|
||||
SRPT_STATE_MGMT_RSP_SENT,
|
||||
SRPT_STATE_DONE);
|
||||
}
|
||||
if (state == SRPT_STATE_DONE)
|
||||
goto out;
|
||||
@@ -1140,19 +1140,26 @@ static void srpt_abort_scst_cmd(struct srpt_ioctx *ioctx,
|
||||
|
||||
switch (state) {
|
||||
case SRPT_STATE_NEW:
|
||||
scst_set_delivery_status(scmnd, SCST_CMD_DELIVERY_ABORTED);
|
||||
break;
|
||||
case SRPT_STATE_NEED_DATA:
|
||||
WARN_ON("This code should never be reached.");
|
||||
scst_rx_data(scmnd, SCST_RX_STATUS_ERROR, context);
|
||||
break;
|
||||
case SRPT_STATE_NEED_DATA:
|
||||
/* RDMA read error or RDMA read timeout. */
|
||||
case SRPT_STATE_DATA_IN:
|
||||
case SRPT_STATE_CMD_RSP_SENT:
|
||||
scst_set_delivery_status(scmnd, SCST_CMD_DELIVERY_ABORTED);
|
||||
scst_tgt_cmd_done(scmnd, context);
|
||||
/*
|
||||
* SCST command abort flag has been set after the RDMA read
|
||||
* started and before srpt_xmit_response() has been invoked.
|
||||
*/
|
||||
scst_rx_data(scmnd, SCST_RX_STATUS_ERROR, context);
|
||||
break;
|
||||
case SRPT_STATE_CMD_RSP_SENT:
|
||||
/*
|
||||
* SRP_RSP sending failed or the SRP_RSP send completion has
|
||||
* not been received in time.
|
||||
*/
|
||||
case SRPT_STATE_MGMT_RSP_SENT:
|
||||
WARN_ON("ERROR: srpt_abort_scst_cmd() has been called for"
|
||||
" a management command.");
|
||||
/* Management command response sending failed. */
|
||||
scst_set_delivery_status(scmnd, SCST_CMD_DELIVERY_ABORTED);
|
||||
scst_tgt_cmd_done(scmnd, context);
|
||||
break;
|
||||
default:
|
||||
@@ -2852,7 +2859,6 @@ static int srpt_xmit_response(struct scst_cmd *scmnd)
|
||||
int ret;
|
||||
int dir;
|
||||
int resp_len;
|
||||
enum srpt_command_state prev_state;
|
||||
|
||||
EXTRACHECKS_BUG_ON(scst_cmd_atomic(scmnd));
|
||||
|
||||
@@ -2862,19 +2868,10 @@ static int srpt_xmit_response(struct scst_cmd *scmnd)
|
||||
ch = scst_sess_get_tgt_priv(scst_cmd_get_session(scmnd));
|
||||
BUG_ON(!ch);
|
||||
|
||||
prev_state = srpt_get_cmd_state(ioctx);
|
||||
if (unlikely(scst_cmd_aborted(scmnd))) {
|
||||
TRACE_DBG("cmd with tag %lld has been aborted (SRPT state"
|
||||
" %d -> %d; SCST state %d)",
|
||||
scst_cmd_get_tag(scmnd), prev_state,
|
||||
srpt_get_cmd_state(ioctx),
|
||||
scmnd->state);
|
||||
srpt_abort_scst_cmd(ioctx, SCST_CONTEXT_SAME);
|
||||
if (scmnd->state != SCST_CMD_STATE_FINISHED)
|
||||
PRINT_INFO("cmd with tag %lld has been aborted"
|
||||
" and has now SCST state %d - session"
|
||||
" unregistration will wait.",
|
||||
scst_cmd_get_tag(scmnd), scmnd->state);
|
||||
WARN_ON(ioctx->mapped_sg_count);
|
||||
srpt_set_cmd_state(ioctx, SRPT_STATE_DONE);
|
||||
scst_set_delivery_status(scmnd, SCST_CMD_DELIVERY_ABORTED);
|
||||
ret = SCST_TGT_RES_SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user