All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: Christoph Hellwig <hch@lst.de>
Cc: qemu-devel@nongnu.org, Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Subject: Re: [Qemu-devel] [PATCH 2/3] block: explicit I/O accounting
Date: Mon, 22 Aug 2011 17:48:37 +0200	[thread overview]
Message-ID: <4E527A55.2070501@redhat.com> (raw)
In-Reply-To: <20110821222606.GB22064@lst.de>

Am 22.08.2011 00:26, schrieb Christoph Hellwig:
> 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>
> 
> Index: qemu/block.c
> ===================================================================
> --- qemu.orig/block.c	2011-08-21 14:53:09.684226561 -0700
> +++ qemu/block.c	2011-08-21 14:57:09.507558463 -0700
> @@ -1915,13 +1915,13 @@ static QObject* bdrv_info_stats_bs(Block
>                               "'wr_highest_offset': %" PRId64 ","
>                               "'flush_operations': %" PRId64
>                               "} }",
> -                             bs->rd_bytes,
> -                             bs->wr_bytes,
> -                             bs->rd_ops,
> -                             bs->wr_ops,
> +                             bs->nr_bytes[BDRV_ACCT_READ],
> +                             bs->nr_bytes[BDRV_ACCT_WRITE],
> +                             bs->nr_ops[BDRV_ACCT_READ],
> +                             bs->nr_ops[BDRV_ACCT_WRITE],
>                               bs->wr_highest_sector *
>                               (uint64_t)BDRV_SECTOR_SIZE,
> -                             bs->flush_ops);
> +                             bs->nr_ops[BDRV_ACCT_FLUSH]);
>      dict  = qobject_to_qdict(res);
>  
>      if (*bs->device_name) {
> @@ -2235,7 +2235,6 @@ char *bdrv_snapshot_dump(char *buf, int
>      return buf;
>  }
>  
> -
>  /**************************************************************/
>  /* async I/Os */
>  
> @@ -2244,7 +2243,6 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDr
>                                   BlockDriverCompletionFunc *cb, void *opaque)
>  {
>      BlockDriver *drv = bs->drv;
> -    BlockDriverAIOCB *ret;
>  
>      trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
>  
> @@ -2253,16 +2251,7 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDr
>      if (bdrv_check_request(bs, sector_num, nb_sectors))
>          return NULL;
>  
> -    ret = drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors,
> -                              cb, opaque);
> -
> -    if (ret) {
> -	/* Update stats even though technically transfer has not happened. */
> -	bs->rd_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE;
> -	bs->rd_ops ++;
> -    }
> -
> -    return ret;
> +    return drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors, cb, opaque);
>  }
>  
>  typedef struct BlockCompleteData {
> @@ -2329,9 +2318,6 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockD
>                                 cb, opaque);
>  
>      if (ret) {
> -        /* Update stats even though technically transfer has not happened. */
> -        bs->wr_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE;
> -        bs->wr_ops ++;
>          if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
>              bs->wr_highest_sector = sector_num + nb_sectors - 1;
>          }
> @@ -2585,8 +2571,6 @@ BlockDriverAIOCB *bdrv_aio_flush(BlockDr
>  
>      trace_bdrv_aio_flush(bs, opaque);
>  
> -    bs->flush_ops++;
> -
>      if (bs->open_flags & BDRV_O_NO_FLUSH) {
>          return bdrv_aio_noop_em(bs, cb, opaque);
>      }
> Index: qemu/block_int.h
> ===================================================================
> --- qemu.orig/block_int.h	2011-08-21 14:53:09.000000000 -0700
> +++ qemu/block_int.h	2011-08-21 14:57:09.510891797 -0700
> @@ -148,6 +148,13 @@ struct BlockDriver {
>      QLIST_ENTRY(BlockDriver) list;
>  };
>  
> +enum BlockIOType {
> +    BDRV_ACCT_READ,
> +    BDRV_ACCT_WRITE,
> +    BDRV_ACCT_FLUSH,
> +    BDRV_MAX_IOTYPE,
> +};
> +
>  struct BlockDriverState {
>      int64_t total_sectors; /* if we are reading a disk image, give its
>                                size in sectors */
> @@ -184,11 +191,8 @@ struct BlockDriverState {
>      void *sync_aiocb;
>  
>      /* I/O stats (display with "info blockstats"). */
> -    uint64_t rd_bytes;
> -    uint64_t wr_bytes;
> -    uint64_t rd_ops;
> -    uint64_t wr_ops;
> -    uint64_t flush_ops;
> +    uint64_t nr_bytes[BDRV_MAX_IOTYPE];
> +    uint64_t nr_ops[BDRV_MAX_IOTYPE];
>      uint64_t wr_highest_sector;
>  
>      /* Whether the disk can expand beyond total_sectors */
> @@ -212,6 +216,27 @@ struct BlockDriverState {
>      void *private;
>  };
>  
> +typedef struct BlockAcctCookie {
> +    int64_t bytes;
> +    enum BlockIOType type;
> +} BlockAcctCookie;
> +
> +static inline void
> +bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes,
> +        enum BlockIOType type)
> +{
> +    cookie->bytes = bytes;
> +    cookie->type = type;
> +}
> +
> +static inline void
> +bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie)
> +{
> +    bs->nr_bytes[cookie->type] += cookie->bytes;
> +    bs->nr_ops[cookie->type]++;
> +}

Device models actually shouldn't include block_int.h, so this isn't very
nice. Moving it to block.h would lose the inline, does it matter?

>  #define CHANGE_MEDIA    0x01
>  #define CHANGE_SIZE     0x02
>  
> Index: qemu/hw/ide/ahci.c
> ===================================================================
> --- qemu.orig/hw/ide/ahci.c	2011-08-21 11:49:29.000000000 -0700
> +++ qemu/hw/ide/ahci.c	2011-08-21 14:57:09.510891797 -0700
> @@ -710,6 +710,7 @@ static void ncq_cb(void *opaque, int ret
>      DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n",
>              ncq_tfs->tag);
>  
> +    bdrv_acct_done(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct);
>      qemu_sglist_destroy(&ncq_tfs->sglist);
>      ncq_tfs->used = 0;
>  }
> @@ -755,7 +756,11 @@ static void process_ncq_command(AHCIStat
>                      ncq_tfs->sector_count-1, ncq_tfs->lba, ncq_tfs->tag);
>              ncq_tfs->is_read = 1;
>  
> -            DPRINTF(port, "tag %d aio read %ld\n", ncq_tfs->tag, ncq_tfs->lba);
> +	    DPRINTF(port, "tag %d aio read %ld\n", ncq_tfs->tag, ncq_tfs->lba);

