diff options
| author | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-11-28 02:55:57 -0500 |
|---|---|---|
| committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-11-28 04:10:59 -0500 |
| commit | 9474b043132f41ee03bd3d8dcb076f8569ae69d3 (patch) | |
| tree | fbeab82e5c98b57bca9177353c730fc5ac7d0dd3 | |
| parent | ffe0067544f93c0e71c793d7f17240486d091a3c (diff) | |
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>
| -rw-r--r-- | drivers/infiniband/ulp/srpt/ib_srpt.c | 122 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/srpt/ib_srpt.h | 1 |
2 files changed, 52 insertions, 71 deletions
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index e6fafc62acae..77b6368fec3d 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
| @@ -1269,7 +1269,6 @@ static struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch) | |||
| 1269 | return ioctx; | 1269 | return ioctx; |
| 1270 | 1270 | ||
| 1271 | BUG_ON(ioctx->ch != ch); | 1271 | BUG_ON(ioctx->ch != ch); |
| 1272 | kref_init(&ioctx->kref); | ||
| 1273 | spin_lock_init(&ioctx->spinlock); | 1272 | spin_lock_init(&ioctx->spinlock); |
| 1274 | ioctx->state = SRPT_STATE_NEW; | 1273 | ioctx->state = SRPT_STATE_NEW; |
| 1275 | ioctx->n_rbuf = 0; | 1274 | ioctx->n_rbuf = 0; |
| @@ -1291,39 +1290,6 @@ static struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch) | |||
| 1291 | } | 1290 | } |
| 1292 | 1291 | ||
| 1293 | /** | 1292 | /** |
| 1294 | * srpt_put_send_ioctx() - Free up resources. | ||
| 1295 | */ | ||
| 1296 | static void srpt_put_send_ioctx(struct srpt_send_ioctx *ioctx) | ||
| 1297 | { | ||
| 1298 | struct srpt_rdma_ch *ch; | ||
| 1299 | unsigned long flags; | ||
| 1300 | |||
| 1301 | BUG_ON(!ioctx); | ||
| 1302 | ch = ioctx->ch; | ||
| 1303 | BUG_ON(!ch); | ||
| 1304 | |||
| 1305 | WARN_ON(srpt_get_cmd_state(ioctx) != SRPT_STATE_DONE); | ||
| 1306 | |||
| 1307 | srpt_unmap_sg_to_ib_sge(ioctx->ch, ioctx); | ||
| 1308 | transport_generic_free_cmd(&ioctx->cmd, 0); | ||
| 1309 | |||
| 1310 | if (ioctx->n_rbuf > 1) { | ||
| 1311 | kfree(ioctx->rbufs); | ||
| 1312 | ioctx->rbufs = NULL; | ||
| 1313 | ioctx->n_rbuf = 0; | ||
| 1314 | } | ||
| 1315 | |||
| 1316 | spin_lock_irqsave(&ch->spinlock, flags); | ||
| 1317 | list_add(&ioctx->free_list, &ch->free_list); | ||
| 1318 | spin_unlock_irqrestore(&ch->spinlock, flags); | ||
| 1319 | } | ||
| 1320 | |||
| 1321 | static void srpt_put_send_ioctx_kref(struct kref *kref) | ||
| 1322 | { | ||
| 1323 | srpt_put_send_ioctx(container_of(kref, struct srpt_send_ioctx, kref)); | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | /** | ||
| 1327 | * srpt_abort_cmd() - Abort a SCSI command. | 1293 | * srpt_abort_cmd() - Abort a SCSI command. |
| 1328 | * @ioctx: I/O context associated with the SCSI command. | 1294 | * @ioctx: I/O context associated with the SCSI command. |
| 1329 | * @context: Preferred execution context. | 1295 | * @context: Preferred execution context. |
| @@ -1359,8 +1325,14 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx) | |||
| 1359 | } | 1325 | } |
| 1360 | spin_unlock_irqrestore(&ioctx->spinlock, flags); | 1326 | spin_unlock_irqrestore(&ioctx->spinlock, flags); |
| 1361 | 1327 | ||
| 1362 | if (state == SRPT_STATE_DONE) | 1328 | if (state == SRPT_STATE_DONE) { |
| 1329 | struct srpt_rdma_ch *ch = ioctx->ch; | ||
| 1330 | |||
| 1331 | BUG_ON(ch->sess == NULL); | ||
| 1332 | |||
| 1333 | target_put_sess_cmd(ch->sess, &ioctx->cmd); | ||
| 1363 | goto out; | 1334 | goto out; |
| 1335 | } | ||
| 1364 | 1336 | ||
| 1365 | pr_debug("Aborting cmd with state %d and tag %lld\n", state, | 1337 | pr_debug("Aborting cmd with state %d and tag %lld\n", state, |
| 1366 | ioctx->tag); | 1338 | ioctx->tag); |
| @@ -1395,11 +1367,11 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx) | |||
| 1395 | spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags); | 1367 | spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags); |
| 1396 | ioctx->cmd.transport_state |= CMD_T_LUN_STOP; | 1368 | ioctx->cmd.transport_state |= CMD_T_LUN_STOP; |
| 1397 | spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags); | 1369 | spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags); |
| 1398 | kref_put(&ioctx->kref, srpt_put_send_ioctx_kref); | 1370 | target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd); |
| 1399 | break; | 1371 | break; |
| 1400 | case SRPT_STATE_MGMT_RSP_SENT: | 1372 | case SRPT_STATE_MGMT_RSP_SENT: |
| 1401 | srpt_set_cmd_state(ioctx, SRPT_STATE_DONE); | 1373 | srpt_set_cmd_state(ioctx, SRPT_STATE_DONE); |
| 1402 | kref_put(&ioctx->kref, srpt_put_send_ioctx_kref); | 1374 | target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd); |
| 1403 | break; | 1375 | break; |
| 1404 | default: | 1376 | default: |
| 1405 | WARN_ON("ERROR: unexpected command state"); | 1377 | WARN_ON("ERROR: unexpected command state"); |
| @@ -1457,11 +1429,13 @@ static void srpt_handle_send_comp(struct srpt_rdma_ch *ch, | |||
| 1457 | && state != SRPT_STATE_DONE)) | 1429 | && state != SRPT_STATE_DONE)) |
| 1458 | pr_debug("state = %d\n", state); | 1430 | pr_debug("state = %d\n", state); |
| 1459 | 1431 | ||
| 1460 | if (state != SRPT_STATE_DONE) | 1432 | if (state != SRPT_STATE_DONE) { |
| 1461 | kref_put(&ioctx->kref, srpt_put_send_ioctx_kref); | 1433 | srpt_unmap_sg_to_ib_sge(ch, ioctx); |
| 1462 | else | 1434 | transport_generic_free_cmd(&ioctx->cmd, 0); |
| 1435 | } else { | ||
| 1463 | printk(KERN_ERR "IB completion has been received too late for" | 1436 | printk(KERN_ERR "IB completion has been received too late for" |
| 1464 | " wr_id = %u.\n", ioctx->ioctx.index); | 1437 | " wr_id = %u.\n", ioctx->ioctx.index); |
| 1438 | } | ||
| 1465 | } | 1439 | } |
| 1466 | 1440 | ||
| 1467 | /** | 1441 | /** |
| @@ -1712,10 +1686,10 @@ out_err: | |||
| 1712 | 1686 | ||
| 1713 | static int srpt_check_stop_free(struct se_cmd *cmd) | 1687 | static int srpt_check_stop_free(struct se_cmd *cmd) |
| 1714 | { | 1688 | { |
| 1715 | struct srpt_send_ioctx *ioctx; | 1689 | struct srpt_send_ioctx *ioctx = container_of(cmd, |
| 1690 | struct srpt_send_ioctx, cmd); | ||
| 1716 | 1691 | ||
| 1717 | ioctx = container_of(cmd, struct srpt_send_ioctx, cmd); | 1692 | return target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd); |
| 1718 | return kref_put(&ioctx->kref, srpt_put_send_ioctx_kref); | ||
| 1719 | } | 1693 | } |
| 1720 | 1694 | ||
| 1721 | /** | 1695 | /** |
| @@ -1731,11 +1705,11 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, | |||
| 1731 | u64 data_len; | 1705 | u64 data_len; |
| 1732 | enum dma_data_direction dir; | 1706 | enum dma_data_direction dir; |
| 1733 | sense_reason_t ret; | 1707 | sense_reason_t ret; |
| 1708 | int rc; | ||
| 1734 | 1709 | ||
| 1735 | BUG_ON(!send_ioctx); | 1710 | BUG_ON(!send_ioctx); |
| 1736 | 1711 | ||
| 1737 | srp_cmd = recv_ioctx->ioctx.buf; | 1712 | srp_cmd = recv_ioctx->ioctx.buf; |
| 1738 | kref_get(&send_ioctx->kref); | ||
| 1739 | cmd = &send_ioctx->cmd; | 1713 | cmd = &send_ioctx->cmd; |
| 1740 | send_ioctx->tag = srp_cmd->tag; | 1714 | send_ioctx->tag = srp_cmd->tag; |
| 1741 | 1715 | ||
| @@ -1759,30 +1733,18 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, | |||
| 1759 | printk(KERN_ERR "0x%llx: parsing SRP descriptor table failed.\n", | 1733 | printk(KERN_ERR "0x%llx: parsing SRP descriptor table failed.\n", |
| 1760 | srp_cmd->tag); | 1734 | srp_cmd->tag); |
| 1761 | ret = TCM_INVALID_CDB_FIELD; | 1735 | ret = TCM_INVALID_CDB_FIELD; |
| 1762 | kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); | ||
| 1763 | goto send_sense; | 1736 | goto send_sense; |
| 1764 | } | 1737 | } |
| 1765 | 1738 | ||
| 1766 | cmd->data_length = data_len; | ||
| 1767 | cmd->data_direction = dir; | ||
| 1768 | unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_cmd->lun, | 1739 | unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_cmd->lun, |
| 1769 | sizeof(srp_cmd->lun)); | 1740 | sizeof(srp_cmd->lun)); |
| 1770 | ret = transport_lookup_cmd_lun(cmd, unpacked_lun); | 1741 | rc = target_submit_cmd(cmd, ch->sess, srp_cmd->cdb, |
| 1771 | if (ret) { | 1742 | &send_ioctx->sense_data[0], unpacked_lun, data_len, |
| 1772 | kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); | 1743 | MSG_SIMPLE_TAG, dir, TARGET_SCF_ACK_KREF); |
| 1744 | if (rc != 0) { | ||
| 1745 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
| 1773 | goto send_sense; | 1746 | goto send_sense; |
| 1774 | } | 1747 | } |
| 1775 | ret = target_setup_cmd_from_cdb(cmd, srp_cmd->cdb); | ||
| 1776 | if (ret) { | ||
| 1777 | kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); | ||
| 1778 | if (ret == TCM_RESERVATION_CONFLICT) { | ||
| 1779 | srpt_queue_status(cmd); | ||
| 1780 | return 0; | ||
| 1781 | } | ||
