[Devel] [PATCH RHEL7 COMMIT] vziolimit: port diff-iolimit-plain-throttler

Konstantin Khorenko khorenko at odin.com
Tue May 5 02:44:34 PDT 2015


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 f3bba392c33dc26ea98d2977e8ddd2861eb8b805
Author: Dmitry Monakhov <dmonakhov at openvz.org>
Date:   Tue May 5 13:44:34 2015 +0400

    vziolimit: port diff-iolimit-plain-throttler
    
    iolimit: implement plain throttler
    
    Implement throttler logic.
    
    Signed-off-by: Konstantin Khlebnikov <khlebnikov at openvz.org>
    
    ====================================
    https://jira.sw.ru/browse/PSBM-20104
    
    Signed-off-by: Dmitry Monakhov <dmonakhov at openvz.org>
---
 kernel/ve/vziolimit.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/kernel/ve/vziolimit.c b/kernel/ve/vziolimit.c
index d8edb1e..d70d416 100644
--- a/kernel/ve/vziolimit.c
+++ b/kernel/ve/vziolimit.c
@@ -13,6 +13,78 @@
 #include <linux/vziolimit.h>
 #include <bc/beancounter.h>
 
+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 */
+};
+
+/**
+ * set throttler initial state, externally serialized
+ * @speed	maximum speed (1/sec)
+ * @burst	maximum burst chunk
+ * @latency	maximum timeout (ms)
+ */
+static void throttle_setup(struct throttle *th, unsigned speed,
+		unsigned burst, unsigned latency)
+{
+	th->time = jiffies;
+	th->burst = burst;
+	th->latency = msecs_to_jiffies(latency);
+	th->state = 0;
+	wmb();
+	th->speed = speed;
+}
+
+/* externally serialized */
+static void throttle_charge(struct throttle *th, unsigned charge)
+{
+	unsigned long now = jiffies;
+	u64 step;
+
+	if (!th->speed)
+		return;
+
+	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);
+		th->time = now;
+	}
+
+	if (charge > th->state) {
+		charge -= th->state;
+		step = (u64)charge * HZ;
+		if (do_div(step, th->speed))
+			step++;
+		th->time += step;
+		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;
+}
+
+/* lockless */
+static unsigned long throttle_timeout(struct throttle *th, unsigned long now)
+{
+	unsigned long time;
+
+	if (!th->speed)
+		return 0;
+	rmb();
+	time = th->time;
+	if (time_before(time, now))
+		return 0;
+	return min(time - now, (unsigned long)th->latency);
+}
+
+
 static int iolimit_virtinfo(struct vnotifier_block *nb,
 		unsigned long cmd, void *arg, int old_ret)
 {



More information about the Devel mailing list