svn commit: r340453 - head/sys/cam
Warner Losh
imp at FreeBSD.org
Thu Nov 15 16:02:48 UTC 2018
Author: imp
Date: Thu Nov 15 16:02:45 2018
New Revision: 340453
URL: https://svnweb.freebsd.org/changeset/base/340453
Log:
Add cam_iosched_set_latfcn to set a latency callback for high latency.
It's often useful to have a callback when an I/O takes more than a
threshold amount of time. This adds the infrastructure for periph
devices to register one.
One use-case is as a debugging aide when you need a semi-realtime
indication of an I/O outlier so you can trigger bus capture gear for
vendor analysis.
Sponsored by: Netflix, Inc
Modified:
head/sys/cam/cam_iosched.c
head/sys/cam/cam_iosched.h
Modified: head/sys/cam/cam_iosched.c
==============================================================================
--- head/sys/cam/cam_iosched.c Thu Nov 15 16:02:34 2018 (r340452)
+++ head/sys/cam/cam_iosched.c Thu Nov 15 16:02:45 2018 (r340453)
@@ -294,6 +294,9 @@ struct cam_iosched_softc {
uint32_t this_frac; /* Fraction of a second (1024ths) for this tick */
sbintime_t last_time; /* Last time we ticked */
struct control_loop cl;
+ sbintime_t max_lat; /* when != 0, if iop latency > max_lat, call max_lat_fcn */
+ cam_iosched_latfcn_t latfcn;
+ void *latarg;
#endif
};
@@ -1171,9 +1174,24 @@ void cam_iosched_sysctl_init(struct cam_iosched_softc
OID_AUTO, "load", CTLFLAG_RD,
&isc->load, 0,
"scaled load average / 100");
+
+ SYSCTL_ADD_U64(ctx, n,
+ OID_AUTO, "latency_trigger", CTLFLAG_RW,
+ &isc->max_lat, 0,
+ "Latency treshold to trigger callbacks");
#endif
}
+void
+cam_iosched_set_latfcn(struct cam_iosched_softc *isc,
+ cam_iosched_latfcn_t fnp, void *argp)
+{
+#ifdef CAM_IOSCHED_DYNAMIC
+ isc->latfcn = fnp;
+ isc->latarg = argp;
+#endif
+}
+
/*
* Flush outstanding I/O. Consumers of this library don't know all the
* queues we may keep, so this allows all I/O to be flushed in one
@@ -1510,10 +1528,21 @@ cam_iosched_bio_complete(struct cam_iosched_softc *isc
printf("Completing command with bio_cmd == %#x\n", bp->bio_cmd);
}
- if (!(bp->bio_flags & BIO_ERROR) && done_ccb != NULL)
- cam_iosched_io_metric_update(isc,
- cam_iosched_sbintime_t(done_ccb->ccb_h.qos.periph_data),
+ if (!(bp->bio_flags & BIO_ERROR) && done_ccb != NULL) {
+ sbintime_t sim_latency;
+
+ sim_latency = cam_iosched_sbintime_t(done_ccb->ccb_h.qos.periph_data);
+
+ cam_iosched_io_metric_update(isc, sim_latency,
bp->bio_cmd, bp->bio_bcount);
+ /*
+ * Debugging code: allow callbacks to the periph driver when latency max
+ * is exceeded. This can be useful for triggering external debugging actions.
+ */
+ if (isc->latfcn && isc->max_lat != 0 && sim_latency > isc->max_lat)
+ isc->latfcn(isc->latarg, sim_latency, bp);
+ }
+
#endif
return retval;
}
Modified: head/sys/cam/cam_iosched.h
==============================================================================
--- head/sys/cam/cam_iosched.h Thu Nov 15 16:02:34 2018 (r340452)
+++ head/sys/cam/cam_iosched.h Thu Nov 15 16:02:45 2018 (r340453)
@@ -80,6 +80,8 @@ cam_iosched_sbintime_t(uintptr_t delta)
return (sbintime_t)((uint64_t)delta << CAM_IOSCHED_TIME_SHIFT);
}
+typedef void (*cam_iosched_latfcn_t)(void *, sbintime_t, struct bio *);
+
int cam_iosched_init(struct cam_iosched_softc **, struct cam_periph *periph);
void cam_iosched_fini(struct cam_iosched_softc *);
void cam_iosched_sysctl_init(struct cam_iosched_softc *, struct sysctl_ctx_list *, struct sysctl_oid *);
@@ -98,6 +100,7 @@ void cam_iosched_set_work_flags(struct cam_iosched_sof
void cam_iosched_clr_work_flags(struct cam_iosched_softc *isc, uint32_t flags);
void cam_iosched_trim_done(struct cam_iosched_softc *isc);
int cam_iosched_bio_complete(struct cam_iosched_softc *isc, struct bio *bp, union ccb *done_ccb);
+void cam_iosched_set_latfcn(struct cam_iosched_softc *isc, cam_iosched_latfcn_t, void *);
#endif
#endif
More information about the svn-src-all
mailing list