diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-09 16:50:14 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-09 16:50:14 -0400 |
| commit | 66a523db70dccb83e3d433383918e43c58a38549 (patch) | |
| tree | ba3c4820cb4aca064d2e2da7b430f113c90c0bb0 | |
| parent | 4c7b70406e5aadc1c78db4d375d5744df65c5b58 (diff) | |
| parent | 16c0ae028989df40bdab46b7f241d331ddc97c59 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target fixes from Nicholas Bellinger:
"This series addresses a number of outstanding issues wrt to active I/O
shutdown using iser-target. This includes:
- Fix a long standing tpg_state bug where a tpg could be referenced
during explicit shutdown (v3.1+ stable)
- Use list_del_init for iscsi_cmd->i_conn_node so list_empty checks
work as expected (v3.10+ stable)
- Fix a isert_conn->state related hung task bug + ensure outstanding
I/O completes during session shutdown. (v3.10+ stable)
- Fix isert_conn->post_send_buf_count accounting for RDMA READ/WRITEs
(v3.10+ stable)
- Ignore FRWR completions during active I/O shutdown (v3.12+ stable)
- Fix command leakage for interrupt coalescing during active I/O
shutdown (v3.13+ stable)
Also included is another DIF emulation fix from Sagi specific to
v3.14-rc code"
* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
Target/sbc: Fix sbc_copy_prot for offset scatters
iser-target: Fix command leak for tx_desc->comp_llnode_batch
iser-target: Ignore completions for FRWRs in isert_cq_tx_work
iser-target: Fix post_send_buf_count for RDMA READ/WRITE
iscsi/iser-target: Fix isert_conn->state hung shutdown issues
iscsi/iser-target: Use list_del_init for ->i_conn_node
iscsi-target: Fix iscsit_get_tpg_from_np tpg_state bug
| -rw-r--r-- | drivers/infiniband/ulp/isert/ib_isert.c | 180 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/isert/ib_isert.h | 7 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 10 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_erl2.c | 16 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_tpg.c | 2 | ||||
| -rw-r--r-- | drivers/target/target_core_sbc.c | 38 | ||||
| -rw-r--r-- | include/target/iscsi/iscsi_transport.h | 1 |
7 files changed, 151 insertions, 103 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index d18d08a076e8..8ee228e9ab5a 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c | |||
| @@ -492,12 +492,11 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | |||
| 492 | isert_conn->state = ISER_CONN_INIT; | 492 | isert_conn->state = ISER_CONN_INIT; |
| 493 | INIT_LIST_HEAD(&isert_conn->conn_accept_node); | 493 | INIT_LIST_HEAD(&isert_conn->conn_accept_node); |
| 494 | init_completion(&isert_conn->conn_login_comp); | 494 | init_completion(&isert_conn->conn_login_comp); |
| 495 | init_waitqueue_head(&isert_conn->conn_wait); | 495 | init_completion(&isert_conn->conn_wait); |
| 496 | init_waitqueue_head(&isert_conn->conn_wait_comp_err); | 496 | init_completion(&isert_conn->conn_wait_comp_err); |
| 497 | kref_init(&isert_conn->conn_kref); | 497 | kref_init(&isert_conn->conn_kref); |
| 498 | kref_get(&isert_conn->conn_kref); | 498 | kref_get(&isert_conn->conn_kref); |
| 499 | mutex_init(&isert_conn->conn_mutex); | 499 | mutex_init(&isert_conn->conn_mutex); |
| 500 | mutex_init(&isert_conn->conn_comp_mutex); | ||
| 501 | spin_lock_init(&isert_conn->conn_lock); | 500 | spin_lock_init(&isert_conn->conn_lock); |
| 502 | 501 | ||
| 503 | cma_id->context = isert_conn; | 502 | cma_id->context = isert_conn; |
| @@ -688,11 +687,11 @@ isert_disconnect_work(struct work_struct *work) | |||
| 688 | 687 | ||
| 689 | pr_debug("isert_disconnect_work(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); | 688 | pr_debug("isert_disconnect_work(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); |
| 690 | mutex_lock(&isert_conn->conn_mutex); | 689 | mutex_lock(&isert_conn->conn_mutex); |
| 691 | isert_conn->state = ISER_CONN_DOWN; | 690 | if (isert_conn->state == ISER_CONN_UP) |
| 691 | isert_conn->state = ISER_CONN_TERMINATING; | ||
| 692 | 692 | ||
| 693 | if (isert_conn->post_recv_buf_count == 0 && | 693 | if (isert_conn->post_recv_buf_count == 0 && |
| 694 | atomic_read(&isert_conn->post_send_buf_count) == 0) { | 694 | atomic_read(&isert_conn->post_send_buf_count) == 0) { |
| 695 | pr_debug("Calling wake_up(&isert_conn->conn_wait);\n"); | ||
| 696 | mutex_unlock(&isert_conn->conn_mutex); | 695 | mutex_unlock(&isert_conn->conn_mutex); |
| 697 | goto wake_up; | 696 | goto wake_up; |
| 698 | } | 697 | } |
| @@ -712,7 +711,7 @@ isert_disconnect_work(struct work_struct *work) | |||
| 712 | mutex_unlock(&isert_conn->conn_mutex); | 711 | mutex_unlock(&isert_conn->conn_mutex); |
| 713 | 712 | ||
| 714 | wake_up: | 713 | wake_up: |
| 715 | wake_up(&isert_conn->conn_wait); | 714 | complete(&isert_conn->conn_wait); |
| 716 | isert_put_conn(isert_conn); | 715 | isert_put_conn(isert_conn); |
| 717 | } | 716 | } |
| 718 | 717 | ||
| @@ -888,16 +887,17 @@ isert_init_send_wr(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd, | |||
| 888 | * Coalesce send completion interrupts by only setting IB_SEND_SIGNALED | 887 | * Coalesce send completion interrupts by only setting IB_SEND_SIGNALED |
| 889 | * bit for every ISERT_COMP_BATCH_COUNT number of ib_post_send() calls. | 888 | * bit for every ISERT_COMP_BATCH_COUNT number of ib_post_send() calls. |
| 890 | */ | 889 | */ |
| 891 | mutex_lock(&isert_conn->conn_comp_mutex); | 890 | mutex_lock(&isert_conn->conn_mutex); |
| 892 | if (coalesce && | 891 | if (coalesce && isert_conn->state == ISER_CONN_UP && |
| 893 | ++isert_conn->conn_comp_batch < ISERT_COMP_BATCH_COUNT) { | 892 | ++isert_conn->conn_comp_batch < ISERT_COMP_BATCH_COUNT) { |
| 893 | tx_desc->llnode_active = true; | ||
| 894 | llist_add(&tx_desc->comp_llnode, &isert_conn->conn_comp_llist); | 894 | llist_add(&tx_desc->comp_llnode, &isert_conn->conn_comp_llist); |
| 895 | mutex_unlock(&isert_conn->conn_comp_mutex); | 895 | mutex_unlock(&isert_conn->conn_mutex); |
| 896 | return; | 896 | return; |
| 897 | } | 897 | } |
| 898 | isert_conn->conn_comp_batch = 0; | 898 | isert_conn->conn_comp_batch = 0; |
| 899 | tx_desc->comp_llnode_batch = llist_del_all(&isert_conn->conn_comp_llist); | 899 | tx_desc->comp_llnode_batch = llist_del_all(&isert_conn->conn_comp_llist); |
| 900 | mutex_unlock(&isert_conn->conn_comp_mutex); | 900 | mutex_unlock(&isert_conn->conn_mutex); |
| 901 | 901 | ||
| 902 | send_wr->send_flags = IB_SEND_SIGNALED; | 902 | send_wr->send_flags = IB_SEND_SIGNALED; |
| 903 | } | 903 | } |
| @@ -1464,7 +1464,7 @@ isert_put_cmd(struct isert_cmd *isert_cmd) | |||
| 1464 | case ISCSI_OP_SCSI_CMD: | 1464 | case ISCSI_OP_SCSI_CMD: |
| 1465 | spin_lock_bh(&conn->cmd_lock); | 1465 | spin_lock_bh(&conn->cmd_lock); |
| 1466 | if (!list_empty(&cmd->i_conn_node)) | 1466 | if (!list_empty(&cmd->i_conn_node)) |
| 1467 | list_del(&cmd->i_conn_node); | 1467 | list_del_init(&cmd->i_conn_node); |
| 1468 | spin_unlock_bh(&conn->cmd_lock); | 1468 | spin_unlock_bh(&conn->cmd_lock); |
| 1469 | 1469 | ||
| 1470 | if (cmd->data_direction == DMA_TO_DEVICE) | 1470 | if (cmd->data_direction == DMA_TO_DEVICE) |
| @@ -1476,7 +1476,7 @@ isert_put_cmd(struct isert_cmd *isert_cmd) | |||
| 1476 | case ISCSI_OP_SCSI_TMFUNC: | 1476 | case ISCSI_OP_SCSI_TMFUNC: |
| 1477 | spin_lock_bh(&conn->cmd_lock); | 1477 | spin_lock_bh(&conn->cmd_lock); |
| 1478 | if (!list_empty(&cmd->i_conn_node)) | 1478 | if (!list_empty(&cmd->i_conn_node)) |
| 1479 | list_del(&cmd->i_conn_node); | 1479 | list_del_init(&cmd->i_conn_node); |
| 1480 | spin_unlock_bh(&conn->cmd_lock); | 1480 | spin_unlock_bh(&conn->cmd_lock); |
| 1481 | 1481 | ||
| 1482 | transport_generic_free_cmd(&cmd->se_cmd, 0); | 1482 | transport_generic_free_cmd(&cmd->se_cmd, 0); |
| @@ -1486,7 +1486,7 @@ isert_put_cmd(struct isert_cmd *isert_cmd) | |||
| 1486 | case ISCSI_OP_TEXT: | 1486 | case ISCSI_OP_TEXT: |
| 1487 | spin_lock_bh(&conn->cmd_lock); | 1487 | spin_lock_bh(&conn->cmd_lock); |
| 1488 | if (!list_empty(&cmd->i_conn_node)) | 1488 | if (!list_empty(&cmd->i_conn_node)) |
| 1489 | list_del(&cmd->i_conn_node); | 1489 | list_del_init(&cmd->i_conn_node); |
| 1490 | spin_unlock_bh(&conn->cmd_lock); | 1490 | spin_unlock_bh(&conn->cmd_lock); |
| 1491 | 1491 | ||
| 1492 | /* | 1492 | /* |
| @@ -1549,6 +1549,7 @@ isert_completion_rdma_read(struct iser_tx_desc *tx_desc, | |||
| 1549 | iscsit_stop_dataout_timer(cmd); | 1549 | iscsit_stop_dataout_timer(cmd); |
| 1550 | device->unreg_rdma_mem(isert_cmd, isert_conn); | 1550 | device->unreg_rdma_mem(isert_cmd, isert_conn); |
| 1551 | cmd->write_data_done = wr->cur_rdma_length; | 1551 | cmd->write_data_done = wr->cur_rdma_length; |
| 1552 | wr->send_wr_num = 0; | ||
| 1552 | 1553 | ||
| 1553 | pr_debug("Cmd: %p RDMA_READ comp calling execute_cmd\n", isert_cmd); | 1554 | pr_debug("Cmd: %p RDMA_READ comp calling execute_cmd\n", isert_cmd); |
| 1554 | spin_lock_bh(&cmd->istate_lock); | 1555 | spin_lock_bh(&cmd->istate_lock); |
| @@ -1589,7 +1590,7 @@ isert_do_control_comp(struct work_struct *work) | |||
| 1589 | pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n"); | 1590 | pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n"); |
| 1590 | /* | 1591 | /* |
| 1591 | * Call atomic_dec(&isert_conn->post_send_buf_count) | 1592 | * Call atomic_dec(&isert_conn->post_send_buf_count) |
| 1592 | * from isert_free_conn() | 1593 | * from isert_wait_conn() |
| 1593 | */ | 1594 | */ |
| 1594 | isert_conn->logout_posted = true; | 1595 | isert_conn->logout_posted = true; |
| 1595 | iscsit_logout_post_handler(cmd, cmd->conn); | 1596 | iscsit_logout_post_handler(cmd, cmd->conn); |
| @@ -1613,6 +1614,7 @@ isert_response_completion(struct iser_tx_desc *tx_desc, | |||
| 1613 | struct ib_device *ib_dev) | 1614 | struct ib_device *ib_dev) |
| 1614 | { | 1615 | { |
| 1615 | struct iscsi_cmd *cmd = isert_cmd->iscsi_cmd; | 1616 | struct iscsi_cmd *cmd = isert_cmd->iscsi_cmd; |
| 1617 | struct isert_rdma_wr *wr = &isert_cmd->rdma_wr; | ||
| 1616 | 1618 | ||
| 1617 | if (cmd->i_state == ISTATE_SEND_TASKMGTRSP || | 1619 | if (cmd->i_state == ISTATE_SEND_TASKMGTRSP || |
| 1618 | cmd->i_state == ISTATE_SEND_LOGOUTRSP || | 1620 | cmd->i_state == ISTATE_SEND_LOGOUTRSP || |
| @@ -1624,7 +1626,7 @@ isert_response_completion(struct iser_tx_desc *tx_desc, | |||
| 1624 | queue_work(isert_comp_wq, &isert_cmd->comp_work); | 1626 | queue_work(isert_comp_wq, &isert_cmd->comp_work); |
| 1625 | return; | 1627 | return; |
| 1626 | } | 1628 | } |
| 1627 | atomic_dec(&isert_conn->post_send_buf_count); | 1629 | atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count); |
| 1628 | 1630 | ||
| 1629 | cmd->i_state = ISTATE_SENT_STATUS; | 1631 | cmd->i_state = ISTATE_SENT_STATUS; |
| 1630 | isert_completion_put(tx_desc, isert_cmd, ib_dev); | 1632 | isert_completion_put(tx_desc, isert_cmd, ib_dev); |
| @@ -1662,7 +1664,7 @@ __isert_send_completion(struct iser_tx_desc *tx_desc, | |||
| 1662 | case ISER_IB_RDMA_READ: | 1664 | case ISER_IB_RDMA_READ: |
| 1663 | pr_debug("isert_send_completion: Got ISER_IB_RDMA_READ:\n"); | 1665 | pr_debug("isert_send_completion: Got ISER_IB_RDMA_READ:\n"); |
| 1664 | 1666 | ||
| 1665 | atomic_dec(&isert_conn->post_send_buf_count); | 1667 | atomic_sub(wr->send_wr_num, &isert_conn->post_send_buf_count); |
| 1666 | isert_completion_rdma_read(tx_desc, isert_cmd); | 1668 | isert_completion_rdma_read(tx_desc, isert_cmd); |
| 1667 | break; | 1669 | break; |
| 1668 | default: | 1670 | default: |
| @@ -1691,31 +1693,76 @@ isert_send_completion(struct iser_tx_desc *tx_desc, | |||
| 1691 | } | 1693 | } |
| 1692 | 1694 | ||
| 1693 | static void | 1695 | static void |
| 1694 | isert_cq_comp_err(struct iser_tx_desc *tx_desc, struct isert_conn *isert_conn) | 1696 | isert_cq_drain_comp_llist(struct isert_conn *isert_conn, struct ib_device *ib_dev) |
| 1697 | { | ||
| 1698 | struct llist_node *llnode; | ||
| 1699 | struct isert_rdma_wr *wr; | ||
| 1700 | struct iser_tx_desc *t; | ||
| 1701 | |||
| 1702 | mutex_lock(&isert_conn->conn_mutex); | ||
| 1703 | llnode = llist_del_all(&isert_conn->conn_comp_llist); | ||
| 1704 | isert_conn->conn_comp_batch = 0; | ||
| 1705 | mutex_unlock(&isert_conn->conn_mutex); | ||
| 1706 | |||
| 1707 | while (llnode) { | ||
| 1708 | t = llist_entry(llnode, struct iser_tx_desc, comp_llnode); | ||
| 1709 | llnode = llist_next(llnode); | ||
| 1710 | wr = &t->isert_cmd->rdma_wr; | ||
| 1711 | |||
| 1712 | atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count); | ||
| 1713 | isert_completion_put(t, t->isert_cmd, ib_dev); | ||
| 1714 | } | ||
| 1715 | } | ||
| 1716 | |||
| 1717 | static void | ||
| 1718 | isert_cq_tx_comp_err(struct iser_tx_desc *tx_desc, struct isert_conn *isert_conn) | ||
| 1695 | { | 1719 | { |
| 1696 | struct ib_device *ib_dev = isert_conn->conn_cm_id->device; | 1720 | struct ib_device *ib_dev = isert_conn->conn_cm_id->device; |
| 1721 | struct isert_cmd *isert_cmd = tx_desc->isert_cmd; | ||
| 1722 | struct llist_node *llnode = tx_desc->comp_llnode_batch; | ||
| 1723 | struct isert_rdma_wr *wr; | ||
| 1724 | struct iser_tx_desc *t; | ||
| 1697 | 1725 | ||
| 1698 | if (tx_desc) { | 1726 | while (llnode) { |
| 1699 | struct isert_cmd *isert_cmd = tx_desc->isert_cmd; | 1727 | t = llist_entry(llnode, struct iser_tx_desc, comp_llnode); |
| 1728 | llnode = llist_next(llnode); | ||
| 1729 | wr = &t->isert_cmd->rdma_wr; | ||
| 1700 | 1730 | ||
| 1701 | if (!isert_cmd) | 1731 | atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count); |
| 1702 | isert_unmap_tx_desc(tx_desc, ib_dev); | 1732 | isert_completion_put(t, t->isert_cmd, ib_dev); |
| 1703 | else | ||
| 1704 | isert_completion_put(tx_desc, isert_cmd, ib_dev); | ||
| 1705 | } | 1733 | } |
| 1734 | tx_desc->comp_llnode_batch = NULL; | ||
| 1706 | 1735 | ||
| 1707 | if (isert_conn->post_recv_buf_count == 0 && | 1736 | if (!isert_cmd) |
| 1708 | atomic_read(&isert_conn->post_send_buf_count) == 0) { | 1737 | isert_unmap_tx_desc(tx_desc, ib_dev); |
| 1709 | pr_debug("isert_cq_comp_err >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); | 1738 | else |
| 1710 | pr_debug("Calling wake_up from isert_cq_comp_err\n"); | 1739 | isert_completion_put(tx_desc, isert_cmd, ib_dev); |
| 1740 | } | ||
| 1711 | 1741 | ||
| 1712 | mutex_lock(&isert_conn->conn_mutex); | 1742 | static void |
| 1713 | if (isert_conn->state != ISER_CONN_DOWN) | 1743 | isert_cq_rx_comp_err(struct isert_conn *isert_conn) |
| 1714 | isert_conn->state = ISER_CONN_TERMINATING; | 1744 | { |
| 1715 | mutex_unlock(&isert_conn->conn_mutex); | 1745 | struct ib_device *ib_dev = isert_conn->conn_cm_id->device; |
| 1746 | struct iscsi_conn *conn = isert_conn->conn; | ||
| 1716 | 1747 | ||
| 1717 | wake_up(&isert_conn->conn_wait_comp_err); | 1748 | if (isert_conn->post_recv_buf_count) |
| 1749 | return; | ||
| 1750 | |||
| 1751 | isert_cq_drain_comp_llist(isert_conn, ib_dev); | ||
| 1752 | |||
| 1753 | if (conn->sess) { | ||
| 1754 | target_sess_cmd_list_set_waiting(conn->sess->se_sess); | ||
| 1755 | target_wait_for_sess_cmds(conn->sess->se_sess); | ||
| 1718 | } | 1756 | } |
| 1757 | |||
| 1758 | while (atomic_read(&isert_conn->post_send_buf_count)) | ||
| 1759 | msleep(3000); | ||
| 1760 | |||
| 1761 | mutex_lock(&isert_conn->conn_mutex); | ||
| 1762 | isert_conn->state = ISER_CONN_DOWN; | ||
| 1763 | mutex_unlock(&isert_conn->conn_mutex); | ||
| 1764 | |||
| 1765 | complete(&isert_conn->conn_wait_comp_err); | ||
| 1719 | } | 1766 | } |
| 1720 | 1767 | ||
| 1721 | static void | 1768 | static void |
| @@ -1740,8 +1787,14 @@ isert_cq_tx_work(struct work_struct *work) | |||
| 1740 | pr_debug("TX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n"); | 1787 | pr_debug("TX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n"); |
| 1741 | pr_debug("TX wc.status: 0x%08x\n", wc.status); | 1788 | pr_debug("TX wc.status: 0x%08x\n", wc.status); |
| 1742 | pr_debug("TX wc.vendor_err: 0x%08x\n", wc.vendor_err); | 1789 | pr_debug("TX wc.vendor_err: 0x%08x\n", wc.vendor_err); |
| 1743 | atomic_dec(&isert_conn->post_send_buf_count); | 1790 | |
| 1744 | isert_cq_comp_err(tx_desc, isert_conn); | 1791 | if (wc.wr_id != ISER_FASTREG_LI_WRID) { |
| 1792 | if (tx_desc->llnode_active) | ||
| 1793 | continue; | ||
| 1794 | |||
| 1795 | atomic_dec(&isert_conn->post_send_buf_count); | ||
| 1796 | isert_cq_tx_comp_err(tx_desc, isert_conn); | ||
| 1797 | } | ||
| 1745 | } | 1798 | } |
| 1746 | } | 1799 | } |
| 1747 | 1800 | ||
| @@ -1784,7 +1837,7 @@ isert_cq_rx_work(struct work_struct *work) | |||
| 1784 | wc.vendor_err); | 1837 | wc.vendor_err); |
| 1785 | } | 1838 | } |
| 1786 | isert_conn->post_recv_buf_count--; | 1839 | isert_conn->post_recv_buf_count--; |
| 1787 | isert_cq_comp_err(NULL, isert_conn); | 1840 | isert_cq_rx_comp_err(isert_conn); |
| 1788 | } | 1841 | } |
| 1789 | } | 1842 | } |
| 1790 | 1843 | ||
| @@ -2202,6 +2255,7 @@ isert_fast_reg_mr(struct fast_reg_descriptor *fr_desc, | |||
| 2202 | 2255 | ||
| 2203 | if (!fr_desc->valid) { | 2256 | if (!fr_desc->valid) { |
| 2204 | memset(&inv_wr, 0, sizeof(inv_wr)); | 2257 | memset(&inv_wr, 0, sizeof(inv_wr)); |
| 2258 | inv_wr.wr_id = ISER_FASTREG_LI_WRID; | ||
| 2205 | inv_wr.opcode = IB_WR_LOCAL_INV; | 2259 | inv_wr.opcode = IB_WR_LOCAL_INV; |
| 2206 | inv_wr.ex.invalidate_rkey = fr_desc->data_mr->rkey; | 2260 | inv_wr.ex.invalidate_rkey = fr_desc->data_mr->rkey; |
| 2207 | wr = &inv_wr; | 2261 | wr = &inv_wr; |
| @@ -2212,6 +2266,7 @@ isert_fast_reg_mr(struct fast_reg_descriptor *fr_desc, | |||
| 2212 | 2266 | ||
| 2213 | /* Prepare FASTREG WR */ | 2267 | /* Prepare FASTREG WR */ |
| 2214 | memset(&fr_wr, 0, sizeof(fr_wr)); | 2268 | memset(&fr_wr, 0, sizeof(fr_wr)); |
| 2269 | fr_wr.wr_id = ISER_FASTREG_LI_WRID; | ||
| 2215 | fr_wr.opcode = IB_WR_FAST_REG_MR; | 2270 | fr_wr.opcode = IB_WR_FAST_REG_MR; |
| 2216 | fr_wr.wr.fast_reg.iova_start = | 2271 | fr_wr.wr.fast_reg.iova_start = |
| 2217 | fr_desc->data_frpl->page_list[0] + page_off; | 2272 | fr_desc->data_frpl->page_list[0] + page_off; |
| @@ -2377,12 +2432,12 @@ isert_put_datain(struct iscsi_conn *conn, struct iscsi_cmd *cmd) | |||
| 2377 | isert_init_send_wr(isert_conn, isert_cmd, | 2432 | isert_init_send_wr(isert_conn, isert_cmd, |
| 2378 | &isert_cmd->tx_desc.send_wr, true); | 2433 | &isert_cmd->tx_desc.send_wr, true); |
| 2379 | 2434 | ||
| 2380 | atomic_inc(&isert_conn->post_send_buf_count); | 2435 | atomic_add(wr->send_wr_num + 1, &isert_conn->post_send_buf_count); |
| 2381 | 2436 | ||
| 2382 | rc = ib_post_send(isert_conn->conn_qp, wr->send_wr, &wr_failed); | 2437 | rc = ib_post_send(isert_conn->conn_qp, wr->send_wr, &wr_failed); |
| 2383 | if (rc) { | 2438 | if (rc) { |
| 2384 | pr_warn("ib_post_send() failed for IB_WR_RDMA_WRITE\n"); | 2439 | pr_warn("ib_post_send() failed for IB_WR_RDMA_WRITE\n"); |
| 2385 | atomic_dec(&isert_conn->post_send_buf_count); | 2440 | atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count); |
| 2386 | } | 2441 | } |
| 2387 | pr_debug("Cmd: %p posted RDMA_WRITE + Response for iSER Data READ\n", | 2442 | pr_debug("Cmd: %p posted RDMA_WRITE + Response for iSER Data READ\n", |
| 2388 | isert_cmd); | 2443 | isert_cmd); |
| @@ -2410,12 +2465,12 @@ isert_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd, bool recovery) | |||
| 2410 | return rc; | 2465 | return rc; |
| 2411 | } | 2466 | } |
| 2412 | 2467 | ||
| 2413 | atomic_inc(&isert_conn->post_send_buf_count); | 2468 | atomic_add(wr->send_wr_num, &isert_conn->post_send_buf_count); |
| 2414 | 2469 | ||
| 2415 | rc = ib_post_send(isert_conn->conn_qp, wr->send_wr, &wr_failed); | 2470 | rc = ib_post_send(isert_conn->conn_qp, wr->send_wr, &wr_failed); |
| 2416 | if (rc) { | 2471 | if (rc) { |
| 2417 | pr_warn("ib_post_send() failed for IB_WR_RDMA_READ\n"); | 2472 | pr_warn("ib_post_send() failed for IB_WR_RDMA_READ\n"); |
| 2418 | atomic_dec(&isert_conn->post_send_buf_count); | 2473 | atomic_sub(wr->send_wr_num, &isert_conn->post_send_buf_count); |
| 2419 | } | 2474 | } |
| 2420 | pr_debug("Cmd: %p posted RDMA_READ memory for ISER Data WRITE\n", | 2475 | pr_debug("Cmd: %p posted RDMA_READ memory for ISER Data WRITE\n", |
| 2421 | isert_cmd); | 2476 | isert_cmd); |
| @@ -2702,22 +2757,11 @@ isert_free_np(struct iscsi_np *np) | |||
| 2702 | kfree(isert_np); | 2757 | kfree(isert_np); |
| 2703 | } | 2758 | } |
| 2704 | 2759 | ||
| 2705 | static int isert_check_state(struct isert_conn *isert_conn, int state) | 2760 | static void isert_wait_conn(struct iscsi_conn *conn) |
| 2706 | { | ||
| 2707 | int ret; | ||
| 2708 | |||
| 2709 | mutex_lock(&isert_conn->conn_mutex); | ||
| 2710 | ret = (isert_conn->state == state); | ||
| 2711 | mutex_unlock(&isert_conn->conn_mutex); | ||
| 2712 | |||
| 2713 | return ret; | ||
| 2714 | } | ||
| 2715 | |||
| 2716 | static void isert_free_conn(struct iscsi_conn *conn) | ||
| 2717 | { | 2761 | { |
| 2718 | struct isert_conn *isert_conn = conn->context; | 2762 | struct isert_conn *isert_conn = conn->context; |
| 2719 | 2763 | ||
| 2720 | pr_debug("isert_free_conn: Starting \n"); | 2764 | pr_debug("isert_wait_conn: Starting \n"); |
| 2721 | /* | 2765 | /* |
| 2722 | * Decrement post_send_buf_count for special case when called | 2766 | * Decrement post_send_buf_count for special case when called |
| 2723 | * from isert_do_control_comp() -> iscsit_logout_post_handler() | 2767 | * from isert_do_control_comp() -> iscsit_logout_post_handler() |
| @@ -2727,38 +2771,29 @@ static void isert_free_conn(struct iscsi_conn *conn) | |||
| 2727 | atomic_dec(&isert_conn->post_send_buf_count); | 2771 | atomic_dec(&isert_conn->post_send_buf_count); |
| 2728 | 2772 | ||
| 2729 | if (isert_conn->conn_cm_id && isert_conn->state != ISER_CONN_DOWN) { | 2773 | if (isert_conn->conn_cm_id && isert_conn->state != ISER_CONN_DOWN) { |
| 2730 | pr_debug("Calling rdma_disconnect from isert_free_conn\n"); | 2774 | pr_debug("Calling rdma_disconnect from isert_wait_conn\n"); |
| 2731 | rdma_disconnect(isert_conn->conn_cm_id); | 2775 | rdma_disconnect(isert_conn->conn_cm_id); |
| 2732 | } | 2776 | } |
| 2733 | /* | 2777 | /* |
| 2734 | * Only wait for conn_wait_comp_err if the isert_conn made it | 2778 | * Only wait for conn_wait_comp_err if the isert_conn made it |
| 2735 | * into full feature phase.. | 2779 | * into full feature phase.. |
| 2736 | */ | 2780 | */ |
| 2737 | if (isert_conn->state == ISER_CONN_UP) { | ||
| 2738 | pr_debug("isert_free_conn: Before wait_event comp_err %d\n", | ||
| 2739 | isert_conn->state); | ||
| 2740 | mutex_unlock(&isert_conn->conn_mutex); | ||
| 2741 | |||
| 2742 | wait_event(isert_conn->conn_wait_comp_err, | ||
| 2743 | (isert_check_state(isert_conn, ISER_CONN_TERMINATING))); | ||
| 2744 | |||
| 2745 | wait_event(isert_conn->conn_wait, | ||
| 2746 | (isert_check_state(isert_conn, ISER_CONN_DOWN))); | ||
| 2747 | |||
| 2748 | isert_put_conn(isert_conn); | ||
| 2749 | return; | ||
| 2750 | } | ||
| 2751 | if (isert_conn->state == ISER_CONN_INIT) { | 2781 | if (isert_conn->state == ISER_CONN_INIT) { |
| 2752 | mutex_unlock(&isert_conn->conn_mutex); | 2782 | mutex_unlock(&isert_conn->conn_mutex); |
| 2753 | isert_put_conn(isert_conn); | ||
| 2754 | return; | 2783 | return; |
| 2755 | } | 2784 | } |
| 2756 | pr_debug("isert_free_conn: wait_event conn_wait %d\n", | 2785 | if (isert_conn->state == ISER_CONN_UP) |
| 2757 | isert_conn->state); | 2786 | isert_conn->state = ISER_CONN_TERMINATING; |
| 2758 | mutex_unlock(&isert_conn->conn_mutex); | 2787 | mutex_unlock(&isert_conn->conn_mutex); |
| 2759 | 2788 | ||
| 2760 | wait_event(isert_conn->conn_wait, | 2789 | wait_for_completion(&isert_conn->conn_wait_comp_err); |
| 2761 | (isert_check_state(isert_conn, ISER_CONN_DOWN))); | 2790 | |
| 2791 | wait_for_completion(&isert_conn->conn_wait); | ||
| 2792 | } | ||
| 2793 | |||
| 2794 | static void isert_free_conn(struct iscsi_conn *conn) | ||
| 2795 | { | ||
| 2796 | struct isert_conn *isert_conn = conn->context; | ||
| 2762 | 2797 | ||
| 2763 | isert_put_conn(isert_conn); | 2798 | isert_put_conn(isert_conn); |
| 2764 | } | 2799 | } |
| @@ -2771,6 +2806,7 @@ static struct iscsit_transport iser_target_transport = { | |||
| 2771 | .iscsit_setup_np = isert_setup_np, | 2806 | .iscsit_setup_np = isert_setup_np, |
| 2772 | .iscsit_accept_np = isert_accept_np, | 2807 | .iscsit_accept_np = isert_accept_np, |
| 2773 | .iscsit_free_np = isert_free_np, | 2808 | .iscsit_free_np = isert_free_np, |
| 2809 | .iscsit_wait_conn = isert_wait_conn, | ||
| 2774 | .iscsit_free_conn = isert_free_conn, | 2810 | .iscsit_free_conn = isert_free_conn, |
| 2775 | .iscsit_get_login_rx = isert_get_login_rx, | 2811 | .iscsit_get_login_rx = isert_get_login_rx, |
| 2776 | .iscsit_put_login_tx = isert_put_login_tx, | 2812 | .iscsit_put_login_tx = isert_put_login_tx, |
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h index 708a069002f3..f6ae7f5dd408 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #define ISERT_RDMA_LISTEN_BACKLOG 10 | 7 | #define ISERT_RDMA_LISTEN_BACKLOG 10 |
| 8 | #define ISCSI_ISER_SG_TABLESIZE 256 | 8 | #define ISCSI_ISER_SG_TABLESIZE 256 |
| 9 | #define ISER_FASTREG_LI_WRID 0xffffffffffffffffULL | ||
| 9 | 10 | ||
| 10 | enum isert_desc_type { | 11 | enum isert_desc_type { |
| 11 | ISCSI_TX_CONTROL, | 12 | ISCSI_TX_CONTROL, |
| @@ -45,6 +46,7 @@ struct iser_tx_desc { | |||
| 45 | struct isert_cmd *isert_cmd; | 46 | struct isert_cmd *isert_cmd; |
| 46 | struct llist_node *comp_llnode_batch; | 47 | struct llist_node *comp_llnode_batch; |
| 47 | struct llist_node comp_llnode; | 48 | struct llist_node comp_llnode; |
| 49 | bool llnode_active; | ||
| 48 | struct ib_send_wr send_wr; | 50 | struct ib_send_wr send_wr; |
| 49 | } __packed; | 51 | } __packed; |
| 50 | 52 | ||
| @@ -116,8 +118,8 @@ struct isert_conn { | |||
| 116 | struct isert_device *conn_device; | 118 | struct isert_device *conn_device; |
| 117 | struct work_struct conn_logout_work; | 119 | struct work_struct conn_logout_work; |
| 118 | struct mutex conn_mutex; | 120 | struct mutex conn_mutex; |
| 119 | wait_queue_head_t conn_wait; | 121 | struct completion conn_wait; |
| 120 | wait_queue_head_t conn_wait_comp_err; | 122 | struct completion conn_wait_comp_err; |
| 121 | struct kref conn_kref; | 123 | struct kref conn_kref; |
| 122 | struct list_head conn_fr_pool; | 124 | struct list_head conn_fr_pool; |
| 123 | int conn_fr_pool_size; | 125 | int conn_fr_pool_size; |
| @@ -126,7 +128,6 @@ struct isert_conn { | |||
| 126 | #define ISERT_COMP_BATCH_COUNT 8 | 128 | #define ISERT_COMP_BATCH_COUNT 8 |
| 127 | int conn_comp_batch; | 129 | int conn_comp_batch; |
| 128 | struct llist_head conn_comp_llist; | 130 | struct llist_head conn_comp_llist; |
| 129 | struct mutex conn_comp_mutex; | ||
| 130 | }; | 131 | }; |
| 131 | 132 | ||
| 132 | #define ISERT_MAX_CQ 64 | 133 | #define ISERT_MAX_CQ 64 |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 7f1a7ce4b771..b83ec378d04f 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
| @@ -785,7 +785,7 @@ static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) | |||
| 785 | spin_unlock_bh(&conn->cmd_lock); | 785 | spin_unlock_bh(&conn->cmd_lock); |
| 786 | 786 | ||
| 787 | list_for_each_entry_safe(cmd, cmd_p, &ack_list, i_conn_node) { | 787 | list_for_each_entry_safe(cmd, cmd_p, &ack_list, i_conn_node) { |
| 788 | list_del(&cmd->i_conn_node); | 788 | list_del_init(&cmd->i_conn_node); |
| 789 | iscsit_free_cmd(cmd, false); | 789 | iscsit_free_cmd(cmd, false); |
| 790 | } | 790 | } |
| 791 | } | 791 | } |
| @@ -3708,7 +3708,7 @@ iscsit_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state | |||
| 3708 | break; | 3708 | break; |
| 3709 | case ISTATE_REMOVE: | 3709 | case ISTATE_REMOVE: |
| 3710 | spin_lock_bh(&conn->cmd_lock); | 3710 | spin_lock_bh(&conn->cmd_lock); |
| 3711 | list_del(&cmd->i_conn_node); | 3711 | list_del_init(&cmd->i_conn_node); |
| 3712 | spin_unlock_bh(&conn->cmd_lock); | 3712 | spin_unlock_bh(&conn->cmd_lock); |
| 3713 | 3713 | ||
| 3714 | iscsit_free_cmd(cmd, false); | 3714 | iscsit_free_cmd(cmd, false); |
| @@ -4151,7 +4151,7 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) | |||
| 4151 | spin_lock_bh(&conn->cmd_lock); | 4151 | spin_lock_bh(&conn->cmd_lock); |
| 4152 | list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_conn_node) { | 4152 | list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_conn_node) { |
| 4153 | 4153 | ||
| 4154 | list_del(&cmd->i_conn_node); | 4154 | list_del_init(&cmd->i_conn_node); |
| 4155 | spin_unlock_bh(&conn->cmd_lock); | 4155 | spin_unlock_bh(&conn->cmd_lock); |
| 4156 | 4156 | ||
| 4157 | iscsit_increment_maxcmdsn(cmd, sess); | 4157 | iscsit_increment_maxcmdsn(cmd, sess); |
| @@ -4196,6 +4196,10 @@ int iscsit_close_connection( | |||
| 4196 | iscsit_stop_timers_for_cmds(conn); | 4196 | iscsit_stop_timers_for_cmds(conn); |
| 4197 | iscsit_stop_nopin_response_timer(conn); | 4197 | iscsit_stop_nopin_response_timer(conn); |
| 4198 | iscsit_stop_nopin_timer(conn); | 4198 | iscsit_stop_nopin_timer(conn); |
| 4199 | |||
| 4200 | if (conn->conn_transport->iscsit_wait_conn) | ||
| 4201 | conn->conn_transport->iscsit_wait_conn(conn); | ||
| 4202 | |||
| 4199 | iscsit_free_queue_reqs_for_conn(conn); | 4203 | iscsit_free_queue_reqs_for_conn(conn); |
| 4200 | 4204 | ||
| 4201 | /* | 4205 | /* |
diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c index 33be1fb1df32..4ca8fd2a70db 100644 --- a/drivers/target/iscsi/iscsi_target_erl2.c +++ b/drivers/target/iscsi/iscsi_target_erl2.c | |||
| @@ -138,7 +138,7 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess) | |||
| 138 | list_for_each_entry_safe(cmd, cmd_tmp, | 138 | list_for_each_entry_safe(cmd, cmd_tmp, |
| 139 | &cr->conn_recovery_cmd_list, i_conn_node) { | 139 | &cr->conn_recovery_cmd_list, i_conn_node) { |
| 140 | 140 | ||
| 141 | list_del(&cmd->i_conn_node); | 141 | list_del_init(&cmd->i_conn_node); |
| 142 | cmd->conn = NULL; | 142 | cmd->conn = NULL; |
| 143 | spin_unlock(&cr->conn_recovery_cmd_lock); | 143 | spin_unlock(&cr->conn_recovery_cmd_lock); |
| 144 | iscsit_free_cmd(cmd, true); | 144 | iscsit_free_cmd(cmd, true); |
| @@ -160,7 +160,7 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess) | |||
| 160 | list_for_each_entry_safe(cmd, cmd_tmp, | 160 | list_for_each_entry_safe(cmd, cmd_tmp, |
| 161 | &cr->conn_recovery_cmd_list, i_conn_node) { | 161 | &cr->conn_recovery_cmd_list, i_conn_node) { |
| 162 | 162 | ||
| 163 | list_del(&cmd->i_conn_node); | 163 | list_del_init(&cmd->i_conn_node); |
| 164 | cmd->conn = NULL; | 164 | cmd->conn = NULL; |
| 165 | spin_unlock(&cr->conn_recovery_cmd_lock); | 165 | spin_unlock(&cr->conn_recovery_cmd_lock); |
| 166 | iscsit_free_cmd(cmd, true); | 166 | iscsit_free_cmd(cmd, true); |
| @@ -216,7 +216,7 @@ int iscsit_remove_cmd_from_connection_recovery( | |||
| 216 | } | 216 | } |
| 217 | cr = cmd->cr; | 217 | cr = cmd->cr; |
| 218 | 218 | ||
| 219 | list_del(&cmd->i_conn_node); | 219 | list_del_init(&cmd->i_conn_node); |
| 220 | return --cr->cmd_count; | 220 | return --cr->cmd_count; |
| 221 | } | 221 | } |
| 222 | 222 | ||
| @@ -297,7 +297,7 @@ int iscsit_discard_unacknowledged_ooo_cmdsns_for_conn(struct iscsi_conn *conn) | |||
| 297 | if (!(cmd->cmd_flags & ICF_OOO_CMDSN)) | 297 | if (!(cmd->cmd_flags & ICF_OOO_CMDSN)) |
| 298 | continue; | 298 | continue; |
| 299 | 299 | ||
| 300 | list_del(&cmd->i_conn_node); | 300 | list_del_init(&cmd->i_conn_node); |
| 301 | 301 | ||
| 302 | spin_unlock_bh(&conn->cmd_lock); | 302 | spin_unlock_bh(&conn->cmd_lock); |
| 303 | iscsit_free_cmd(cmd, true); | 303 | iscsit_free_cmd(cmd, true); |
| @@ -335,7 +335,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) | |||
| 335 | /* | 335 | /* |
| 336 | * Only perform connection recovery on ISCSI_OP_SCSI_CMD or | 336 | * Only perform connection recovery on ISCSI_OP_SCSI_CMD or |
| 337 | * ISCSI_OP_NOOP_OUT opcodes. For all other opcodes call | 337 | * ISCSI_OP_NOOP_OUT opcodes. For all other opcodes call |
| 338 | * list_del(&cmd->i_conn_node); to release the command to the | 338 | * list_del_init(&cmd->i_conn_node); to release the command to the |
| 339 | * session pool and remove it from the connection's list. | 339 | * session pool and remove it from the connection's list. |
| 340 | * | 340 | * |
| 341 | * Also stop the DataOUT timer, which will be restarted after | 341 | * Also stop the DataOUT timer, which will be restarted after |
| @@ -351,7 +351,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) | |||
| 351 | " CID: %hu\n", cmd->iscsi_opcode, | 351 | " CID: %hu\n", cmd->iscsi_opcode, |
| 352 | cmd->init_task_tag, cmd->cmd_sn, conn->cid); | 352 | cmd->init_task_tag, cmd->cmd_sn, conn->cid); |
| 353 | 353 | ||
| 354 | list_del(&cmd->i_conn_node); | 354 | list_del_init(&cmd->i_conn_node); |
| 355 | spin_unlock_bh(&conn->cmd_lock); | 355 | spin_unlock_bh(&conn->cmd_lock); |
| 356 | iscsit_free_cmd(cmd, true); | 356 | iscsit_free_cmd(cmd, true); |
| 357 | spin_lock_bh(&conn->cmd_lock); | 357 | spin_lock_bh(&conn->cmd_lock); |
| @@ -371,7 +371,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) | |||
| 371 | */ | 371 | */ |
| 372 | if (!(cmd->cmd_flags & ICF_OOO_CMDSN) && !cmd->immediate_cmd && | 372 | if (!(cmd->cmd_flags & ICF_OOO_CMDSN) && !cmd->immediate_cmd && |
| 373 | iscsi_sna_gte(cmd->cmd_sn, conn->sess->exp_cmd_sn)) { | 373 | iscsi_sna_gte(cmd->cmd_sn, conn->sess->exp_cmd_sn)) { |
| 374 | list_del(&cmd->i_conn_node); | 374 | list_del_init(&cmd->i_conn_node); |
| 375 | spin_unlock_bh(&conn->cmd_lock); | 375 | spin_unlock_bh(&conn->cmd_lock); |
| 376 | iscsit_free_cmd(cmd, true); | 376 | iscsit_free_cmd(cmd, true); |
| 377 | spin_lock_bh(&conn->cmd_lock); | 377 | spin_lock_bh(&conn->cmd_lock); |
| @@ -393,7 +393,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) | |||
| 393 | 393 | ||
| 394 | cmd->sess = conn->sess; | 394 | cmd->sess = conn->sess; |
| 395 | 395 | ||
| 396 | list_del(&cmd->i_conn_node); | 396 | list_del_init(&cmd->i_conn_node); |
| 397 | spin_unlock_bh(&conn->cmd_lock); | 397 | spin_unlock_bh(&conn->cmd_lock); |
| 398 | 398 | ||
| 399 | iscsit_free_all_datain_reqs(cmd); | 399 | iscsit_free_all_datain_reqs(cmd); |
diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index 39761837608d..44a5471de00f 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c | |||
| @@ -137,7 +137,7 @@ struct iscsi_portal_group *iscsit_get_tpg_from_np( | |||
| 137 | list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) { | 137 | list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) { |
| 138 | 138 | ||
| 139 | spin_lock(&tpg->tpg_state_lock); | 139 | spin_lock(&tpg->tpg_state_lock); |
| 140 | if (tpg->tpg_state == TPG_STATE_FREE) { | 140 | if (tpg->tpg_state != TPG_STATE_ACTIVE) { |
| 141 | spin_unlock(&tpg->tpg_state_lock); | 141 | spin_unlock(&tpg->tpg_state_lock); |
| 142 | continue; | 142 | continue; |
| 143 | } | 143 | } |
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 42f18fc1067b..77e6531fb0a1 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
| @@ -1079,25 +1079,31 @@ sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read, | |||
| 1079 | left = sectors * dev->prot_length; | 1079 | left = sectors * dev->prot_length; |
| 1080 | 1080 | ||
| 1081 | for_each_sg(cmd->t_prot_sg, psg, cmd->t_prot_nents, i) { | 1081 | for_each_sg(cmd->t_prot_sg, psg, cmd->t_prot_nents, i) { |
| 1082 | 1082 | unsigned int psg_len, copied = 0; | |
| 1083 | len = min(psg->length, left); | ||
| 1084 | if (offset >= sg->length) { | ||
| 1085 | sg = sg_next(sg); | ||
| 1086 | offset = 0; | ||
| 1087 | } | ||
| 1088 | 1083 | ||
| 1089 | paddr = kmap_atomic(sg_page(psg)) + psg->offset; | 1084 | paddr = kmap_atomic(sg_page(psg)) + psg->offset; |
| 1090 | addr = kmap_atomic(sg_page(sg)) + sg->offset + offset; | 1085 | psg_len = min(left, psg->length); |
| 1091 | 1086 | while (psg_len) { | |
| 1092 | if (read) | 1087 | len = min(psg_len, sg->length - offset); |
| 1093 | memcpy(paddr, addr, len); | 1088 | addr = kmap_atomic(sg_page(sg)) + sg->offset + offset; |
| 1094 | else | 1089 | |
| 1095 | memcpy(addr, paddr, len); | 1090 | if (read) |
| 1096 | 1091 | memcpy(paddr + copied, addr, len); | |
| 1097 | left -= len; | 1092 | else |
| 1098 | offset += len; | 1093 | memcpy(addr, paddr + copied, len); |
| 1094 | |||
| 1095 | left -= len; | ||
| 1096 | offset += len; | ||
| 1097 | copied += len; | ||
| 1098 | psg_len -= len; | ||
| 1099 | |||
| 1100 | if (offset >= sg->length) { | ||
| 1101 | sg = sg_next(sg); | ||
| 1102 | offset = 0; | ||
| 1103 | } | ||
| 1104 | kunmap_atomic(addr); | ||
| 1105 | } | ||
| 1099 | kunmap_atomic(paddr); | 1106 | kunmap_atomic(paddr); |
| 1100 | kunmap_atomic(addr); | ||
| 1101 | } | 1107 | } |
| 1102 | } | 1108 | } |
| 1103 | 1109 | ||
diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h index ae5a17111968..4483fadfa68d 100644 --- a/include/target/iscsi/iscsi_transport.h +++ b/include/target/iscsi/iscsi_transport.h | |||
| @@ -12,6 +12,7 @@ struct iscsit_transport { | |||
| 12 | int (*iscsit_setup_np)(struct iscsi_np *, struct __kernel_sockaddr_storage *); | 12 | int (*iscsit_setup_np)(struct iscsi_np *, struct __kernel_sockaddr_storage *); |
| 13 | int (*iscsit_accept_np)(struct iscsi_np *, struct iscsi_conn *); | 13 | int (*iscsit_accept_np)(struct iscsi_np *, struct iscsi_conn *); |
| 14 | void (*iscsit_free_np)(struct iscsi_np *); | 14 | void (*iscsit_free_np)(struct iscsi_np *); |
| 15 | void (*iscsit_wait_conn)(struct iscsi_conn *); | ||
| 15 | void (*iscsit_free_conn)(struct iscsi_conn *); | 16 | void (*iscsit_free_conn)(struct iscsi_conn *); |
| 16 | int (*iscsit_get_login_rx)(struct iscsi_conn *, struct iscsi_login *); | 17 | int (*iscsit_get_login_rx)(struct iscsi_conn *, struct iscsi_login *); |
| 17 | int (*iscsit_put_login_tx)(struct iscsi_conn *, struct iscsi_login *, u32); | 18 | int (*iscsit_put_login_tx)(struct iscsi_conn *, struct iscsi_login *, u32); |
