qemu-stable
[Top][All Lists]
Advanced

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

Re: [Qemu-stable] [Qemu-devel] [PATCH 1/3] scsi-disk: Limit zero write r


From: Fam Zheng
Subject: Re: [Qemu-stable] [Qemu-devel] [PATCH 1/3] scsi-disk: Limit zero write request to SCSI_WRITE_SAME_MAX
Date: Fri, 24 Apr 2015 17:02:51 +0800
User-agent: Mutt/1.5.23 (2014-03-12)

On Fri, 04/24 10:50, Paolo Bonzini wrote:
> 
> 
> On 24/04/2015 10:33, Fam Zheng wrote:
> > SBC-4 says:
> > 
> >     If the number of logical blocks specified to be unmapped or written
> >     exceeds the value indicated in the MAXIMUM WRITE SAME LENGTH field
> >     in the Block Limits VPD page (see 6.6.4), then the device server
> >     shall terminate the command with CHECK CONDITION status with the
> >     sense key set to ILLEGAL REQUEST and the additional sense code set
> >     to INVALID FIELD IN CDB.
> > 
> > Check the request size to match the spec.
> > 
> > Signed-off-by: Fam Zheng <address@hidden>
> > ---
> >  hw/scsi/scsi-disk.c | 7 ++++++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> > 
> > diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
> > index 54d71f4..b748982 100644
> > --- a/hw/scsi/scsi-disk.c
> > +++ b/hw/scsi/scsi-disk.c
> > @@ -1707,6 +1707,11 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq 
> > *r, uint8_t *inbuf)
> >          return;
> >      }
> >  
> > +    if (nb_sectors * (s->qdev.blocksize / 512) * 512 > 
> > SCSI_WRITE_SAME_MAX) {
> > +        scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
> > +        return;
> > +    }
> > +
> >      if (buffer_is_zero(inbuf, s->qdev.blocksize)) {
> >          int flags = (req->cmd.buf[1] & 0x8) ? BDRV_REQ_MAY_UNMAP : 0;
> >  
> > @@ -1726,7 +1731,7 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq 
> > *r, uint8_t *inbuf)
> >      data->r = r;
> >      data->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
> >      data->nb_sectors = nb_sectors * (s->qdev.blocksize / 512);
> > -    data->iov.iov_len = MIN(data->nb_sectors * 512, SCSI_WRITE_SAME_MAX);
> > +    data->iov.iov_len = data->nb_sectors * 512;
> >      data->iov.iov_base = buf = blk_blockalign(s->qdev.conf.blk,
> >                                                data->iov.iov_len);
> >      qemu_iovec_init_external(&data->qiov, &data->iov, 1);
> > 
> 
> SCSI_WRITE_SAME_MAX is not exported as the MAXIMUM WRITE SAME LENGTH in
> the VPD.  In fact, we don't export anything and prefer to get very large
> requests, because then we can choose ourselves how to split them and
> serialize them.  By contrast, if you have a low limit, some guests
> including Linux will send a lot of concurrent WRITE SAME requests which
> will have a huge latency.
> 
> In addition, SCSI_WRITE_SAME_MAX is 512 *kilo*bytes.  That's really
> little :) as some disks have a multi-*mega*byte unmap granularity.  So
> what is SCSI_WRITE_SAME_MAX?
> 
> Simply, when we're asked to do a WRITE SAME with non-zero payload, we
> build a 512 KiB buffer and fill it repeatedly with the pattern.  Then
> the I/O is split in multiple writes, each covering 512 KiB except
> possibly the last.  Note that non-zero WRITE SAME is not a fast path.
> 
> So this patch is not correct.

OK, I get it. Thanks for explanation.

> However, it shouldn't be a problem for
> the rest of the series.

It is. The request has to be splitted to aligned part and unaligned part
because the latter requires a buffer, as we don't like unbounded allocation.

Fam




reply via email to

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