diff mbox

[1/4] qemu-io: New option "-a" to aio_read and aio_write

Message ID 1390984843-2101-2-git-send-email-famz@redhat.com
State New
Headers show

Commit Message

Fam Zheng Jan. 29, 2014, 8:40 a.m. UTC
This option will enable accounting of aio requests.

Signed-off-by: Fam Zheng <famz@redhat.com>
---
 qemu-io-cmds.c | 35 +++++++++++++++++++++++++++++++----
 1 file changed, 31 insertions(+), 4 deletions(-)

Comments

Stefan Hajnoczi Jan. 29, 2014, 2:11 p.m. UTC | #1
On Wed, Jan 29, 2014 at 04:40:40PM +0800, Fam Zheng wrote:
> @@ -1442,6 +1453,7 @@ static void aio_read_help(void)
>  " -P, -- use a pattern to verify read data\n"
>  " -v, -- dump buffer to standard output\n"
>  " -q, -- quiet mode, do not show I/O statistics\n"
> +" -a, -- account IO\n"
>  "\n");
>  }

This is too brief and probably won't help users.  Maybe "use BlockStats
I/O accounting"?

(I can fix this up when merging if you do not want to respin.)
Benoît Canet Jan. 29, 2014, 3:25 p.m. UTC | #2
Le Wednesday 29 Jan 2014 à 16:40:40 (+0800), Fam Zheng a écrit :
> This option will enable accounting of aio requests.
> 
> Signed-off-by: Fam Zheng <famz@redhat.com>
> ---
>  qemu-io-cmds.c | 35 +++++++++++++++++++++++++++++++----
>  1 file changed, 31 insertions(+), 4 deletions(-)
> 
> diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
> index f1de24c..d6e20e6 100644
> --- a/qemu-io-cmds.c
> +++ b/qemu-io-cmds.c
> @@ -1346,6 +1346,7 @@ out:
>  }
>  
>  struct aio_ctx {
> +    BlockDriverState *bs;
>      QEMUIOVector qiov;
>      int64_t offset;
>      char *buf;
> @@ -1353,6 +1354,8 @@ struct aio_ctx {
>      int vflag;
>      int Cflag;
>      int Pflag;
> +    int aflag;
> +    BlockAcctCookie acct;
>      int pattern;
>      struct timeval t1;
>  };
> @@ -1370,6 +1373,10 @@ static void aio_write_done(void *opaque, int ret)
>          goto out;
>      }
>  
> +    if (ctx->aflag) {
> +        bdrv_acct_done(ctx->bs, &ctx->acct);
> +    }
> +
>      if (ctx->qflag) {
>          goto out;
>      }
> @@ -1407,6 +1414,10 @@ static void aio_read_done(void *opaque, int ret)
>          g_free(cmp_buf);
>      }
>  
> +    if (ctx->aflag) {
> +        bdrv_acct_done(ctx->bs, &ctx->acct);
> +    }
> +
>      if (ctx->qflag) {
>          goto out;
>      }
> @@ -1442,6 +1453,7 @@ static void aio_read_help(void)
>  " -P, -- use a pattern to verify read data\n"
>  " -v, -- dump buffer to standard output\n"
>  " -q, -- quiet mode, do not show I/O statistics\n"
> +" -a, -- account IO\n"
>  "\n");
>  }
>  
> @@ -1452,7 +1464,7 @@ static const cmdinfo_t aio_read_cmd = {
>      .cfunc      = aio_read_f,
>      .argmin     = 2,
>      .argmax     = -1,
> -    .args       = "[-Cqv] [-P pattern ] off len [len..]",
> +    .args       = "[-Cqva] [-P pattern ] off len [len..]",
>      .oneline    = "asynchronously reads a number of bytes",
>      .help       = aio_read_help,
>  };
> @@ -1462,7 +1474,8 @@ static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
>      int nr_iov, c;
>      struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
>  
> -    while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
> +    ctx->bs = bs;
> +    while ((c = getopt(argc, argv, "CP:qva")) != EOF) {
>          switch (c) {
>          case 'C':
>              ctx->Cflag = 1;
> @@ -1481,6 +1494,9 @@ static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
>          case 'v':
>              ctx->vflag = 1;
>              break;
> +        case 'a':
> +            ctx->aflag = 1;
> +            break;
>          default:
>              g_free(ctx);
>              return qemuio_command_usage(&aio_read_cmd);
> @@ -1515,6 +1531,9 @@ static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
>      }
>  
>      gettimeofday(&ctx->t1, NULL);
> +    if (ctx->aflag) {
> +        bdrv_acct_start(bs, &ctx->acct, ctx->qiov.size, BDRV_ACCT_READ);
> +    }
>      bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
>                     ctx->qiov.size >> 9, aio_read_done, ctx);
>      return 0;
> @@ -1537,6 +1556,7 @@ static void aio_write_help(void)
>  " -P, -- use different pattern to fill file\n"
>  " -C, -- report statistics in a machine parsable format\n"
>  " -q, -- quiet mode, do not show I/O statistics\n"
> +" -a, -- account IO\n"
>  "\n");
>  }
>  
> @@ -1547,7 +1567,7 @@ static const cmdinfo_t aio_write_cmd = {
>      .cfunc      = aio_write_f,
>      .argmin     = 2,
>      .argmax     = -1,
> -    .args       = "[-Cq] [-P pattern ] off len [len..]",
> +    .args       = "[-Cqa] [-P pattern ] off len [len..]",
>      .oneline    = "asynchronously writes a number of bytes",
>      .help       = aio_write_help,
>  };
> @@ -1558,7 +1578,8 @@ static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
>      int pattern = 0xcd;
>      struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
>  
> -    while ((c = getopt(argc, argv, "CqP:")) != EOF) {
> +    ctx->bs = bs;
> +    while ((c = getopt(argc, argv, "CqP:a")) != EOF) {
>          switch (c) {
>          case 'C':
>              ctx->Cflag = 1;
> @@ -1573,6 +1594,9 @@ static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
>                  return 0;
>              }
>              break;
> +        case 'a':
> +            ctx->aflag = 1;
> +            break;
>          default:
>              g_free(ctx);
>              return qemuio_command_usage(&aio_write_cmd);
> @@ -1607,6 +1631,9 @@ static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
>      }
>  
>      gettimeofday(&ctx->t1, NULL);
> +    if (ctx->aflag) {
> +        bdrv_acct_start(bs, &ctx->acct, ctx->qiov.size, BDRV_ACCT_WRITE);
> +    }
>      bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
>                      ctx->qiov.size >> 9, aio_write_done, ctx);
>      return 0;
> -- 
> 1.8.5.3
> 
> 
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Paolo Bonzini Jan. 29, 2014, 3:58 p.m. UTC | #3
Il 29/01/2014 09:40, Fam Zheng ha scritto:
> This option will enable accounting of aio requests.
>
> Signed-off-by: Fam Zheng <famz@redhat.com>
> ---
>  qemu-io-cmds.c | 35 +++++++++++++++++++++++++++++++----
>  1 file changed, 31 insertions(+), 4 deletions(-)
>
> diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
> index f1de24c..d6e20e6 100644
> --- a/qemu-io-cmds.c
> +++ b/qemu-io-cmds.c
> @@ -1346,6 +1346,7 @@ out:
>  }
>
>  struct aio_ctx {
> +    BlockDriverState *bs;
>      QEMUIOVector qiov;
>      int64_t offset;
>      char *buf;
> @@ -1353,6 +1354,8 @@ struct aio_ctx {
>      int vflag;
>      int Cflag;
>      int Pflag;
> +    int aflag;
> +    BlockAcctCookie acct;
>      int pattern;
>      struct timeval t1;
>  };
> @@ -1370,6 +1373,10 @@ static void aio_write_done(void *opaque, int ret)
>          goto out;
>      }
>
> +    if (ctx->aflag) {
> +        bdrv_acct_done(ctx->bs, &ctx->acct);
> +    }
> +
>      if (ctx->qflag) {
>          goto out;
>      }
> @@ -1407,6 +1414,10 @@ static void aio_read_done(void *opaque, int ret)
>          g_free(cmp_buf);
>      }
>
> +    if (ctx->aflag) {
> +        bdrv_acct_done(ctx->bs, &ctx->acct);
> +    }
> +
>      if (ctx->qflag) {
>          goto out;
>      }
> @@ -1442,6 +1453,7 @@ static void aio_read_help(void)
>  " -P, -- use a pattern to verify read data\n"
>  " -v, -- dump buffer to standard output\n"
>  " -q, -- quiet mode, do not show I/O statistics\n"
> +" -a, -- account IO\n"
>  "\n");
>  }
>
> @@ -1452,7 +1464,7 @@ static const cmdinfo_t aio_read_cmd = {
>      .cfunc      = aio_read_f,
>      .argmin     = 2,
>      .argmax     = -1,
> -    .args       = "[-Cqv] [-P pattern ] off len [len..]",
> +    .args       = "[-Cqva] [-P pattern ] off len [len..]",
>      .oneline    = "asynchronously reads a number of bytes",
>      .help       = aio_read_help,
>  };
> @@ -1462,7 +1474,8 @@ static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
>      int nr_iov, c;
>      struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
>
> -    while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
> +    ctx->bs = bs;
> +    while ((c = getopt(argc, argv, "CP:qva")) != EOF) {
>          switch (c) {
>          case 'C':
>              ctx->Cflag = 1;
> @@ -1481,6 +1494,9 @@ static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
>          case 'v':
>              ctx->vflag = 1;
>              break;
> +        case 'a':
> +            ctx->aflag = 1;
> +            break;
>          default:
>              g_free(ctx);
>              return qemuio_command_usage(&aio_read_cmd);
> @@ -1515,6 +1531,9 @@ static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
>      }
>
>      gettimeofday(&ctx->t1, NULL);
> +    if (ctx->aflag) {
> +        bdrv_acct_start(bs, &ctx->acct, ctx->qiov.size, BDRV_ACCT_READ);
> +    }
>      bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
>                     ctx->qiov.size >> 9, aio_read_done, ctx);
>      return 0;
> @@ -1537,6 +1556,7 @@ static void aio_write_help(void)
>  " -P, -- use different pattern to fill file\n"
>  " -C, -- report statistics in a machine parsable format\n"
>  " -q, -- quiet mode, do not show I/O statistics\n"
> +" -a, -- account IO\n"
>  "\n");
>  }
>
> @@ -1547,7 +1567,7 @@ static const cmdinfo_t aio_write_cmd = {
>      .cfunc      = aio_write_f,
>      .argmin     = 2,
>      .argmax     = -1,
> -    .args       = "[-Cq] [-P pattern ] off len [len..]",
> +    .args       = "[-Cqa] [-P pattern ] off len [len..]",
>      .oneline    = "asynchronously writes a number of bytes",
>      .help       = aio_write_help,
>  };
> @@ -1558,7 +1578,8 @@ static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
>      int pattern = 0xcd;
>      struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
>
> -    while ((c = getopt(argc, argv, "CqP:")) != EOF) {
> +    ctx->bs = bs;
> +    while ((c = getopt(argc, argv, "CqP:a")) != EOF) {
>          switch (c) {
>          case 'C':
>              ctx->Cflag = 1;
> @@ -1573,6 +1594,9 @@ static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
>                  return 0;
>              }
>              break;
> +        case 'a':
> +            ctx->aflag = 1;
> +            break;
>          default:
>              g_free(ctx);
>              return qemuio_command_usage(&aio_write_cmd);
> @@ -1607,6 +1631,9 @@ static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
>      }
>
>      gettimeofday(&ctx->t1, NULL);
> +    if (ctx->aflag) {
> +        bdrv_acct_start(bs, &ctx->acct, ctx->qiov.size, BDRV_ACCT_WRITE);
> +    }
>      bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
>                      ctx->qiov.size >> 9, aio_write_done, ctx);
>      return 0;
>

