Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=8cba2077325b361dedf058c7dfc6c33691422497
Commit:     8cba2077325b361dedf058c7dfc6c33691422497
Parent:     a9e527e3f9f4510e9f3450ca3bc51bc3ef2854fd
Author:     David Dillow <[EMAIL PROTECTED]>
AuthorDate: Wed Dec 19 17:08:43 2007 -0500
Committer:  Roland Dreier <[EMAIL PROTECTED]>
CommitDate: Fri Jan 25 14:15:37 2008 -0800

    IB/srp: Respect target credit limit
    
    The current SRP initiator will send requests even if it has no credits
    available.  The results of sending extra requests are vendor specific,
    but on some devices, overrunning credits will cost 85% of peak
    performance -- e.g. 100 MB/s vs 720 MB/s.  Other devices may just drop
    the requests.
    
    This patch will tell the SCSI midlayer to queue requests if there are
    fewer than two credits remaining, and will not issue a task management
    request if there are no credits remaining.  The mid-layer will retry
    the queued command once an outstanding command completes.
    
    The patch also removes the unlikely() in __srp_get_tx_iu(), as it is
    not at all unlikely to hit this limit under heavy load.
    
    Signed-off-by: David Dillow <[EMAIL PROTECTED]>
    Signed-off-by: Roland Dreier <[EMAIL PROTECTED]>
---
 drivers/infiniband/ulp/srp/ib_srp.c |   13 +++++++++----
 drivers/infiniband/ulp/srp/ib_srp.h |    5 +++++
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/infiniband/ulp/srp/ib_srp.c 
b/drivers/infiniband/ulp/srp/ib_srp.c
index bdb6f85..e98d061 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -930,13 +930,18 @@ static int srp_post_recv(struct srp_target_port *target)
  * req_lim and tx_head.  Lock cannot be dropped between call here and
  * call to __srp_post_send().
  */
-static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target)
+static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target,
+                                       enum srp_request_type req_type)
 {
+       s32 min = (req_type == SRP_REQ_TASK_MGMT) ? 1 : 2;
+
        if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE)
                return NULL;
 
-       if (unlikely(target->req_lim < 1))
+       if (target->req_lim < min) {
                ++target->zero_req_lim;
+               return NULL;
+       }
 
        return target->tx_ring[target->tx_head & SRP_SQ_SIZE];
 }
@@ -993,7 +998,7 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd,
                return 0;
        }
 
-       iu = __srp_get_tx_iu(target);
+       iu = __srp_get_tx_iu(target, SRP_REQ_NORMAL);
        if (!iu)
                goto err;
 
@@ -1283,7 +1288,7 @@ static int srp_send_tsk_mgmt(struct srp_target_port 
*target,
 
        init_completion(&req->done);
 
-       iu = __srp_get_tx_iu(target);
+       iu = __srp_get_tx_iu(target, SRP_REQ_TASK_MGMT);
        if (!iu)
                goto out;
 
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h 
b/drivers/infiniband/ulp/srp/ib_srp.h
index e3573e7..4a3c1f3 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -79,6 +79,11 @@ enum srp_target_state {
        SRP_TARGET_REMOVED
 };
 
+enum srp_request_type {
+       SRP_REQ_NORMAL,
+       SRP_REQ_TASK_MGMT,
+};
+
 struct srp_device {
        struct list_head        dev_list;
        struct ib_device       *dev;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to