aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/cxgbi
diff options
context:
space:
mode:
authorkxie@chelsio.com <kxie@chelsio.com>2010-09-23 19:43:23 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-10-07 18:20:42 -0400
commite3d2ad8cb2775e4201446489efd1cf26c5bbce5c (patch)
treed5aa3e14f43072338a75555e6436c07aefe21bd1 /drivers/scsi/cxgbi
parent24d3f95a5b6082ca4aba89071ca6259e15d3e564 (diff)
[SCSI] libcxgbi: pdu read fixes
Fixed the locking and releasing skb in the case of error in the pdu read path, and added define iscsi_task_cxgbi_data to access the private data inside the iscsi_task. Signed-off-by: Karen Xie <kxie@chelsio.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/cxgbi')
-rw-r--r--drivers/scsi/cxgbi/libcxgbi.c79
-rw-r--r--drivers/scsi/cxgbi/libcxgbi.h2
2 files changed, 53 insertions, 28 deletions
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index db9d08a831d0..6cfce2726ea3 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -593,11 +593,11 @@ static void cxgbi_inform_iscsi_conn_closing(struct cxgbi_sock *csk)
593 csk, csk->state, csk->flags, csk->user_data); 593 csk, csk->state, csk->flags, csk->user_data);
594 594
595 if (csk->state != CTP_ESTABLISHED) { 595 if (csk->state != CTP_ESTABLISHED) {
596 read_lock(&csk->callback_lock); 596 read_lock_bh(&csk->callback_lock);
597 if (csk->user_data) 597 if (csk->user_data)
598 iscsi_conn_failure(csk->user_data, 598 iscsi_conn_failure(csk->user_data,
599 ISCSI_ERR_CONN_FAILED); 599 ISCSI_ERR_CONN_FAILED);
600 read_unlock(&csk->callback_lock); 600 read_unlock_bh(&csk->callback_lock);
601 } 601 }
602} 602}
603 603
@@ -1712,12 +1712,10 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)
1712 "csk 0x%p, conn 0x%p, id %d, suspend_rx %lu!\n", 1712 "csk 0x%p, conn 0x%p, id %d, suspend_rx %lu!\n",
1713 csk, conn, conn ? conn->id : 0xFF, 1713 csk, conn, conn ? conn->id : 0xFF,
1714 conn ? conn->suspend_rx : 0xFF); 1714 conn ? conn->suspend_rx : 0xFF);
1715 read_unlock(&csk->callback_lock);
1716 return; 1715 return;
1717 } 1716 }
1718 1717
1719 while (!err) { 1718 while (!err) {
1720 read_lock(&csk->callback_lock);
1721 skb = skb_peek(&csk->receive_queue); 1719 skb = skb_peek(&csk->receive_queue);
1722 if (!skb || 1720 if (!skb ||
1723 !(cxgbi_skcb_test_flag(skb, SKCBF_RX_STATUS))) { 1721 !(cxgbi_skcb_test_flag(skb, SKCBF_RX_STATUS))) {
@@ -1725,11 +1723,9 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)
1725 log_debug(1 << CXGBI_DBG_PDU_RX, 1723 log_debug(1 << CXGBI_DBG_PDU_RX,
1726 "skb 0x%p, NOT ready 0x%lx.\n", 1724 "skb 0x%p, NOT ready 0x%lx.\n",
1727 skb, cxgbi_skcb_flags(skb)); 1725 skb, cxgbi_skcb_flags(skb));
1728 read_unlock(&csk->callback_lock);
1729 break; 1726 break;
1730 } 1727 }
1731 __skb_unlink(skb, &csk->receive_queue); 1728 __skb_unlink(skb, &csk->receive_queue);
1732 read_unlock(&csk->callback_lock);
1733 1729
1734 read += cxgbi_skcb_rx_pdulen(skb); 1730 read += cxgbi_skcb_rx_pdulen(skb);
1735 log_debug(1 << CXGBI_DBG_PDU_RX, 1731 log_debug(1 << CXGBI_DBG_PDU_RX,
@@ -1739,37 +1735,66 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)
1739 1735
1740 if (cxgbi_skcb_test_flag(skb, SKCBF_RX_COALESCED)) { 1736 if (cxgbi_skcb_test_flag(skb, SKCBF_RX_COALESCED)) {
1741 err = skb_read_pdu_bhs(conn, skb); 1737 err = skb_read_pdu_bhs(conn, skb);
1742 if (err < 0) 1738 if (err < 0) {
1743 break; 1739 pr_err("coalesced bhs, csk 0x%p, skb 0x%p,%u, "
1740 "f 0x%lx, plen %u.\n",
1741 csk, skb, skb->len,
1742 cxgbi_skcb_flags(skb),
1743 cxgbi_skcb_rx_pdulen(skb));
1744 goto skb_done;
1745 }
1744 err = skb_read_pdu_data(conn, skb, skb, 1746 err = skb_read_pdu_data(conn, skb, skb,
1745 err + cdev->skb_rx_extra); 1747 err + cdev->skb_rx_extra);
1748 if (err < 0)
1749 pr_err("coalesced data, csk 0x%p, skb 0x%p,%u, "
1750 "f 0x%lx, plen %u.\n",
1751 csk, skb, skb->len,
1752 cxgbi_skcb_flags(skb),
1753 cxgbi_skcb_rx_pdulen(skb));
1746 } else { 1754 } else {
1747 err = skb_read_pdu_bhs(conn, skb); 1755 err = skb_read_pdu_bhs(conn, skb);
1748 if (err < 0) 1756 if (err < 0) {
1749 break; 1757 pr_err("bhs, csk 0x%p, skb 0x%p,%u, "
1758 "f 0x%lx, plen %u.\n",
1759 csk, skb, skb->len,
1760 cxgbi_skcb_flags(skb),
1761 cxgbi_skcb_rx_pdulen(skb));
1762 goto skb_done;
1763 }
1764
1750 if (cxgbi_skcb_test_flag(skb, SKCBF_RX_DATA)) { 1765 if (cxgbi_skcb_test_flag(skb, SKCBF_RX_DATA)) {
1751 struct sk_buff *dskb; 1766 struct sk_buff *dskb;
1752 1767
1753 read_lock(&csk->callback_lock);
1754 dskb = skb_peek(&csk->receive_queue); 1768 dskb = skb_peek(&csk->receive_queue);
1755 if (!dskb) { 1769 if (!dskb) {
1756 read_unlock(&csk->callback_lock); 1770 pr_err("csk 0x%p, skb 0x%p,%u, f 0x%lx,"
1757 pr_err("csk 0x%p, NO data.\n", csk); 1771 " plen %u, NO data.\n",
1758 err = -EAGAIN; 1772 csk, skb, skb->len,
1759 break; 1773 cxgbi_skcb_flags(skb),
1774 cxgbi_skcb_rx_pdulen(skb));
1775 err = -EIO;
1776 goto skb_done;
1760 } 1777 }
1761 __skb_unlink(dskb, &csk->receive_queue); 1778 __skb_unlink(dskb, &csk->receive_queue);
1762 read_unlock(&csk->callback_lock);
1763 1779
1764 err = skb_read_pdu_data(conn, skb, dskb, 0); 1780 err = skb_read_pdu_data(conn, skb, dskb, 0);
1781 if (err < 0)
1782 pr_err("data, csk 0x%p, skb 0x%p,%u, "
1783 "f 0x%lx, plen %u, dskb 0x%p,"
1784 "%u.\n",
1785 csk, skb, skb->len,
1786 cxgbi_skcb_flags(skb),
1787 cxgbi_skcb_rx_pdulen(skb),
1788 dskb, dskb->len);
1765 __kfree_skb(dskb); 1789 __kfree_skb(dskb);
1766 } else 1790 } else
1767 err = skb_read_pdu_data(conn, skb, skb, 0); 1791 err = skb_read_pdu_data(conn, skb, skb, 0);
1768 } 1792 }
1793skb_done:
1794 __kfree_skb(skb);
1795
1769 if (err < 0) 1796 if (err < 0)
1770 break; 1797 break;
1771
1772 __kfree_skb(skb);
1773 } 1798 }
1774 1799
1775 log_debug(1 << CXGBI_DBG_PDU_RX, "csk 0x%p, read %u.\n", csk, read); 1800 log_debug(1 << CXGBI_DBG_PDU_RX, "csk 0x%p, read %u.\n", csk, read);
@@ -1780,7 +1805,8 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)
1780 } 1805 }
1781 1806
1782 if (err < 0) { 1807 if (err < 0) {
1783 pr_info("csk 0x%p, 0x%p, rx failed %d.\n", csk, conn, err); 1808 pr_info("csk 0x%p, 0x%p, rx failed %d, read %u.\n",
1809 csk, conn, err, read);
1784 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); 1810 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
1785 } 1811 }
1786} 1812}
@@ -1861,7 +1887,7 @@ int cxgbi_conn_alloc_pdu(struct iscsi_task *task, u8 opcode)
1861 struct cxgbi_device *cdev = cconn->chba->cdev; 1887 struct cxgbi_device *cdev = cconn->chba->cdev;
1862 struct iscsi_conn *conn = task->conn; 1888 struct iscsi_conn *conn = task->conn;
1863 struct iscsi_tcp_task *tcp_task = task->dd_data; 1889 struct iscsi_tcp_task *tcp_task = task->dd_data;
1864 struct cxgbi_task_data *tdata = task->dd_data + sizeof(*tcp_task); 1890 struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
1865 struct scsi_cmnd *sc = task->sc; 1891 struct scsi_cmnd *sc = task->sc;
1866 int headroom = SKB_TX_ISCSI_PDU_HEADER_MAX; 1892 int headroom = SKB_TX_ISCSI_PDU_HEADER_MAX;
1867 1893
@@ -1916,8 +1942,7 @@ int cxgbi_conn_init_pdu(struct iscsi_task *task, unsigned int offset,
1916 unsigned int count) 1942 unsigned int count)
1917{ 1943{
1918 struct iscsi_conn *conn = task->conn; 1944 struct iscsi_conn *conn = task->conn;
1919 struct iscsi_tcp_task *tcp_task = task->dd_data; 1945 struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
1920 struct cxgbi_task_data *tdata = tcp_task->dd_data;
1921 struct sk_buff *skb = tdata->skb; 1946 struct sk_buff *skb = tdata->skb;
1922 unsigned int datalen = count; 1947 unsigned int datalen = count;
1923 int i, padlen = iscsi_padding(count); 1948 int i, padlen = iscsi_padding(count);
@@ -2019,8 +2044,7 @@ int cxgbi_conn_xmit_pdu(struct iscsi_task *task)
2019{ 2044{
2020 struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data; 2045 struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data;
2021 struct cxgbi_conn *cconn = tcp_conn->dd_data; 2046 struct cxgbi_conn *cconn = tcp_conn->dd_data;
2022 struct iscsi_tcp_task *tcp_task = task->dd_data; 2047 struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
2023 struct cxgbi_task_data *tdata = tcp_task->dd_data;
2024 struct sk_buff *skb = tdata->skb; 2048 struct sk_buff *skb = tdata->skb;
2025 unsigned int datalen; 2049 unsigned int datalen;
2026 int err; 2050 int err;
@@ -2072,8 +2096,7 @@ EXPORT_SYMBOL_GPL(cxgbi_conn_xmit_pdu);
2072 2096
2073void cxgbi_cleanup_task(struct iscsi_task *task) 2097void cxgbi_cleanup_task(struct iscsi_task *task)
2074{ 2098{
2075 struct cxgbi_task_data *tdata = task->dd_data + 2099 struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
2076 sizeof(struct iscsi_tcp_task);
2077 2100
2078 log_debug(1 << CXGBI_DBG_ISCSI, 2101 log_debug(1 << CXGBI_DBG_ISCSI,
2079 "task 0x%p, skb 0x%p, itt 0x%x.\n", 2102 "task 0x%p, skb 0x%p, itt 0x%x.\n",
@@ -2290,12 +2313,12 @@ int cxgbi_bind_conn(struct iscsi_cls_session *cls_session,
2290 /* calculate the tag idx bits needed for this conn based on cmds_max */ 2313 /* calculate the tag idx bits needed for this conn based on cmds_max */
2291 cconn->task_idx_bits = (__ilog2_u32(conn->session->cmds_max - 1)) + 1; 2314 cconn->task_idx_bits = (__ilog2_u32(conn->session->cmds_max - 1)) + 1;
2292 2315
2293 write_lock(&csk->callback_lock); 2316 write_lock_bh(&csk->callback_lock);
2294 csk->user_data = conn; 2317 csk->user_data = conn;
2295 cconn->chba = cep->chba; 2318 cconn->chba = cep->chba;
2296 cconn->cep = cep; 2319 cconn->cep = cep;
2297 cep->cconn = cconn; 2320 cep->cconn = cconn;
2298 write_unlock(&csk->callback_lock); 2321 write_unlock_bh(&csk->callback_lock);
2299 2322
2300 cxgbi_conn_max_xmit_dlength(conn); 2323 cxgbi_conn_max_xmit_dlength(conn);
2301 cxgbi_conn_max_recv_dlength(conn); 2324 cxgbi_conn_max_recv_dlength(conn);
diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h
index 2f2485b0f9ec..48e6d623f76d 100644
--- a/drivers/scsi/cxgbi/libcxgbi.h
+++ b/drivers/scsi/cxgbi/libcxgbi.h
@@ -592,6 +592,8 @@ struct cxgbi_task_data {
592 unsigned int count; 592 unsigned int count;
593 unsigned int sgoffset; 593 unsigned int sgoffset;
594}; 594};
595#define iscsi_task_cxgbi_data(task) \
596 ((task)->dd_data + sizeof(struct iscsi_tcp_task))
595 597
596static inline int cxgbi_is_ddp_tag(struct cxgbi_tag_format *tformat, u32 tag) 598static inline int cxgbi_is_ddp_tag(struct cxgbi_tag_format *tformat, u32 tag)
597{ 599{