On Thu, Jul 28, 2011 at 6:43 AM, Zhi Yong Wu <zwu.kernel@xxxxxxxxx> wrote: > On Wed, Jul 27, 2011 at 8:58 PM, Stefan Hajnoczi <stefanha@xxxxxxxxx> wrote: >> On Wed, Jul 27, 2011 at 11:17 AM, Zhi Yong Wu <zwu.kernel@xxxxxxxxx> wrote: >>> On Wed, Jul 27, 2011 at 3:26 AM, Marcelo Tosatti <mtosatti@xxxxxxxxxx> wrote: >>>> On Tue, Jul 26, 2011 at 04:59:06PM +0800, Zhi Yong Wu wrote: >>>>> Welcome to give me your comments, thanks. >>>>> >>>>> Signed-off-by: Zhi Yong Wu <wuzhy@xxxxxxxxxxxxxxxxxx> >>>>> --- >>>>> Makefile.objs | 2 +- >>>>> block.c | 288 +++++++++++++++++++++++++++++++++++++++++++++++++++-- >>>>> block.h | 1 - >>>>> block/blk-queue.c | 116 +++++++++++++++++++++ >>>>> block/blk-queue.h | 70 +++++++++++++ >>>>> block_int.h | 28 +++++ >>>>> blockdev.c | 21 ++++ >>>>> qemu-config.c | 24 +++++ >>>>> qemu-option.c | 17 +++ >>>>> qemu-option.h | 1 + >>>>> qemu-options.hx | 1 + >>>>> 11 files changed, 559 insertions(+), 10 deletions(-) >>>>> create mode 100644 block/blk-queue.c >>>>> create mode 100644 block/blk-queue.h >>>>> >>>>> diff --git a/Makefile.objs b/Makefile.objs >>>>> index 9f99ed4..06f2033 100644 >>>>> --- a/Makefile.objs >>>>> +++ b/Makefile.objs >>>>> @@ -23,7 +23,7 @@ block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vv >>>>> block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o >>>>> block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o >>>>> block-nested-y += qed-check.o >>>>> -block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o >>>>> +block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o blk-queue.o >>>>> block-nested-$(CONFIG_WIN32) += raw-win32.o >>>>> block-nested-$(CONFIG_POSIX) += raw-posix.o >>>>> block-nested-$(CONFIG_CURL) += curl.o >>>>> diff --git a/block.c b/block.c >>>>> index 24a25d5..e54e59c 100644 >>>>> --- a/block.c >>>>> +++ b/block.c >>>>> @@ -29,6 +29,9 @@ >>>>> #include "module.h" >>>>> #include "qemu-objects.h" >>>>> >>>>> +#include "qemu-timer.h" >>>>> +#include "block/blk-queue.h" >>>>> + >>>>> #ifdef CONFIG_BSD >>>>> #include <sys/types.h> >>>>> #include <sys/stat.h> >>>>> @@ -58,6 +61,13 @@ static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, >>>>> static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, >>>>> const uint8_t *buf, int nb_sectors); >>>>> >>>>> +static bool bdrv_exceed_bps_limits(BlockDriverState *bs, int nb_sectors, >>>>> + bool is_write, double elapsed_time, uint64_t *wait); >>>>> +static bool bdrv_exceed_iops_limits(BlockDriverState *bs, bool is_write, >>>>> + double elapsed_time, uint64_t *wait); >>>>> +static bool bdrv_exceed_io_limits(BlockDriverState *bs, int nb_sectors, >>>>> + bool is_write, uint64_t *wait); >>>>> + >>>>> static QTAILQ_HEAD(, BlockDriverState) bdrv_states = >>>>> QTAILQ_HEAD_INITIALIZER(bdrv_states); >>>>> >>>>> @@ -90,6 +100,20 @@ int is_windows_drive(const char *filename) >>>>> } >>>>> #endif >>>>> >>>>> +static int bdrv_io_limits_enable(BlockIOLimit *io_limits) >>>>> +{ >>>>> + if ((io_limits->bps[0] == 0) >>>>> + && (io_limits->bps[1] == 0) >>>>> + && (io_limits->bps[2] == 0) >>>>> + && (io_limits->iops[0] == 0) >>>>> + && (io_limits->iops[1] == 0) >>>>> + && (io_limits->iops[2] == 0)) { >>>>> + return 0; >>>>> + } >>>>> + >>>>> + return 1; >>>>> +} >>>>> + >>>>> /* check if the path starts with "<protocol>:" */ >>>>> static int path_has_protocol(const char *path) >>>>> { >>>>> @@ -167,6 +191,28 @@ void path_combine(char *dest, int dest_size, >>>>> } >>>>> } >>>>> >>>>> +static void bdrv_block_timer(void *opaque) >>>>> +{ >>>>> + BlockDriverState *bs = opaque; >>>>> + BlockQueue *queue = bs->block_queue; >>>>> + >>>>> + while (!QTAILQ_EMPTY(&queue->requests)) { >>>>> + BlockIORequest *request; >>>>> + int ret; >>>>> + >>>>> + request = QTAILQ_FIRST(&queue->requests); >>>>> + QTAILQ_REMOVE(&queue->requests, request, entry); >>>>> + >>>>> + ret = qemu_block_queue_handler(request); >>>>> + if (ret == 0) { >>>>> + QTAILQ_INSERT_HEAD(&queue->requests, request, entry); >>>>> + break; >>>>> + } >>>>> + >>>>> + qemu_free(request); >>>>> + } >>>>> +} >>>>> + >>>>> void bdrv_register(BlockDriver *bdrv) >>>>> { >>>>> if (!bdrv->bdrv_aio_readv) { >>>>> @@ -642,6 +688,15 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, >>>>> bs->change_cb(bs->change_opaque, CHANGE_MEDIA); >>>>> } >>>>> >>>>> + /* throttling disk I/O limits */ >>>>> + if (bdrv_io_limits_enable(&bs->io_limits)) { >>>>> + bs->block_queue = qemu_new_block_queue(); >>>>> + bs->block_timer = qemu_new_timer_ns(vm_clock, bdrv_block_timer, bs); >>>>> + >>>>> + bs->slice_start[0] = qemu_get_clock_ns(vm_clock); >>>>> + bs->slice_start[1] = qemu_get_clock_ns(vm_clock); >>>>> + } >>>>> + >>>> >>>> It should be possible to tune the limits on the flight, please introduce >>>> QMP commands for that. >>> Yeah, I am working on this. >> >> It's worth mentioning that the I/O limits commands can use Supriya's >> new block_set command for changing block device parameters at runtime. >> So I think the runtime limits changing can be a separate patch. > Since I/O limits commands will depend on Supriya's block_set patch, > when will her patch be merged into qemu.git? The block_set patch is on the mailing list with an ongoing discussion. Until agreement is reached it will not be merged - hard to tell when exactly that will be, but hopefully over the next few days. You can always add temporary QMP/HMP commands in order to test setting limits at runtime. It should be easy to switch to a different QMP/HMP command later, if necessary. Stefan -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html