qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-block] [Qemu-devel] [PATCH 4/7] scsi-disk: introduce dma_readv


From: Mark Cave-Ayland
Subject: Re: [Qemu-block] [Qemu-devel] [PATCH 4/7] scsi-disk: introduce dma_readv and dma_writev
Date: Wed, 1 Jun 2016 20:07:23 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Icedove/38.8.0

On 23/05/16 13:54, Paolo Bonzini wrote:

> These are replacements for blk_aio_preadv and blk_aio_pwritev that allow
> customization of the data path.  They reuse the DMA helpers' DMAIOFunc
> callback type, so that the same function can be used in either the
> QEMUSGList or the bounce-buffered case.
> 
> This customization will be needed in the next patch to do zero-copy
> SG_IO on scsi-block.
> 
> Signed-off-by: Paolo Bonzini <address@hidden>
> ---
>  hw/scsi/scsi-disk.c | 63 
> +++++++++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 52 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
> index eaadfd6..4b5db59 100644
> --- a/hw/scsi/scsi-disk.c
> +++ b/hw/scsi/scsi-disk.c
> @@ -55,7 +55,21 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while 
> (0)
>  
>  #define TYPE_SCSI_DISK_BASE         "scsi-disk-base"
>  
> +#define SCSI_DISK_BASE(obj) \
> +     OBJECT_CHECK(SCSIDiskState, (obj), TYPE_SCSI_DISK_BASE)
> +#define SCSI_DISK_BASE_CLASS(klass) \
> +     OBJECT_CLASS_CHECK(SCSIDiskClass, (klass), TYPE_SCSI_DISK_BASE)
> +#define SCSI_DISK_BASE_GET_CLASS(obj) \
> +     OBJECT_GET_CLASS(SCSIDiskClass, (obj), TYPE_SCSI_DISK_BASE)
> +
>  typedef struct SCSIDiskState SCSIDiskState;
> +typedef struct SCSIDiskClass SCSIDiskClass;
> +
> +typedef struct SCSIDiskClass {
> +    SCSIDeviceClass parent_class;
> +    DMAIOFunc       *dma_readv;
> +    DMAIOFunc       *dma_writev;
> +} SCSIDiskClass;
>  
>  typedef struct SCSIDiskReq {
>      SCSIRequest req;
> @@ -317,6 +331,7 @@ done:
>  static void scsi_do_read(SCSIDiskReq *r, int ret)
>  {
>      SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
> +    SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));
>  
>      assert (r->req.aiocb == NULL);
>  
> @@ -337,16 +352,16 @@ static void scsi_do_read(SCSIDiskReq *r, int ret)
>      if (r->req.sg) {
>          dma_acct_start(s->qdev.conf.blk, &r->acct, r->req.sg, 
> BLOCK_ACCT_READ);
>          r->req.resid -= r->req.sg->size;
> -        r->req.aiocb = dma_blk_read(s->qdev.conf.blk, r->req.sg,
> -                                    r->sector << BDRV_SECTOR_BITS,
> -                                    scsi_dma_complete, r);
> +        r->req.aiocb = dma_blk_io(blk_get_aio_context(s->qdev.conf.blk),
> +                                  r->req.sg, r->sector << BDRV_SECTOR_BITS,
> +                                  sdc->dma_readv, r, scsi_dma_complete, r,
> +                                  DMA_DIRECTION_FROM_DEVICE);
>      } else {
>          scsi_init_iovec(r, SCSI_DMA_BUF_SIZE);
>          block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
>                           r->qiov.size, BLOCK_ACCT_READ);
> -        r->req.aiocb = blk_aio_preadv(s->qdev.conf.blk,
> -                                      r->sector << BDRV_SECTOR_BITS, 
> &r->qiov,
> -                                      0, scsi_read_complete, r);
> +        r->req.aiocb = sdc->dma_readv(r->sector, &r->qiov,
> +                                      scsi_read_complete, r, r);
>      }
>  
>  done:
> @@ -506,6 +521,7 @@ static void scsi_write_data(SCSIRequest *req)
>  {
>      SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
>      SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
> +    SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));
>  
>      /* No data transfer may already be in progress */
>      assert(r->req.aiocb == NULL);
> @@ -542,15 +558,16 @@ static void scsi_write_data(SCSIRequest *req)
>      if (r->req.sg) {
>          dma_acct_start(s->qdev.conf.blk, &r->acct, r->req.sg, 
> BLOCK_ACCT_WRITE);
>          r->req.resid -= r->req.sg->size;
> -        r->req.aiocb = dma_blk_write(s->qdev.conf.blk, r->req.sg,
> -                                     r->sector << BDRV_SECTOR_BITS,
>                                       scsi_dma_complete, r);
> +        r->req.aiocb = dma_blk_io(blk_get_aio_context(s->qdev.conf.blk),
> +                                  r->req.sg, r->sector << BDRV_SECTOR_BITS,
> +                                  sdc->dma_writev, r, scsi_dma_complete, r,
> +                                  DMA_DIRECTION_TO_DEVICE);
>      } else {
>          block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
>                           r->qiov.size, BLOCK_ACCT_WRITE);
> -        r->req.aiocb = blk_aio_pwritev(s->qdev.conf.blk,
> -                                       r->sector << BDRV_SECTOR_BITS, 
> &r->qiov,
> -                                       0, scsi_write_complete, r);
> +        r->req.aiocb = sdc->dma_writev(r->sector << BDRV_SECTOR_BITS, 
> &r->qiov,
> +                                       scsi_write_complete, r, r);
>      }
>  }
>  
> @@ -2658,12 +2675,35 @@ static int scsi_block_parse_cdb(SCSIDevice *d, 
> SCSICommand *cmd,
>  
>  #endif
>  
> +static
> +BlockAIOCB *scsi_dma_readv(int64_t offset, QEMUIOVector *iov,
> +                           BlockCompletionFunc *cb, void *cb_opaque,
> +                           void *opaque)
> +{
> +    SCSIDiskReq *r = opaque;
> +    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
> +    return blk_aio_preadv(s->qdev.conf.blk, offset, iov, 0, cb, cb_opaque);
> +}
> +
> +static
> +BlockAIOCB *scsi_dma_writev(int64_t offset, QEMUIOVector *iov,
> +                            BlockCompletionFunc *cb, void *cb_opaque,
> +                            void *opaque)
> +{
> +    SCSIDiskReq *r = opaque;
> +    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
> +    return blk_aio_pwritev(s->qdev.conf.blk, offset, iov, 0, cb, cb_opaque);
> +}
> +
>  static void scsi_disk_base_class_initfn(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> +    SCSIDiskClass *sdc = SCSI_DISK_BASE_CLASS(klass);
>  
>      dc->fw_name = "disk";
>      dc->reset = scsi_disk_reset;
> +    sdc->dma_readv = scsi_dma_readv;
> +    sdc->dma_writev = scsi_dma_writev;
>  }
>  
>  static const TypeInfo scsi_disk_base_info = {
> @@ -2671,6 +2711,7 @@ static const TypeInfo scsi_disk_base_info = {
>      .parent        = TYPE_SCSI_DEVICE,
>      .class_init    = scsi_disk_base_class_initfn,
>      .instance_size = sizeof(SCSIDiskState),
> +    .class_size    = sizeof(SCSIDiskClass),
>  };
>  
>  #define DEFINE_SCSI_DISK_PROPERTIES()                                \

Hi Paolo,

This patch appears to break qemu-system-sparc booting from CDROM with
the following command line:

./qemu-system-sparc -cdrom debian-40r4a-sparc-netinst.iso -boot d

Instead of booting straight into SILO, OpenBIOS hangs when trying to
read from the CDROM device.


ATB,

Mark.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]