qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

qemu-fsdev-throttle.c (4596B)


      1 /*
      2  * Fsdev Throttle
      3  *
      4  * Copyright (C) 2016 Huawei Technologies Duesseldorf GmbH
      5  *
      6  * Author: Pradeep Jagadeesh <pradeep.jagadeesh@huawei.com>
      7  *
      8  * This work is licensed under the terms of the GNU GPL, version 2 or
      9  * (at your option) any later version.
     10  *
     11  * See the COPYING file in the top-level directory for details.
     12  *
     13  */
     14 
     15 #include "qemu/osdep.h"
     16 #include "qemu/error-report.h"
     17 #include "qemu-fsdev-throttle.h"
     18 #include "qemu/iov.h"
     19 #include "qemu/main-loop.h"
     20 #include "qemu/option.h"
     21 
     22 static void fsdev_throttle_read_timer_cb(void *opaque)
     23 {
     24     FsThrottle *fst = opaque;
     25     qemu_co_enter_next(&fst->throttled_reqs[false], NULL);
     26 }
     27 
     28 static void fsdev_throttle_write_timer_cb(void *opaque)
     29 {
     30     FsThrottle *fst = opaque;
     31     qemu_co_enter_next(&fst->throttled_reqs[true], NULL);
     32 }
     33 
     34 int fsdev_throttle_parse_opts(QemuOpts *opts, FsThrottle *fst, Error **errp)
     35 {
     36     throttle_config_init(&fst->cfg);
     37     fst->cfg.buckets[THROTTLE_BPS_TOTAL].avg =
     38         qemu_opt_get_number(opts, "throttling.bps-total", 0);
     39     fst->cfg.buckets[THROTTLE_BPS_READ].avg  =
     40         qemu_opt_get_number(opts, "throttling.bps-read", 0);
     41     fst->cfg.buckets[THROTTLE_BPS_WRITE].avg =
     42         qemu_opt_get_number(opts, "throttling.bps-write", 0);
     43     fst->cfg.buckets[THROTTLE_OPS_TOTAL].avg =
     44         qemu_opt_get_number(opts, "throttling.iops-total", 0);
     45     fst->cfg.buckets[THROTTLE_OPS_READ].avg =
     46         qemu_opt_get_number(opts, "throttling.iops-read", 0);
     47     fst->cfg.buckets[THROTTLE_OPS_WRITE].avg =
     48         qemu_opt_get_number(opts, "throttling.iops-write", 0);
     49 
     50     fst->cfg.buckets[THROTTLE_BPS_TOTAL].max =
     51         qemu_opt_get_number(opts, "throttling.bps-total-max", 0);
     52     fst->cfg.buckets[THROTTLE_BPS_READ].max  =
     53         qemu_opt_get_number(opts, "throttling.bps-read-max", 0);
     54     fst->cfg.buckets[THROTTLE_BPS_WRITE].max =
     55         qemu_opt_get_number(opts, "throttling.bps-write-max", 0);
     56     fst->cfg.buckets[THROTTLE_OPS_TOTAL].max =
     57         qemu_opt_get_number(opts, "throttling.iops-total-max", 0);
     58     fst->cfg.buckets[THROTTLE_OPS_READ].max =
     59         qemu_opt_get_number(opts, "throttling.iops-read-max", 0);
     60     fst->cfg.buckets[THROTTLE_OPS_WRITE].max =
     61         qemu_opt_get_number(opts, "throttling.iops-write-max", 0);
     62 
     63     fst->cfg.buckets[THROTTLE_BPS_TOTAL].burst_length =
     64         qemu_opt_get_number(opts, "throttling.bps-total-max-length", 1);
     65     fst->cfg.buckets[THROTTLE_BPS_READ].burst_length  =
     66         qemu_opt_get_number(opts, "throttling.bps-read-max-length", 1);
     67     fst->cfg.buckets[THROTTLE_BPS_WRITE].burst_length =
     68         qemu_opt_get_number(opts, "throttling.bps-write-max-length", 1);
     69     fst->cfg.buckets[THROTTLE_OPS_TOTAL].burst_length =
     70         qemu_opt_get_number(opts, "throttling.iops-total-max-length", 1);
     71     fst->cfg.buckets[THROTTLE_OPS_READ].burst_length =
     72         qemu_opt_get_number(opts, "throttling.iops-read-max-length", 1);
     73     fst->cfg.buckets[THROTTLE_OPS_WRITE].burst_length =
     74         qemu_opt_get_number(opts, "throttling.iops-write-max-length", 1);
     75     fst->cfg.op_size =
     76         qemu_opt_get_number(opts, "throttling.iops-size", 0);
     77 
     78     return throttle_is_valid(&fst->cfg, errp) ? 0 : -1;
     79 }
     80 
     81 void fsdev_throttle_init(FsThrottle *fst)
     82 {
     83     if (throttle_enabled(&fst->cfg)) {
     84         throttle_init(&fst->ts);
     85         throttle_timers_init(&fst->tt,
     86                              qemu_get_aio_context(),
     87                              QEMU_CLOCK_REALTIME,
     88                              fsdev_throttle_read_timer_cb,
     89                              fsdev_throttle_write_timer_cb,
     90                              fst);
     91         throttle_config(&fst->ts, QEMU_CLOCK_REALTIME, &fst->cfg);
     92         qemu_co_queue_init(&fst->throttled_reqs[0]);
     93         qemu_co_queue_init(&fst->throttled_reqs[1]);
     94     }
     95 }
     96 
     97 void coroutine_fn fsdev_co_throttle_request(FsThrottle *fst, bool is_write,
     98                                             struct iovec *iov, int iovcnt)
     99 {
    100     if (throttle_enabled(&fst->cfg)) {
    101         if (throttle_schedule_timer(&fst->ts, &fst->tt, is_write) ||
    102             !qemu_co_queue_empty(&fst->throttled_reqs[is_write])) {
    103             qemu_co_queue_wait(&fst->throttled_reqs[is_write], NULL);
    104         }
    105 
    106         throttle_account(&fst->ts, is_write, iov_size(iov, iovcnt));
    107 
    108         if (!qemu_co_queue_empty(&fst->throttled_reqs[is_write]) &&
    109             !throttle_schedule_timer(&fst->ts, &fst->tt, is_write)) {
    110             qemu_co_queue_next(&fst->throttled_reqs[is_write]);
    111         }
    112     }
    113 }
    114 
    115 void fsdev_throttle_cleanup(FsThrottle *fst)
    116 {
    117     if (throttle_enabled(&fst->cfg)) {
    118         throttle_timers_destroy(&fst->tt);
    119     }
    120 }