The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at 
https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.4.9
------>
commit c476e1a6d365c8ee156b05ab0a0ccbcb9601a984
Author: Dmitry Monakhov <dmonak...@openvz.org>
Date:   Tue May 5 13:44:39 2015 +0400

    vziolimit: port diff-ubc-iolimit-keep-charge-in-throttler
    
    iolimit: keep charge in throttler
    
    Now throttler can keep precharge, so we can start throttling earlier.
    * use long long for state to avoid overflows.
    
    Signed-off-by: Konstantin Khlebnikov <khlebni...@openvz.org>
    Acked-by: Pavel Emelyanov <xe...@parallels.com>
    
    ====================================
    https://jira.sw.ru/browse/PSBM-20104
    
    Signed-off-by: Dmitry Monakhov <dmonak...@openvz.org>
---
 kernel/ve/vziolimit.c | 53 ++++++++++++++++++++++++++++++++-------------------
 1 file changed, 33 insertions(+), 20 deletions(-)

diff --git a/kernel/ve/vziolimit.c b/kernel/ve/vziolimit.c
index e2eedae..7ff2854 100644
--- a/kernel/ve/vziolimit.c
+++ b/kernel/ve/vziolimit.c
@@ -18,8 +18,8 @@ struct throttle {
        unsigned speed;         /* maximum speed, units per second */
        unsigned burst;         /* maximum bust, units */
        unsigned latency;       /* maximum wait delay, jiffies */
-       unsigned state;         /* current state */
        unsigned long time;     /* wall time in jiffies */
+       long long state;                /* current state in units */
 };
 
 /**
@@ -34,41 +34,46 @@ static void throttle_setup(struct throttle *th, unsigned 
speed,
        th->time = jiffies;
        th->burst = burst;
        th->latency = msecs_to_jiffies(latency);
-       th->state = 0;
+       /* feed throttler to avoid freezing */
+       if (th->state < burst)
+               th->state = burst;
        wmb();
        th->speed = speed;
 }
 
 /* externally serialized */
-static void throttle_charge(struct throttle *th, unsigned charge)
+static void throttle_charge(struct throttle *th, long long charge)
 {
-       unsigned long now = jiffies;
-       u64 step;
-
-       if (!th->speed)
-               return;
+       unsigned long time, now = jiffies;
+       long long step, ceiling = charge + th->burst;
 
        if (time_before(th->time, now)) {
                step = (u64)th->speed * (now - th->time);
                do_div(step, HZ);
-               th->state = min((unsigned)step + th->state, charge + th->burst);
+               step += th->state;
+               /* feed throttler as much as we can */
+               if (step <= ceiling)
+                       th->state = step;
+               else if (th->state < ceiling)
+                       th->state = ceiling;
                th->time = now;
        }
 
        if (charge > th->state) {
                charge -= th->state;
-               step = (u64)charge * HZ;
+               step = charge * HZ;
                if (do_div(step, th->speed))
                        step++;
-               th->time += step;
+               time = th->time + step;
+               /* limit maximum latency */
+               if (time_after(time, now + th->latency))
+                       time = now + th->latency;
+               th->time = time;
                step *= th->speed;
-               do_div(step, HZ);
-               th->state = max_t(int, (int)step - charge, 0);
-       } else
-               th->state -= charge;
-
-       if (time_after(th->time, now + th->latency))
-               th->time = now + th->latency;
+               if (do_div(step, HZ))
+                       step++;
+               th->state += step;
+       }
 }
 
 /* lockless */
@@ -133,14 +138,22 @@ static int iolimit_virtinfo(struct vnotifier_block *nb,
                        if (!iolimit->throttle.speed)
                                break;
                        spin_lock_irqsave(&ub->ub_lock, flags);
-                       throttle_charge(&iolimit->throttle, *(size_t*)arg);
+                       if (iolimit->throttle.speed) {
+                               long long charge = *(size_t*)arg;
+
+                               throttle_charge(&iolimit->throttle, charge);
+                               iolimit->throttle.state -= charge;
+                       }
                        spin_unlock_irqrestore(&ub->ub_lock, flags);
                        break;
                case VIRTINFO_IO_OP_ACCOUNT:
                        if (!iolimit->iops.speed)
                                break;
                        spin_lock_irqsave(&ub->ub_lock, flags);
-                       throttle_charge(&iolimit->iops, 1);
+                       if (iolimit->iops.speed) {
+                               throttle_charge(&iolimit->iops, 1);
+                               iolimit->iops.state--;
+                       }
                        spin_unlock_irqrestore(&ub->ub_lock, flags);
                        break;
                case VIRTINFO_IO_PREPARE:
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to