diff options
Diffstat (limited to 'drivers/infiniband/ulp/srpt')
-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 | } | ||
1782 | goto send_sense; | ||
1783 | } | ||
1784 | |||
1785 | transport_handle_cdb_direct(cmd); | ||
1786 | return 0; | 1748 | return 0; |
1787 | 1749 | ||
1788 | send_sense: | 1750 | send_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; |
1908 | fail: | 1872 | fail: |
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 | ||
3098 | out: | 3063 | out: |
@@ -3483,6 +3448,23 @@ static u32 srpt_tpg_get_inst_index(struct se_portal_group *se_tpg) | |||
3483 | 3448 | ||
3484 | static void srpt_release_cmd(struct se_cmd *se_cmd) | 3449 | static 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 { | |||
228 | struct srpt_send_ioctx { | 228 | struct 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; |