The patch is adding tabs here and in other places. Please fix.

> +
> +            bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
> +                            (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
> +                            BDRV_ACCT_READ);
>              ncq_tfs->aiocb = dma_bdrv_read(ncq_tfs->drive->port.ifs[0].bs,
>                                             &ncq_tfs->sglist, ncq_tfs->lba,
>                                             ncq_cb, ncq_tfs);
> @@ -766,6 +771,10 @@ static void process_ncq_command(AHCIStat
>              ncq_tfs->is_read = 0;
>  
>              DPRINTF(port, "tag %d aio write %ld\n", ncq_tfs->tag, ncq_tfs->lba);
> +
> +            bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
> +                            (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
> +                            BDRV_ACCT_WRITE);
>              ncq_tfs->aiocb = dma_bdrv_write(ncq_tfs->drive->port.ifs[0].bs,
>                                              &ncq_tfs->sglist, ncq_tfs->lba,
>                                              ncq_cb, ncq_tfs);
> Index: qemu/hw/ide/atapi.c
> ===================================================================
> --- qemu.orig/hw/ide/atapi.c	2011-08-21 11:49:17.000000000 -0700
> +++ qemu/hw/ide/atapi.c	2011-08-21 14:57:09.510891797 -0700
> @@ -250,6 +250,7 @@ static void ide_atapi_cmd_reply(IDEState
>      s->io_buffer_index = 0;
>  
>      if (s->atapi_dma) {
> +        bdrv_acct_start(s->bs, &s->acct, size, BDRV_ACCT_READ);
>          s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
>          s->bus->dma->ops->start_dma(s->bus->dma, s,
>                                     ide_atapi_cmd_read_dma_cb);
> @@ -322,10 +323,7 @@ static void ide_atapi_cmd_read_dma_cb(vo
>          s->status = READY_STAT | SEEK_STAT;
>          s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
>          ide_set_irq(s->bus);
> -    eot:
> -        s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
> -        ide_set_inactive(s);
> -        return;
> +        goto eot;
>      }
>  
>      s->io_buffer_index = 0;
> @@ -343,9 +341,11 @@ static void ide_atapi_cmd_read_dma_cb(vo
>  #ifdef DEBUG_AIO
>      printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
>  #endif
> +
>      s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset);
>      s->bus->dma->iov.iov_len = n * 4 * 512;
>      qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
> +
>      s->bus->dma->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2,
>                                         &s->bus->dma->qiov, n * 4,
>                                         ide_atapi_cmd_read_dma_cb, s);
> @@ -355,6 +355,12 @@ static void ide_atapi_cmd_read_dma_cb(vo
>                              ASC_MEDIUM_NOT_PRESENT);
>          goto eot;
>      }
> +
> +    return;
> +eot:
> +    bdrv_acct_done(s->bs, &s->acct);
> +    s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
> +    ide_set_inactive(s);
>  }
>  
>  /* start a CD-CDROM read command with DMA */
> @@ -368,6 +374,8 @@ static void ide_atapi_cmd_read_dma(IDESt
>      s->io_buffer_size = 0;
>      s->cd_sector_size = sector_size;
>  
> +    bdrv_acct_start(s->bs, &s->acct, s->packet_transfer_size, BDRV_ACCT_READ);
> +
>      /* XXX: check if BUSY_STAT should be set */
>      s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
>      s->bus->dma->ops->start_dma(s->bus->dma, s,
> Index: qemu/hw/ide/core.c
> ===================================================================
> --- qemu.orig/hw/ide/core.c	2011-08-21 11:49:17.000000000 -0700
> +++ qemu/hw/ide/core.c	2011-08-21 14:57:09.510891797 -0700
> @@ -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);

The commit message says that you're only converting bdrv_aio_readv. I
think it makes sense to add the accounting to the sychronous calls, too,
so that devices have complete accounting or none at all.

If your plan is to convert all bdrv_read calls, I think you've missed
some in atapi.c.

>          if (ret != 0) {
>              if (ide_handle_rw_error(s, -ret,
>                  BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ))
> @@ -610,7 +613,8 @@ handle_rw_error:
>      return;
>  
>  eot:
> -   ide_set_inactive(s);
> +    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 +623,20 @@ static void ide_sector_start_dma(IDEStat
>      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;
> +    }

So should the semantics of bdrv_acct_done be that it does nothing if no
bdrv_acct_start has been called before? If so, its implementation is
broken. Otherwise, the default case of this switch statement looks
broken to me.

> +
>      s->bus->dma->ops->start_dma(s->bus->dma, s, ide_dma_cb);
>  }
>  
> @@ -641,7 +659,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 +706,7 @@ static void ide_flush_cb(void *opaque, i
>          }
>      }
>  
> +    bdrv_acct_done(s->bs, &s->acct);
>      s->status = READY_STAT | SEEK_STAT;
>      ide_set_irq(s->bus);
>  }
> @@ -698,6 +720,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);
> Index: qemu/hw/ide/macio.c
> ===================================================================
> --- qemu.orig/hw/ide/macio.c	2011-08-21 11:49:29.000000000 -0700
> +++ qemu/hw/ide/macio.c	2011-08-21 14:57:09.514225130 -0700
> @@ -52,8 +52,7 @@ static void pmac_ide_atapi_transfer_cb(v
>          m->aiocb = NULL;
>          qemu_sglist_destroy(&s->sg);
>          ide_atapi_io_error(s, ret);
> -        io->dma_end(opaque);
> -        return;
> +        goto done;
>      }
>  
>      if (s->io_buffer_size > 0) {
> @@ -71,8 +70,7 @@ static void pmac_ide_atapi_transfer_cb(v
>          ide_atapi_cmd_ok(s);
>  
>      if (io->len == 0) {
> -        io->dma_end(opaque);
> -        return;
> +        goto done;
>      }
>  
>      /* launch next transfer */
> @@ -92,9 +90,14 @@ static void pmac_ide_atapi_transfer_cb(v
>          /* Note: media not present is the most likely case */
>          ide_atapi_cmd_error(s, SENSE_NOT_READY,
>                              ASC_MEDIUM_NOT_PRESENT);
> -        io->dma_end(opaque);
> -        return;
> +        goto done;
>      }
> +    return;
> +
> +done:
> +    bdrv_acct_done(s->bs, &s->acct);
> +    io->dma_end(opaque);
> +    return;
>  }
>  
>  static void pmac_ide_transfer_cb(void *opaque, int ret)
> @@ -109,8 +112,7 @@ static void pmac_ide_transfer_cb(void *o
>          m->aiocb = NULL;
>          qemu_sglist_destroy(&s->sg);
>  	ide_dma_error(s);
> -        io->dma_end(io);
> -        return;
> +        goto done;
>      }
>  
>      sector_num = ide_get_sector(s);
> @@ -130,10 +132,8 @@ static void pmac_ide_transfer_cb(void *o
>      }
>  
>      /* end of DMA ? */
> -
>      if (io->len == 0) {
> -        io->dma_end(io);
> -	return;
> +        goto done;
>      }
>  
>      /* launch next transfer */
> @@ -163,6 +163,10 @@ static void pmac_ide_transfer_cb(void *o
>  
>      if (!m->aiocb)
>          pmac_ide_transfer_cb(io, -1);
> +    return;
> +done:
> +    bdrv_acct_done(s->bs, &s->acct);
> +    io->dma_end(io);
>  }
>  
>  static void pmac_ide_transfer(DBDMA_io *io)
> @@ -172,10 +176,22 @@ static void pmac_ide_transfer(DBDMA_io *
>  
>      s->io_buffer_size = 0;
>      if (s->drive_kind == IDE_CD) {
> +        bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ);
>          pmac_ide_atapi_transfer_cb(io, 0);
>          return;
>      }
>  
> +    switch (s->dma_cmd) {
> +    case IDE_DMA_READ:
> +        bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ);
> +        break;
> +    case IDE_DMA_WRITE:
> +        bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_WRITE);
> +        break;
> +    default:
> +        break;

