summaryrefslogtreecommitdiff
path: root/hw/ide/core.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2011-08-25 08:26:01 +0200
committerKevin Wolf <kwolf@redhat.com>2011-08-25 18:18:42 +0200
commita597e79ce14ea62266924acc7b8a7030a42ed29b (patch)
tree2dfae8672b7a3b85d3fa5e138c2ffe361e97cf29 /hw/ide/core.c
parent2f4b7593674e986e60b0b0f1a46707e0e149eb6d (diff)
downloadqemu-a597e79ce14ea62266924acc7b8a7030a42ed29b.tar.gz
block: explicit I/O accounting
Decouple the I/O accounting from bdrv_aio_readv/writev/flush and make the hardware models call directly into the accounting helpers. This means: - we do not count internal requests from image formats in addition to guest originating I/O - we do not double count I/O ops if the device model handles it chunk wise - we only account I/O once it actuall is done - can extent I/O accounting to synchronous or coroutine I/O easily - implement I/O latency tracking easily (see the next patch) I've conveted the existing device model callers to the new model, device models that are using synchronous I/O and weren't accounted before haven't been updated yet. Also scsi hasn't been converted to the end-to-end accounting as I want to defer that after the pending scsi layer overhaul. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'hw/ide/core.c')
-rw-r--r--hw/ide/core.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/hw/ide/core.c b/hw/ide/core.c
index d145b19b0c..40abc1edd2 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -473,7 +473,10 @@ void ide_sector_read(IDEState *s)
#endif
if (n > s->req_nb_sectors)
n = s->req_nb_sectors;
+
+ bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
+ bdrv_acct_done(s->bs, &s->acct);
if (ret != 0) {
if (ide_handle_rw_error(s, -ret,
BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ))
@@ -610,7 +613,10 @@ handle_rw_error:
return;
eot:
- ide_set_inactive(s);
+ if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
+ bdrv_acct_done(s->bs, &s->acct);
+ }
+ ide_set_inactive(s);
}
static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
@@ -619,6 +625,20 @@ static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
s->io_buffer_index = 0;
s->io_buffer_size = 0;
s->dma_cmd = dma_cmd;
+
+ switch (dma_cmd) {
+ case IDE_DMA_READ:
+ bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE,
+ BDRV_ACCT_READ);
+ break;
+ case IDE_DMA_WRITE:
+ bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE,
+ BDRV_ACCT_WRITE);
+ break;
+ default:
+ break;
+ }
+
s->bus->dma->ops->start_dma(s->bus->dma, s, ide_dma_cb);
}
@@ -641,7 +661,10 @@ void ide_sector_write(IDEState *s)
n = s->nsector;
if (n > s->req_nb_sectors)
n = s->req_nb_sectors;
+
+ bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
+ bdrv_acct_done(s->bs, &s->acct);
if (ret != 0) {
if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY))
@@ -685,6 +708,7 @@ static void ide_flush_cb(void *opaque, int ret)
}
}
+ bdrv_acct_done(s->bs, &s->acct);
s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus);
}
@@ -698,6 +722,7 @@ void ide_flush_cache(IDEState *s)
return;
}
+ bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH);
acb = bdrv_aio_flush(s->bs, ide_flush_cb, s);
if (acb == NULL) {
ide_flush_cb(s, -EIO);