[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