qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Alberto Garcia <berto@igalia.com>,
	Stefan Hajnoczi <stefanha@redhat.com>
Subject: [Qemu-devel] [PULL for-2.10 05/15] throttle: Remove throttle_fix_bucket() / throttle_unfix_bucket()
Date: Thu, 31 Aug 2017 09:22:00 +0100	[thread overview]
Message-ID: <20170831082210.8362-6-stefanha@redhat.com> (raw)
In-Reply-To: <20170831082210.8362-1-stefanha@redhat.com>

From: Alberto Garcia <berto@igalia.com>

The throttling code can change internally the value of bkt->max if it
hasn't been set by the user. The problem with this is that if we want
to retrieve the original value we have to undo this change first. This
is ugly and unnecessary: this patch removes the throttle_fix_bucket()
and throttle_unfix_bucket() functions completely and moves the logic
to throttle_compute_wait().

Signed-off-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
Message-id: 5b0b9e1ac6eb208d709eddc7b09e7669a523bff3.1503580370.git.berto@igalia.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 util/throttle.c | 62 +++++++++++++++++++++------------------------------------
 1 file changed, 23 insertions(+), 39 deletions(-)

diff --git a/util/throttle.c b/util/throttle.c
index bde56fe3de..4e80a7ea54 100644
--- a/util/throttle.c
+++ b/util/throttle.c
@@ -95,23 +95,36 @@ static int64_t throttle_do_compute_wait(double limit, double extra)
 int64_t throttle_compute_wait(LeakyBucket *bkt)
 {
     double extra; /* the number of extra units blocking the io */
+    double bucket_size;   /* I/O before throttling to bkt->avg */
+    double burst_bucket_size; /* Before throttling to bkt->max */
 
     if (!bkt->avg) {
         return 0;
     }
 
-    /* If the bucket is full then we have to wait */
-    extra = bkt->level - bkt->max * bkt->burst_length;
+    if (!bkt->max) {
+        /* If bkt->max is 0 we still want to allow short bursts of I/O
+         * from the guest, otherwise every other request will be throttled
+         * and performance will suffer considerably. */
+        bucket_size = bkt->avg / 10;
+        burst_bucket_size = 0;
+    } else {
+        /* If we have a burst limit then we have to wait until all I/O
+         * at burst rate has finished before throttling to bkt->avg */
+        bucket_size = bkt->max * bkt->burst_length;
+        burst_bucket_size = bkt->max / 10;
+    }
+
+    /* If the main bucket is full then we have to wait */
+    extra = bkt->level - bucket_size;
     if (extra > 0) {
         return throttle_do_compute_wait(bkt->avg, extra);
     }
 
-    /* If the bucket is not full yet we have to make sure that we
-     * fulfill the goal of bkt->max units per second. */
+    /* If the main bucket is not full yet we still have to check the
+     * burst bucket in order to enforce the burst limit */
     if (bkt->burst_length > 1) {
-        /* We use 1/10 of the max value to smooth the throttling.
-         * See throttle_fix_bucket() for more details. */
-        extra = bkt->burst_level - bkt->max / 10;
+        extra = bkt->burst_level - burst_bucket_size;
         if (extra > 0) {
             return throttle_do_compute_wait(bkt->max, extra);
         }
@@ -357,31 +370,6 @@ bool throttle_is_valid(ThrottleConfig *cfg, Error **errp)
     return true;
 }
 
-/* fix bucket parameters */
-static void throttle_fix_bucket(LeakyBucket *bkt)
-{
-    double min;
-
-    /* zero bucket level */
-    bkt->level = bkt->burst_level = 0;
-
-    /* If bkt->max is 0 we still want to allow short bursts of I/O
-     * from the guest, otherwise every other request will be throttled
-     * and performance will suffer considerably. */
-    min = bkt->avg / 10;
-    if (bkt->avg && !bkt->max) {
-        bkt->max = min;
-    }
-}
-
-/* undo internal bucket parameter changes (see throttle_fix_bucket()) */
-static void throttle_unfix_bucket(LeakyBucket *bkt)
-{
-    if (bkt->max < bkt->avg) {
-        bkt->max = 0;
-    }
-}
-
 /* Used to configure the throttle
  *
  * @ts: the throttle state we are working on
@@ -396,8 +384,10 @@ void throttle_config(ThrottleState *ts,
 
     ts->cfg = *cfg;
 
+    /* Zero bucket level */
     for (i = 0; i < BUCKETS_COUNT; i++) {
-        throttle_fix_bucket(&ts->cfg.buckets[i]);
+        ts->cfg.buckets[i].level = 0;
+        ts->cfg.buckets[i].burst_level = 0;
     }
 
     ts->previous_leak = qemu_clock_get_ns(clock_type);
@@ -410,13 +400,7 @@ void throttle_config(ThrottleState *ts,
  */
 void throttle_get_config(ThrottleState *ts, ThrottleConfig *cfg)
 {
-    int i;
-
     *cfg = ts->cfg;
-
-    for (i = 0; i < BUCKETS_COUNT; i++) {
-        throttle_unfix_bucket(&cfg->buckets[i]);
-    }
 }
 
 
-- 
2.13.5

  parent reply	other threads:[~2017-08-31  8:22 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-31  8:21 [Qemu-devel] [PULL for-2.10 00/15] Block patches Stefan Hajnoczi
2017-08-31  8:21 ` [Qemu-devel] [PULL for-2.10 01/15] nvme: Fix get/set number of queues feature, again Stefan Hajnoczi
2017-08-31  8:21 ` [Qemu-devel] [PULL for-2.10 02/15] throttle: Fix wrong variable name in the header documentation Stefan Hajnoczi
2017-08-31  8:21 ` [Qemu-devel] [PULL for-2.10 03/15] throttle: Update the throttle_fix_bucket() documentation Stefan Hajnoczi
2017-08-31  8:21 ` [Qemu-devel] [PULL for-2.10 04/15] throttle: Make throttle_is_valid() a bit less verbose Stefan Hajnoczi
2017-08-31  8:22 ` Stefan Hajnoczi [this message]
2017-09-12 17:37   ` [Qemu-devel] [PULL for-2.10 05/15] throttle: Remove throttle_fix_bucket() / throttle_unfix_bucket() Peter Maydell
2017-08-31  8:22 ` [Qemu-devel] [PULL for-2.10 06/15] throttle: Make LeakyBucket.avg and LeakyBucket.max integer types Stefan Hajnoczi
2017-08-31  8:22 ` [Qemu-devel] [PULL for-2.10 07/15] throttle: Make burst_length 64bit and add range checks Stefan Hajnoczi
2017-08-31  8:22 ` [Qemu-devel] [PULL for-2.10 08/15] throttle: Test the valid range of config values Stefan Hajnoczi
2017-08-31  8:22 ` [Qemu-devel] [PULL for-2.10 09/15] oslib-posix: Print errors before aborting on qemu_alloc_stack() Stefan Hajnoczi
2017-08-31  8:22 ` [Qemu-devel] [PULL for-2.10 10/15] misc: Remove unused Error variables Stefan Hajnoczi
2017-08-31  8:22 ` [Qemu-devel] [PULL for-2.10 11/15] scripts: add argparse module for Python 2.6 compatibility Stefan Hajnoczi
2017-08-31  8:22 ` [Qemu-devel] [PULL for-2.10 12/15] docker.py: Python 2.6 argparse compatibility Stefan Hajnoczi
2017-08-31  8:22 ` [Qemu-devel] [PULL for-2.10 13/15] tests: migration/guestperf " Stefan Hajnoczi
2017-08-31  8:22 ` [Qemu-devel] [PULL for-2.10 14/15] qemu-doc: Add UUID support in initiator name Stefan Hajnoczi
2017-08-31  8:22 ` [Qemu-devel] [PULL for-2.10 15/15] qcow2: allocate cluster_cache/cluster_data on demand Stefan Hajnoczi
2017-08-31  8:37 ` [Qemu-devel] [PULL for-2.10 00/15] Block patches no-reply
2017-08-31 13:47 ` Eric Blake
2017-08-31 14:51 ` Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170831082210.8362-6-stefanha@redhat.com \
    --to=stefanha@redhat.com \
    --cc=berto@igalia.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).