Why can't it be enabled unconditionally?

Paolo
Fam Zheng Feb. 1, 2014, 2:31 p.m. UTC | #4
On Wed, 01/29 16:58, Paolo Bonzini wrote:
> Il 29/01/2014 09:40, Fam Zheng ha scritto:
> >This option will enable accounting of aio requests.
> >
> >Signed-off-by: Fam Zheng <famz@redhat.com>
> >---
> > qemu-io-cmds.c | 35 +++++++++++++++++++++++++++++++----
> > 1 file changed, 31 insertions(+), 4 deletions(-)
> >
> >diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
> >index f1de24c..d6e20e6 100644
> >--- a/qemu-io-cmds.c
> >+++ b/qemu-io-cmds.c
> >@@ -1346,6 +1346,7 @@ out:
> > }
> >
> > struct aio_ctx {
> >+    BlockDriverState *bs;
> >     QEMUIOVector qiov;
> >     int64_t offset;
> >     char *buf;
> >@@ -1353,6 +1354,8 @@ struct aio_ctx {
> >     int vflag;
> >     int Cflag;
> >     int Pflag;
> >+    int aflag;
> >+    BlockAcctCookie acct;
> >     int pattern;
> >     struct timeval t1;
> > };
> >@@ -1370,6 +1373,10 @@ static void aio_write_done(void *opaque, int ret)
> >         goto out;
> >     }
> >
> >+    if (ctx->aflag) {
> >+        bdrv_acct_done(ctx->bs, &ctx->acct);
> >+    }
> >+
> >     if (ctx->qflag) {
> >         goto out;
> >     }
> >@@ -1407,6 +1414,10 @@ static void aio_read_done(void *opaque, int ret)
> >         g_free(cmp_buf);
> >     }
> >
> >+    if (ctx->aflag) {
> >+        bdrv_acct_done(ctx->bs, &ctx->acct);
> >+    }
> >+
> >     if (ctx->qflag) {
> >         goto out;
> >     }
> >@@ -1442,6 +1453,7 @@ static void aio_read_help(void)
> > " -P, -- use a pattern to verify read data\n"
> > " -v, -- dump buffer to standard output\n"
> > " -q, -- quiet mode, do not show I/O statistics\n"
> >+" -a, -- account IO\n"
> > "\n");
> > }
> >
> >@@ -1452,7 +1464,7 @@ static const cmdinfo_t aio_read_cmd = {
> >     .cfunc      = aio_read_f,
> >     .argmin     = 2,
> >     .argmax     = -1,
> >-    .args       = "[-Cqv] [-P pattern ] off len [len..]",
> >+    .args       = "[-Cqva] [-P pattern ] off len [len..]",
> >     .oneline    = "asynchronously reads a number of bytes",
> >     .help       = aio_read_help,
> > };
> >@@ -1462,7 +1474,8 @@ static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
> >     int nr_iov, c;
> >     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
> >
> >-    while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
> >+    ctx->bs = bs;
> >+    while ((c = getopt(argc, argv, "CP:qva")) != EOF) {
> >         switch (c) {
> >         case 'C':
> >             ctx->Cflag = 1;
> >@@ -1481,6 +1494,9 @@ static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
> >         case 'v':
> >             ctx->vflag = 1;
> >             break;
> >+        case 'a':
> >+            ctx->aflag = 1;
> >+            break;
> >         default:
> >             g_free(ctx);
> >             return qemuio_command_usage(&aio_read_cmd);
> >@@ -1515,6 +1531,9 @@ static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
> >     }
> >
> >     gettimeofday(&ctx->t1, NULL);
> >+    if (ctx->aflag) {
> >+        bdrv_acct_start(bs, &ctx->acct, ctx->qiov.size, BDRV_ACCT_READ);
> >+    }
> >     bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
> >                    ctx->qiov.size >> 9, aio_read_done, ctx);
> >     return 0;
> >@@ -1537,6 +1556,7 @@ static void aio_write_help(void)
> > " -P, -- use different pattern to fill file\n"
> > " -C, -- report statistics in a machine parsable format\n"
> > " -q, -- quiet mode, do not show I/O statistics\n"
> >+" -a, -- account IO\n"
> > "\n");
> > }
> >
> >@@ -1547,7 +1567,7 @@ static const cmdinfo_t aio_write_cmd = {
> >     .cfunc      = aio_write_f,
> >     .argmin     = 2,
> >     .argmax     = -1,
> >-    .args       = "[-Cq] [-P pattern ] off len [len..]",
> >+    .args       = "[-Cqa] [-P pattern ] off len [len..]",
> >     .oneline    = "asynchronously writes a number of bytes",
> >     .help       = aio_write_help,
> > };
> >@@ -1558,7 +1578,8 @@ static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
> >     int pattern = 0xcd;
> >     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
> >
> >-    while ((c = getopt(argc, argv, "CqP:")) != EOF) {
> >+    ctx->bs = bs;
> >+    while ((c = getopt(argc, argv, "CqP:a")) != EOF) {
> >         switch (c) {
> >         case 'C':
> >             ctx->Cflag = 1;
> >@@ -1573,6 +1594,9 @@ static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
> >                 return 0;
> >             }
> >             break;
> >+        case 'a':
> >+            ctx->aflag = 1;
> >+            break;
> >         default:
> >             g_free(ctx);
> >             return qemuio_command_usage(&aio_write_cmd);
> >@@ -1607,6 +1631,9 @@ static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
> >     }
> >
> >     gettimeofday(&ctx->t1, NULL);
> >+    if (ctx->aflag) {
> >+        bdrv_acct_start(bs, &ctx->acct, ctx->qiov.size, BDRV_ACCT_WRITE);
> >+    }
> >     bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
> >                     ctx->qiov.size >> 9, aio_write_done, ctx);
> >     return 0;
> >
> 
> Why can't it be enabled unconditionally?
> 

