IB/srp: Increase block layer timeout
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>
This commit is contained in:
parent
f4a75d2eb7
commit
c9b03c1ae5
|
@ -1419,6 +1419,33 @@ err:
|
|||
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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue