Am 03.08.2017 um 13:48 hat Manos Pitsidianakis geschrieben: > On Thu, Aug 03, 2017 at 10:07:41AM +0200, Kevin Wolf wrote: > > Am 31.07.2017 um 11:54 hat Manos Pitsidianakis geschrieben: > > > +/* Extract ThrottleConfig options. Assumes cfg is initialized and will be > > > + * checked for validity. > > > + */ > > > +static int throttle_extract_options(QemuOpts *opts, ThrottleConfig *cfg, > > > + Error **errp) > > > +{ > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL)) { > > > + cfg->buckets[THROTTLE_BPS_TOTAL].avg = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL, > > > + 0); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ)) { > > > + cfg->buckets[THROTTLE_BPS_READ].avg = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ, > > > + 0); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE)) { > > > + cfg->buckets[THROTTLE_BPS_WRITE].avg = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE, > > > + 0); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL)) { > > > + cfg->buckets[THROTTLE_OPS_TOTAL].avg = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL, > > > + 0); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ)) { > > > + cfg->buckets[THROTTLE_OPS_READ].avg = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ, > > > + 0); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE)) { > > > + cfg->buckets[THROTTLE_OPS_WRITE].avg = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE, > > > + 0); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL_MAX)) { > > > + cfg->buckets[THROTTLE_BPS_TOTAL].max = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_BPS_TOTAL_MAX, 0); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ_MAX)) { > > > + cfg->buckets[THROTTLE_BPS_READ].max = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_BPS_READ_MAX, 0); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE_MAX)) { > > > + cfg->buckets[THROTTLE_BPS_WRITE].max = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_BPS_WRITE_MAX, 0); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL_MAX)) { > > > + cfg->buckets[THROTTLE_OPS_TOTAL].max = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_IOPS_TOTAL_MAX, 0); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ_MAX)) { > > > + cfg->buckets[THROTTLE_OPS_READ].max = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_IOPS_READ_MAX, 0); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE_MAX)) { > > > + cfg->buckets[THROTTLE_OPS_WRITE].max = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_IOPS_WRITE_MAX, 0); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL_MAX_LENGTH)) { > > > + if (qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_BPS_TOTAL_MAX_LENGTH, 1) > UINT_MAX) { > > > + error_setg(errp, "%s value must be in the range [0, %u]", > > > + THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL_MAX_LENGTH, > > > + UINT_MAX); > > > + return -1; > > > + } > > > + cfg->buckets[THROTTLE_BPS_TOTAL].burst_length = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_BPS_TOTAL_MAX_LENGTH, 1); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ_MAX_LENGTH)) { > > > + if (qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_BPS_READ_MAX_LENGTH, 1) > UINT_MAX) { > > > + error_setg(errp, "%s must be in the range [0, %u]", > > > + THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ_MAX_LENGTH, > > > + UINT_MAX); > > > + return -1; > > > + } > > > + cfg->buckets[THROTTLE_BPS_READ].burst_length = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_BPS_READ_MAX_LENGTH, 1); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE_MAX_LENGTH)) { > > > + if (qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_BPS_WRITE_MAX_LENGTH, 1) > UINT_MAX) { > > > + error_setg(errp, "%s must be in the range [0, %u]", > > > + THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE_MAX_LENGTH, > > > + UINT_MAX); > > > + return -1; > > > + } > > > + cfg->buckets[THROTTLE_BPS_WRITE].burst_length = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_BPS_WRITE_MAX_LENGTH, 1); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL_MAX_LENGTH)) { > > > + if (qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_IOPS_TOTAL_MAX_LENGTH, 1) > UINT_MAX) { > > > + error_setg(errp, "%s must be in the range [0, %u]", > > > + THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL_MAX_LENGTH, > > > + UINT_MAX); > > > + return -1; > > > + } > > > + cfg->buckets[THROTTLE_OPS_TOTAL].burst_length = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_IOPS_TOTAL_MAX_LENGTH, 1); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ_MAX_LENGTH)) { > > > + if (qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_IOPS_READ_MAX_LENGTH, 1) > UINT_MAX) { > > > + error_setg(errp, "%s must be in the range [0, %u]", > > > + THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ_MAX_LENGTH, > > > + UINT_MAX); > > > + return -1; > > > + } > > > + cfg->buckets[THROTTLE_OPS_READ].burst_length = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_IOPS_READ_MAX_LENGTH, 1); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE_MAX_LENGTH)) { > > > + if (qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_IOPS_WRITE_MAX_LENGTH, 1) > UINT_MAX) { > > > + error_setg(errp, "%s must be in the range [0, %u]", > > > + THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE_MAX_LENGTH, > > > + UINT_MAX); > > > + return -1; > > > + } > > > + cfg->buckets[THROTTLE_OPS_WRITE].burst_length = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX > > > + QEMU_OPT_IOPS_WRITE_MAX_LENGTH, 1); > > > + } > > > + if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_SIZE)) { > > > + cfg->op_size = > > > + qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_SIZE, > > > + 0); > > > + } > > > + return 0; > > > +} > > > > This function is very repetitive, but each block is long enough that > > you have to look closely to review whether the right constants are used > > everywhere. > > > > Maybe this could become a bit more readable with a macro or two? > > How about this? > > > # #define IF_OPT_SET(rvalue,opt_name) \ > # if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX opt_name)) { \ > # rvalue = qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX opt_name, > 0); } > > # IF_OPT_SET(cfg->buckets[THROTTLE_BPS_TOTAL].avg, QEMU_OPT_BPS_TOTAL); > # IF_OPT_SET(cfg->buckets[THROTTLE_BPS_READ].avg, QEMU_OPT_BPS_READ); > [...] Looks a lot more readable to me. :-) If nobody objects, I'd suggest to go this way. > > > +static int coroutine_fn throttle_co_pwritev(BlockDriverState *bs, > > > + uint64_t offset, uint64_t bytes, > > > + QEMUIOVector *qiov, int flags) > > > +{ > > > + ThrottleGroupMember *tgm = bs->opaque; > > > + throttle_group_co_io_limits_intercept(tgm, bytes, true); > > > + > > > + return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags); > > > +} > > > > I think we want to set BlockDriver.supported_write_flags so that passing > > down flags is actually of any use. > > Can you explain what you mean? Do you mean doing this in throttle_open(): > > bs->supported_write_flags = bs->file->bs->supported_write_flags; > bs->supported_zero_flags = bs->file->bs->supported_zero_flags; Yes, I think that should do the trick. Kevin