So the default behavior is unchanged.

Fam
Paolo Bonzini Feb. 2, 2014, 12:20 a.m. UTC | #5
Il 01/02/2014 15:31, Fam Zheng ha scritto:
>> Why can't it be enabled unconditionally?
>>
>
> So the default behavior is unchanged.

For the stand-alone executable there is no difference, is there anything 
that breaks for the monitor if you always do the accounting?

Paolo
Fam Zheng Feb. 7, 2014, 7:47 a.m. UTC | #6
On Sun, 02/02 01:20, Paolo Bonzini wrote:
> Il 01/02/2014 15:31, Fam Zheng ha scritto:
> >>Why can't it be enabled unconditionally?
> >>
> >
> >So the default behavior is unchanged.
> 
> For the stand-alone executable there is no difference, is there anything
> that breaks for the monitor if you always do the accounting?
> 

I don't see anything broken, it just affacts the numbers in block stats. So it
should be fine to enable it unconditionally, will do a respin for that. Thanks.

Fam
diff mbox

Patch

diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index f1de24c..d6e20e6 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -1346,6 +1346,7 @@  out:
 }
 
 struct aio_ctx {
+    BlockDriverState *bs;
     QEMUIOVector qiov;
     int64_t offset;
     char *buf;
@@ -1353,6 +1354,8 @@  struct aio_ctx {
     int vflag;
     int Cflag;
     int Pflag;
+    int aflag;
+    BlockAcctCookie acct;
     int pattern;
     struct timeval t1;
 };
@@ -1370,6 +1373,10 @@  static void aio_write_done(void *opaque, int ret)
         goto out;
     }
 
