qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH V5] fsdev: add IO throttle support to fsdev devi


From: Pradeep Jagadeesh
Subject: Re: [Qemu-devel] [PATCH V5] fsdev: add IO throttle support to fsdev devices
Date: Fri, 21 Oct 2016 18:04:48 +0200
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0

Alberto,

Thanks for reviewing the patch.

On Thu 20 Oct 2016 04:14:23 PM CEST, Pradeep Jagadeesh wrote:
+static void fsdev_throttle_schedule_next_request(FsThrottle *fst, bool 
is_write)
+{
+    bool must_wait;
+
+    if (qemu_co_queue_empty(&fst->throttled_reqs[is_write])) {
+        return;
+    }
+    must_wait = fsdev_throttle_check_for_wait(fst, is_write);
+    if (!must_wait) {
+        if (qemu_in_coroutine() &&
+            qemu_co_queue_next(&fst->throttled_reqs[is_write])) {
+            ;
+       } else {
+           int64_t now = qemu_clock_get_ns(fst->tt.clock_type);
+           timer_mod(fst->tt.timers[is_write], now + 1);
+       }
+   }
+}

I think you don't need to schedule the timer here. This was added for
group throttling for disks because once a disk completes an I/O request,
the next request might be in a different disk (due to the round-robin
algorithm). So we put a timer in that disk to handle that.

In your case that cannot happen, see fsdev_throttle_request() below[1]
for a suggestion of how it can look like.
OK

+static void fsdev_throttle_timer_cb(FsThrottle *fst, bool is_write)
+{
+    bool empty_queue;
+    empty_queue = !qemu_co_enter_next(&fst->throttled_reqs[is_write]);
+    if (empty_queue) {
+        fsdev_throttle_schedule_next_request(fst, is_write);
+    }
+}

This doesn't make any sense, if the throttled_reqs queue is empty then
you're calling fsdev_throttle_schedule_next_request(), but how can a
next request be scheduled if the queue is empty? :-)

You don't need fsdev_throttle_timer_cb() at all, but you can simply do
this instead:
OK

+static void fsdev_throttle_read_timer_cb(void *opaque)
+{
       FsThrottle *fst = opaque;
       qemu_co_enter_next(&fst->throttled_reqs[false]);
+}
+
+static void fsdev_throttle_write_timer_cb(void *opaque)
+{
       FsThrottle *fst = opaque;
       qemu_co_enter_next(&fst->throttled_reqs[true]);
+}

+static int get_num_bytes(struct iovec *iov, int iovcnt)
+{
+    int index = 0;
+    int bytes = 0;
+
+    while (index < iovcnt) {
+        bytes += iov[index].iov_len;
+        index++;
+    }
+    return bytes;

You're looping over the iov vector, use a for loop instead, no?:

for (i = 0; i < iovcnt; i++) {
   bytes += iov[i].iov_len;
}

OK
+void fsdev_throttle_request(FsThrottle *fst, bool is_write,
+                            struct iovec *iov, int iovcnt)

First, mark the function as running in a coroutine context:

OK
void coroutine_fn fsdev_throttle_request(FsThrottle *fst, bool is_write,
                                         struct iovec *iov, int iovcnt)

+{
+    int bytes;
+
+    if (throttle_enabled(&fst->cfg)) {

I think it's probably better to check that in the caller, but I don't
have a strong opinion. If you keep it like this, put the definition of
'bytes' inside the if block instead.

I just thought its better to check for throttle enabled or not.

+        bytes = get_num_bytes(iov, iovcnt);
+        bool must_wait = fsdev_throttle_check_for_wait(fst, is_write);
+        if (must_wait || !qemu_co_queue_empty(&fst->throttled_reqs[is_write])) 
{
+            qemu_co_queue_wait(&fst->throttled_reqs[is_write]);
+       }
+       throttle_account(&fst->ts, is_write, bytes);
+
+       fsdev_throttle_schedule_next_request(fst, is_write);

So this is the [1] that I mentioned earlier. In your case instead of
fsdev_throttle_schedule_next_request() I think you simply something
like:

    if (!qemu_co_queue_empty(&fst->throttled_reqs[is_write])) {
       /* If there's a timer set, don't do anything else, the timer
          callback will schedule the next request */
       if (fsdev_throttle_check_for_wait(fst, is_write)) {
           return;
       }

       /* If a timer is not set, then schedule the next request now */
       qemu_co_queue_next(&fst->throttled_reqs[is_write]);
    }

OK, also I changed the name as you suggested.

-Pradeep
Berto





reply via email to

[Prev in Thread] Current Thread [Next in Thread]