* [Qemu-devel] [PATCH v2 0/2] dataplane: Enable "scsi=on" @ 2014-05-22 7:37 Fam Zheng 2014-05-22 7:37 ` [Qemu-devel] [PATCH v2 1/2] virtio-blk: Factor out virtio_blk_handle_scsi_req from virtio_blk_handle_scsi Fam Zheng ` (2 more replies) 0 siblings, 3 replies; 5+ messages in thread From: Fam Zheng @ 2014-05-22 7:37 UTC (permalink / raw) To: qemu-devel; +Cc: Paolo Bonzini, Stefan Hajnoczi This makes the SG_IO code of non-dataplane available to dataplane, so that dataplane can use to allow scsi=on. v2: [1/2] Fix scsi=off case and drop VirtIOBlockReq.scsi. [2/2] Pass conf to virtio_blk_handle_scsi_req. Fam Fam Zheng (2): virtio-blk: Factor out virtio_blk_handle_scsi_req from virtio_blk_handle_scsi dataplane: Support VIRTIO_BLK_T_SCSI_CMD hw/block/dataplane/virtio-blk.c | 18 +++++---- hw/block/virtio-blk.c | 83 +++++++++++++++++++++++------------------ include/hw/virtio/virtio-blk.h | 4 ++ 3 files changed, 60 insertions(+), 45 deletions(-) -- 1.9.2 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH v2 1/2] virtio-blk: Factor out virtio_blk_handle_scsi_req from virtio_blk_handle_scsi 2014-05-22 7:37 [Qemu-devel] [PATCH v2 0/2] dataplane: Enable "scsi=on" Fam Zheng @ 2014-05-22 7:37 ` Fam Zheng 2014-05-22 7:58 ` Paolo Bonzini 2014-05-22 7:37 ` [Qemu-devel] [PATCH v2 2/2] dataplane: Support VIRTIO_BLK_T_SCSI_CMD Fam Zheng 2014-05-22 12:48 ` [Qemu-devel] [PATCH v2 0/2] dataplane: Enable "scsi=on" Stefan Hajnoczi 2 siblings, 1 reply; 5+ messages in thread From: Fam Zheng @ 2014-05-22 7:37 UTC (permalink / raw) To: qemu-devel; +Cc: Paolo Bonzini, Stefan Hajnoczi The common logic to process a scsi request in a VirtQueueElement is extracted to a function to share with dataplane. This makes VirtIOBlockReq.scsi unused, so drop it. Signed-off-by: Fam Zheng <famz@redhat.com> --- hw/block/virtio-blk.c | 83 +++++++++++++++++++++++------------------- include/hw/virtio/virtio-blk.h | 4 ++ 2 files changed, 50 insertions(+), 37 deletions(-) diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 5e9433d..78e81a6 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -33,7 +33,6 @@ typedef struct VirtIOBlockReq VirtQueueElement elem; struct virtio_blk_inhdr *in; struct virtio_blk_outhdr *out; - struct virtio_scsi_inhdr *scsi; QEMUIOVector qiov; struct VirtIOBlockReq *next; BlockAcctCookie acct; @@ -125,13 +124,16 @@ static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s) return req; } -static void virtio_blk_handle_scsi(VirtIOBlockReq *req) +int virtio_blk_handle_scsi_req(BlockDriverState *bs, + VirtIOBlkConf *conf, + VirtQueueElement *elem) { + int status = VIRTIO_BLK_S_OK; + struct virtio_scsi_inhdr *scsi = NULL; #ifdef __linux__ - int ret; int i; + struct sg_io_hdr hdr; #endif - int status = VIRTIO_BLK_S_OK; /* * We require at least one output segment each for the virtio_blk_outhdr @@ -140,63 +142,61 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req) * We also at least require the virtio_blk_inhdr, the virtio_scsi_inhdr * and the sense buffer pointer in the input segments. */ - if (req->elem.out_num < 2 || req->elem.in_num < 3) { - virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR); - g_free(req); - return; + if (elem->out_num < 2 || elem->in_num < 3) { + status = VIRTIO_BLK_S_IOERR; + goto fail; } /* * The scsi inhdr is placed in the second-to-last input segment, just * before the regular inhdr. */ - req->scsi = (void *)req->elem.in_sg[req->elem.in_num - 2].iov_base; + scsi = (void *)elem->in_sg[elem->in_num - 2].iov_base; - if (!req->dev->blk.scsi) { + /* + * No support for bidirection commands yet. + */ + if (elem->out_num > 2 && elem->in_num > 3) { status = VIRTIO_BLK_S_UNSUPP; goto fail; } - /* - * No support for bidirection commands yet. - */ - if (req->elem.out_num > 2 && req->elem.in_num > 3) { + if (!conf->scsi) { status = VIRTIO_BLK_S_UNSUPP; goto fail; } #ifdef __linux__ - struct sg_io_hdr hdr; memset(&hdr, 0, sizeof(struct sg_io_hdr)); hdr.interface_id = 'S'; - hdr.cmd_len = req->elem.out_sg[1].iov_len; - hdr.cmdp = req->elem.out_sg[1].iov_base; + hdr.cmd_len = elem->out_sg[1].iov_len; + hdr.cmdp = elem->out_sg[1].iov_base; hdr.dxfer_len = 0; - if (req->elem.out_num > 2) { + if (elem->out_num > 2) { /* * If there are more than the minimally required 2 output segments * there is write payload starting from the third iovec. */ hdr.dxfer_direction = SG_DXFER_TO_DEV; - hdr.iovec_count = req->elem.out_num - 2; + hdr.iovec_count = elem->out_num - 2; for (i = 0; i < hdr.iovec_count; i++) - hdr.dxfer_len += req->elem.out_sg[i + 2].iov_len; + hdr.dxfer_len += elem->out_sg[i + 2].iov_len; - hdr.dxferp = req->elem.out_sg + 2; + hdr.dxferp = elem->out_sg + 2; - } else if (req->elem.in_num > 3) { + } else if (elem->in_num > 3) { /* * If we have more than 3 input segments the guest wants to actually * read data. */ hdr.dxfer_direction = SG_DXFER_FROM_DEV; - hdr.iovec_count = req->elem.in_num - 3; + hdr.iovec_count = elem->in_num - 3; for (i = 0; i < hdr.iovec_count; i++) - hdr.dxfer_len += req->elem.in_sg[i].iov_len; + hdr.dxfer_len += elem->in_sg[i].iov_len; - hdr.dxferp = req->elem.in_sg; + hdr.dxferp = elem->in_sg; } else { /* * Some SCSI commands don't actually transfer any data. @@ -204,11 +204,11 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req) hdr.dxfer_direction = SG_DXFER_NONE; } - hdr.sbp = req->elem.in_sg[req->elem.in_num - 3].iov_base; - hdr.mx_sb_len = req->elem.in_sg[req->elem.in_num - 3].iov_len; + hdr.sbp = elem->in_sg[elem->in_num - 3].iov_base; + hdr.mx_sb_len = elem->in_sg[elem->in_num - 3].iov_len; - ret = bdrv_ioctl(req->dev->bs, SG_IO, &hdr); - if (ret) { + status = bdrv_ioctl(bs, SG_IO, &hdr); + if (status) { status = VIRTIO_BLK_S_UNSUPP; goto fail; } @@ -224,23 +224,32 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req) hdr.status = CHECK_CONDITION; } - stl_p(&req->scsi->errors, + stl_p(&scsi->errors, hdr.status | (hdr.msg_status << 8) | (hdr.host_status << 16) | (hdr.driver_status << 24)); - stl_p(&req->scsi->residual, hdr.resid); - stl_p(&req->scsi->sense_len, hdr.sb_len_wr); - stl_p(&req->scsi->data_len, hdr.dxfer_len); + stl_p(&scsi->residual, hdr.resid); + stl_p(&scsi->sense_len, hdr.sb_len_wr); + stl_p(&scsi->data_len, hdr.dxfer_len); - virtio_blk_req_complete(req, status); - g_free(req); - return; + return status; #else abort(); #endif fail: /* Just put anything nonzero so that the ioctl fails in the guest. */ - stl_p(&req->scsi->errors, 255); + if (scsi) { + stl_p(&scsi->errors, 255); + } + return status; +} + +static void virtio_blk_handle_scsi(VirtIOBlockReq *req) +{ + int status; + + status = virtio_blk_handle_scsi_req(req->dev->bs, &req->dev->blk, + &req->elem); virtio_blk_req_complete(req, status); g_free(req); } diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index e4c41ff..1b00b48 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -155,4 +155,8 @@ typedef struct VirtIOBlock { void virtio_blk_set_conf(DeviceState *dev, VirtIOBlkConf *blk); +int virtio_blk_handle_scsi_req(BlockDriverState *bs, + VirtIOBlkConf *conf, + VirtQueueElement *elem); + #endif -- 1.9.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v2 1/2] virtio-blk: Factor out virtio_blk_handle_scsi_req from virtio_blk_handle_scsi 2014-05-22 7:37 ` [Qemu-devel] [PATCH v2 1/2] virtio-blk: Factor out virtio_blk_handle_scsi_req from virtio_blk_handle_scsi Fam Zheng @ 2014-05-22 7:58 ` Paolo Bonzini 0 siblings, 0 replies; 5+ messages in thread From: Paolo Bonzini @ 2014-05-22 7:58 UTC (permalink / raw) To: Fam Zheng, qemu-devel; +Cc: Stefan Hajnoczi Il 22/05/2014 09:37, Fam Zheng ha scritto: > -static void virtio_blk_handle_scsi(VirtIOBlockReq *req) > +int virtio_blk_handle_scsi_req(BlockDriverState *bs, > + VirtIOBlkConf *conf, > + VirtQueueElement *elem) Two more comments... please pass the VirtIOBlock * instead of bs/conf here. > { > + int status = VIRTIO_BLK_S_OK; > + struct virtio_scsi_inhdr *scsi = NULL; > #ifdef __linux__ > - int ret; > int i; > + struct sg_io_hdr hdr; > #endif > - int status = VIRTIO_BLK_S_OK; > > /* > * We require at least one output segment each for the virtio_blk_outhdr > @@ -140,63 +142,61 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req) > * We also at least require the virtio_blk_inhdr, the virtio_scsi_inhdr > * and the sense buffer pointer in the input segments. > */ > - if (req->elem.out_num < 2 || req->elem.in_num < 3) { > - virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR); > - g_free(req); > - return; > + if (elem->out_num < 2 || elem->in_num < 3) { > + status = VIRTIO_BLK_S_IOERR; > + goto fail; > } > > /* > * The scsi inhdr is placed in the second-to-last input segment, just > * before the regular inhdr. > */ > - req->scsi = (void *)req->elem.in_sg[req->elem.in_num - 2].iov_base; > + scsi = (void *)elem->in_sg[elem->in_num - 2].iov_base; > > - if (!req->dev->blk.scsi) { > + /* > + * No support for bidirection commands yet. > + */ > + if (elem->out_num > 2 && elem->in_num > 3) { > status = VIRTIO_BLK_S_UNSUPP; > goto fail; > } > > - /* > - * No support for bidirection commands yet. > - */ > - if (req->elem.out_num > 2 && req->elem.in_num > 3) { > + if (!conf->scsi) { > status = VIRTIO_BLK_S_UNSUPP; > goto fail; > } Swapping the two conditionals unnecessarily makes the patch bigger. Paolo > #ifdef __linux__ > - struct sg_io_hdr hdr; > memset(&hdr, 0, sizeof(struct sg_io_hdr)); > hdr.interface_id = 'S'; > - hdr.cmd_len = req->elem.out_sg[1].iov_len; > - hdr.cmdp = req->elem.out_sg[1].iov_base; > + hdr.cmd_len = elem->out_sg[1].iov_len; > + hdr.cmdp = elem->out_sg[1].iov_base; > hdr.dxfer_len = 0; > > - if (req->elem.out_num > 2) { > + if (elem->out_num > 2) { > /* > * If there are more than the minimally required 2 output segments > * there is write payload starting from the third iovec. > */ > hdr.dxfer_direction = SG_DXFER_TO_DEV; > - hdr.iovec_count = req->elem.out_num - 2; > + hdr.iovec_count = elem->out_num - 2; > > for (i = 0; i < hdr.iovec_count; i++) > - hdr.dxfer_len += req->elem.out_sg[i + 2].iov_len; > + hdr.dxfer_len += elem->out_sg[i + 2].iov_len; > > - hdr.dxferp = req->elem.out_sg + 2; > + hdr.dxferp = elem->out_sg + 2; > > - } else if (req->elem.in_num > 3) { > + } else if (elem->in_num > 3) { > /* > * If we have more than 3 input segments the guest wants to actually > * read data. > */ > hdr.dxfer_direction = SG_DXFER_FROM_DEV; > - hdr.iovec_count = req->elem.in_num - 3; > + hdr.iovec_count = elem->in_num - 3; > for (i = 0; i < hdr.iovec_count; i++) > - hdr.dxfer_len += req->elem.in_sg[i].iov_len; > + hdr.dxfer_len += elem->in_sg[i].iov_len; > > - hdr.dxferp = req->elem.in_sg; > + hdr.dxferp = elem->in_sg; > } else { > /* > * Some SCSI commands don't actually transfer any data. > @@ -204,11 +204,11 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req) > hdr.dxfer_direction = SG_DXFER_NONE; > } > > - hdr.sbp = req->elem.in_sg[req->elem.in_num - 3].iov_base; > - hdr.mx_sb_len = req->elem.in_sg[req->elem.in_num - 3].iov_len; > + hdr.sbp = elem->in_sg[elem->in_num - 3].iov_base; > + hdr.mx_sb_len = elem->in_sg[elem->in_num - 3].iov_len; > > - ret = bdrv_ioctl(req->dev->bs, SG_IO, &hdr); > - if (ret) { > + status = bdrv_ioctl(bs, SG_IO, &hdr); > + if (status) { > status = VIRTIO_BLK_S_UNSUPP; > goto fail; > } > @@ -224,23 +224,32 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req) > hdr.status = CHECK_CONDITION; > } > > - stl_p(&req->scsi->errors, > + stl_p(&scsi->errors, > hdr.status | (hdr.msg_status << 8) | > (hdr.host_status << 16) | (hdr.driver_status << 24)); > - stl_p(&req->scsi->residual, hdr.resid); > - stl_p(&req->scsi->sense_len, hdr.sb_len_wr); > - stl_p(&req->scsi->data_len, hdr.dxfer_len); > + stl_p(&scsi->residual, hdr.resid); > + stl_p(&scsi->sense_len, hdr.sb_len_wr); > + stl_p(&scsi->data_len, hdr.dxfer_len); > > - virtio_blk_req_complete(req, status); > - g_free(req); > - return; > + return status; > #else > abort(); > #endif > > fail: > /* Just put anything nonzero so that the ioctl fails in the guest. */ > - stl_p(&req->scsi->errors, 255); > + if (scsi) { > + stl_p(&scsi->errors, 255); > + } > + return status; > +} > + > +static void virtio_blk_handle_scsi(VirtIOBlockReq *req) > +{ > + int status; > + > + status = virtio_blk_handle_scsi_req(req->dev->bs, &req->dev->blk, > + &req->elem); > virtio_blk_req_complete(req, status); > g_free(req); > } > diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h > index e4c41ff..1b00b48 100644 > --- a/include/hw/virtio/virtio-blk.h > +++ b/include/hw/virtio/virtio-blk.h > @@ -155,4 +155,8 @@ typedef struct VirtIOBlock { > > void virtio_blk_set_conf(DeviceState *dev, VirtIOBlkConf *blk); > > +int virtio_blk_handle_scsi_req(BlockDriverState *bs, > + VirtIOBlkConf *conf, > + VirtQueueElement *elem); > + > #endif > ^ permalink raw reply [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH v2 2/2] dataplane: Support VIRTIO_BLK_T_SCSI_CMD 2014-05-22 7:37 [Qemu-devel] [PATCH v2 0/2] dataplane: Enable "scsi=on" Fam Zheng 2014-05-22 7:37 ` [Qemu-devel] [PATCH v2 1/2] virtio-blk: Factor out virtio_blk_handle_scsi_req from virtio_blk_handle_scsi Fam Zheng @ 2014-05-22 7:37 ` Fam Zheng 2014-05-22 12:48 ` [Qemu-devel] [PATCH v2 0/2] dataplane: Enable "scsi=on" Stefan Hajnoczi 2 siblings, 0 replies; 5+ messages in thread From: Fam Zheng @ 2014-05-22 7:37 UTC (permalink / raw) To: qemu-devel; +Cc: Paolo Bonzini, Stefan Hajnoczi Signed-off-by: Fam Zheng <famz@redhat.com> --- hw/block/dataplane/virtio-blk.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index 46a6824..e833045 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -201,6 +201,15 @@ static void do_flush_cmd(VirtIOBlockDataPlane *s, VirtQueueElement *elem, bdrv_aio_flush(s->blk->conf.bs, complete_flush, req); } +static void do_scsi_cmd(VirtIOBlockDataPlane *s, VirtQueueElement *elem, + QEMUIOVector *inhdr) +{ + int status; + + status = virtio_blk_handle_scsi_req(s->blk->conf.bs, s->blk, elem); + complete_request_early(s, elem, inhdr, status); +} + static int process_request(VirtIOBlockDataPlane *s, VirtQueueElement *elem) { struct iovec *iov = elem->out_sg; @@ -249,8 +258,7 @@ static int process_request(VirtIOBlockDataPlane *s, VirtQueueElement *elem) return 0; case VIRTIO_BLK_T_SCSI_CMD: - /* TODO support SCSI commands */ - complete_request_early(s, elem, inhdr, VIRTIO_BLK_S_UNSUPP); + do_scsi_cmd(s, elem, inhdr); return 0; case VIRTIO_BLK_T_FLUSH: @@ -326,12 +334,6 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk, return; } - if (blk->scsi) { - error_setg(errp, - "device is incompatible with x-data-plane, use scsi=off"); - return; - } - /* If dataplane is (re-)enabled while the guest is running there could be * block jobs that can conflict. */ -- 1.9.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v2 0/2] dataplane: Enable "scsi=on" 2014-05-22 7:37 [Qemu-devel] [PATCH v2 0/2] dataplane: Enable "scsi=on" Fam Zheng 2014-05-22 7:37 ` [Qemu-devel] [PATCH v2 1/2] virtio-blk: Factor out virtio_blk_handle_scsi_req from virtio_blk_handle_scsi Fam Zheng 2014-05-22 7:37 ` [Qemu-devel] [PATCH v2 2/2] dataplane: Support VIRTIO_BLK_T_SCSI_CMD Fam Zheng @ 2014-05-22 12:48 ` Stefan Hajnoczi 2 siblings, 0 replies; 5+ messages in thread From: Stefan Hajnoczi @ 2014-05-22 12:48 UTC (permalink / raw) To: Fam Zheng; +Cc: Paolo Bonzini, qemu-devel On Thu, May 22, 2014 at 03:37:10PM +0800, Fam Zheng wrote: > This makes the SG_IO code of non-dataplane available to dataplane, so that > dataplane can use to allow scsi=on. > > v2: > [1/2] Fix scsi=off case and drop VirtIOBlockReq.scsi. > [2/2] Pass conf to virtio_blk_handle_scsi_req. > > Fam > > > Fam Zheng (2): > virtio-blk: Factor out virtio_blk_handle_scsi_req from > virtio_blk_handle_scsi > dataplane: Support VIRTIO_BLK_T_SCSI_CMD > > hw/block/dataplane/virtio-blk.c | 18 +++++---- > hw/block/virtio-blk.c | 83 +++++++++++++++++++++++------------------ > include/hw/virtio/virtio-blk.h | 4 ++ > 3 files changed, 60 insertions(+), 45 deletions(-) I wonder if it's okay to use synchronous bdrv_ioctl() but the existing code already does it. It would be bad to block the thread. Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-05-22 12:49 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-05-22 7:37 [Qemu-devel] [PATCH v2 0/2] dataplane: Enable "scsi=on" Fam Zheng 2014-05-22 7:37 ` [Qemu-devel] [PATCH v2 1/2] virtio-blk: Factor out virtio_blk_handle_scsi_req from virtio_blk_handle_scsi Fam Zheng 2014-05-22 7:58 ` Paolo Bonzini 2014-05-22 7:37 ` [Qemu-devel] [PATCH v2 2/2] dataplane: Support VIRTIO_BLK_T_SCSI_CMD Fam Zheng 2014-05-22 12:48 ` [Qemu-devel] [PATCH v2 0/2] dataplane: Enable "scsi=on" Stefan Hajnoczi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).