+    if (ctx->aflag) {
+        bdrv_acct_done(ctx->bs, &ctx->acct);
+    }
+
     if (ctx->qflag) {
         goto out;
     }
@@ -1407,6 +1414,10 @@  static void aio_read_done(void *opaque, int ret)
         g_free(cmp_buf);
     }
 
+    if (ctx->aflag) {
+        bdrv_acct_done(ctx->bs, &ctx->acct);
+    }
+
     if (ctx->qflag) {
         goto out;
     }
@@ -1442,6 +1453,7 @@  static void aio_read_help(void)
 " -P, -- use a pattern to verify read data\n"
 " -v, -- dump buffer to standard output\n"
 " -q, -- quiet mode, do not show I/O statistics\n"
+" -a, -- account IO\n"
 "\n");
 }
 
@@ -1452,7 +1464,7 @@  static const cmdinfo_t aio_read_cmd = {
     .cfunc      = aio_read_f,
     .argmin     = 2,
     .argmax     = -1,
-    .args       = "[-Cqv] [-P pattern ] off len [len..]",
+    .args       = "[-Cqva] [-P pattern ] off len [len..]",
     .oneline    = "asynchronously reads a number of bytes",
     .help       = aio_read_help,
 };
@@ -1462,7 +1474,8 @@  static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
     int nr_iov, c;
     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
 
