cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

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
     22static 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
     28static 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
     34int 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
     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);
     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
     97void 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
    115void fsdev_throttle_cleanup(FsThrottle *fst)
    116{
    117    if (throttle_enabled(&fst->cfg)) {
    118        throttle_timers_destroy(&fst->tt);
    119    }
    120}