aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjohn fastabend <john.r.fastabend@intel.com>2010-11-30 19:18:44 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-12-21 13:24:22 -0500
commite0883a3c3e7766b390971a49bf728004816c9520 (patch)
tree503e3ad2aa159def3f97e8001338bfeab4649b2f
parentac17ea8d7d45d0495316edff13faa0dfd6bb2225 (diff)
[SCSI] libfc: use rport timeout values for fcp recovery
Use the rport value for rec_tov for timeout values when sending fcp commands. Currently, defaults are being used which may or may not match the advertised values. The default may cause i/o to timeout on networks that set this value larger then the default value. To make the timeout more configurable in the non-REC mode we remove the FC_SCSI_ER_TIMEOUT completely allowing the scsi-ml to do the timeout. This removes an unneeded timer and allows the i/o timeout to be configured using the scsi-ml knobs. Signed-off-by: John Fastabend <john.r.fastabend@intel.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/libfc/fc_fcp.c58
1 files changed, 42 insertions, 16 deletions
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 8eb67676d0dd..a7d956ad16e3 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -57,6 +57,9 @@ struct kmem_cache *scsi_pkt_cachep;
57#define FC_SRB_READ (1 << 1) 57#define FC_SRB_READ (1 << 1)
58#define FC_SRB_WRITE (1 << 0) 58#define FC_SRB_WRITE (1 << 0)
59 59
60/* constant added to e_d_tov timeout to get rec_tov value */
61#define REC_TOV_CONST 1
62
60/* 63/*
61 * The SCp.ptr should be tested and set under the scsi_pkt_queue lock 64 * The SCp.ptr should be tested and set under the scsi_pkt_queue lock
62 */ 65 */
@@ -126,9 +129,7 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *, struct fc_frame *);
126/* 129/*
127 * Error recovery timeout values. 130 * Error recovery timeout values.
128 */ 131 */
129#define FC_SCSI_ER_TIMEOUT (10 * HZ)
130#define FC_SCSI_TM_TOV (10 * HZ) 132#define FC_SCSI_TM_TOV (10 * HZ)
131#define FC_SCSI_REC_TOV (2 * HZ)
132#define FC_HOST_RESET_TIMEOUT (30 * HZ) 133#define FC_HOST_RESET_TIMEOUT (30 * HZ)
133#define FC_CAN_QUEUE_PERIOD (60 * HZ) 134#define FC_CAN_QUEUE_PERIOD (60 * HZ)
134 135
@@ -1083,6 +1084,21 @@ static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp)
1083} 1084}
1084 1085
1085/** 1086/**
1087 * get_fsp_rec_tov() - Helper function to get REC_TOV
1088 * @fsp: the FCP packet
1089 */
1090static inline unsigned int get_fsp_rec_tov(struct fc_fcp_pkt *fsp)
1091{
1092 struct fc_rport *rport;
1093 struct fc_rport_libfc_priv *rpriv;
1094
1095 rport = fsp->rport;
1096 rpriv = rport->dd_data;
1097
1098 return rpriv->e_d_tov + REC_TOV_CONST;
1099}
1100
1101/**
1086 * fc_fcp_cmd_send() - Send a FCP command 1102 * fc_fcp_cmd_send() - Send a FCP command
1087 * @lport: The local port to send the command on 1103 * @lport: The local port to send the command on
1088 * @fsp: The FCP packet the command is on 1104 * @fsp: The FCP packet the command is on
@@ -1099,6 +1115,7 @@ static int fc_fcp_cmd_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
1099 struct fc_rport_libfc_priv *rpriv; 1115 struct fc_rport_libfc_priv *rpriv;
1100 const size_t len = sizeof(fsp->cdb_cmd); 1116 const size_t len = sizeof(fsp->cdb_cmd);
1101 int rc = 0; 1117 int rc = 0;
1118 unsigned int rec_tov;
1102 1119
1103 if (fc_fcp_lock_pkt(fsp)) 1120 if (fc_fcp_lock_pkt(fsp))
1104 return 0; 1121 return 0;
@@ -1129,10 +1146,12 @@ static int fc_fcp_cmd_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
1129 fsp->seq_ptr = seq; 1146 fsp->seq_ptr = seq;
1130 fc_fcp_pkt_hold(fsp); /* hold for fc_fcp_pkt_destroy */ 1147 fc_fcp_pkt_hold(fsp); /* hold for fc_fcp_pkt_destroy */
1131 1148
1149 rec_tov = get_fsp_rec_tov(fsp);
1150
1132 setup_timer(&fsp->timer, fc_fcp_timeout, (unsigned long)fsp); 1151 setup_timer(&fsp->timer, fc_fcp_timeout, (unsigned long)fsp);
1133 fc_fcp_timer_set(fsp, 1152
1134 (fsp->tgt_flags & FC_RP_FLAGS_REC_SUPPORTED) ? 1153 if (fsp->tgt_flags & FC_RP_FLAGS_REC_SUPPORTED)
1135 FC_SCSI_REC_TOV : FC_SCSI_ER_TIMEOUT); 1154 fc_fcp_timer_set(fsp, rec_tov);
1136unlock: 1155unlock:
1137 fc_fcp_unlock_pkt(fsp); 1156 fc_fcp_unlock_pkt(fsp);
1138 return rc; 1157 return rc;
@@ -1207,13 +1226,16 @@ static void fc_lun_reset_send(unsigned long data)
1207{ 1226{
1208 struct fc_fcp_pkt *fsp = (struct fc_fcp_pkt *)data; 1227 struct fc_fcp_pkt *fsp = (struct fc_fcp_pkt *)data;
1209 struct fc_lport *lport = fsp->lp; 1228 struct fc_lport *lport = fsp->lp;
1229 unsigned int rec_tov;
1230
1210 if (lport->tt.fcp_cmd_send(lport, fsp, fc_tm_done)) { 1231 if (lport->tt.fcp_cmd_send(lport, fsp, fc_tm_done)) {
1211 if (fsp->recov_retry++ >= FC_MAX_RECOV_RETRY) 1232 if (fsp->recov_retry++ >= FC_MAX_RECOV_RETRY)
1212 return; 1233 return;
1213 if (fc_fcp_lock_pkt(fsp)) 1234 if (fc_fcp_lock_pkt(fsp))
1214 return; 1235 return;
1236 rec_tov = get_fsp_rec_tov(fsp);
1215 setup_timer(&fsp->timer, fc_lun_reset_send, (unsigned long)fsp); 1237 setup_timer(&fsp->timer, fc_lun_reset_send, (unsigned long)fsp);
1216 fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV); 1238 fc_fcp_timer_set(fsp, rec_tov);
1217 fc_fcp_unlock_pkt(fsp); 1239 fc_fcp_unlock_pkt(fsp);
1218 } 1240 }
1219} 1241}
@@ -1351,9 +1373,6 @@ static void fc_fcp_timeout(unsigned long data)
1351 1373
1352 if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED) 1374 if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
1353 fc_fcp_rec(fsp); 1375 fc_fcp_rec(fsp);
1354 else if (time_after_eq(fsp->last_pkt_time + (FC_SCSI_ER_TIMEOUT / 2),
1355 jiffies))
1356 fc_fcp_timer_set(fsp, FC_SCSI_ER_TIMEOUT);
1357 else if (fsp->state & FC_SRB_RCV_STATUS) 1376 else if (fsp->state & FC_SRB_RCV_STATUS)
1358 fc_fcp_complete_locked(fsp); 1377 fc_fcp_complete_locked(fsp);
1359 else 1378 else
@@ -1373,6 +1392,7 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
1373 struct fc_frame *fp; 1392 struct fc_frame *fp;
1374 struct fc_rport *rport; 1393 struct fc_rport *rport;
1375 struct fc_rport_libfc_priv *rpriv; 1394 struct fc_rport_libfc_priv *rpriv;
1395 unsigned int rec_tov;
1376 1396
1377 lport = fsp->lp; 1397 lport = fsp->lp;
1378 rport = fsp->rport; 1398 rport = fsp->rport;
@@ -1383,6 +1403,9 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
1383 fc_fcp_complete_locked(fsp); 1403 fc_fcp_complete_locked(fsp);
1384 return; 1404 return;
1385 } 1405 }
1406
1407 rec_tov = get_fsp_rec_tov(fsp);
1408
1386 fp = fc_fcp_frame_alloc(lport, sizeof(struct fc_els_rec)); 1409 fp = fc_fcp_frame_alloc(lport, sizeof(struct fc_els_rec));
1387 if (!fp) 1410 if (!fp)
1388 goto retry; 1411 goto retry;
@@ -1393,13 +1416,13 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
1393 FC_FCTL_REQ, 0); 1416 FC_FCTL_REQ, 0);
1394 if (lport->tt.elsct_send(lport, rport->port_id, fp, ELS_REC, 1417 if (lport->tt.elsct_send(lport, rport->port_id, fp, ELS_REC,
1395 fc_fcp_rec_resp, fsp, 1418 fc_fcp_rec_resp, fsp,
1396 jiffies_to_msecs(FC_SCSI_REC_TOV))) { 1419 jiffies_to_msecs(rec_tov))) {
1397 fc_fcp_pkt_hold(fsp); /* hold while REC outstanding */ 1420 fc_fcp_pkt_hold(fsp); /* hold while REC outstanding */
1398 return; 1421 return;
1399 } 1422 }
1400retry: 1423retry:
1401 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) 1424 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
1402 fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV); 1425 fc_fcp_timer_set(fsp, rec_tov);
1403 else 1426 else
1404 fc_fcp_recovery(fsp, FC_TIMED_OUT); 1427 fc_fcp_recovery(fsp, FC_TIMED_OUT);
1405} 1428}
@@ -1455,7 +1478,6 @@ static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
1455 * making progress. 1478 * making progress.
1456 */ 1479 */
1457 rpriv->flags &= ~FC_RP_FLAGS_REC_SUPPORTED; 1480 rpriv->flags &= ~FC_RP_FLAGS_REC_SUPPORTED;
1458 fc_fcp_timer_set(fsp, FC_SCSI_ER_TIMEOUT);
1459 break; 1481 break;
1460 case ELS_RJT_LOGIC: 1482 case ELS_RJT_LOGIC:
1461 case ELS_RJT_UNAB: 1483 case ELS_RJT_UNAB:
@@ -1508,12 +1530,12 @@ static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
1508 } 1530 }
1509 fc_fcp_srr(fsp, r_ctl, offset); 1531 fc_fcp_srr(fsp, r_ctl, offset);
1510 } else if (e_stat & ESB_ST_SEQ_INIT) { 1532 } else if (e_stat & ESB_ST_SEQ_INIT) {
1511 1533 unsigned int rec_tov = get_fsp_rec_tov(fsp);
1512 /* 1534 /*
1513 * The remote port has the initiative, so just 1535 * The remote port has the initiative, so just
1514 * keep waiting for it to complete. 1536 * keep waiting for it to complete.
1515 */ 1537 */
1516 fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV); 1538 fc_fcp_timer_set(fsp, rec_tov);
1517 } else { 1539 } else {
1518 1540
1519 /* 1541 /*
@@ -1626,6 +1648,7 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
1626 struct fcp_srr *srr; 1648 struct fcp_srr *srr;
1627 struct fc_frame *fp; 1649 struct fc_frame *fp;
1628 u8 cdb_op; 1650 u8 cdb_op;
1651 unsigned int rec_tov;
1629 1652
1630 rport = fsp->rport; 1653 rport = fsp->rport;
1631 rpriv = rport->dd_data; 1654 rpriv = rport->dd_data;
@@ -1650,8 +1673,9 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
1650 rpriv->local_port->port_id, FC_TYPE_FCP, 1673 rpriv->local_port->port_id, FC_TYPE_FCP,
1651 FC_FCTL_REQ, 0); 1674 FC_FCTL_REQ, 0);
1652 1675
1676 rec_tov = get_fsp_rec_tov(fsp);
1653 seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp, NULL, 1677 seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp, NULL,
1654 fsp, jiffies_to_msecs(FC_SCSI_REC_TOV)); 1678 fsp, jiffies_to_msecs(rec_tov));
1655 if (!seq) 1679 if (!seq)
1656 goto retry; 1680 goto retry;
1657 1681
@@ -1675,6 +1699,7 @@ static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
1675{ 1699{
1676 struct fc_fcp_pkt *fsp = arg; 1700 struct fc_fcp_pkt *fsp = arg;
1677 struct fc_frame_header *fh; 1701 struct fc_frame_header *fh;
1702 unsigned int rec_tov;
1678 1703
1679 if (IS_ERR(fp)) { 1704 if (IS_ERR(fp)) {
1680 fc_fcp_srr_error(fsp, fp); 1705 fc_fcp_srr_error(fsp, fp);
@@ -1701,7 +1726,8 @@ static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
1701 switch (fc_frame_payload_op(fp)) { 1726 switch (fc_frame_payload_op(fp)) {
1702 case ELS_LS_ACC: 1727 case ELS_LS_ACC:
1703 fsp->recov_retry = 0; 1728 fsp->recov_retry = 0;
1704 fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV); 1729 rec_tov = get_fsp_rec_tov(fsp);
1730 fc_fcp_timer_set(fsp, rec_tov);
1705 break; 1731 break;
1706 case ELS_LS_RJT: 1732 case ELS_LS_RJT:
1707 default: 1733 default: