From nobody Sun Apr 28 23:37:11 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1497966559215639.9384569426578; Tue, 20 Jun 2017 06:49:19 -0700 (PDT) Received: from localhost ([::1]:48947 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dNJWt-0002ht-VW for importer@patchew.org; Tue, 20 Jun 2017 09:49:16 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34131) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dNJVn-000217-5Q for qemu-devel@nongnu.org; Tue, 20 Jun 2017 09:48:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dNJVk-0008U3-E2 for qemu-devel@nongnu.org; Tue, 20 Jun 2017 09:48:07 -0400 Received: from smtp02.citrix.com ([66.165.176.63]:32274) by eggs.gnu.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.71) (envelope-from ) id 1dNJVk-0008QO-6m; Tue, 20 Jun 2017 09:48:04 -0400 X-IronPort-AV: E=Sophos;i="5.39,364,1493683200"; d="scan'208";a="437138721" From: Paul Durrant To: , , Date: Tue, 20 Jun 2017 09:47:54 -0400 Message-ID: <20170620134756.9632-2-paul.durrant@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170620134756.9632-1-paul.durrant@citrix.com> References: <20170620134756.9632-1-paul.durrant@citrix.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 66.165.176.63 Subject: [Qemu-devel] [PATCH 1/3] xen-disk: only advertize feature-persistent if grant copy is not available X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Anthony Perard , Kevin Wolf , Paul Durrant , Stefano Stabellini , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If grant copy is available then it will always be used in preference to persistent maps. In this case feature-persistent should not be advertized to the frontend, otherwise it may needlessly copy data into persistently granted buffers. Signed-off-by: Paul Durrant --- Cc: Stefano Stabellini Cc: Anthony Perard Cc: Kevin Wolf Cc: Max Reitz --- hw/block/xen_disk.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index 3a22805fbc..9b06e3aa81 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -1023,11 +1023,18 @@ static int blk_init(struct XenDevice *xendev) =20 blkdev->file_blk =3D BLOCK_SIZE; =20 + blkdev->feature_grant_copy =3D + (xengnttab_grant_copy(blkdev->xendev.gnttabdev, 0, NULL) = =3D=3D 0); + + xen_pv_printf(&blkdev->xendev, 3, "grant copy operation %s\n", + blkdev->feature_grant_copy ? "enabled" : "disabled"); + /* fill info * blk_connect supplies sector-size and sectors */ xenstore_write_be_int(&blkdev->xendev, "feature-flush-cache", 1); - xenstore_write_be_int(&blkdev->xendev, "feature-persistent", 1); + xenstore_write_be_int(&blkdev->xendev, "feature-persistent", + !blkdev->feature_grant_copy); xenstore_write_be_int(&blkdev->xendev, "info", info); =20 blk_parse_discard(blkdev); @@ -1202,12 +1209,6 @@ static int blk_connect(struct XenDevice *xendev) =20 xen_be_bind_evtchn(&blkdev->xendev); =20 - blkdev->feature_grant_copy =3D - (xengnttab_grant_copy(blkdev->xendev.gnttabdev, 0, NULL) = =3D=3D 0); - - xen_pv_printf(&blkdev->xendev, 3, "grant copy operation %s\n", - blkdev->feature_grant_copy ? "enabled" : "disabled"); - xen_pv_printf(&blkdev->xendev, 1, "ok: proto %s, ring-ref %d, " "remote port %d, local port %d\n", blkdev->xendev.protocol, blkdev->ring_ref, --=20 2.11.0 From nobody Sun Apr 28 23:37:11 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1497966618330800.5608543666675; Tue, 20 Jun 2017 06:50:18 -0700 (PDT) Received: from localhost ([::1]:48952 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dNJXs-0003Sh-Oq for importer@patchew.org; Tue, 20 Jun 2017 09:50:16 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34301) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dNJWK-0002IO-Fc for qemu-devel@nongnu.org; Tue, 20 Jun 2017 09:48:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dNJWH-0000P6-AA for qemu-devel@nongnu.org; Tue, 20 Jun 2017 09:48:40 -0400 Received: from smtp.citrix.com ([66.165.176.89]:14201) by eggs.gnu.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.71) (envelope-from ) id 1dNJWH-0000Oz-33; Tue, 20 Jun 2017 09:48:37 -0400 X-IronPort-AV: E=Sophos;i="5.39,364,1493683200"; d="scan'208";a="428636657" From: Paul Durrant To: , , Date: Tue, 20 Jun 2017 09:47:55 -0400 Message-ID: <20170620134756.9632-3-paul.durrant@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170620134756.9632-1-paul.durrant@citrix.com> References: <20170620134756.9632-1-paul.durrant@citrix.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 66.165.176.89 Subject: [Qemu-devel] [PATCH 2/3] xen-disk: add support for multi-page shared rings X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Anthony Perard , Kevin Wolf , Paul Durrant , Stefano Stabellini , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The blkif protocol has had provision for negotiation of multi-page shared rings for some time now and many guest OS have support in their frontend drivers. This patch makes the necessary modifications to xen-disk support a shared ring up to order 4 (i.e. 16 pages). Signed-off-by: Paul Durrant --- Cc: Stefano Stabellini Cc: Anthony Perard Cc: Kevin Wolf Cc: Max Reitz --- hw/block/xen_disk.c | 141 ++++++++++++++++++++++++++++++++++++++++--------= ---- 1 file changed, 110 insertions(+), 31 deletions(-) diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index 9b06e3aa81..a9942d32db 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -36,8 +36,6 @@ =20 static int batch_maps =3D 0; =20 -static int max_requests =3D 32; - /* ------------------------------------------------------------- */ =20 #define BLOCK_SIZE 512 @@ -84,6 +82,8 @@ struct ioreq { BlockAcctCookie acct; }; =20 +#define MAX_RING_PAGE_ORDER 4 + struct XenBlkDev { struct XenDevice xendev; /* must be first */ char *params; @@ -94,7 +94,8 @@ struct XenBlkDev { bool directiosafe; const char *fileproto; const char *filename; - int ring_ref; + unsigned int ring_ref[1 << MAX_RING_PAGE_ORDER]; + unsigned int nr_ring_ref; void *sring; int64_t file_blk; int64_t file_size; @@ -110,6 +111,7 @@ struct XenBlkDev { int requests_total; int requests_inflight; int requests_finished; + unsigned int max_requests; =20 /* Persistent grants extension */ gboolean feature_discard; @@ -199,7 +201,7 @@ static struct ioreq *ioreq_start(struct XenBlkDev *blkd= ev) struct ioreq *ioreq =3D NULL; =20 if (QLIST_EMPTY(&blkdev->freelist)) { - if (blkdev->requests_total >=3D max_requests) { + if (blkdev->requests_total >=3D blkdev->max_requests) { goto out; } /* allocate new struct */ @@ -905,7 +907,7 @@ static void blk_handle_requests(struct XenBlkDev *blkde= v) ioreq_runio_qemu_aio(ioreq); } =20 - if (blkdev->more_work && blkdev->requests_inflight < max_requests) { + if (blkdev->more_work && blkdev->requests_inflight < blkdev->max_reque= sts) { qemu_bh_schedule(blkdev->bh); } } @@ -918,15 +920,6 @@ static void blk_bh(void *opaque) blk_handle_requests(blkdev); } =20 -/* - * We need to account for the grant allocations requiring contiguous - * chunks; the worst case number would be - * max_req * max_seg + (max_req - 1) * (max_seg - 1) + 1, - * but in order to keep things simple just use - * 2 * max_req * max_seg. - */ -#define MAX_GRANTS(max_req, max_seg) (2 * (max_req) * (max_seg)) - static void blk_alloc(struct XenDevice *xendev) { struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); @@ -938,11 +931,6 @@ static void blk_alloc(struct XenDevice *xendev) if (xen_mode !=3D XEN_EMULATE) { batch_maps =3D 1; } - if (xengnttab_set_max_grants(xendev->gnttabdev, - MAX_GRANTS(max_requests, BLKIF_MAX_SEGMENTS_PER_REQUEST)) < 0)= { - xen_pv_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n", - strerror(errno)); - } } =20 static void blk_parse_discard(struct XenBlkDev *blkdev) @@ -1037,6 +1025,9 @@ static int blk_init(struct XenDevice *xendev) !blkdev->feature_grant_copy); xenstore_write_be_int(&blkdev->xendev, "info", info); =20 + xenstore_write_be_int(&blkdev->xendev, "max-ring-page-order", + MAX_RING_PAGE_ORDER); + blk_parse_discard(blkdev); =20 g_free(directiosafe); @@ -1058,12 +1049,25 @@ out_error: return -1; } =20 +/* + * We need to account for the grant allocations requiring contiguous + * chunks; the worst case number would be + * max_req * max_seg + (max_req - 1) * (max_seg - 1) + 1, + * but in order to keep things simple just use + * 2 * max_req * max_seg. + */ +#define MAX_GRANTS(max_req, max_seg) (2 * (max_req) * (max_seg)) + static int blk_connect(struct XenDevice *xendev) { struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); int pers, index, qflags; bool readonly =3D true; bool writethrough =3D true; + int order, ring_ref; + unsigned int ring_size, max_grants; + unsigned int i; + uint32_t *domids; =20 /* read-only ? */ if (blkdev->directiosafe) { @@ -1138,9 +1142,39 @@ static int blk_connect(struct XenDevice *xendev) xenstore_write_be_int64(&blkdev->xendev, "sectors", blkdev->file_size / blkdev->file_blk); =20 - if (xenstore_read_fe_int(&blkdev->xendev, "ring-ref", &blkdev->ring_re= f) =3D=3D -1) { + if (xenstore_read_fe_int(&blkdev->xendev, "ring-page-order", + &order) =3D=3D -1) { + blkdev->nr_ring_ref =3D 1; + + if (xenstore_read_fe_int(&blkdev->xendev, "ring-ref", + &ring_ref) =3D=3D -1) { + return -1; + } + blkdev->ring_ref[0] =3D ring_ref; + + } else if (order >=3D 0 && order <=3D MAX_RING_PAGE_ORDER) { + blkdev->nr_ring_ref =3D 1 << order; + + for (i =3D 0; i < blkdev->nr_ring_ref; i++) { + char *key; + + key =3D g_strdup_printf("ring-ref%u", i); + if (!key) { + return -1; + } + + if (xenstore_read_fe_int(&blkdev->xendev, key, + &ring_ref) =3D=3D -1) { + return -1; + } + blkdev->ring_ref[i] =3D ring_ref; + + g_free(key); + } + } else { return -1; } + if (xenstore_read_fe_int(&blkdev->xendev, "event-channel", &blkdev->xendev.remote_port) =3D=3D -1) { return -1; @@ -1163,41 +1197,85 @@ static int blk_connect(struct XenDevice *xendev) blkdev->protocol =3D BLKIF_PROTOCOL_NATIVE; } =20 - blkdev->sring =3D xengnttab_map_grant_ref(blkdev->xendev.gnttabdev, - blkdev->xendev.dom, - blkdev->ring_ref, - PROT_READ | PROT_WRITE); + ring_size =3D XC_PAGE_SIZE * blkdev->nr_ring_ref; + switch (blkdev->protocol) { + case BLKIF_PROTOCOL_NATIVE: + { + blkdev->max_requests =3D __CONST_RING_SIZE(blkif, ring_size); + break; + } + case BLKIF_PROTOCOL_X86_32: + { + blkdev->max_requests =3D __CONST_RING_SIZE(blkif_x86_32, ring_size= ); + break; + } + case BLKIF_PROTOCOL_X86_64: + { + blkdev->max_requests =3D __CONST_RING_SIZE(blkif_x86_64, ring_size= ); + break; + } + default: + return -1; + } + + /* Calculate the maximum number of grants needed by ioreqs */ + max_grants =3D MAX_GRANTS(blkdev->max_requests, + BLKIF_MAX_SEGMENTS_PER_REQUEST); + /* Add on the number needed for the ring pages */ + max_grants +=3D blkdev->nr_ring_ref; + + if (xengnttab_set_max_grants(blkdev->xendev.gnttabdev, max_grants)) { + xen_pv_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n", + strerror(errno)); + return -1; + } + + domids =3D g_malloc0_n(blkdev->nr_ring_ref, sizeof(uint32_t)); + for (i =3D 0; i < blkdev->nr_ring_ref; i++) { + domids[i] =3D blkdev->xendev.dom; + } + + blkdev->sring =3D xengnttab_map_grant_refs(blkdev->xendev.gnttabdev, + blkdev->nr_ring_ref, + domids, + blkdev->ring_ref, + PROT_READ | PROT_WRITE); + + g_free(domids); + if (!blkdev->sring) { return -1; } + blkdev->cnt_map++; =20 switch (blkdev->protocol) { case BLKIF_PROTOCOL_NATIVE: { blkif_sring_t *sring_native =3D blkdev->sring; - BACK_RING_INIT(&blkdev->rings.native, sring_native, XC_PAGE_SIZE); + BACK_RING_INIT(&blkdev->rings.native, sring_native, ring_size); break; } case BLKIF_PROTOCOL_X86_32: { blkif_x86_32_sring_t *sring_x86_32 =3D blkdev->sring; =20 - BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32, XC_PAGE_S= IZE); + BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32, ring_size= ); break; } case BLKIF_PROTOCOL_X86_64: { blkif_x86_64_sring_t *sring_x86_64 =3D blkdev->sring; =20 - BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, XC_PAGE_S= IZE); + BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, ring_size= ); break; } } =20 if (blkdev->feature_persistent) { /* Init persistent grants */ - blkdev->max_grants =3D max_requests * BLKIF_MAX_SEGMENTS_PER_REQUE= ST; + blkdev->max_grants =3D blkdev->max_requests * + BLKIF_MAX_SEGMENTS_PER_REQUEST; blkdev->persistent_gnts =3D g_tree_new_full((GCompareDataFunc)int_= cmp, NULL, NULL, batch_maps ? @@ -1209,9 +1287,9 @@ static int blk_connect(struct XenDevice *xendev) =20 xen_be_bind_evtchn(&blkdev->xendev); =20 - xen_pv_printf(&blkdev->xendev, 1, "ok: proto %s, ring-ref %d, " + xen_pv_printf(&blkdev->xendev, 1, "ok: proto %s, nr-ring-ref %u, " "remote port %d, local port %d\n", - blkdev->xendev.protocol, blkdev->ring_ref, + blkdev->xendev.protocol, blkdev->nr_ring_ref, blkdev->xendev.remote_port, blkdev->xendev.local_port); return 0; } @@ -1228,7 +1306,8 @@ static void blk_disconnect(struct XenDevice *xendev) xen_pv_unbind_evtchn(&blkdev->xendev); =20 if (blkdev->sring) { - xengnttab_unmap(blkdev->xendev.gnttabdev, blkdev->sring, 1); + xengnttab_unmap(blkdev->xendev.gnttabdev, blkdev->sring, + blkdev->nr_ring_ref); blkdev->cnt_map--; blkdev->sring =3D NULL; } --=20 2.11.0 From nobody Sun Apr 28 23:37:11 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1497966616219465.52088066852707; Tue, 20 Jun 2017 06:50:16 -0700 (PDT) Received: from localhost ([::1]:48948 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dNJXp-0003Qv-Cc for importer@patchew.org; Tue, 20 Jun 2017 09:50:13 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34299) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dNJWK-0002IL-EK for qemu-devel@nongnu.org; Tue, 20 Jun 2017 09:48:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dNJWH-0000PD-Lm for qemu-devel@nongnu.org; Tue, 20 Jun 2017 09:48:40 -0400 Received: from smtp.citrix.com ([66.165.176.89]:14201) by eggs.gnu.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.71) (envelope-from ) id 1dNJWH-0000Oz-Ep; Tue, 20 Jun 2017 09:48:37 -0400 X-IronPort-AV: E=Sophos;i="5.39,364,1493683200"; d="scan'208";a="428636658" From: Paul Durrant To: , , Date: Tue, 20 Jun 2017 09:47:56 -0400 Message-ID: <20170620134756.9632-4-paul.durrant@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170620134756.9632-1-paul.durrant@citrix.com> References: <20170620134756.9632-1-paul.durrant@citrix.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 66.165.176.89 Subject: [Qemu-devel] [PATCH 3/3] xen-disk: use an IOThread per instance X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Anthony Perard , Kevin Wolf , Paul Durrant , Stefano Stabellini , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This patch allocates an IOThread object for each xen_disk instance and sets the AIO context appropriately on connect. This allows processing of I/O to proceed in parallel. The patch also adds tracepoints into xen_disk to make it possible to follow the state transtions of an instance in the log. Signed-off-by: Paul Durrant --- Cc: Stefano Stabellini Cc: Anthony Perard Cc: Kevin Wolf Cc: Max Reitz --- hw/block/trace-events | 7 +++++++ hw/block/xen_disk.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/hw/block/trace-events b/hw/block/trace-events index 65e83dc258..608b24ba66 100644 --- a/hw/block/trace-events +++ b/hw/block/trace-events @@ -10,3 +10,10 @@ virtio_blk_submit_multireq(void *mrb, int start, int num= _reqs, uint64_t offset, # hw/block/hd-geometry.c hd_geometry_lchs_guess(void *blk, int cyls, int heads, int secs) "blk %p L= CHS %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 a9942d32db..ec1085c802 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -27,10 +27,13 @@ #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 "qom/object_interfaces.h" +#include "trace.h" =20 /* ------------------------------------------------------------- */ =20 @@ -128,6 +131,9 @@ struct XenBlkDev { DriveInfo *dinfo; BlockBackend *blk; QEMUBH *bh; + + IOThread *iothread; + AioContext *ctx; }; =20 /* ------------------------------------------------------------- */ @@ -923,11 +929,31 @@ static void blk_bh(void *opaque) static void blk_alloc(struct XenDevice *xendev) { struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); + Object *obj; + char *name; + Error *err =3D NULL; + + trace_xen_disk_alloc(xendev->name); =20 QLIST_INIT(&blkdev->inflight); QLIST_INIT(&blkdev->finished); QLIST_INIT(&blkdev->freelist); - blkdev->bh =3D qemu_bh_new(blk_bh, blkdev); + + obj =3D object_new(TYPE_IOTHREAD); + name =3D g_strdup_printf("iothread-%s", xendev->name); + + object_property_add_child(object_get_objects_root(), name, obj, &err); + assert(!err); + + g_free(name); + + user_creatable_complete(obj, &err); + assert(!err); + + blkdev->iothread =3D (IOThread *)object_dynamic_cast(obj, TYPE_IOTHREA= D); + blkdev->ctx =3D iothread_get_aio_context(blkdev->iothread); + blkdev->bh =3D aio_bh_new(blkdev->ctx, blk_bh, blkdev); + if (xen_mode !=3D XEN_EMULATE) { batch_maps =3D 1; } @@ -954,6 +980,8 @@ static int blk_init(struct XenDevice *xendev) int info =3D 0; char *directiosafe =3D NULL; =20 + trace_xen_disk_init(xendev->name); + /* read xenstore entries */ if (blkdev->params =3D=3D NULL) { char *h =3D NULL; @@ -1069,6 +1097,8 @@ static int blk_connect(struct XenDevice *xendev) unsigned int i; uint32_t *domids; =20 + trace_xen_disk_connect(xendev->name); + /* read-only ? */ if (blkdev->directiosafe) { qflags =3D BDRV_O_NOCACHE | BDRV_O_NATIVE_AIO; @@ -1285,6 +1315,8 @@ static int blk_connect(struct XenDevice *xendev) blkdev->persistent_gnt_count =3D 0; } =20 + blk_set_aio_context(blkdev->blk, blkdev->ctx); + xen_be_bind_evtchn(&blkdev->xendev); =20 xen_pv_printf(&blkdev->xendev, 1, "ok: proto %s, nr-ring-ref %u, " @@ -1298,13 +1330,20 @@ static void blk_disconnect(struct XenDevice *xendev) { struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); =20 + 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 =3D NULL; } xen_pv_unbind_evtchn(&blkdev->xendev); =20 + aio_context_release(blkdev->ctx); + if (blkdev->sring) { xengnttab_unmap(blkdev->xendev.gnttabdev, blkdev->sring, blkdev->nr_ring_ref); @@ -1338,6 +1377,8 @@ static int blk_free(struct XenDevice *xendev) struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); struct ioreq *ioreq; =20 + trace_xen_disk_free(xendev->name); + if (blkdev->blk || blkdev->sring) { blk_disconnect(xendev); } @@ -1355,6 +1396,7 @@ static int blk_free(struct XenDevice *xendev) g_free(blkdev->dev); g_free(blkdev->devtype); qemu_bh_delete(blkdev->bh); + object_unparent(OBJECT(blkdev->iothread)); return 0; } =20 --=20 2.11.0