mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-17 20:56:24 +00:00
Refinements for SRPT command processing state management.
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1059 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
+40
-21
@@ -226,7 +226,8 @@ static void srpt_qp_event(struct ib_event *event, void *ctx)
|
||||
case IB_EVENT_QP_LAST_WQE_REACHED:
|
||||
if (srpt_test_and_set_channel_state(ch, RDMA_CHANNEL_LIVE,
|
||||
RDMA_CHANNEL_DISCONNECTING)) {
|
||||
TRACE_DBG("%s", "Disconnecting channel.");
|
||||
printk(KERN_INFO PFX "disconnected session %s.\n",
|
||||
ch->sess_name);
|
||||
ib_send_cm_dreq(ch->cm_id, NULL, 0);
|
||||
}
|
||||
break;
|
||||
@@ -881,6 +882,7 @@ static void srpt_abort_scst_cmd(struct srpt_device *sdev,
|
||||
{
|
||||
struct srpt_ioctx *ioctx;
|
||||
scst_data_direction dir;
|
||||
enum srpt_command_state orig_ioctx_state;
|
||||
|
||||
ioctx = scst_cmd_get_tgt_priv(scmnd);
|
||||
BUG_ON(!ioctx);
|
||||
@@ -891,7 +893,7 @@ static void srpt_abort_scst_cmd(struct srpt_device *sdev,
|
||||
scst_cmd_get_sg_cnt(scmnd),
|
||||
scst_to_tgt_dma_dir(dir));
|
||||
|
||||
#if 1
|
||||
#ifdef CONFIG_SCST_EXTRACHECKS
|
||||
switch (scmnd->state) {
|
||||
case SCST_CMD_STATE_DATA_WAIT:
|
||||
WARN_ON(ioctx->state != SRPT_STATE_NEED_DATA);
|
||||
@@ -905,7 +907,12 @@ static void srpt_abort_scst_cmd(struct srpt_device *sdev,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ioctx->state == SRPT_STATE_NEED_DATA) {
|
||||
orig_ioctx_state = ioctx->state;
|
||||
ioctx->state = SRPT_STATE_ABORTED;
|
||||
|
||||
if (orig_ioctx_state == SRPT_STATE_NEED_DATA) {
|
||||
WARN_ON(scst_cmd_get_data_direction(ioctx->scmnd)
|
||||
== SCST_DATA_READ);
|
||||
scst_rx_data(scmnd,
|
||||
tell_initiator ? SCST_RX_STATUS_ERROR
|
||||
: SCST_RX_STATUS_ERROR_FATAL,
|
||||
@@ -913,12 +920,8 @@ static void srpt_abort_scst_cmd(struct srpt_device *sdev,
|
||||
goto out;
|
||||
} else if (ioctx->state == SRPT_STATE_PROCESSED)
|
||||
;
|
||||
else {
|
||||
printk(KERN_ERR PFX
|
||||
"unexpected cmd state %d (SCST) %d (SRPT)\n",
|
||||
scmnd->state, ioctx->state);
|
||||
else
|
||||
WARN_ON("unexpected cmd state");
|
||||
}
|
||||
}
|
||||
|
||||
scst_set_delivery_status(scmnd, SCST_CMD_DELIVERY_FAILED);
|
||||
@@ -964,17 +967,28 @@ static void srpt_handle_send_comp(struct srpt_rdma_ch *ch,
|
||||
srpt_reset_ioctx(ch, ioctx);
|
||||
}
|
||||
|
||||
/** Process an RDMA completion notification. */
|
||||
static void srpt_handle_rdma_comp(struct srpt_rdma_ch *ch,
|
||||
struct srpt_ioctx *ioctx)
|
||||
{
|
||||
if (!ioctx->scmnd) {
|
||||
WARN_ON("ERROR: ioctx->scmnd == NULL");
|
||||
srpt_reset_ioctx(ch, ioctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (scst_cmd_get_data_direction(ioctx->scmnd) == SCST_DATA_WRITE)
|
||||
/*
|
||||
* If an RDMA completion notification has been received for a write
|
||||
* command, tell SCST that processing can continue by calling
|
||||
* scst_rx_data().
|
||||
*/
|
||||
if (ioctx->state == SRPT_STATE_NEED_DATA) {
|
||||
WARN_ON(scst_cmd_get_data_direction(ioctx->scmnd)
|
||||
== SCST_DATA_READ);
|
||||
ioctx->state = SRPT_STATE_DATA_IN;
|
||||
scst_rx_data(ioctx->scmnd, SCST_RX_STATUS_SUCCESS,
|
||||
scst_estimate_context());
|
||||
scst_estimate_context());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1077,7 +1091,7 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, struct srpt_ioctx *ioctx)
|
||||
struct scst_cmd *scmnd;
|
||||
struct srp_cmd *srp_cmd;
|
||||
struct srp_rsp *srp_rsp;
|
||||
scst_data_direction dir = SCST_DATA_NONE;
|
||||
scst_data_direction dir;
|
||||
int indirect_desc = 0;
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
@@ -1085,6 +1099,7 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, struct srpt_ioctx *ioctx)
|
||||
srp_cmd = ioctx->buf;
|
||||
srp_rsp = ioctx->buf;
|
||||
|
||||
dir = SCST_DATA_NONE;
|
||||
if (srp_cmd->buf_fmt) {
|
||||
ret = srpt_get_desc_tbl(ioctx, srp_cmd, &indirect_desc);
|
||||
if (ret) {
|
||||
@@ -1101,14 +1116,18 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, struct srpt_ioctx *ioctx)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* The lower four bits of the buffer format field contain the
|
||||
* DATA-IN buffer descriptor format, and the highest four bits
|
||||
* contain the DATA-OUT buffer descriptor format.
|
||||
*/
|
||||
if (srp_cmd->buf_fmt & 0xf)
|
||||
/* DATA-IN: transfer data from target to initiator. */
|
||||
dir = SCST_DATA_READ;
|
||||
else if (srp_cmd->buf_fmt >> 4)
|
||||
/* DATA-OUT: transfer data from initiator to target. */
|
||||
dir = SCST_DATA_WRITE;
|
||||
else
|
||||
dir = SCST_DATA_NONE;
|
||||
} else
|
||||
dir = SCST_DATA_NONE;
|
||||
}
|
||||
|
||||
scmnd = scst_rx_cmd(ch->scst_sess, (u8 *) &srp_cmd->lun,
|
||||
sizeof srp_cmd->lun, srp_cmd->cdb, 16,
|
||||
@@ -2223,7 +2242,7 @@ static int srpt_perform_rdmas(struct srpt_rdma_ch *ch, struct srpt_ioctx *ioctx,
|
||||
}
|
||||
|
||||
/*
|
||||
* Start data reception. Must not block.
|
||||
* Start data transfer between initiator and target. Must not block.
|
||||
*/
|
||||
static int srpt_xfer_data(struct srpt_rdma_ch *ch, struct srpt_ioctx *ioctx,
|
||||
struct scst_cmd *scmnd)
|
||||
@@ -2254,8 +2273,8 @@ out:
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by the SCST core to inform ib_srpt that data reception should start.
|
||||
* Must not block.
|
||||
* Called by the SCST core to inform ib_srpt that data reception from the
|
||||
* initiator should start (SCST_DATA_WRITE). Must not block.
|
||||
*/
|
||||
static int srpt_rdy_to_xfer(struct scst_cmd *scmnd)
|
||||
{
|
||||
@@ -2300,6 +2319,8 @@ static int srpt_xmit_response(struct scst_cmd *scmnd)
|
||||
|
||||
tag = scst_cmd_get_tag(scmnd);
|
||||
|
||||
ioctx->state = SRPT_STATE_PROCESSED;
|
||||
|
||||
if (ch->state != RDMA_CHANNEL_LIVE) {
|
||||
printk(KERN_ERR PFX
|
||||
"%s: tag= %lld channel in bad state %d\n",
|
||||
@@ -2352,7 +2373,7 @@ static int srpt_xmit_response(struct scst_cmd *scmnd)
|
||||
|
||||
srp_rsp->status = status;
|
||||
|
||||
/* transfer read data if any */
|
||||
/* For read commands, transfer the data to the initiator. */
|
||||
if (dir == SCST_DATA_READ && scst_cmd_get_resp_data_len(scmnd)) {
|
||||
ret = srpt_xfer_data(ch, ioctx, scmnd);
|
||||
if (ret != SCST_TGT_RES_SUCCESS) {
|
||||
@@ -2363,8 +2384,6 @@ static int srpt_xmit_response(struct scst_cmd *scmnd)
|
||||
}
|
||||
}
|
||||
|
||||
ioctx->state = SRPT_STATE_PROCESSED;
|
||||
|
||||
if (srpt_post_send(ch, ioctx,
|
||||
sizeof *srp_rsp +
|
||||
be32_to_cpu(srp_rsp->sense_data_len))) {
|
||||
|
||||
+10
-5
@@ -108,11 +108,16 @@ struct rdma_iu {
|
||||
|
||||
/* Command states. */
|
||||
enum srpt_command_state {
|
||||
SRPT_STATE_NEW = 0, /* New command being processed. */
|
||||
SRPT_STATE_PROCESSED = 1, /* Processing finished. */
|
||||
SRPT_STATE_NEED_DATA = 2, /* Data needed to continue. */
|
||||
SRPT_STATE_DATA_IN = 3, /* Data arrived and being processed. */
|
||||
SRPT_STATE_ABORTED = 4, /* Command aborted. */
|
||||
/* New command arrived and is being processed. */
|
||||
SRPT_STATE_NEW = 0,
|
||||
/* Processing a write or bidir command and waiting for data arrival. */
|
||||
SRPT_STATE_NEED_DATA = 1,
|
||||
/* Data for the write or bidir command arrived and is being processed.*/
|
||||
SRPT_STATE_DATA_IN = 2,
|
||||
/* Command processing finished. */
|
||||
SRPT_STATE_PROCESSED = 3,
|
||||
/* Command processing has been aborted. */
|
||||
SRPT_STATE_ABORTED = 4,
|
||||
};
|
||||
|
||||
/* SRPT I/O context: SRPT-private data associated with a struct scst_cmd. */
|
||||
|
||||
Reference in New Issue
Block a user