summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorken <ken@FreeBSD.org>2015-03-24 16:53:16 +0000
committerken <ken@FreeBSD.org>2015-03-24 16:53:16 +0000
commitddca3950421c8dc4688a7d241129225cf978819f (patch)
tree1adce41b8c12d027f9581a9d7119681c90c610ca
parent13b9654564f73857ff55ee6ea6d118aaf1c1e731 (diff)
downloadFreeBSD-src-ddca3950421c8dc4688a7d241129225cf978819f.zip
FreeBSD-src-ddca3950421c8dc4688a7d241129225cf978819f.tar.gz
MFC, r279375
------------------------------------------------------------------------ r279375 | ken | 2015-02-27 14:35:36 -0700 (Fri, 27 Feb 2015) | 26 lines Fix I/O size calculation for pass(4) driver requests and add latency tracking. It is important to subtract the residual from the requested transfer size to see how much data was actually transferred. With tape drives in particular, it is common to request more data than is returned. Also, add I/O latency tracking for CAM requests issued by cam_periph_runccb(). If the caller supplies a struct devstat, and the I/O is a SCSI or ATA I/O, we will track the elapsed time to provide I/O latency statistics for the request. sys/cam/scsi/cam_periph.c: In cam_periph_runccb(), subtract the residual when reporting I/O totals to devstat(9) for SCSI and ATA passthrough requests. In cam_periph_runccb(), grab the I/O start time and supply the start time to devstat_end_transaction() so that it can calculate the elapsed I/O time. Sponsored by: Spectra Logic MFC after: 1 week ------------------------------------------------------------------------ Sponsored by: Spectra Logic
-rw-r--r--sys/cam/cam_periph.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c
index 87c1bdd..2544d27 100644
--- a/sys/cam/cam_periph.c
+++ b/sys/cam/cam_periph.c
@@ -1048,8 +1048,11 @@ cam_periph_runccb(union ccb *ccb,
cam_flags camflags, u_int32_t sense_flags,
struct devstat *ds)
{
+ struct bintime *starttime;
+ struct bintime ltime;
int error;
+ starttime = NULL;
xpt_path_assert(ccb->ccb_h.path, MA_OWNED);
/*
@@ -1057,8 +1060,11 @@ cam_periph_runccb(union ccb *ccb,
* this particular type of ccb, record the transaction start.
*/
if ((ds != NULL) && (ccb->ccb_h.func_code == XPT_SCSI_IO ||
- ccb->ccb_h.func_code == XPT_ATA_IO))
- devstat_start_transaction(ds, NULL);
+ ccb->ccb_h.func_code == XPT_ATA_IO)) {
+ starttime = &ltime;
+ binuptime(starttime);
+ devstat_start_transaction(ds, starttime);
+ }
ccb->ccb_h.cbfcnp = cam_periph_done;
xpt_action(ccb);
@@ -1086,22 +1092,22 @@ cam_periph_runccb(union ccb *ccb,
if (ds != NULL) {
if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
devstat_end_transaction(ds,
- ccb->csio.dxfer_len,
+ ccb->csio.dxfer_len - ccb->csio.resid,
ccb->csio.tag_action & 0x3,
((ccb->ccb_h.flags & CAM_DIR_MASK) ==
CAM_DIR_NONE) ? DEVSTAT_NO_DATA :
(ccb->ccb_h.flags & CAM_DIR_OUT) ?
DEVSTAT_WRITE :
- DEVSTAT_READ, NULL, NULL);
+ DEVSTAT_READ, NULL, starttime);
} else if (ccb->ccb_h.func_code == XPT_ATA_IO) {
devstat_end_transaction(ds,
- ccb->ataio.dxfer_len,
+ ccb->ataio.dxfer_len - ccb->ataio.resid,
ccb->ataio.tag_action & 0x3,
((ccb->ccb_h.flags & CAM_DIR_MASK) ==
CAM_DIR_NONE) ? DEVSTAT_NO_DATA :
(ccb->ccb_h.flags & CAM_DIR_OUT) ?
DEVSTAT_WRITE :
- DEVSTAT_READ, NULL, NULL);
+ DEVSTAT_READ, NULL, starttime);
}
}
OpenPOWER on IntegriCloud