Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20190726' into...
[qemu/ar7.git] / fsdev / qemu-fsdev-throttle.c
blobcfd86418aca71138373f97fc1b7e5f6e57539731
1 /*
2 * Fsdev Throttle
4 * Copyright (C) 2016 Huawei Technologies Duesseldorf GmbH
6 * Author: Pradeep Jagadeesh <pradeep.jagadeesh@huawei.com>
8 * This work is licensed under the terms of the GNU GPL, version 2 or
9 * (at your option) any later version.
11 * See the COPYING file in the top-level directory for details.
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/option.h"
21 static void fsdev_throttle_read_timer_cb(void *opaque)
23 FsThrottle *fst = opaque;
24 qemu_co_enter_next(&fst->throttled_reqs[false], NULL);
27 static void fsdev_throttle_write_timer_cb(void *opaque)
29 FsThrottle *fst = opaque;
30 qemu_co_enter_next(&fst->throttled_reqs[true], NULL);
33 void fsdev_throttle_parse_opts(QemuOpts *opts, FsThrottle *fst, Error **errp)
35 throttle_config_init(&fst->cfg);
36 fst->cfg.buckets[THROTTLE_BPS_TOTAL].avg =
37 qemu_opt_get_number(opts, "throttling.bps-total", 0);
38 fst->cfg.buckets[THROTTLE_BPS_READ].avg =
39 qemu_opt_get_number(opts, "throttling.bps-read", 0);
40 fst->cfg.buckets[THROTTLE_BPS_WRITE].avg =
41 qemu_opt_get_number(opts, "throttling.bps-write", 0);
42 fst->cfg.buckets[THROTTLE_OPS_TOTAL].avg =
43 qemu_opt_get_number(opts, "throttling.iops-total", 0);
44 fst->cfg.buckets[THROTTLE_OPS_READ].avg =
45 qemu_opt_get_number(opts, "throttling.iops-read", 0);
46 fst->cfg.buckets[THROTTLE_OPS_WRITE].avg =
47 qemu_opt_get_number(opts, "throttling.iops-write", 0);
49 fst->cfg.buckets[THROTTLE_BPS_TOTAL].max =
50 qemu_opt_get_number(opts, "throttling.bps-total-max", 0);
51 fst->cfg.buckets[THROTTLE_BPS_READ].max =
52 qemu_opt_get_number(opts, "throttling.bps-read-max", 0);
53 fst->cfg.buckets[THROTTLE_BPS_WRITE].max =
54 qemu_opt_get_number(opts, "throttling.bps-write-max", 0);
55 fst->cfg.buckets[THROTTLE_OPS_TOTAL].max =
56 qemu_opt_get_number(opts, "throttling.iops-total-max", 0);
57 fst->cfg.buckets[THROTTLE_OPS_READ].max =
58 qemu_opt_get_number(opts, "throttling.iops-read-max", 0);
59 fst->cfg.buckets[THROTTLE_OPS_WRITE].max =
60 qemu_opt_get_number(opts, "throttling.iops-write-max", 0);
62 fst->cfg.buckets[THROTTLE_BPS_TOTAL].burst_length =
63 qemu_opt_get_number(opts, "throttling.bps-total-max-length", 1);
64 fst->cfg.buckets[THROTTLE_BPS_READ].burst_length =
65 qemu_opt_get_number(opts, "throttling.bps-read-max-length", 1);
66 fst->cfg.buckets[THROTTLE_BPS_WRITE].burst_length =
67 qemu_opt_get_number(opts, "throttling.bps-write-max-length", 1);
68 fst->cfg.buckets[THROTTLE_OPS_TOTAL].burst_length =
69 qemu_opt_get_number(opts, "throttling.iops-total-max-length", 1);
70 fst->cfg.buckets[THROTTLE_OPS_READ].burst_length =
71 qemu_opt_get_number(opts, "throttling.iops-read-max-length", 1);
72 fst->cfg.buckets[THROTTLE_OPS_WRITE].burst_length =
73 qemu_opt_get_number(opts, "throttling.iops-write-max-length", 1);
74 fst->cfg.op_size =
75 qemu_opt_get_number(opts, "throttling.iops-size", 0);
77 throttle_is_valid(&fst->cfg, errp);
80 void fsdev_throttle_init(FsThrottle *fst)
82 if (throttle_enabled(&fst->cfg)) {
83 throttle_init(&fst->ts);
84 throttle_timers_init(&fst->tt,
85 qemu_get_aio_context(),
86 QEMU_CLOCK_REALTIME,
87 fsdev_throttle_read_timer_cb,
88 fsdev_throttle_write_timer_cb,
89 fst);
90 throttle_config(&fst->ts, QEMU_CLOCK_REALTIME, &fst->cfg);
91 qemu_co_queue_init(&fst->throttled_reqs[0]);
92 qemu_co_queue_init(&fst->throttled_reqs[1]);
96 void coroutine_fn fsdev_co_throttle_request(FsThrottle *fst, bool is_write,
97 struct iovec *iov, int iovcnt)
99 if (throttle_enabled(&fst->cfg)) {
100 if (throttle_schedule_timer(&fst->ts, &fst->tt, is_write) ||
101 !qemu_co_queue_empty(&fst->throttled_reqs[is_write])) {
102 qemu_co_queue_wait(&fst->throttled_reqs[is_write], NULL);
105 throttle_account(&fst->ts, is_write, iov_size(iov, iovcnt));
107 if (!qemu_co_queue_empty(&fst->throttled_reqs[is_write]) &&
108 !throttle_schedule_timer(&fst->ts, &fst->tt, is_write)) {
109 qemu_co_queue_next(&fst->throttled_reqs[is_write]);
114 void fsdev_throttle_cleanup(FsThrottle *fst)
116 if (throttle_enabled(&fst->cfg)) {
117 throttle_timers_destroy(&fst->tt);