Lines 110-122
typedef int l_tick_t(struct iop_stats *);
Link Here
|
110 |
|
110 |
|
111 |
/* |
111 |
/* |
112 |
* Called to see if the limiter thinks this IOP can be allowed to |
112 |
* Called to see if the limiter thinks this IOP can be allowed to |
113 |
* proceed. If so, the limiter assumes that the while IOP proceeded |
113 |
* proceed. If so, the limiter assumes that the IOP proceeded |
114 |
* and makes any accounting of it that's needed. |
114 |
* and makes any accounting of it that's needed. |
115 |
*/ |
115 |
*/ |
116 |
typedef int l_iop_t(struct iop_stats *, struct bio *); |
116 |
typedef int l_iop_t(struct iop_stats *, struct bio *); |
117 |
|
117 |
|
118 |
/* |
118 |
/* |
119 |
* Called when an I/O completes so the limiter can updates its |
119 |
* Called when an I/O completes so the limiter can update its |
120 |
* accounting. Pending I/Os may complete in any order (even when |
120 |
* accounting. Pending I/Os may complete in any order (even when |
121 |
* sent to the hardware at the same time), so the limiter may not |
121 |
* sent to the hardware at the same time), so the limiter may not |
122 |
* make any assumptions other than this I/O has completed. If it |
122 |
* make any assumptions other than this I/O has completed. If it |
Lines 471-478
cam_iosched_bw_caniop(struct iop_stats *ios, struct bio *bp)
Link Here
|
471 |
{ |
471 |
{ |
472 |
/* |
472 |
/* |
473 |
* So if we have any more bw quota left, allow it, |
473 |
* So if we have any more bw quota left, allow it, |
474 |
* otherwise wait. Not, we'll go negative and that's |
474 |
* otherwise wait. Note, we'll go negative and that's |
475 |
* OK. We'll just get a lettle less next quota. |
475 |
* OK. We'll just get a little less next quota. |
476 |
* |
476 |
* |
477 |
* Note on going negative: that allows us to process |
477 |
* Note on going negative: that allows us to process |
478 |
* requests in order better, since we won't allow |
478 |
* requests in order better, since we won't allow |
Lines 586-592
cam_iosched_cl_maybe_steer(struct control_loop *clp)
Link Here
|
586 |
* ~10. At .25 it only takes ~8. However some preliminary data |
586 |
* ~10. At .25 it only takes ~8. However some preliminary data |
587 |
* from the SSD drives suggests a reasponse time in 10's of |
587 |
* from the SSD drives suggests a reasponse time in 10's of |
588 |
* seconds before latency drops regardless of the new write |
588 |
* seconds before latency drops regardless of the new write |
589 |
* rate. Careful observation will be reqiured to tune this |
589 |
* rate. Careful observation will be required to tune this |
590 |
* effectively. |
590 |
* effectively. |
591 |
* |
591 |
* |
592 |
* Also, when there's no read traffic, we jack up the write |
592 |
* Also, when there's no read traffic, we jack up the write |
Lines 1147-1153
cam_iosched_put_back_trim(struct cam_iosched_softc *isc, struct bio *bp)
Link Here
|
1147 |
* gets the next trim from the trim queue. |
1147 |
* gets the next trim from the trim queue. |
1148 |
* |
1148 |
* |
1149 |
* Assumes we're called with the periph lock held. It removes this |
1149 |
* Assumes we're called with the periph lock held. It removes this |
1150 |
* trim from the queue and the device must explicitly reinstert it |
1150 |
* trim from the queue and the device must explicitly reinsert it |
1151 |
* should the need arise. |
1151 |
* should the need arise. |
1152 |
*/ |
1152 |
*/ |
1153 |
struct bio * |
1153 |
struct bio * |
Lines 1168-1176
cam_iosched_next_trim(struct cam_iosched_softc *isc)
Link Here
|
1168 |
} |
1168 |
} |
1169 |
|
1169 |
|
1170 |
/* |
1170 |
/* |
1171 |
* gets the an available trim from the trim queue, if there's no trim |
1171 |
* gets an available trim from the trim queue, if there's no trim |
1172 |
* already pending. It removes this trim from the queue and the device |
1172 |
* already pending. It removes this trim from the queue and the device |
1173 |
* must explicitly reinstert it should the need arise. |
1173 |
* must explicitly reinsert it should the need arise. |
1174 |
* |
1174 |
* |
1175 |
* Assumes we're called with the periph lock held. |
1175 |
* Assumes we're called with the periph lock held. |
1176 |
*/ |
1176 |
*/ |
Lines 1406-1412
cam_iosched_clr_work_flags(struct cam_iosched_softc *isc, uint32_t flags)
Link Here
|
1406 |
#ifdef CAM_IOSCHED_DYNAMIC |
1406 |
#ifdef CAM_IOSCHED_DYNAMIC |
1407 |
/* |
1407 |
/* |
1408 |
* After the method presented in Jack Crenshaw's 1998 article "Integer |
1408 |
* After the method presented in Jack Crenshaw's 1998 article "Integer |
1409 |
* Suqare Roots," reprinted at |
1409 |
* Square Roots," reprinted at |
1410 |
* http://www.embedded.com/electronics-blogs/programmer-s-toolbox/4219659/Integer-Square-Roots |
1410 |
* http://www.embedded.com/electronics-blogs/programmer-s-toolbox/4219659/Integer-Square-Roots |
1411 |
* and well worth the read. Briefly, we find the power of 4 that's the |
1411 |
* and well worth the read. Briefly, we find the power of 4 that's the |
1412 |
* largest smaller than val. We then check each smaller power of 4 to |
1412 |
* largest smaller than val. We then check each smaller power of 4 to |
Lines 1415-1421
cam_iosched_clr_work_flags(struct cam_iosched_softc *isc, uint32_t flags)
Link Here
|
1415 |
* accumulating the right answer. It could also have been accumulated |
1415 |
* accumulating the right answer. It could also have been accumulated |
1416 |
* using a separate root counter, but this code is smaller and faster |
1416 |
* using a separate root counter, but this code is smaller and faster |
1417 |
* than that method. This method is also integer size invariant. |
1417 |
* than that method. This method is also integer size invariant. |
1418 |
* It returns floor(sqrt((float)val)), or the larget integer less than |
1418 |
* It returns floor(sqrt((float)val)), or the largest integer less than |
1419 |
* or equal to the square root. |
1419 |
* or equal to the square root. |
1420 |
*/ |
1420 |
*/ |
1421 |
static uint64_t |
1421 |
static uint64_t |
Lines 1459-1465
isqrt64(uint64_t val)
Link Here
|
1459 |
* (ah + al / R) * (bh + bl / R) |
1459 |
* (ah + al / R) * (bh + bl / R) |
1460 |
* ah * bh + (al * bh + ah * bl) / R + al * bl / R^2 |
1460 |
* ah * bh + (al * bh + ah * bl) / R + al * bl / R^2 |
1461 |
* |
1461 |
* |
1462 |
* After multiplicaiton, we have to renormalize by multiply by |
1462 |
* After multiplication, we have to renormalize by multiply by |
1463 |
* R, so we wind up with |
1463 |
* R, so we wind up with |
1464 |
* ah * bh * R + al * bh + ah * bl + al * bl / R |
1464 |
* ah * bh * R + al * bh + ah * bl + al * bl / R |
1465 |
* which turns out to be a very nice way to compute this value |
1465 |
* which turns out to be a very nice way to compute this value |
Lines 1485-1491
cam_iosched_update(struct iop_stats *iop, sbintime_t sim_latency)
Link Here
|
1485 |
uint64_t var; |
1485 |
uint64_t var; |
1486 |
|
1486 |
|
1487 |
/* |
1487 |
/* |
1488 |
* Classic expoentially decaying average with a tiny alpha |
1488 |
* Classic exponentially decaying average with a tiny alpha |
1489 |
* (2 ^ -alpha_bits). For more info see the NIST statistical |
1489 |
* (2 ^ -alpha_bits). For more info see the NIST statistical |
1490 |
* handbook. |
1490 |
* handbook. |
1491 |
* |
1491 |
* |
Lines 1520-1526
cam_iosched_update(struct iop_stats *iop, sbintime_t sim_latency)
Link Here
|
1520 |
* which is the formula used here to get a decent estimate of sd which |
1520 |
* which is the formula used here to get a decent estimate of sd which |
1521 |
* we use to detect outliers. Note that when first starting up, it |
1521 |
* we use to detect outliers. Note that when first starting up, it |
1522 |
* takes a while for emss sum of squares estimator to converge on a |
1522 |
* takes a while for emss sum of squares estimator to converge on a |
1523 |
* good value. during this time, it can be less than ema^2. We |
1523 |
* good value. During this time, it can be less than ema^2. We |
1524 |
* compute a sd of 0 in that case, and ignore outliers. |
1524 |
* compute a sd of 0 in that case, and ignore outliers. |
1525 |
*/ |
1525 |
*/ |
1526 |
var = iop->emss - mul(iop->ema, iop->ema); |
1526 |
var = iop->emss - mul(iop->ema, iop->ema); |
1527 |
- |
|
|