diff options
author | Erez Zilber <erezz@voltaire.com> | 2007-01-07 05:28:02 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-01-07 13:15:15 -0500 |
commit | f0938401f2252bf39615c0815734650eab9053c8 (patch) | |
tree | 5b915a7569b7b25138eec1027a6fb40f7080b147 /drivers/infiniband/ulp | |
parent | 46707e96b7254663139225ab6c9ab9922cd8c435 (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.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_initiator.c | 26 |
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) | |||
304 | static int | 304 | static int |
305 | iser_check_xmit(struct iscsi_conn *conn, void *task) | 305 | iser_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 */ |