From: Paolo Bonzini <pbonzini@redhat.com>
To: Fam Zheng <famz@redhat.com>, qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>, Stefan Hajnoczi <stefanha@redhat.com>
Subject: Re: [Qemu-devel] [RFC PATCH 9/9] scsi: Cancel request asynchronously
Date: Thu, 21 Aug 2014 14:19:27 +0200 [thread overview]
Message-ID: <53F5E3CF.9020001@redhat.com> (raw)
In-Reply-To: <1408622216-9578-10-git-send-email-famz@redhat.com>
Il 21/08/2014 13:56, Fam Zheng ha scritto:
> We are blocking the whole VM, which means that an irresponsive storage
> backend will hang the whole guest. Let's switch to bdrv_aio_cancel_async
> to improve this.
Unforuntately, the TMF must only return after the request has been
canceled. I think you need to add a scsi_cancel_io_async function, and
keep all the remaining machinery (also, you need a better commit message
that explains what you are removing and the new invariants).
Then in virtio-scsi you need to add a list of "dependent" (controlq)
VirtIOSCSIReq to the "main" (requestq) VirtIOSCSIReq, and complete them
all after signaling the completion of the main request.
Paolo
> Signed-off-by: Fam Zheng <famz@redhat.com>
> ---
> hw/scsi/scsi-bus.c | 6 ++----
> hw/scsi/scsi-disk.c | 41 ++++++++++-------------------------------
> hw/scsi/scsi-generic.c | 21 ++++++---------------
> 3 files changed, 18 insertions(+), 50 deletions(-)
>
> diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
> index 6f4462b..59ec9f9 100644
> --- a/hw/scsi/scsi-bus.c
> +++ b/hw/scsi/scsi-bus.c
> @@ -1615,7 +1615,6 @@ void scsi_req_continue(SCSIRequest *req)
> {
> if (req->io_canceled) {
> trace_scsi_req_continue_canceled(req->dev->id, req->lun, req->tag);
> - return;
> }
> trace_scsi_req_continue(req->dev->id, req->lun, req->tag);
> if (req->cmd.mode == SCSI_XFER_TO_DEV) {
> @@ -1633,7 +1632,6 @@ void scsi_req_data(SCSIRequest *req, int len)
> uint8_t *buf;
> if (req->io_canceled) {
> trace_scsi_req_data_canceled(req->dev->id, req->lun, req->tag, len);
> - return;
> }
> trace_scsi_req_data(req->dev->id, req->lun, req->tag, len);
> assert(req->cmd.mode != SCSI_XFER_NONE);
> @@ -1721,7 +1719,7 @@ void scsi_req_complete(SCSIRequest *req, int status)
> void scsi_req_cancel(SCSIRequest *req)
> {
> trace_scsi_req_cancel(req->dev->id, req->lun, req->tag);
> - if (!req->enqueued) {
> + if (req->io_canceled) {
> return;
> }
> scsi_req_ref(req);
> @@ -1738,7 +1736,7 @@ void scsi_req_cancel(SCSIRequest *req)
>
> void scsi_req_abort(SCSIRequest *req, int status)
> {
> - if (!req->enqueued) {
> + if (req->io_canceled) {
> return;
> }
> scsi_req_ref(req);
> diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
> index d55521d..46b1e53 100644
> --- a/hw/scsi/scsi-disk.c
> +++ b/hw/scsi/scsi-disk.c
> @@ -112,14 +112,9 @@ static void scsi_cancel_io(SCSIRequest *req)
>
> DPRINTF("Cancel tag=0x%x\n", req->tag);
> if (r->req.aiocb) {
> - bdrv_aio_cancel(r->req.aiocb);
> -
> - /* This reference was left in by scsi_*_data. We take ownership of
> - * it the moment scsi_req_cancel is called, independent of whether
> - * bdrv_aio_cancel completes the request or not. */
> - scsi_req_unref(&r->req);
> + assert(req->io_canceled);
> + bdrv_aio_cancel_async(r->req.aiocb);
> }
> - r->req.aiocb = NULL;
> }
>
> static uint32_t scsi_init_iovec(SCSIDiskReq *r, size_t size)
> @@ -197,9 +192,7 @@ static void scsi_aio_complete(void *opaque, int ret)
> scsi_req_complete(&r->req, GOOD);
>
> done:
> - if (!r->req.io_canceled) {
> - scsi_req_unref(&r->req);
> - }
> + scsi_req_unref(&r->req);
> }
>
> static bool scsi_is_cmd_fua(SCSICommand *cmd)
> @@ -245,9 +238,7 @@ static void scsi_write_do_fua(SCSIDiskReq *r)
> scsi_req_complete(&r->req, GOOD);
>
> done:
> - if (!r->req.io_canceled) {
> - scsi_req_unref(&r->req);
> - }
> + scsi_req_unref(&r->req);
> }
>
> static void scsi_dma_complete_noio(void *opaque, int ret)
> @@ -279,9 +270,7 @@ static void scsi_dma_complete_noio(void *opaque, int ret)
> }
>
> done:
> - if (!r->req.io_canceled) {
> - scsi_req_unref(&r->req);
> - }
> + scsi_req_unref(&r->req);
> }
>
> static void scsi_dma_complete(void *opaque, int ret)
> @@ -319,9 +308,7 @@ static void scsi_read_complete(void * opaque, int ret)
> scsi_req_data(&r->req, r->qiov.size);
>
> done:
> - if (!r->req.io_canceled) {
> - scsi_req_unref(&r->req);
> - }
> + scsi_req_unref(&r->req);
> }
>
> /* Actually issue a read to the block device. */
> @@ -361,9 +348,7 @@ static void scsi_do_read(void *opaque, int ret)
> }
>
> done:
> - if (!r->req.io_canceled) {
> - scsi_req_unref(&r->req);
> - }
> + scsi_req_unref(&r->req);
> }
>
> /* Read more data from scsi device into buffer. */
> @@ -478,9 +463,7 @@ static void scsi_write_complete(void * opaque, int ret)
> }
>
> done:
> - if (!r->req.io_canceled) {
> - scsi_req_unref(&r->req);
> - }
> + scsi_req_unref(&r->req);
> }
>
> static void scsi_write_data(SCSIRequest *req)
> @@ -1577,9 +1560,7 @@ static void scsi_unmap_complete(void *opaque, int ret)
> scsi_req_complete(&r->req, GOOD);
>
> done:
> - if (!r->req.io_canceled) {
> - scsi_req_unref(&r->req);
> - }
> + scsi_req_unref(&r->req);
> g_free(data);
> }
>
> @@ -1672,9 +1653,7 @@ static void scsi_write_same_complete(void *opaque, int ret)
> scsi_req_complete(&r->req, GOOD);
>
> done:
> - if (!r->req.io_canceled) {
> - scsi_req_unref(&r->req);
> - }
> + scsi_req_unref(&r->req);
> qemu_vfree(data->iov.iov_base);
> g_free(data);
> }
> diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
> index 0b2ff90..1c29ecb 100644
> --- a/hw/scsi/scsi-generic.c
> +++ b/hw/scsi/scsi-generic.c
> @@ -132,27 +132,20 @@ static void scsi_command_complete(void *opaque, int ret)
> DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
> r, r->req.tag, status);
>
> - scsi_req_complete(&r->req, status);
> if (!r->req.io_canceled) {
> - scsi_req_unref(&r->req);
> + scsi_req_complete(&r->req, status);
> }
> + scsi_req_unref(&r->req);
> }
>
> /* Cancel a pending data transfer. */
> static void scsi_cancel_io(SCSIRequest *req)
> {
> - SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
> -
> DPRINTF("Cancel tag=0x%x\n", req->tag);
> - if (r->req.aiocb) {
> - bdrv_aio_cancel(r->req.aiocb);
> -
> - /* This reference was left in by scsi_*_data. We take ownership of
> - * it independent of whether bdrv_aio_cancel completes the request
> - * or not. */
> - scsi_req_unref(&r->req);
> + if (req->aiocb) {
> + req->io_canceled = true;
> + bdrv_aio_cancel_async(req->aiocb);
> }
> - r->req.aiocb = NULL;
> }
>
> static int execute_command(BlockDriverState *bdrv,
> @@ -211,9 +204,7 @@ static void scsi_read_complete(void * opaque, int ret)
> bdrv_set_guest_block_size(s->conf.bs, s->blocksize);
>
> scsi_req_data(&r->req, len);
> - if (!r->req.io_canceled) {
> - scsi_req_unref(&r->req);
> - }
> + scsi_req_unref(&r->req);
> }
> }
>
>
next prev parent reply other threads:[~2014-08-21 12:19 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-21 11:56 [Qemu-devel] [RFC PATCH 0/9] scsi, block: Asynchronous request cancellation Fam Zheng
2014-08-21 11:56 ` [Qemu-devel] [RFC PATCH 1/9] block: Add bdrv_aio_cancel_async Fam Zheng
2014-08-21 12:14 ` Paolo Bonzini
2014-08-22 1:23 ` Fam Zheng
2014-08-22 8:14 ` Paolo Bonzini
2014-08-22 9:37 ` Fam Zheng
2014-08-22 10:10 ` Paolo Bonzini
2014-08-22 10:51 ` Fam Zheng
2014-08-21 13:44 ` Stefan Hajnoczi
2014-08-21 11:56 ` [Qemu-devel] [RFC PATCH 2/9] tests: Add testing code for bdrv_aio_cancel_async Fam Zheng
2014-08-21 11:56 ` [Qemu-devel] [RFC PATCH 3/9] iscsi: Implement .cancel_async in acb info Fam Zheng
2014-08-21 11:56 ` [Qemu-devel] [RFC PATCH 4/9] linux-aio: Implement .cancel_async Fam Zheng
2014-08-21 16:31 ` Stefan Hajnoczi
2014-08-22 4:56 ` Fam Zheng
2014-08-21 11:56 ` [Qemu-devel] [RFC PATCH 5/9] thread-pool: " Fam Zheng
2014-08-21 11:56 ` [Qemu-devel] [RFC PATCH 6/9] blkdebug: " Fam Zheng
2014-08-21 16:52 ` Stefan Hajnoczi
2014-08-22 4:29 ` Fam Zheng
2014-08-21 11:56 ` [Qemu-devel] [RFC PATCH 7/9] dma: " Fam Zheng
2014-08-21 11:56 ` [Qemu-devel] [RFC PATCH 8/9] block: Implement stub bdrv_em_co_aiocb_info.cancel_async Fam Zheng
2014-08-21 17:01 ` Stefan Hajnoczi
2014-08-22 4:28 ` Fam Zheng
2014-08-21 11:56 ` [Qemu-devel] [RFC PATCH 9/9] scsi: Cancel request asynchronously Fam Zheng
2014-08-21 12:19 ` Paolo Bonzini [this message]
2014-08-22 4:57 ` Fam Zheng
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=53F5E3CF.9020001@redhat.com \
--to=pbonzini@redhat.com \
--cc=famz@redhat.com \
--cc=kwolf@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.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.