From nobody Sun May 5 07:04:36 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 149805089740633.124346490656876; Wed, 21 Jun 2017 06:14:57 -0700 (PDT) Received: from localhost ([::1]:53891 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dNfTC-0005Mt-HZ for importer@patchew.org; Wed, 21 Jun 2017 09:14:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34835) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dNf7z-0000o8-9o for qemu-devel@nongnu.org; Wed, 21 Jun 2017 08:53:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dNf7u-0005jf-Me for qemu-devel@nongnu.org; Wed, 21 Jun 2017 08:52:59 -0400 Received: from smtp02.citrix.com ([66.165.176.63]:16846) by eggs.gnu.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.71) (envelope-from ) id 1dNf7u-0005jJ-FR; Wed, 21 Jun 2017 08:52:54 -0400 X-IronPort-AV: E=Sophos;i="5.39,369,1493683200"; d="scan'208";a="437300029" From: Paul Durrant To: , , Date: Wed, 21 Jun 2017 08:52:47 -0400 Message-ID: <20170621125249.8805-2-paul.durrant@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170621125249.8805-1-paul.durrant@citrix.com> References: <20170621125249.8805-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 v2 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 Reviewed-by: Stefano Stabellini --- 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 May 5 07:04:36 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 1498050437886824.1621176779946; Wed, 21 Jun 2017 06:07:17 -0700 (PDT) Received: from localhost ([::1]:53839 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dNfLn-00061m-C7 for importer@patchew.org; Wed, 21 Jun 2017 09:07:15 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34843) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dNf7z-0000oX-NZ for qemu-devel@nongnu.org; Wed, 21 Jun 2017 08:53:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dNf7v-0005jq-0j for qemu-devel@nongnu.org; Wed, 21 Jun 2017 08:52:59 -0400 Received: from smtp.citrix.com ([66.165.176.89]:17173) by eggs.gnu.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.71) (envelope-from ) id 1dNf7u-0005jL-LZ; Wed, 21 Jun 2017 08:52:54 -0400 X-IronPort-AV: E=Sophos;i="5.39,369,1493683200"; d="scan'208";a="428801464" From: Paul Durrant To: , , Date: Wed, 21 Jun 2017 08:52:48 -0400 Message-ID: <20170621125249.8805-3-paul.durrant@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170621125249.8805-1-paul.durrant@citrix.com> References: <20170621125249.8805-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 v2 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 Reviewed-by: Stefano Stabellini --- Cc: Stefano Stabellini Cc: Anthony Perard Cc: Kevin Wolf Cc: Max Reitz v2: - Fix memory leak in error path - Print warning if ring-page-order exceeds limits --- hw/block/xen_disk.c | 144 +++++++++++++++++++++++++++++++++++++++++-------= ---- 1 file changed, 113 insertions(+), 31 deletions(-) diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index 9b06e3aa81..0e6513708e 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,42 @@ 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) { + g_free(key); + return -1; + } + blkdev->ring_ref[i] =3D ring_ref; + + g_free(key); + } + } else { + xen_pv_printf(xendev, 0, "invalid ring-page-order: %d\n", + order); return -1; } + if (xenstore_read_fe_int(&blkdev->xendev, "event-channel", &blkdev->xendev.remote_port) =3D=3D -1) { return -1; @@ -1163,41 +1200,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 +1290,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 +1309,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 May 5 07:04:36 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 1498050592236834.3023789964557; Wed, 21 Jun 2017 06:09:52 -0700 (PDT) Received: from localhost ([::1]:53849 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dNfOG-0008Er-Rg for importer@patchew.org; Wed, 21 Jun 2017 09:09:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34854) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dNf7z-0000ok-VO for qemu-devel@nongnu.org; Wed, 21 Jun 2017 08:53:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dNf7v-0005jy-9F for qemu-devel@nongnu.org; Wed, 21 Jun 2017 08:53:00 -0400 Received: from smtp.citrix.com ([66.165.176.89]:17173) by eggs.gnu.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.71) (envelope-from ) id 1dNf7v-0005jL-3d; Wed, 21 Jun 2017 08:52:55 -0400 X-IronPort-AV: E=Sophos;i="5.39,369,1493683200"; d="scan'208";a="428801465" From: Paul Durrant To: , , Date: Wed, 21 Jun 2017 08:52:49 -0400 Message-ID: <20170621125249.8805-4-paul.durrant@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170621125249.8805-1-paul.durrant@citrix.com> References: <20170621125249.8805-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 v2 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 v2: - explicitly acquire and release AIO context in qemu_aio_complete() and blk_bh() --- hw/block/trace-events | 7 ++++++ hw/block/xen_disk.c | 69 ++++++++++++++++++++++++++++++++++++++++++++---= ---- 2 files changed, 67 insertions(+), 9 deletions(-) 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 0e6513708e..8548195195 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 /* ------------------------------------------------------------- */ @@ -599,9 +605,12 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq); static void qemu_aio_complete(void *opaque, int ret) { struct ioreq *ioreq =3D opaque; + struct XenBlkDev *blkdev =3D ioreq->blkdev; + + aio_context_acquire(blkdev->ctx); =20 if (ret !=3D 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 =3D=3D BLKIF_OP_READ ? "read" := "write"); ioreq->aio_errors++; } @@ -610,13 +619,13 @@ static void qemu_aio_complete(void *opaque, int ret) if (ioreq->presync) { ioreq->presync =3D 0; ioreq_runio_qemu_aio(ioreq); - return; + goto done; } if (ioreq->aio_inflight > 0) { - return; + goto done; } =20 - if (ioreq->blkdev->feature_grant_copy) { + if (blkdev->feature_grant_copy) { switch (ioreq->req.operation) { case BLKIF_OP_READ: /* in case of failure ioreq->aio_errors is increased */ @@ -638,7 +647,7 @@ static void qemu_aio_complete(void *opaque, int ret) } =20 ioreq->status =3D ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY; - if (!ioreq->blkdev->feature_grant_copy) { + if (!blkdev->feature_grant_copy) { ioreq_unmap(ioreq); } ioreq_finish(ioreq); @@ -650,16 +659,19 @@ static void qemu_aio_complete(void *opaque, int ret) } case BLKIF_OP_READ: if (ioreq->status =3D=3D BLKIF_RSP_OKAY) { - block_acct_done(blk_get_stats(ioreq->blkdev->blk), &ioreq->acc= t); + block_acct_done(blk_get_stats(blkdev->blk), &ioreq->acct); } else { - block_acct_failed(blk_get_stats(ioreq->blkdev->blk), &ioreq->a= cct); + 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); } =20 static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_n= umber, @@ -917,17 +929,40 @@ static void blk_handle_requests(struct XenBlkDev *blk= dev) static void blk_bh(void *opaque) { struct XenBlkDev *blkdev =3D opaque; + + aio_context_acquire(blkdev->ctx); blk_handle_requests(blkdev); + aio_context_release(blkdev->ctx); } =20 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 +989,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 +1106,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; @@ -1288,6 +1327,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, " @@ -1301,13 +1342,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); @@ -1341,6 +1389,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); } @@ -1358,6 +1408,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