All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: John Snow <jsnow@redhat.com>, qemu-block@nongnu.org
Cc: kwolf@redhat.com, qemu-devel@nongnu.org, stefanha@redhat.com
Subject: Re: [Qemu-devel] [PATCH 3/5] ide: move buffered DMA cancel to core
Date: Tue, 19 Jan 2016 12:50:43 +0100	[thread overview]
Message-ID: <569E2313.3080607@redhat.com> (raw)
In-Reply-To: <1453179117-17909-4-git-send-email-jsnow@redhat.com>



On 19/01/2016 05:51, John Snow wrote:
> Buffered DMA cancellation was added to ATAPI devices and implemented
> for the BMDMA HBA. Move the code over to common IDE code and allow
> it to be used for any HBA.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>  hw/ide/core.c     | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  hw/ide/internal.h |  1 +
>  hw/ide/pci.c      | 36 +-----------------------------------
>  3 files changed, 47 insertions(+), 35 deletions(-)
> 
> diff --git a/hw/ide/core.c b/hw/ide/core.c
> index 75486c2..5d81840 100644
> --- a/hw/ide/core.c
> +++ b/hw/ide/core.c
> @@ -608,6 +608,51 @@ BlockAIOCB *ide_buffered_readv(IDEState *s, int64_t sector_num,
>      return aioreq;
>  }
>  
> +/**
> + * Cancel all pending DMA requests.
> + * Any buffered DMA requests are instantly canceled,
> + * but any pending unbuffered DMA requests must be waited on.
> + */
> +void ide_cancel_dma_sync(IDEState *s)
> +{
> +    IDEBufferedRequest *req;
> +
> +    /* First invoke the callbacks of all buffered requests
> +     * and flag those requests as orphaned. Ideally there
> +     * are no unbuffered (Scatter Gather DMA Requests or
> +     * write requests) pending and we can avoid to drain. */
> +    QLIST_FOREACH(req, &s->buffered_requests, list) {
> +        if (!req->orphaned) {
> +#ifdef DEBUG_IDE
> +            printf("%s: invoking cb %p of buffered request %p with"
> +                   " -ECANCELED\n", __func__, req->original_cb, req);
> +#endif
> +            req->original_cb(req->original_opaque, -ECANCELED);
> +        }
> +        req->orphaned = true;
> +    }
> +
> +    /*
> +     * We can't cancel Scatter Gather DMA in the middle of the
> +     * operation or a partial (not full) DMA transfer would reach
> +     * the storage so we wait for completion instead (we beahve
> +     * like if the DMA was completed by the time the guest trying
> +     * to cancel dma with bmdma_cmd_writeb with BM_CMD_START not
> +     * set).
> +     *
> +     * In the future we'll be able to safely cancel the I/O if the
> +     * whole DMA operation will be submitted to disk with a single
> +     * aio operation with preadv/pwritev.
> +     */
> +    if (s->bus->dma->aiocb) {
> +#ifdef DEBUG_IDE
> +        printf("%s: draining all remaining requests", __func__);
> +#endif
> +        blk_drain_all();

As a separate patch you can change this to blk_drain(s->blk), which is
already an improvement.

Paolo

> +        assert(s->bus->dma->aiocb == NULL);
> +    }
> +}
> +
>  static void ide_sector_read(IDEState *s);
>  
>  static void ide_sector_read_cb(void *opaque, int ret)
> diff --git a/hw/ide/internal.h b/hw/ide/internal.h
> index 2d1e2d2..86bde26 100644
> --- a/hw/ide/internal.h
> +++ b/hw/ide/internal.h
> @@ -586,6 +586,7 @@ BlockAIOCB *ide_issue_trim(BlockBackend *blk,
>  BlockAIOCB *ide_buffered_readv(IDEState *s, int64_t sector_num,
>                                 QEMUIOVector *iov, int nb_sectors,
>                                 BlockCompletionFunc *cb, void *opaque);
> +void ide_cancel_dma_sync(IDEState *s);
>  
>  /* hw/ide/atapi.c */
>  void ide_atapi_cmd(IDEState *s);
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index 37dbc29..6b780b8 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -233,41 +233,7 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
>      /* Ignore writes to SSBM if it keeps the old value */
>      if ((val & BM_CMD_START) != (bm->cmd & BM_CMD_START)) {
>          if (!(val & BM_CMD_START)) {
> -            /* First invoke the callbacks of all buffered requests
> -             * and flag those requests as orphaned. Ideally there
> -             * are no unbuffered (Scatter Gather DMA Requests or
> -             * write requests) pending and we can avoid to drain. */
> -            IDEBufferedRequest *req;
> -            IDEState *s = idebus_active_if(bm->bus);
> -            QLIST_FOREACH(req, &s->buffered_requests, list) {
> -                if (!req->orphaned) {
> -#ifdef DEBUG_IDE
> -                    printf("%s: invoking cb %p of buffered request %p with"
> -                           " -ECANCELED\n", __func__, req->original_cb, req);
> -#endif
> -                    req->original_cb(req->original_opaque, -ECANCELED);
> -                }
> -                req->orphaned = true;
> -            }
> -            /*
> -             * We can't cancel Scatter Gather DMA in the middle of the
> -             * operation or a partial (not full) DMA transfer would reach
> -             * the storage so we wait for completion instead (we beahve
> -             * like if the DMA was completed by the time the guest trying
> -             * to cancel dma with bmdma_cmd_writeb with BM_CMD_START not
> -             * set).
> -             *
> -             * In the future we'll be able to safely cancel the I/O if the
> -             * whole DMA operation will be submitted to disk with a single
> -             * aio operation with preadv/pwritev.
> -             */
> -            if (bm->bus->dma->aiocb) {
> -#ifdef DEBUG_IDE
> -                printf("%s: draining all remaining requests", __func__);
> -#endif
> -                blk_drain_all();
> -                assert(bm->bus->dma->aiocb == NULL);
> -            }
> +            ide_cancel_dma_sync(idebus_active_if(bm->bus));
>              bm->status &= ~BM_STATUS_DMAING;
>          } else {
>              bm->cur_addr = bm->addr;
> 

  reply	other threads:[~2016-01-19 11:50 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-19  4:51 [Qemu-devel] [PATCH 0/5] ide: fix atapi software reset John Snow
2016-01-19  4:51 ` [Qemu-devel] [PATCH 1/5] ide: Prohibit RESET on IDE drives John Snow
2016-01-19 11:48   ` Paolo Bonzini
2016-01-19 17:04     ` John Snow
2016-01-19 17:26       ` Laszlo Ersek
2016-01-19  4:51 ` [Qemu-devel] [PATCH 2/5] ide: code motion John Snow
2016-01-19  4:51 ` [Qemu-devel] [PATCH 3/5] ide: move buffered DMA cancel to core John Snow
2016-01-19 11:50   ` Paolo Bonzini [this message]
2016-01-19  4:51 ` [Qemu-devel] [PATCH 4/5] ide: Add silent DRQ cancellation John Snow
2016-01-19  4:51 ` [Qemu-devel] [PATCH 5/5] ide: fix device_reset to not ignore pending AIO John Snow

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=569E2313.3080607@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --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.