Changeset View
Changeset View
Standalone View
Standalone View
sys/cam/cam_iosched.h
Show All 35 Lines | |||||
/* Forward declare all structs to keep interface thin */ | /* Forward declare all structs to keep interface thin */ | ||||
struct cam_iosched_softc; | struct cam_iosched_softc; | ||||
struct sysctl_ctx_list; | struct sysctl_ctx_list; | ||||
struct sysctl_oid; | struct sysctl_oid; | ||||
union ccb; | union ccb; | ||||
struct bio; | 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 | |||||
mjoras: If we're being pedantic the maximum interval is actually 255 seconds + the maximum fractional… | |||||
Not Done Inline Actions256s - 232picoseconds. imp: 256s - 232picoseconds.
| |||||
* is ~200x what our current uses require. Provide some convenience functions to | |||||
Not Done Inline ActionsFor my own curiosity, where does the ~2s requirement come from? mjoras: For my own curiosity, where does the ~2s requirement come from? | |||||
Not Done Inline Actions1.024ms is the upper bound for the power-of-two latency histogram, which is what this data drives. imp: 1.024ms is the upper bound for the power-of-two latency histogram, which is what this data… | |||||
* 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); | int cam_iosched_init(struct cam_iosched_softc **, struct cam_periph *periph); | ||||
void cam_iosched_fini(struct cam_iosched_softc *); | void cam_iosched_fini(struct cam_iosched_softc *); | ||||
void cam_iosched_sysctl_init(struct cam_iosched_softc *, struct sysctl_ctx_list *, struct sysctl_oid *); | void cam_iosched_sysctl_init(struct cam_iosched_softc *, struct sysctl_ctx_list *, struct sysctl_oid *); | ||||
struct bio *cam_iosched_next_trim(struct cam_iosched_softc *isc); | struct bio *cam_iosched_next_trim(struct cam_iosched_softc *isc); | ||||
struct bio *cam_iosched_get_trim(struct cam_iosched_softc *isc); | struct bio *cam_iosched_get_trim(struct cam_iosched_softc *isc); | ||||
struct bio *cam_iosched_next_bio(struct cam_iosched_softc *isc); | struct bio *cam_iosched_next_bio(struct cam_iosched_softc *isc); | ||||
void cam_iosched_queue_work(struct cam_iosched_softc *isc, struct bio *bp); | void cam_iosched_queue_work(struct cam_iosched_softc *isc, struct bio *bp); | ||||
void cam_iosched_flush(struct cam_iosched_softc *isc, struct devstat *stp, int err); | void cam_iosched_flush(struct cam_iosched_softc *isc, struct devstat *stp, int err); | ||||
Show All 13 Lines |
If we're being pedantic the maximum interval is actually 255 seconds + the maximum fractional second which gives nearly 256 seconds in total but not quite. Maybe add a ~ to indicate it is almost 256?