mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 08:44:21 +08:00
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 <dillowda@ornl.gov> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
a9e527e3f9
commit
8cba207732
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user