Can it happen? If yes, see above. If no, abort() is better.

> +    }
> +
>      pmac_ide_transfer_cb(io, 0);
>  }
>  
> Index: qemu/hw/scsi-disk.c
> ===================================================================
> --- qemu.orig/hw/scsi-disk.c	2011-08-21 11:49:29.000000000 -0700
> +++ qemu/hw/scsi-disk.c	2011-08-21 14:57:09.514225130 -0700
> @@ -57,6 +57,7 @@ typedef struct SCSIDiskReq {
>      struct iovec iov;
>      QEMUIOVector qiov;
>      uint32_t status;
> +    BlockAcctCookie acct;
>  } SCSIDiskReq;
>  
>  struct SCSIDiskState
> @@ -107,6 +108,7 @@ static void scsi_cancel_io(SCSIRequest *
>  static void scsi_read_complete(void * opaque, int ret)
>  {
>      SCSIDiskReq *r = (SCSIDiskReq *)opaque;
> +    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
>      int n;
>  
>      r->req.aiocb = NULL;
> @@ -117,6 +119,8 @@ static void scsi_read_complete(void * op
>          }
>      }
>  
> +    bdrv_acct_done(s->bs, &r->acct);
> +
>      DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->iov.iov_len);

scsi-disk doesn't account for failed requests. IDE does. I don't have a
strong preference on which way we handle it, but I think it should be
consistent.

