ib_srpt: Convert I/O path to target_submit_cmd + drop legacy ioctx->kref
This patch converts the main srpt_handle_cmd() I/O path to use modern target_submit_cmd() with TARGET_SCF_ACK_KREF flag usage. This includes dropping the original internal ioctx->kref + srpt_put_send_ioctx() usage in favor of target_put_sess_cmd() w/ se_cmd_t->cmd_kref within ib_srpt response callbacks. It also updates srpt_abort_cmd() to call target_put_sess_cmd() for completion of aborted commands, and adds target_wait_for_sess_cmds() into srpt_release_channel_work() to allow outstanding I/O to complete during session shutdown. Also, go ahead and update srpt_handle_tsk_mgmt() to make the remaining transport_init_se_cmd() to setup the ioctx->cmd with se_tmr_req. Cc: Christoph Hellwig <hch@lst.de> Cc: Bart Van Assche <bvanassche@acm.org> Cc: Roland Dreier <roland@kernel.org> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
ffe0067544
commit
9474b04313
|
@ -1269,7 +1269,6 @@ static struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch)
|
|||
return ioctx;
|
||||
|
||||
BUG_ON(ioctx->ch != ch);
|
||||
kref_init(&ioctx->kref);
|
||||
spin_lock_init(&ioctx->spinlock);
|
||||
ioctx->state = SRPT_STATE_NEW;
|
||||
ioctx->n_rbuf = 0;
|
||||
|
@ -1290,39 +1289,6 @@ static struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch)
|
|||
return ioctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* srpt_put_send_ioctx() - Free up resources.
|
||||
*/
|
||||
static void srpt_put_send_ioctx(struct srpt_send_ioctx *ioctx)
|
||||
{
|
||||
struct srpt_rdma_ch *ch;
|
||||
unsigned long flags;
|
||||
|
||||
BUG_ON(!ioctx);
|
||||
ch = ioctx->ch;
|
||||
BUG_ON(!ch);
|
||||
|
||||
WARN_ON(srpt_get_cmd_state(ioctx) != SRPT_STATE_DONE);
|
||||
|
||||
srpt_unmap_sg_to_ib_sge(ioctx->ch, ioctx);
|
||||
transport_generic_free_cmd(&ioctx->cmd, 0);
|
||||
|
||||
if (ioctx->n_rbuf > 1) {
|
||||
kfree(ioctx->rbufs);
|
||||
ioctx->rbufs = NULL;
|
||||
ioctx->n_rbuf = 0;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ch->spinlock, flags);
|
||||
list_add(&ioctx->free_list, &ch->free_list);
|
||||
spin_unlock_irqrestore(&ch->spinlock, flags);
|
||||
}
|
||||
|
||||
static void srpt_put_send_ioctx_kref(struct kref *kref)
|
||||
{
|
||||
srpt_put_send_ioctx(container_of(kref, struct srpt_send_ioctx, kref));
|
||||
}
|
||||
|
||||
/**
|
||||
* srpt_abort_cmd() - Abort a SCSI command.
|
||||
* @ioctx: I/O context associated with the SCSI command.
|
||||
|
@ -1359,8 +1325,14 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx)
|
|||
}
|
||||
spin_unlock_irqrestore(&ioctx->spinlock, flags);
|
||||
|
||||
if (state == SRPT_STATE_DONE)
|
||||
if (state == SRPT_STATE_DONE) {
|
||||
struct srpt_rdma_ch *ch = ioctx->ch;
|
||||
|
||||
BUG_ON(ch->sess == NULL);
|
||||
|
||||
target_put_sess_cmd(ch->sess, &ioctx->cmd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
pr_debug("Aborting cmd with state %d and tag %lld\n", state,
|
||||
ioctx->tag);
|
||||
|
@ -1395,11 +1367,11 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx)
|
|||
spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags);
|
||||
ioctx->cmd.transport_state |= CMD_T_LUN_STOP;
|
||||
spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags);
|
||||
kref_put(&ioctx->kref, srpt_put_send_ioctx_kref);
|
||||
target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd);
|
||||
break;
|
||||
case SRPT_STATE_MGMT_RSP_SENT:
|
||||
srpt_set_cmd_state(ioctx, SRPT_STATE_DONE);
|
||||
kref_put(&ioctx->kref, srpt_put_send_ioctx_kref);
|
||||
target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd);
|
||||
break;
|
||||
default:
|
||||
WARN_ON("ERROR: unexpected command state");
|
||||
|
@ -1457,11 +1429,13 @@ static void srpt_handle_send_comp(struct srpt_rdma_ch *ch,
|
|||
&& state != SRPT_STATE_DONE))
|
||||
pr_debug("state = %d\n", state);
|
||||
|
||||
if (state != SRPT_STATE_DONE)
|
||||
kref_put(&ioctx->kref, srpt_put_send_ioctx_kref);
|
||||
else
|
||||
if (state != SRPT_STATE_DONE) {
|
||||
srpt_unmap_sg_to_ib_sge(ch, ioctx);
|
||||
transport_generic_free_cmd(&ioctx->cmd, 0);
|
||||
} else {
|
||||
printk(KERN_ERR "IB completion has been received too late for"
|
||||
" wr_id = %u.\n", ioctx->ioctx.index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1712,10 +1686,10 @@ out_err:
|
|||
|
||||
static int srpt_check_stop_free(struct se_cmd *cmd)
|
||||
{
|
||||
struct srpt_send_ioctx *ioctx;
|
||||
struct srpt_send_ioctx *ioctx = container_of(cmd,
|
||||
struct srpt_send_ioctx, cmd);
|
||||
|
||||
ioctx = container_of(cmd, struct srpt_send_ioctx, cmd);
|
||||
return kref_put(&ioctx->kref, srpt_put_send_ioctx_kref);
|
||||
return target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1731,11 +1705,11 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
|
|||
u64 data_len;
|
||||
enum dma_data_direction dir;
|
||||
sense_reason_t ret;
|
||||
int rc;
|
||||
|
||||
BUG_ON(!send_ioctx);
|
||||
|
||||
srp_cmd = recv_ioctx->ioctx.buf;
|
||||
kref_get(&send_ioctx->kref);
|
||||
cmd = &send_ioctx->cmd;
|
||||
send_ioctx->tag = srp_cmd->tag;
|
||||
|
||||
|
@ -1759,30 +1733,18 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
|
|||
printk(KERN_ERR "0x%llx: parsing SRP descriptor table failed.\n",
|
||||
srp_cmd->tag);
|
||||
ret = TCM_INVALID_CDB_FIELD;
|
||||
kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
|
||||
goto send_sense;
|
||||
}
|
||||
|
||||
cmd->data_length = data_len;
|
||||
cmd->data_direction = dir;
|
||||
unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_cmd->lun,
|
||||
sizeof(srp_cmd->lun));
|
||||
ret = transport_lookup_cmd_lun(cmd, unpacked_lun);
|
||||
if (ret) {
|
||||
kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
|
||||
rc = target_submit_cmd(cmd, ch->sess, srp_cmd->cdb,
|
||||
&send_ioctx->sense_data[0], unpacked_lun, data_len,
|
||||
MSG_SIMPLE_TAG, dir, TARGET_SCF_ACK_KREF);
|
||||
if (rc != 0) {
|
||||
ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||
goto send_sense;
|
||||
}
|
||||
ret = target_setup_cmd_from_cdb(cmd, srp_cmd->cdb);
|
||||
if (ret) {
|
||||
kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
|
||||
if (ret == TCM_RESERVATION_CONFLICT) {
|
||||
srpt_queue_status(cmd);
|
||||
return 0;
|
||||
}
|
||||
goto send_sense;
|
||||
}
|
||||
|
||||
transport_handle_cdb_direct(cmd);
|
||||
return 0;
|
||||
|
||||
send_sense:
|
||||
|
@ -1884,6 +1846,9 @@ static void srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch,
|
|||
TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED;
|
||||
goto fail;
|
||||
}
|
||||
transport_init_se_cmd(&send_ioctx->cmd, &srpt_target->tf_ops, ch->sess,
|
||||
0, DMA_NONE, MSG_SIMPLE_TAG, send_ioctx->sense_data);
|
||||
|
||||
res = core_tmr_alloc_req(cmd, NULL, tcm_tmr, GFP_KERNEL);
|
||||
if (res < 0) {
|
||||
send_ioctx->cmd.se_tmr_req->response = TMR_FUNCTION_REJECTED;
|
||||
|
@ -1902,11 +1867,9 @@ static void srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch,
|
|||
if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK)
|
||||
srpt_rx_mgmt_fn_tag(send_ioctx, srp_tsk->task_tag);
|
||||
|
||||
kref_get(&send_ioctx->kref);
|
||||
transport_generic_handle_tmr(&send_ioctx->cmd);
|
||||
return;
|
||||
fail:
|
||||
kref_get(&send_ioctx->kref);
|
||||
transport_send_check_condition_and_sense(cmd, 0, 0); // XXX:
|
||||
}
|
||||
|
||||
|
@ -1949,10 +1912,6 @@ static void srpt_handle_new_iu(struct srpt_rdma_ch *ch,
|
|||
}
|
||||
}
|
||||
|
||||
transport_init_se_cmd(&send_ioctx->cmd, &srpt_target->tf_ops, ch->sess,
|
||||
0, DMA_NONE, MSG_SIMPLE_TAG,
|
||||
send_ioctx->sense_data);
|
||||
|
||||
switch (srp_cmd->opcode) {
|
||||
case SRP_CMD:
|
||||
srpt_handle_cmd(ch, recv_ioctx, send_ioctx);
|
||||
|
@ -2358,6 +2317,7 @@ static void srpt_release_channel_work(struct work_struct *w)
|
|||
{
|
||||
struct srpt_rdma_ch *ch;
|
||||
struct srpt_device *sdev;
|
||||
struct se_session *se_sess;
|
||||
|
||||
ch = container_of(w, struct srpt_rdma_ch, release_work);
|
||||
pr_debug("ch = %p; ch->sess = %p; release_done = %p\n", ch, ch->sess,
|
||||
|
@ -2366,8 +2326,13 @@ static void srpt_release_channel_work(struct work_struct *w)
|
|||
sdev = ch->sport->sdev;
|
||||
BUG_ON(!sdev);
|
||||
|
||||
transport_deregister_session_configfs(ch->sess);
|
||||
transport_deregister_session(ch->sess);
|
||||
se_sess = ch->sess;
|
||||
BUG_ON(!se_sess);
|
||||
|
||||
target_wait_for_sess_cmds(se_sess, 0);
|
||||
|
||||
transport_deregister_session_configfs(se_sess);
|
||||
transport_deregister_session(se_sess);
|
||||
ch->sess = NULL;
|
||||
|
||||
srpt_destroy_ch_ib(ch);
|
||||
|
@ -3092,7 +3057,7 @@ static int srpt_queue_response(struct se_cmd *cmd)
|
|||
ioctx->tag);
|
||||
srpt_unmap_sg_to_ib_sge(ch, ioctx);
|
||||
srpt_set_cmd_state(ioctx, SRPT_STATE_DONE);
|
||||
kref_put(&ioctx->kref, srpt_put_send_ioctx_kref);
|
||||
target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd);
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -3483,6 +3448,23 @@ static u32 srpt_tpg_get_inst_index(struct se_portal_group *se_tpg)
|
|||
|
||||
static void srpt_release_cmd(struct se_cmd *se_cmd)
|
||||
{
|
||||
struct srpt_send_ioctx *ioctx = container_of(se_cmd,
|
||||
struct srpt_send_ioctx, cmd);
|
||||
struct srpt_rdma_ch *ch = ioctx->ch;
|
||||
unsigned long flags;
|
||||
|
||||
WARN_ON(ioctx->state != SRPT_STATE_DONE);
|
||||
WARN_ON(ioctx->mapped_sg_count != 0);
|
||||
|
||||
if (ioctx->n_rbuf > 1) {
|
||||
kfree(ioctx->rbufs);
|
||||
ioctx->rbufs = NULL;
|
||||
ioctx->n_rbuf = 0;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ch->spinlock, flags);
|
||||
list_add(&ioctx->free_list, &ch->free_list);
|
||||
spin_unlock_irqrestore(&ch->spinlock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -228,7 +228,6 @@ struct srpt_recv_ioctx {
|
|||
struct srpt_send_ioctx {
|
||||
struct srpt_ioctx ioctx;
|
||||
struct srpt_rdma_ch *ch;
|
||||
struct kref kref;
|
||||
struct rdma_iu *rdma_ius;
|
||||
struct srp_direct_buf *rbufs;
|
||||
struct srp_direct_buf single_rbuf;
|
||||
|
|
Loading…
Reference in New Issue