aboutsummarylogtreecommitdiffstats
path: root/bfq-lock-division-zero.patch
diff options
context:
space:
mode:
Diffstat (limited to 'bfq-lock-division-zero.patch')
-rw-r--r--bfq-lock-division-zero.patch35
1 files changed, 35 insertions, 0 deletions
diff --git a/bfq-lock-division-zero.patch b/bfq-lock-division-zero.patch
new file mode 100644
index 000000000000..e8d8727d5117
--- /dev/null
+++ b/bfq-lock-division-zero.patch
@@ -0,0 +1,35 @@
+Rate should never overflow or become zero because it is used as divider.
+This patch accumulates it with saturation.
+
+Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+---
+ block/bfq-iosched.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index aeca22d91101..a236c8d541b5 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -2546,7 +2546,8 @@ static void bfq_reset_rate_computation(struct bfq_data *bfqd,
+
+ static void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
+ {
+- u32 rate, weight, divisor;
++ u32 weight, divisor;
++ u64 rate;
+
+ /*
+ * For the convergence property to hold (see comments on
+@@ -2634,9 +2635,10 @@ static void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
+ */
+ bfqd->peak_rate *= divisor-1;
+ bfqd->peak_rate /= divisor;
+- rate /= divisor; /* smoothing constant alpha = 1/divisor */
++ do_div(rate, divisor); /* smoothing constant alpha = 1/divisor */
+
+- bfqd->peak_rate += rate;
++ /* rate should never overlow or become zero */
++ bfqd->peak_rate = clamp_t(u64, rate + bfqd->peak_rate, 1, U32_MAX);
+ update_thr_responsiveness_params(bfqd);
+
+ reset_computation: