diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2017-02-13 14:52:32 +0100 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2017-02-21 11:39:39 +0000 |
commit | b9e413dd3756f71abe4e8cafe1d7a459ce74ccf4 (patch) | |
tree | 3ac75c8cdeedba60249c6eed8d0f35d060b884cf /hw | |
parent | 1919631e6b5562e474690853eca3c35610201e16 (diff) | |
download | qemu-b9e413dd3756f71abe4e8cafe1d7a459ce74ccf4.zip qemu-b9e413dd3756f71abe4e8cafe1d7a459ce74ccf4.tar.gz qemu-b9e413dd3756f71abe4e8cafe1d7a459ce74ccf4.tar.bz2 |
block: explicitly acquire aiocontext in aio callbacks that need it
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Message-id: 20170213135235.12274-16-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/block/virtio-blk.c | 12 | ||||
-rw-r--r-- | hw/scsi/scsi-disk.c | 15 | ||||
-rw-r--r-- | hw/scsi/scsi-generic.c | 20 |
3 files changed, 43 insertions, 4 deletions
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index de3cf7b..843bd2f 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -89,7 +89,9 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, static void virtio_blk_rw_complete(void *opaque, int ret) { VirtIOBlockReq *next = opaque; + VirtIOBlock *s = next->dev; + aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); while (next) { VirtIOBlockReq *req = next; next = req->mr_next; @@ -122,21 +124,27 @@ static void virtio_blk_rw_complete(void *opaque, int ret) block_acct_done(blk_get_stats(req->dev->blk), &req->acct); virtio_blk_free_request(req); } + aio_context_release(blk_get_aio_context(s->conf.conf.blk)); } static void virtio_blk_flush_complete(void *opaque, int ret) { VirtIOBlockReq *req = opaque; + VirtIOBlock *s = req->dev; + aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); if (ret) { if (virtio_blk_handle_rw_error(req, -ret, 0)) { - return; + goto out; } } virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); block_acct_done(blk_get_stats(req->dev->blk), &req->acct); virtio_blk_free_request(req); + +out: + aio_context_release(blk_get_aio_context(s->conf.conf.blk)); } #ifdef __linux__ @@ -183,8 +191,10 @@ static void virtio_blk_ioctl_complete(void *opaque, int status) virtio_stl_p(vdev, &scsi->data_len, hdr->dxfer_len); out: + aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); virtio_blk_req_complete(req, status); virtio_blk_free_request(req); + aio_context_release(blk_get_aio_context(s->conf.conf.blk)); g_free(ioctl_req); } diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index cc06fe5..bbfb5dc 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -207,6 +207,7 @@ static void scsi_aio_complete(void *opaque, int ret) assert(r->req.aiocb != NULL); r->req.aiocb = NULL; + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); if (scsi_disk_req_check_error(r, ret, true)) { goto done; } @@ -215,6 +216,7 @@ static void scsi_aio_complete(void *opaque, int ret) scsi_req_complete(&r->req, GOOD); done: + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); scsi_req_unref(&r->req); } @@ -290,12 +292,14 @@ static void scsi_dma_complete(void *opaque, int ret) assert(r->req.aiocb != NULL); r->req.aiocb = NULL; + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); if (ret < 0) { block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); } else { block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); } scsi_dma_complete_noio(r, ret); + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); } static void scsi_read_complete(void * opaque, int ret) @@ -306,6 +310,7 @@ static void scsi_read_complete(void * opaque, int ret) assert(r->req.aiocb != NULL); r->req.aiocb = NULL; + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); if (scsi_disk_req_check_error(r, ret, true)) { goto done; } @@ -320,6 +325,7 @@ static void scsi_read_complete(void * opaque, int ret) done: scsi_req_unref(&r->req); + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); } /* Actually issue a read to the block device. */ @@ -364,12 +370,14 @@ static void scsi_do_read_cb(void *opaque, int ret) assert (r->req.aiocb != NULL); r->req.aiocb = NULL; + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); if (ret < 0) { block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); } else { block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); } scsi_do_read(opaque, ret); + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); } /* Read more data from scsi device into buffer. */ @@ -489,12 +497,14 @@ static void scsi_write_complete(void * opaque, int ret) assert (r->req.aiocb != NULL); r->req.aiocb = NULL; + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); if (ret < 0) { block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); } else { block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); } scsi_write_complete_noio(r, ret); + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); } static void scsi_write_data(SCSIRequest *req) @@ -1625,11 +1635,14 @@ static void scsi_unmap_complete(void *opaque, int ret) { UnmapCBData *data = opaque; SCSIDiskReq *r = data->r; + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); assert(r->req.aiocb != NULL); r->req.aiocb = NULL; + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); scsi_unmap_complete_noio(data, ret); + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); } static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf) @@ -1696,6 +1709,7 @@ static void scsi_write_same_complete(void *opaque, int ret) assert(r->req.aiocb != NULL); r->req.aiocb = NULL; + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); if (scsi_disk_req_check_error(r, ret, true)) { goto done; } @@ -1724,6 +1738,7 @@ done: scsi_req_unref(&r->req); qemu_vfree(data->iov.iov_base); g_free(data); + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); } static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf) diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index 92f091a..2933119 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -143,10 +143,14 @@ done: static void scsi_command_complete(void *opaque, int ret) { SCSIGenericReq *r = (SCSIGenericReq *)opaque; + SCSIDevice *s = r->req.dev; assert(r->req.aiocb != NULL); r->req.aiocb = NULL; + + aio_context_acquire(blk_get_aio_context(s->conf.blk)); scsi_command_complete_noio(r, ret); + aio_context_release(blk_get_aio_context(s->conf.blk)); } static int execute_command(BlockBackend *blk, @@ -182,9 +186,11 @@ static void scsi_read_complete(void * opaque, int ret) assert(r->req.aiocb != NULL); r->req.aiocb = NULL; + aio_context_acquire(blk_get_aio_context(s->conf.blk)); + if (ret || r->req.io_canceled) { scsi_command_complete_noio(r, ret); - return; + goto done; } len = r->io_header.dxfer_len - r->io_header.resid; @@ -193,7 +199,7 @@ static void scsi_read_complete(void * opaque, int ret) r->len = -1; if (len == 0) { scsi_command_complete_noio(r, 0); - return; + goto done; } /* Snoop READ CAPACITY output to set the blocksize. */ @@ -237,6 +243,9 @@ static void scsi_read_complete(void * opaque, int ret) } scsi_req_data(&r->req, len); scsi_req_unref(&r->req); + +done: + aio_context_release(blk_get_aio_context(s->conf.blk)); } /* Read more data from scsi device into buffer. */ @@ -272,9 +281,11 @@ static void scsi_write_complete(void * opaque, int ret) assert(r->req.aiocb != NULL); r->req.aiocb = NULL; + aio_context_acquire(blk_get_aio_context(s->conf.blk)); + if (ret || r->req.io_canceled) { scsi_command_complete_noio(r, ret); - return; + goto done; } if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 && @@ -284,6 +295,9 @@ static void scsi_write_complete(void * opaque, int ret) } scsi_command_complete_noio(r, ret); + +done: + aio_context_release(blk_get_aio_context(s->conf.blk)); } /* Write data to a scsi device. Returns nonzero on failure. |