aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp
diff options
context:
space:
mode:
authorErez Zilber <erezz@voltaire.com>2007-01-07 05:28:02 -0500
committerRoland Dreier <rolandd@cisco.com>2007-01-07 13:15:15 -0500
commitf0938401f2252bf39615c0815734650eab9053c8 (patch)
tree5b915a7569b7b25138eec1027a6fb40f7080b147 /drivers/infiniband/ulp
parent46707e96b7254663139225ab6c9ab9922cd8c435 (diff)
IB/iser: Return error code when PDUs may not be sent
iSER limits the number of outstanding PDUs to send. When this threshold is reached, it should return an error code (-ENOBUFS) instead of setting the suspend_tx bit (which should be used only by libiscsi). Signed-off-by: Erez Zilber <erezz@voltaire.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c4
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c26
2 files changed, 14 insertions, 16 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 9b2041e25d59..dd221eda3ea6 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -177,7 +177,7 @@ iscsi_iser_mtask_xmit(struct iscsi_conn *conn,
177 * - if yes, the mtask is recycled at iscsi_complete_pdu 177 * - if yes, the mtask is recycled at iscsi_complete_pdu
178 * - if no, the mtask is recycled at iser_snd_completion 178 * - if no, the mtask is recycled at iser_snd_completion
179 */ 179 */
180 if (error && error != -EAGAIN) 180 if (error && error != -ENOBUFS)
181 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); 181 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
182 182
183 return error; 183 return error;
@@ -241,7 +241,7 @@ iscsi_iser_ctask_xmit(struct iscsi_conn *conn,
241 error = iscsi_iser_ctask_xmit_unsol_data(conn, ctask); 241 error = iscsi_iser_ctask_xmit_unsol_data(conn, ctask);
242 242
243 iscsi_iser_ctask_xmit_exit: 243 iscsi_iser_ctask_xmit_exit:
244 if (error && error != -EAGAIN) 244 if (error && error != -ENOBUFS)
245 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); 245 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
246 return error; 246 return error;
247} 247}
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index e73c87b9be43..0a7d1ab60e6d 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -304,18 +304,14 @@ int iser_conn_set_full_featured_mode(struct iscsi_conn *conn)
304static int 304static int
305iser_check_xmit(struct iscsi_conn *conn, void *task) 305iser_check_xmit(struct iscsi_conn *conn, void *task)
306{ 306{
307 int rc = 0;
308 struct iscsi_iser_conn *iser_conn = conn->dd_data; 307 struct iscsi_iser_conn *iser_conn = conn->dd_data;
309 308
310 write_lock_bh(conn->recv_lock);
311 if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) == 309 if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
312 ISER_QP_MAX_REQ_DTOS) { 310 ISER_QP_MAX_REQ_DTOS) {
313 iser_dbg("%ld can't xmit task %p, suspending tx\n",jiffies,task); 311 iser_dbg("%ld can't xmit task %p\n",jiffies,task);
314 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); 312 return -ENOBUFS;
315 rc = -EAGAIN;
316 } 313 }
317 write_unlock_bh(conn->recv_lock); 314 return 0;
318 return rc;
319} 315}
320 316
321 317
@@ -340,7 +336,7 @@ int iser_send_command(struct iscsi_conn *conn,
340 return -EPERM; 336 return -EPERM;
341 } 337 }
342 if (iser_check_xmit(conn, ctask)) 338 if (iser_check_xmit(conn, ctask))
343 return -EAGAIN; 339 return -ENOBUFS;
344 340
345 edtl = ntohl(hdr->data_length); 341 edtl = ntohl(hdr->data_length);
346 342
@@ -426,7 +422,7 @@ int iser_send_data_out(struct iscsi_conn *conn,
426 } 422 }
427 423
428 if (iser_check_xmit(conn, ctask)) 424 if (iser_check_xmit(conn, ctask))
429 return -EAGAIN; 425 return -ENOBUFS;
430 426
431 itt = ntohl(hdr->itt); 427 itt = ntohl(hdr->itt);
432 data_seg_len = ntoh24(hdr->dlength); 428 data_seg_len = ntoh24(hdr->dlength);
@@ -498,7 +494,7 @@ int iser_send_control(struct iscsi_conn *conn,
498 } 494 }
499 495
500 if (iser_check_xmit(conn,mtask)) 496 if (iser_check_xmit(conn,mtask))
501 return -EAGAIN; 497 return -ENOBUFS;
502 498
503 /* build the tx desc regd header and add it to the tx desc dto */ 499 /* build the tx desc regd header and add it to the tx desc dto */
504 mdesc->type = ISCSI_TX_CONTROL; 500 mdesc->type = ISCSI_TX_CONTROL;
@@ -605,6 +601,7 @@ void iser_snd_completion(struct iser_desc *tx_desc)
605 struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn; 601 struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn;
606 struct iscsi_conn *conn = iser_conn->iscsi_conn; 602 struct iscsi_conn *conn = iser_conn->iscsi_conn;
607 struct iscsi_mgmt_task *mtask; 603 struct iscsi_mgmt_task *mtask;
604 int resume_tx = 0;
608 605
609 iser_dbg("Initiator, Data sent dto=0x%p\n", dto); 606 iser_dbg("Initiator, Data sent dto=0x%p\n", dto);
610 607
@@ -613,15 +610,16 @@ void iser_snd_completion(struct iser_desc *tx_desc)
613 if (tx_desc->type == ISCSI_TX_DATAOUT) 610 if (tx_desc->type == ISCSI_TX_DATAOUT)
614 kmem_cache_free(ig.desc_cache, tx_desc); 611 kmem_cache_free(ig.desc_cache, tx_desc);
615 612
613 if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
614 ISER_QP_MAX_REQ_DTOS)
615 resume_tx = 1;
616
616 atomic_dec(&ib_conn->post_send_buf_count); 617 atomic_dec(&ib_conn->post_send_buf_count);
617 618
618 write_lock(conn->recv_lock); 619 if (resume_tx) {
619 if (conn->suspend_tx) {
620 iser_dbg("%ld resuming tx\n",jiffies); 620 iser_dbg("%ld resuming tx\n",jiffies);
621 clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
622 scsi_queue_work(conn->session->host, &conn->xmitwork); 621 scsi_queue_work(conn->session->host, &conn->xmitwork);
623 } 622 }
624 write_unlock(conn->recv_lock);
625 623
626 if (tx_desc->type == ISCSI_TX_CONTROL) { 624 if (tx_desc->type == ISCSI_TX_CONTROL) {
627 /* this arithmetic is legal by libiscsi dd_data allocation */ 625 /* this arithmetic is legal by libiscsi dd_data allocation */