Skip to content

Commit

Permalink
IB/srp: Increase block layer timeout
Browse files Browse the repository at this point in the history
Increase the block layer timeout for disks so that it is above the
InfiniBand transport layer timeout.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Acked-by: David Dillow <dillowda@ornl.gov>
Signed-off-by: Roland Dreier <roland@purestorage.com>
  • Loading branch information
Bart Van Assche authored and Roland Dreier committed Dec 1, 2012
1 parent f4a75d2 commit c9b03c1
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
45 changes: 45 additions & 0 deletions drivers/infiniband/ulp/srp/ib_srp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1419,6 +1419,33 @@ static int srp_alloc_iu_bufs(struct srp_target_port *target)
return -ENOMEM;
}

static uint32_t srp_compute_rq_tmo(struct ib_qp_attr *qp_attr, int attr_mask)
{
uint64_t T_tr_ns, max_compl_time_ms;
uint32_t rq_tmo_jiffies;

/*
* According to section 11.2.4.2 in the IBTA spec (Modify Queue Pair,
* table 91), both the QP timeout and the retry count have to be set
* for RC QP's during the RTR to RTS transition.
*/
WARN_ON_ONCE((attr_mask & (IB_QP_TIMEOUT | IB_QP_RETRY_CNT)) !=
(IB_QP_TIMEOUT | IB_QP_RETRY_CNT));

/*
* Set target->rq_tmo_jiffies to one second more than the largest time
* it can take before an error completion is generated. See also
* C9-140..142 in the IBTA spec for more information about how to
* convert the QP Local ACK Timeout value to nanoseconds.
*/
T_tr_ns = 4096 * (1ULL << qp_attr->timeout);
max_compl_time_ms = qp_attr->retry_cnt * 4 * T_tr_ns;
do_div(max_compl_time_ms, NSEC_PER_MSEC);
rq_tmo_jiffies = msecs_to_jiffies(max_compl_time_ms + 1000);

return rq_tmo_jiffies;
}

static void srp_cm_rep_handler(struct ib_cm_id *cm_id,
struct srp_login_rsp *lrsp,
struct srp_target_port *target)
Expand Down Expand Up @@ -1478,6 +1505,8 @@ static void srp_cm_rep_handler(struct ib_cm_id *cm_id,
if (ret)
goto error_free;

target->rq_tmo_jiffies = srp_compute_rq_tmo(qp_attr, attr_mask);

ret = ib_modify_qp(target->qp, qp_attr, attr_mask);
if (ret)
goto error_free;
Expand Down Expand Up @@ -1729,6 +1758,21 @@ static int srp_reset_host(struct scsi_cmnd *scmnd)
return ret;
}

static int srp_slave_configure(struct scsi_device *sdev)
{
struct Scsi_Host *shost = sdev->host;
struct srp_target_port *target = host_to_target(shost);
struct request_queue *q = sdev->request_queue;
unsigned long timeout;

if (sdev->type == TYPE_DISK) {
timeout = max_t(unsigned, 30 * HZ, target->rq_tmo_jiffies);
blk_queue_rq_timeout(q, timeout);
}

return 0;
}

static ssize_t show_id_ext(struct device *dev, struct device_attribute *attr,
char *buf)
{
Expand Down Expand Up @@ -1861,6 +1905,7 @@ static struct scsi_host_template srp_template = {
.module = THIS_MODULE,
.name = "InfiniBand SRP initiator",
.proc_name = DRV_NAME,
.slave_configure = srp_slave_configure,
.info = srp_target_info,
.queuecommand = srp_queuecommand,
.eh_abort_handler = srp_abort,
Expand Down
2 changes: 2 additions & 0 deletions drivers/infiniband/ulp/srp/ib_srp.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ struct srp_target_port {
struct ib_sa_query *path_query;
int path_query_id;

u32 rq_tmo_jiffies;

struct ib_cm_id *cm_id;

int max_ti_iu_len;
Expand Down

0 comments on commit c9b03c1

Please sign in to comment.