>  
>      n = r->iov.iov_len / 512;
> @@ -161,6 +165,8 @@ static void scsi_read_data(SCSIRequest *
>  
>      r->iov.iov_len = n * 512;
>      qemu_iovec_init_external(&r->qiov, &r->iov, 1);
> +
> +    bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
>      r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n,
>                                scsi_read_complete, r);
>      if (r->req.aiocb == NULL) {
> @@ -207,6 +213,7 @@ static int scsi_handle_rw_error(SCSIDisk
>  static void scsi_write_complete(void * opaque, int ret)
>  {
>      SCSIDiskReq *r = (SCSIDiskReq *)opaque;
> +    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
>      uint32_t len;
>      uint32_t n;
>  
> @@ -218,6 +225,8 @@ static void scsi_write_complete(void * o
>          }
>      }
>  
> +    bdrv_acct_done(s->bs, &r->acct);
> +
>      n = r->iov.iov_len / 512;
>      r->sector += n;
>      r->sector_count -= n;
> @@ -252,6 +261,8 @@ static void scsi_write_data(SCSIRequest
>      n = r->iov.iov_len / 512;
>      if (n) {
>          qemu_iovec_init_external(&r->qiov, &r->iov, 1);
> +
> +        bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE);
>          r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n,
>                                     scsi_write_complete, r);
>          if (r->req.aiocb == NULL) {
> @@ -854,13 +865,19 @@ static int scsi_disk_emulate_command(SCS
>          buflen = 8;
>          break;
>      case SYNCHRONIZE_CACHE:
> +{
> +        BlockAcctCookie acct;
> +
> +        bdrv_acct_start(s->bs, &acct, 0, BDRV_ACCT_FLUSH);
>          ret = bdrv_flush(s->bs);
>          if (ret < 0) {
>              if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_FLUSH)) {
>                  return -1;
>              }
>          }
> +        bdrv_acct_done(s->bs, &acct);
>          break;
> +}
>      case GET_CONFIGURATION:
>          memset(outbuf, 0, 8);
>          /* ??? This should probably return much more information.  For now
> Index: qemu/hw/virtio-blk.c
> ===================================================================
> --- qemu.orig/hw/virtio-blk.c	2011-08-21 11:49:29.000000000 -0700
> +++ qemu/hw/virtio-blk.c	2011-08-21 14:57:44.887558247 -0700
> @@ -47,6 +47,7 @@ typedef struct VirtIOBlockReq
>      struct virtio_scsi_inhdr *scsi;
>      QEMUIOVector qiov;
>      struct VirtIOBlockReq *next;
> +    BlockAcctCookie acct;
>  } VirtIOBlockReq;
>  
>  static void virtio_blk_req_complete(VirtIOBlockReq *req, int status)
> @@ -59,6 +60,7 @@ static void virtio_blk_req_complete(Virt
>      virtqueue_push(s->vq, &req->elem, req->qiov.size + sizeof(*req->in));
>      virtio_notify(&s->vdev, s->vq);
>  
> +    bdrv_acct_done(s->bs, &req->acct);
>      g_free(req);
>  }
>  
> @@ -266,6 +268,8 @@ static void virtio_blk_handle_flush(Virt
>  {
>      BlockDriverAIOCB *acb;
>  
> +    bdrv_acct_start(req->dev->bs, &req->acct, 0, BDRV_ACCT_FLUSH);
> +
>      /*
>       * Make sure all outstanding writes are posted to the backing device.
>       */
> @@ -284,6 +288,8 @@ static void virtio_blk_handle_write(Virt
>  
>      sector = ldq_p(&req->out->sector);
>  
> +    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE);
> +
>      trace_virtio_blk_handle_write(req, sector, req->qiov.size / 512);
>  
>      if (sector & req->dev->sector_mask) {
> @@ -317,6 +323,8 @@ static void virtio_blk_handle_read(VirtI
>  
>      sector = ldq_p(&req->out->sector);
>  
> +    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ);
> +
>      if (sector & req->dev->sector_mask) {
>          virtio_blk_rw_complete(req, -EIO);
>          return;
> Index: qemu/hw/xen_disk.c
> ===================================================================
> --- qemu.orig/hw/xen_disk.c	2011-08-21 11:49:29.000000000 -0700
> +++ qemu/hw/xen_disk.c	2011-08-21 14:57:09.517558463 -0700
> @@ -79,6 +79,7 @@ struct ioreq {
>  
>      struct XenBlkDev    *blkdev;
>      QLIST_ENTRY(ioreq)   list;
> +    BlockAcctCookie     acct;

Indentation is off.

Kevin

  reply	other threads:[~2011-08-22 15:45 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-21 22:25 [Qemu-devel] [PATCH 0/3] better I/O accounting V2 Christoph Hellwig
2011-08-21 22:25 ` [Qemu-devel] [PATCH 1/3] block: include flush requests in info blockstats Christoph Hellwig
2011-08-21 22:26 ` [Qemu-devel] [PATCH 2/3] block: explicit I/O accounting Christoph Hellwig
2011-08-22 15:48   ` Kevin Wolf [this message]
2011-08-24 18:22     ` Christoph Hellwig
2011-08-21 22:26 ` [Qemu-devel] [PATCH 3/3] block: latency accounting Christoph Hellwig
2011-08-22  8:45 ` [Qemu-devel] [PATCH 0/3] better I/O accounting V2 Stefan Hajnoczi
2011-08-22 14:59 ` Ryan Harper
2011-08-22 15:12   ` Christoph Hellwig
2011-08-22 15:29     ` Ryan Harper
2011-08-22 15:35       ` Christoph Hellwig
2011-08-22 16:46         ` Ryan Harper
2011-08-24 18:45           ` Christoph Hellwig
2011-08-25 16:41             ` Ryan Harper
2011-08-22 15:55 ` Kevin Wolf
2011-08-25  6:25 ` [Qemu-devel] [PATCH 0/3] better I/O accounting V3 Christoph Hellwig
2011-08-25  6:25   ` [Qemu-devel] [PATCH 1/3] block: include flush requests in info blockstats Christoph Hellwig
2011-08-25  6:26   ` [Qemu-devel] [PATCH 2/3] block: explicit I/O accounting Christoph Hellwig
2011-08-25  6:26   ` [Qemu-devel] [PATCH 3/3] block: latency accounting Christoph Hellwig
2011-08-26 13:05     ` Kevin Wolf
2011-08-26 16:06       ` Christoph Hellwig
2011-08-25 16:10   ` [Qemu-devel] [PATCH 0/3] better I/O accounting V3 Kevin Wolf
  -- strict thread matches above, loose matches on Subject: below --
2011-08-11 23:44 [Qemu-devel] [PATCH 0/3] better I/O accounting Christoph Hellwig
2011-08-11 23:44 ` [Qemu-devel] [PATCH 2/3] block: explicit " Christoph Hellwig

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4E527A55.2070501@redhat.com \
    --to=kwolf@redhat.com \
    --cc=hch@lst.de \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.