-    while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
+    ctx->bs = bs;
+    while ((c = getopt(argc, argv, "CP:qva")) != EOF) {
         switch (c) {
         case 'C':
             ctx->Cflag = 1;
@@ -1481,6 +1494,9 @@  static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
         case 'v':
             ctx->vflag = 1;
             break;
+        case 'a':
+            ctx->aflag = 1;
+            break;
         default:
             g_free(ctx);
             return qemuio_command_usage(&aio_read_cmd);
@@ -1515,6 +1531,9 @@  static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
     }
 
     gettimeofday(&ctx->t1, NULL);
+    if (ctx->aflag) {
+        bdrv_acct_start(bs, &ctx->acct, ctx->qiov.size, BDRV_ACCT_READ);
+    }
     bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
                    ctx->qiov.size >> 9, aio_read_done, ctx);
     return 0;
@@ -1537,6 +1556,7 @@  static void aio_write_help(void)
 " -P, -- use different pattern to fill file\n"
 " -C, -- report statistics in a machine parsable format\n"
 " -q, -- quiet mode, do not show I/O statistics\n"
+" -a, -- account IO\n"
 "\n");
 }
 
@@ -1547,7 +1567,7 @@  static const cmdinfo_t aio_write_cmd = {
     .cfunc      = aio_write_f,
     .argmin     = 2,
     .argmax     = -1,
-    .args       = "[-Cq] [-P pattern ] off len [len..]",
+    .args       = "[-Cqa] [-P pattern ] off len [len..]",
     .oneline    = "asynchronously writes a number of bytes",
     .help       = aio_write_help,
 };
@@ -1558,7 +1578,8 @@  static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
     int pattern = 0xcd;
     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
 
-    while ((c = getopt(argc, argv, "CqP:")) != EOF) {
+    ctx->bs = bs;
+    while ((c = getopt(argc, argv, "CqP:a")) != EOF) {
         switch (c) {
         case 'C':
             ctx->Cflag = 1;
@@ -1573,6 +1594,9 @@  static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
                 return 0;
             }
             break;
+        case 'a':
+            ctx->aflag = 1;
+            break;
         default:
             g_free(ctx);
             return qemuio_command_usage(&aio_write_cmd);
@@ -1607,6 +1631,9 @@  static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
     }
 
     gettimeofday(&ctx->t1, NULL);
+    if (ctx->aflag) {
+        bdrv_acct_start(bs, &ctx->acct, ctx->qiov.size, BDRV_ACCT_WRITE);
+    }
     bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
                     ctx->qiov.size >> 9, aio_write_done, ctx);
     return 0;