aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2012-11-28 02:55:57 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2012-11-28 04:10:59 -0500
commit9474b043132f41ee03bd3d8dcb076f8569ae69d3 (patch)
treefbeab82e5c98b57bca9177353c730fc5ac7d0dd3 /drivers/infiniband
parentffe0067544f93c0e71c793d7f17240486d091a3c (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>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/ulp/srpt/ib_srpt.c122
-rw-r--r--drivers/infiniband/ulp/srpt/ib_srpt.h1
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 */
1296static 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
1321static 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
1713static int srpt_check_stop_free(struct se_cmd *cmd) 1687static 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 }
1782 goto send_sense;
1783 }
1784
1785 transport_handle_cdb_direct(cmd);
1786 return 0; 1748 return 0;
1787 1749
1788send_sense: 1750send_sense:
@@ -1884,6 +1846,9 @@ static void srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch,
1884 TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED; 1846 TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED;
1885 goto fail; 1847 goto fail;
1886 } 1848 }
1849 transport_init_se_cmd(&send_ioctx->cmd, &srpt_target->tf_ops, ch->sess,
1850 0, DMA_NONE, MSG_SIMPLE_TAG, send_ioctx->sense_data);
1851
1887 res = core_tmr_alloc_req(cmd, NULL, tcm_tmr, GFP_KERNEL); 1852 res = core_tmr_alloc_req(cmd, NULL, tcm_tmr, GFP_KERNEL);
1888 if (res < 0) { 1853 if (res < 0) {
1889 send_ioctx->cmd.se_tmr_req->response = TMR_FUNCTION_REJECTED; 1854 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,
1902 if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK) 1867 if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK)
1903 srpt_rx_mgmt_fn_tag(send_ioctx, srp_tsk->task_tag); 1868 srpt_rx_mgmt_fn_tag(send_ioctx, srp_tsk->task_tag);
1904 1869
1905 kref_get(&send_ioctx->kref);
1906 transport_generic_handle_tmr(&send_ioctx->cmd); 1870 transport_generic_handle_tmr(&send_ioctx->cmd);
1907 return; 1871 return;
1908fail: 1872fail:
1909 kref_get(&send_ioctx->kref);
1910 transport_send_check_condition_and_sense(cmd, 0, 0); // XXX: 1873 transport_send_check_condition_and_sense(cmd, 0, 0); // XXX:
1911} 1874}
1912 1875
@@ -1949,10 +1912,6 @@ static void srpt_handle_new_iu(struct srpt_rdma_ch *ch,
1949 } 1912 }
1950 } 1913 }
1951 1914
1952 transport_init_se_cmd(&send_ioctx->cmd, &srpt_target->tf_ops, ch->sess,
1953 0, DMA_NONE, MSG_SIMPLE_TAG,
1954 send_ioctx->sense_data);
1955
1956 switch (srp_cmd->opcode) { 1915 switch (srp_cmd->opcode) {
1957 case SRP_CMD: 1916 case SRP_CMD:
1958 srpt_handle_cmd(ch, recv_ioctx, send_ioctx); 1917 srpt_handle_cmd(ch, recv_ioctx, send_ioctx);
@@ -2358,6 +2317,7 @@ static void srpt_release_channel_work(struct work_struct *w)
2358{ 2317{
2359 struct srpt_rdma_ch *ch; 2318 struct srpt_rdma_ch *ch;
2360 struct srpt_device *sdev; 2319 struct srpt_device *sdev;
2320 struct se_session *se_sess;
2361 2321
2362 ch = container_of(w, struct srpt_rdma_ch, release_work); 2322 ch = container_of(w, struct srpt_rdma_ch, release_work);
2363 pr_debug("ch = %p; ch->sess = %p; release_done = %p\n", ch, ch->sess, 2323 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)
2366 sdev = ch->sport->sdev; 2326 sdev = ch->sport->sdev;
2367 BUG_ON(!sdev); 2327 BUG_ON(!sdev);
2368 2328
2369 transport_deregister_session_configfs(ch->sess); 2329 se_sess = ch->sess;
2370 transport_deregister_session(ch->sess); 2330 BUG_ON(!se_sess);
2331
2332 target_wait_for_sess_cmds(se_sess, 0);
2333
2334 transport_deregister_session_configfs(se_sess);
2335 transport_deregister_session(se_sess);
2371 ch->sess = NULL; 2336 ch->sess = NULL;
2372 2337
2373 srpt_destroy_ch_ib(ch); 2338 srpt_destroy_ch_ib(ch);
@@ -3092,7 +3057,7 @@ static int srpt_queue_response(struct se_cmd *cmd)
3092 ioctx->tag); 3057 ioctx->tag);
3093 srpt_unmap_sg_to_ib_sge(ch, ioctx); 3058 srpt_unmap_sg_to_ib_sge(ch, ioctx);
3094 srpt_set_cmd_state(ioctx, SRPT_STATE_DONE); 3059 srpt_set_cmd_state(ioctx, SRPT_STATE_DONE);
3095 kref_put(&ioctx->kref, srpt_put_send_ioctx_kref); 3060 target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd);
3096 } 3061 }
3097 3062
3098out: 3063out:
@@ -3483,6 +3448,23 @@ static u32 srpt_tpg_get_inst_index(struct se_portal_group *se_tpg)
3483 3448
3484static void srpt_release_cmd(struct se_cmd *se_cmd) 3449static void srpt_release_cmd(struct se_cmd *se_cmd)
3485{ 3450{
3451 struct srpt_send_ioctx *ioctx = container_of(se_cmd,
3452 struct srpt_send_ioctx, cmd);
3453 struct srpt_rdma_ch *ch = ioctx->ch;
3454 unsigned long flags;
3455
3456 WARN_ON(ioctx->state != SRPT_STATE_DONE);
3457 WARN_ON(ioctx->mapped_sg_count != 0);
3458
3459 if (ioctx->n_rbuf > 1) {
3460 kfree(ioctx->rbufs);
3461 ioctx->rbufs = NULL;
3462 ioctx->n_rbuf = 0;
3463 }
3464
3465 spin_lock_irqsave(&ch->spinlock, flags);
3466 list_add(&ioctx->free_list, &ch->free_list);
3467 spin_unlock_irqrestore(&ch->spinlock, flags);
3486} 3468}
3487 3469
3488/** 3470/**
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h
index 61e52b830816..4caf55cda7b1 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.h
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.h
@@ -228,7 +228,6 @@ struct srpt_recv_ioctx {
228struct srpt_send_ioctx { 228struct srpt_send_ioctx {
229 struct srpt_ioctx ioctx; 229 struct srpt_ioctx ioctx;
230 struct srpt_rdma_ch *ch; 230 struct srpt_rdma_ch *ch;
231 struct kref kref;
232 struct rdma_iu *rdma_ius; 231 struct rdma_iu *rdma_ius;
233 struct srp_direct_buf *rbufs; 232 struct srp_direct_buf *rbufs;
234 struct srp_direct_buf single_rbuf; 233 struct srp_direct_buf single_rbuf;