]> git.proxmox.com Git - mirror_qemu.git/blame - fsdev/qemu-fsdev-throttle.c
Merge tag 'pull-parallels-2023-09-20-v2' of https://src.openvz.org/scm/~den/qemu...
[mirror_qemu.git] / fsdev / qemu-fsdev-throttle.c
CommitLineData
b8bbdb88
PJ
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"
db725815 19#include "qemu/main-loop.h"
922a01a0 20#include "qemu/option.h"
b8bbdb88
PJ
21
22static void fsdev_throttle_read_timer_cb(void *opaque)
23{
24 FsThrottle *fst = opaque;
5261dd7b 25 qemu_co_enter_next(&fst->throttled_reqs[false], NULL);
b8bbdb88
PJ
26}
27
28static void fsdev_throttle_write_timer_cb(void *opaque)
29{
30 FsThrottle *fst = opaque;
5261dd7b 31 qemu_co_enter_next(&fst->throttled_reqs[true], NULL);
b8bbdb88
PJ
32}
33
ea52cdd4 34int fsdev_throttle_parse_opts(QemuOpts *opts, FsThrottle *fst, Error **errp)
b8bbdb88
PJ
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
ea52cdd4 78 return throttle_is_valid(&fst->cfg, errp) ? 0 : -1;
b8bbdb88
PJ
79}
80
81void 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);
27e4cf13 91 throttle_config(&fst->ts, QEMU_CLOCK_REALTIME, &fst->cfg);
b8bbdb88
PJ
92 qemu_co_queue_init(&fst->throttled_reqs[0]);
93 qemu_co_queue_init(&fst->throttled_reqs[1]);
94 }
95}
96
00ea69f5
ZP
97void coroutine_fn fsdev_co_throttle_request(FsThrottle *fst,
98 ThrottleDirection direction,
b8bbdb88
PJ
99 struct iovec *iov, int iovcnt)
100{
00ea69f5 101 assert(direction < THROTTLE_MAX);
b8bbdb88 102 if (throttle_enabled(&fst->cfg)) {
e76f201f 103 if (throttle_schedule_timer(&fst->ts, &fst->tt, direction) ||
00ea69f5
ZP
104 !qemu_co_queue_empty(&fst->throttled_reqs[direction])) {
105 qemu_co_queue_wait(&fst->throttled_reqs[direction], NULL);
b8bbdb88
PJ
106 }
107
e76f201f 108 throttle_account(&fst->ts, direction, iov_size(iov, iovcnt));
b8bbdb88 109
00ea69f5 110 if (!qemu_co_queue_empty(&fst->throttled_reqs[direction]) &&
e76f201f 111 !throttle_schedule_timer(&fst->ts, &fst->tt, direction)) {
00ea69f5 112 qemu_co_queue_next(&fst->throttled_reqs[direction]);
b8bbdb88
PJ
113 }
114 }
115}
116
117void fsdev_throttle_cleanup(FsThrottle *fst)
118{
119 if (throttle_enabled(&fst->cfg)) {
120 throttle_timers_destroy(&fst->tt);
121 }
122}