diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-12-15 09:52:07 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-12-15 09:52:07 +0000 |
commit | 1c3b51a796a8eacfa5dfc840f0d8b736246167d4 (patch) | |
tree | df953b807ab8ae2e265af308dac877683cf39af2 /hw/block | |
parent | 0ef0583d5adceb9138bdb47494dabd1549ac5b6d (diff) | |
parent | 2e63eb2becc228232f12a1ea30a91b2aa8c5cecd (diff) |
Merge remote-tracking branch 'remotes/sstabellini/tags/xen-20171214-tag' into staging
Xen 2017/12/14
# gpg: Signature made Fri 15 Dec 2017 00:26:26 GMT
# gpg: using RSA key 0x894F8F4870E1AE90
# gpg: Good signature from "Stefano Stabellini <stefano.stabellini@eu.citrix.com>"
# gpg: aka "Stefano Stabellini <sstabellini@kernel.org>"
# Primary key fingerprint: D04E 33AB A51F 67BA 07D3 0AEA 894F 8F48 70E1 AE90
* remotes/sstabellini/tags/xen-20171214-tag:
xen/pt: Set is_express to avoid out-of-bounds write
xenfb: activate input handlers for raw pointer devices
xenfb: Add [feature|request]-raw-pointer
xenfb: Use Input Handlers directly
ui: generate qcode to linux mappings
xen-disk: use an IOThread per instance
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/block')
-rw-r--r-- | hw/block/trace-events | 7 | ||||
-rw-r--r-- | hw/block/xen_disk.c | 53 |
2 files changed, 53 insertions, 7 deletions
diff --git a/hw/block/trace-events b/hw/block/trace-events index cb6767b3ee..962a3bfa24 100644 --- a/hw/block/trace-events +++ b/hw/block/trace-events @@ -10,3 +10,10 @@ virtio_blk_submit_multireq(void *vdev, void *mrb, int start, int num_reqs, uint6 # hw/block/hd-geometry.c hd_geometry_lchs_guess(void *blk, int cyls, int heads, int secs) "blk %p LCHS %d %d %d" hd_geometry_guess(void *blk, uint32_t cyls, uint32_t heads, uint32_t secs, int trans) "blk %p CHS %u %u %u trans %d" + +# hw/block/xen_disk.c +xen_disk_alloc(char *name) "%s" +xen_disk_init(char *name) "%s" +xen_disk_connect(char *name) "%s" +xen_disk_disconnect(char *name) "%s" +xen_disk_free(char *name) "%s" diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index e431bd89e8..f74fcd42d1 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -27,10 +27,12 @@ #include "hw/xen/xen_backend.h" #include "xen_blkif.h" #include "sysemu/blockdev.h" +#include "sysemu/iothread.h" #include "sysemu/block-backend.h" #include "qapi/error.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qstring.h" +#include "trace.h" /* ------------------------------------------------------------- */ @@ -125,6 +127,9 @@ struct XenBlkDev { DriveInfo *dinfo; BlockBackend *blk; QEMUBH *bh; + + IOThread *iothread; + AioContext *ctx; }; /* ------------------------------------------------------------- */ @@ -596,9 +601,12 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq); static void qemu_aio_complete(void *opaque, int ret) { struct ioreq *ioreq = opaque; + struct XenBlkDev *blkdev = ioreq->blkdev; + + aio_context_acquire(blkdev->ctx); if (ret != 0) { - xen_pv_printf(&ioreq->blkdev->xendev, 0, "%s I/O error\n", + xen_pv_printf(&blkdev->xendev, 0, "%s I/O error\n", ioreq->req.operation == BLKIF_OP_READ ? "read" : "write"); ioreq->aio_errors++; } @@ -607,10 +615,10 @@ static void qemu_aio_complete(void *opaque, int ret) if (ioreq->presync) { ioreq->presync = 0; ioreq_runio_qemu_aio(ioreq); - return; + goto done; } if (ioreq->aio_inflight > 0) { - return; + goto done; } if (xen_feature_grant_copy) { @@ -647,16 +655,19 @@ static void qemu_aio_complete(void *opaque, int ret) } case BLKIF_OP_READ: if (ioreq->status == BLKIF_RSP_OKAY) { - block_acct_done(blk_get_stats(ioreq->blkdev->blk), &ioreq->acct); + block_acct_done(blk_get_stats(blkdev->blk), &ioreq->acct); } else { - block_acct_failed(blk_get_stats(ioreq->blkdev->blk), &ioreq->acct); + block_acct_failed(blk_get_stats(blkdev->blk), &ioreq->acct); } break; case BLKIF_OP_DISCARD: default: break; } - qemu_bh_schedule(ioreq->blkdev->bh); + qemu_bh_schedule(blkdev->bh); + +done: + aio_context_release(blkdev->ctx); } static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number, @@ -913,17 +924,29 @@ static void blk_handle_requests(struct XenBlkDev *blkdev) static void blk_bh(void *opaque) { struct XenBlkDev *blkdev = opaque; + + aio_context_acquire(blkdev->ctx); blk_handle_requests(blkdev); + aio_context_release(blkdev->ctx); } static void blk_alloc(struct XenDevice *xendev) { struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev); + Error *err = NULL; + + trace_xen_disk_alloc(xendev->name); QLIST_INIT(&blkdev->inflight); QLIST_INIT(&blkdev->finished); QLIST_INIT(&blkdev->freelist); - blkdev->bh = qemu_bh_new(blk_bh, blkdev); + + blkdev->iothread = iothread_create(xendev->name, &err); + assert(!err); + + blkdev->ctx = iothread_get_aio_context(blkdev->iothread); + blkdev->bh = aio_bh_new(blkdev->ctx, blk_bh, blkdev); + if (xen_mode != XEN_EMULATE) { batch_maps = 1; } @@ -950,6 +973,8 @@ static int blk_init(struct XenDevice *xendev) int info = 0; char *directiosafe = NULL; + trace_xen_disk_init(xendev->name); + /* read xenstore entries */ if (blkdev->params == NULL) { char *h = NULL; @@ -1062,6 +1087,8 @@ static int blk_connect(struct XenDevice *xendev) unsigned int i; uint32_t *domids; + trace_xen_disk_connect(xendev->name); + /* read-only ? */ if (blkdev->directiosafe) { qflags = BDRV_O_NOCACHE | BDRV_O_NATIVE_AIO; @@ -1287,6 +1314,8 @@ static int blk_connect(struct XenDevice *xendev) blkdev->persistent_gnt_count = 0; } + blk_set_aio_context(blkdev->blk, blkdev->ctx); + xen_be_bind_evtchn(&blkdev->xendev); xen_pv_printf(&blkdev->xendev, 1, "ok: proto %s, nr-ring-ref %u, " @@ -1300,13 +1329,20 @@ static void blk_disconnect(struct XenDevice *xendev) { struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev); + trace_xen_disk_disconnect(xendev->name); + + aio_context_acquire(blkdev->ctx); + if (blkdev->blk) { + blk_set_aio_context(blkdev->blk, qemu_get_aio_context()); blk_detach_dev(blkdev->blk, blkdev); blk_unref(blkdev->blk); blkdev->blk = NULL; } xen_pv_unbind_evtchn(&blkdev->xendev); + aio_context_release(blkdev->ctx); + if (blkdev->sring) { xengnttab_unmap(blkdev->xendev.gnttabdev, blkdev->sring, blkdev->nr_ring_ref); @@ -1345,6 +1381,8 @@ static int blk_free(struct XenDevice *xendev) struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev); struct ioreq *ioreq; + trace_xen_disk_free(xendev->name); + blk_disconnect(xendev); while (!QLIST_EMPTY(&blkdev->freelist)) { @@ -1360,6 +1398,7 @@ static int blk_free(struct XenDevice *xendev) g_free(blkdev->dev); g_free(blkdev->devtype); qemu_bh_delete(blkdev->bh); + iothread_destroy(blkdev->iothread); return 0; } |