diff options
author | ken <ken@FreeBSD.org> | 2015-03-24 16:53:16 +0000 |
---|---|---|
committer | ken <ken@FreeBSD.org> | 2015-03-24 16:53:16 +0000 |
commit | ddca3950421c8dc4688a7d241129225cf978819f (patch) | |
tree | 1adce41b8c12d027f9581a9d7119681c90c610ca /sys/cam/cam_periph.c | |
parent | 13b9654564f73857ff55ee6ea6d118aaf1c1e731 (diff) | |
download | FreeBSD-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
Diffstat (limited to 'sys/cam/cam_periph.c')
-rw-r--r-- | sys/cam/cam_periph.c | 18 |
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 = <ime; + 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); } } |