Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F159605793
D12119.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D12119.id.diff
View Options
Index: sys/cam/cam_iosched.h
===================================================================
--- sys/cam/cam_iosched.h
+++ sys/cam/cam_iosched.h
@@ -41,6 +41,44 @@
union ccb;
struct bio;
+/*
+ * For 64-bit platforms, we know that uintptr_t is the same size as sbintime_t
+ * so we can store values in it. For 32-bit systems, however, uintptr_t is only
+ * 32-bits, so it won't fit. For those systems, store 24 bits of fraction and 8
+ * bits of seconds. This allows us to measure an interval of up to ~256s, which
+ * is ~200x what our current uses require. Provide some convenience functions to
+ * get the time, subtract two times and convert back to sbintime_t in a safe way
+ * that can be centralized.
+ */
+#ifdef __LP64__
+#define CAM_IOSCHED_TIME_SHIFT 0
+#else
+#define CAM_IOSCHED_TIME_SHIFT 8
+#endif
+static inline uintptr_t
+cam_iosched_now(void)
+{
+
+ /* Cast here is to avoid right shifting a signed value */
+ return (uintptr_t)((uint64_t)sbinuptime() >> CAM_IOSCHED_TIME_SHIFT);
+}
+
+static inline uintptr_t
+cam_iosched_delta_t(uintptr_t then)
+{
+
+ /* Since the types are identical, wrapping works correctly */
+ return (cam_iosched_now() - then);
+}
+
+static inline sbintime_t
+cam_iosched_sbintime_t(uintptr_t delta)
+{
+
+ /* Cast here is to widen the type so the left shift doesn't lose precision */
+ return (sbintime_t)((uint64_t)delta << CAM_IOSCHED_TIME_SHIFT);
+}
+
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 *);
Index: sys/cam/cam_iosched.c
===================================================================
--- sys/cam/cam_iosched.c
+++ sys/cam/cam_iosched.c
@@ -1428,7 +1428,8 @@
}
if (!(bp->bio_flags & BIO_ERROR))
- cam_iosched_io_metric_update(isc, done_ccb->ccb_h.qos.sim_data,
+ cam_iosched_io_metric_update(isc,
+ cam_iosched_sbintime_t(done_ccb->ccb_h.qos.periph_data),
bp->bio_cmd, bp->bio_bcount);
#endif
return retval;
Index: sys/cam/cam_xpt.c
===================================================================
--- sys/cam/cam_xpt.c
+++ sys/cam/cam_xpt.c
@@ -55,6 +55,7 @@
#include <cam/cam.h>
#include <cam/cam_ccb.h>
+#include <cam/cam_iosched.h>
#include <cam/cam_periph.h>
#include <cam/cam_queue.h>
#include <cam/cam_sim.h>
@@ -3494,7 +3495,7 @@
mtx_lock(mtx);
else
mtx = NULL;
- work_ccb->ccb_h.qos.sim_data = sbinuptime(); // xxx uintprt_t too small 32bit platforms
+ work_ccb->ccb_h.qos.periph_data = cam_iosched_now();
(*(sim->sim_action))(sim, work_ccb);
if (mtx)
mtx_unlock(mtx);
@@ -4641,7 +4642,7 @@
return;
/* Store the time the ccb was in the sim */
- done_ccb->ccb_h.qos.sim_data = sbinuptime() - done_ccb->ccb_h.qos.sim_data;
+ done_ccb->ccb_h.qos.periph_data = cam_iosched_delta_t(done_ccb->ccb_h.qos.periph_data);
hash = (done_ccb->ccb_h.path_id + done_ccb->ccb_h.target_id +
done_ccb->ccb_h.target_lun) % cam_num_doneqs;
queue = &cam_doneqs[hash];
@@ -4664,7 +4665,7 @@
return;
/* Store the time the ccb was in the sim */
- done_ccb->ccb_h.qos.sim_data = sbinuptime() - done_ccb->ccb_h.qos.sim_data;
+ done_ccb->ccb_h.qos.periph_data = cam_iosched_delta_t(done_ccb->ccb_h.qos.periph_data);
xpt_done_process(&done_ccb->ccb_h);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Jun 17, 4:54 AM (13 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33971257
Default Alt Text
D12119.id.diff (3 KB)
Attached To
Mode
D12119: Fix 32-bit overflow on latency measurements
Attached
Detach File
Event Timeline
Log In to Comment