From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547128344370921.0098389259948; Thu, 10 Jan 2019 05:52:24 -0800 (PST) Received: from localhost ([127.0.0.1]:53524 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghaks-0006JF-9L for importer@patchew.org; Thu, 10 Jan 2019 08:52:18 -0500 Received: from eggs.gnu.org ([209.51.188.92]:53179) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghaik-00053e-OJ for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghaij-0001gM-NK for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:06 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:11318) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghaij-0001ep-Dx for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:05 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75262369" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:48:53 +0000 Message-ID: <20190110134917.16425-2-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 01/25] hw/xen/xen_pt_graphics: Don't trust the BIOS ROM contents so much 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 , xen-devel@lists.xenproject.org, Peter Maydell Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Peter Maydell Coverity (CID 796599) points out that xen_pt_setup_vga() trusts the rom->size field in the BIOS ROM from a PCI passthrough VGA device, and uses it as an index into the memory which contains the BIOS image. A corrupt BIOS ROM could therefore cause us to index off the end of the buffer. Check that the size is within bounds before we use it. We are also trusting the pcioffset field, and assuming that the whole rom_header is present; Coverity doesn't notice these, but check them too. Signed-off-by: Peter Maydell Acked-by: Anthony PERARD Signed-off-by: Anthony PERARD --- hw/xen/xen_pt_graphics.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c index 135c8df1e7..60d6b4a556 100644 --- a/hw/xen/xen_pt_graphics.c +++ b/hw/xen/xen_pt_graphics.c @@ -185,8 +185,19 @@ void xen_pt_setup_vga(XenPCIPassthroughState *s, XenHo= stPCIDevice *dev, return; } =20 + if (bios_size < sizeof(struct rom_header)) { + error_setg(errp, "VGA: VBIOS image corrupt (too small)"); + return; + } + /* Currently we fixed this address as a primary. */ rom =3D (struct rom_header *)bios; + + if (rom->pcioffset + sizeof(struct pci_data) > bios_size) { + error_setg(errp, "VGA: VBIOS image corrupt (bad pcioffset field)"); + return; + } + pd =3D (void *)(bios + (unsigned char)rom->pcioffset); =20 /* We may need to fixup Device Identification. */ @@ -194,6 +205,11 @@ void xen_pt_setup_vga(XenPCIPassthroughState *s, XenHo= stPCIDevice *dev, pd->device =3D s->real_device.device_id; =20 len =3D rom->size * 512; + if (len > bios_size) { + error_setg(errp, "VGA: VBIOS image corrupt (bad size field)"); + return; + } + /* Then adjust the bios checksum */ for (c =3D (char *)bios; c < ((char *)bios + len); c++) { checksum +=3D *c; --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 154712871086556.324958820798884; Thu, 10 Jan 2019 05:58:30 -0800 (PST) Received: from localhost ([127.0.0.1]:55235 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghaqm-0003Ez-PF for importer@patchew.org; Thu, 10 Jan 2019 08:58:24 -0500 Received: from eggs.gnu.org ([209.51.188.92]:53185) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghail-00053i-9C for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghaik-0001go-6V for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:07 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:11318) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghaij-0001ep-U9 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:06 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75262378" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:48:54 +0000 Message-ID: <20190110134917.16425-3-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 02/25] xen/pt: allow passthrough of devices with bogus interrupt pin 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 , xen-devel@lists.xenproject.org, Zhao Yan Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Zhao Yan For some pci device, even its PCI_INTERRUPT_PIN is not 0, it actually doesn't support INTx mode, so its machine irq read from host sysfs is 0. In that case, report PCI_INTERRUPT_PIN as 0 to guest and let passthrough continue. Reviewed-by: Roger Pau Monn=C3=A9 Signed-off-by: Zhao Yan Acked-by: Anthony PERARD Signed-off-by: Anthony PERARD --- hw/xen/xen_pt.c | 6 ++++++ hw/xen/xen_pt_config_init.c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index f1f3a3727c..815dc46ba7 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -847,6 +847,12 @@ static void xen_pt_realize(PCIDevice *d, Error **errp) } =20 machine_irq =3D s->real_device.irq; + if (machine_irq =3D=3D 0) { + XEN_PT_LOG(d, "machine irq is 0\n"); + cmd |=3D PCI_COMMAND_INTX_DISABLE; + goto out; + } + rc =3D xc_physdev_map_pirq(xen_xc, xen_domid, machine_irq, &pirq); if (rc < 0) { error_setg_errno(errp, errno, "Mapping machine irq %u to" diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c index 47f9010c75..9fd953a689 100644 --- a/hw/xen/xen_pt_config_init.c +++ b/hw/xen/xen_pt_config_init.c @@ -300,7 +300,9 @@ static int xen_pt_irqpin_reg_init(XenPCIPassthroughStat= e *s, XenPTRegInfo *reg, uint32_t real_offset, uint32_t *data) { - *data =3D xen_pt_pci_read_intx(s); + if (s->real_device.irq) { + *data =3D xen_pt_pci_read_intx(s); + } return 0; } =20 --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547128514616614.4357275072632; Thu, 10 Jan 2019 05:55:14 -0800 (PST) Received: from localhost ([127.0.0.1]:54262 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghanh-0000lJ-9v for importer@patchew.org; Thu, 10 Jan 2019 08:55:13 -0500 Received: from eggs.gnu.org ([209.51.188.92]:53246) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghaip-00057f-2K for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghaik-0001gb-3s for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:11 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:11315) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghaij-0001eA-Nb for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:06 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75262372" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:48:55 +0000 Message-ID: <20190110134917.16425-4-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 03/25] xen: re-name XenDevice to XenLegacyDevice... 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant ...and xen_backend.h to xen-legacy-backend.h Rather than attempting to convert the existing backend infrastructure to be QOM compliant (which would be hard to do in an incremental fashion), subsequent patches will introduce a completely new framework for Xen PV backends. Hence it is necessary to re-name parts of existing code to avoid name clashes. The re-named 'legacy' infrastructure will be removed once all backends have been ported to the new framework. This patch is purely cosmetic. No functional change. Signed-off-by: Paul Durrant Acked-by: Anthony Perard Signed-off-by: Anthony PERARD --- hw/9pfs/xen-9p-backend.c | 16 ++-- hw/block/xen_disk.c | 24 +++--- hw/char/xen_console.c | 12 +-- hw/display/xenfb.c | 25 +++--- hw/i386/xen/xen-hvm.c | 2 +- hw/i386/xen/xen-mapcache.c | 2 +- hw/i386/xen/xen_platform.c | 2 +- hw/net/xen_nic.c | 14 ++-- hw/usb/xen-usb.c | 25 +++--- hw/xen/Makefile.objs | 2 +- hw/xen/xen-common.c | 2 +- .../{xen_backend.c =3D> xen-legacy-backend.c} | 79 +++++++++++-------- hw/xen/xen_devconfig.c | 2 +- hw/xen/xen_pt.c | 2 +- hw/xen/xen_pt_config_init.c | 2 +- hw/xen/xen_pt_graphics.c | 2 +- hw/xen/xen_pt_msi.c | 2 +- hw/xen/xen_pvdev.c | 20 ++--- hw/xenpv/xen_domainbuild.c | 2 +- hw/xenpv/xen_machine_pv.c | 2 +- .../{xen_backend.h =3D> xen-legacy-backend.h} | 43 +++++----- include/hw/xen/xen_pvdev.h | 38 ++++----- 22 files changed, 169 insertions(+), 151 deletions(-) rename hw/xen/{xen_backend.c =3D> xen-legacy-backend.c} (89%) rename include/hw/xen/{xen_backend.h =3D> xen-legacy-backend.h} (61%) diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c index 9015fe7773..25ab04d95a 100644 --- a/hw/9pfs/xen-9p-backend.c +++ b/hw/9pfs/xen-9p-backend.c @@ -12,7 +12,7 @@ =20 #include "hw/hw.h" #include "hw/9pfs/9p.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" #include "hw/9pfs/xen-9pfs.h" #include "qapi/error.h" #include "qemu/config-file.h" @@ -45,7 +45,7 @@ typedef struct Xen9pfsRing { } Xen9pfsRing; =20 typedef struct Xen9pfsDev { - struct XenDevice xendev; /* must be first */ + struct XenLegacyDevice xendev; /* must be first */ V9fsState state; char *path; char *security_model; @@ -56,7 +56,7 @@ typedef struct Xen9pfsDev { Xen9pfsRing *rings; } Xen9pfsDev; =20 -static void xen_9pfs_disconnect(struct XenDevice *xendev); +static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev); =20 static void xen_9pfs_in_sg(Xen9pfsRing *ring, struct iovec *in_sg, @@ -243,7 +243,7 @@ static const V9fsTransport xen_9p_transport =3D { .push_and_notify =3D xen_9pfs_push_and_notify, }; =20 -static int xen_9pfs_init(struct XenDevice *xendev) +static int xen_9pfs_init(struct XenLegacyDevice *xendev) { return 0; } @@ -305,7 +305,7 @@ static void xen_9pfs_evtchn_event(void *opaque) qemu_bh_schedule(ring->bh); } =20 -static void xen_9pfs_disconnect(struct XenDevice *xendev) +static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev) { Xen9pfsDev *xen_9pdev =3D container_of(xendev, Xen9pfsDev, xendev); int i; @@ -321,7 +321,7 @@ static void xen_9pfs_disconnect(struct XenDevice *xende= v) } } =20 -static int xen_9pfs_free(struct XenDevice *xendev) +static int xen_9pfs_free(struct XenLegacyDevice *xendev) { Xen9pfsDev *xen_9pdev =3D container_of(xendev, Xen9pfsDev, xendev); int i; @@ -354,7 +354,7 @@ static int xen_9pfs_free(struct XenDevice *xendev) return 0; } =20 -static int xen_9pfs_connect(struct XenDevice *xendev) +static int xen_9pfs_connect(struct XenLegacyDevice *xendev) { Error *err =3D NULL; int i; @@ -467,7 +467,7 @@ static int xen_9pfs_connect(struct XenDevice *xendev) return -1; } =20 -static void xen_9pfs_alloc(struct XenDevice *xendev) +static void xen_9pfs_alloc(struct XenLegacyDevice *xendev) { xenstore_write_be_str(xendev, "versions", VERSIONS); xenstore_write_be_int(xendev, "max-rings", MAX_RINGS); diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index 36eff94f84..75fe55f2ae 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -25,7 +25,7 @@ #include =20 #include "hw/hw.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" #include "xen_blkif.h" #include "sysemu/blockdev.h" #include "sysemu/iothread.h" @@ -63,7 +63,7 @@ struct ioreq { #define MAX_RING_PAGE_ORDER 4 =20 struct XenBlkDev { - struct XenDevice xendev; /* must be first */ + struct XenLegacyDevice xendev; /* must be first */ char *params; char *mode; char *type; @@ -179,7 +179,7 @@ static void ioreq_release(struct ioreq *ioreq, bool fin= ish) static int ioreq_parse(struct ioreq *ioreq) { struct XenBlkDev *blkdev =3D ioreq->blkdev; - struct XenDevice *xendev =3D &blkdev->xendev; + struct XenLegacyDevice *xendev =3D &blkdev->xendev; size_t len; int i; =20 @@ -243,7 +243,7 @@ static int ioreq_parse(struct ioreq *ioreq) static int ioreq_grant_copy(struct ioreq *ioreq) { struct XenBlkDev *blkdev =3D ioreq->blkdev; - struct XenDevice *xendev =3D &blkdev->xendev; + struct XenLegacyDevice *xendev =3D &blkdev->xendev; XenGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST]; int i, count, rc; int64_t file_blk =3D blkdev->file_blk; @@ -289,7 +289,7 @@ static void qemu_aio_complete(void *opaque, int ret) { struct ioreq *ioreq =3D opaque; struct XenBlkDev *blkdev =3D ioreq->blkdev; - struct XenDevice *xendev =3D &blkdev->xendev; + struct XenLegacyDevice *xendev =3D &blkdev->xendev; =20 aio_context_acquire(blkdev->ctx); =20 @@ -608,7 +608,7 @@ static void blk_bh(void *opaque) aio_context_release(blkdev->ctx); } =20 -static void blk_alloc(struct XenDevice *xendev) +static void blk_alloc(struct XenLegacyDevice *xendev) { struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); Error *err =3D NULL; @@ -628,7 +628,7 @@ static void blk_alloc(struct XenDevice *xendev) =20 static void blk_parse_discard(struct XenBlkDev *blkdev) { - struct XenDevice *xendev =3D &blkdev->xendev; + struct XenLegacyDevice *xendev =3D &blkdev->xendev; int enable; =20 blkdev->feature_discard =3D true; @@ -642,7 +642,7 @@ static void blk_parse_discard(struct XenBlkDev *blkdev) } } =20 -static int blk_init(struct XenDevice *xendev) +static int blk_init(struct XenLegacyDevice *xendev) { struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); int info =3D 0; @@ -737,7 +737,7 @@ static int blk_init(struct XenDevice *xendev) return -1; } =20 -static int blk_connect(struct XenDevice *xendev) +static int blk_connect(struct XenLegacyDevice *xendev) { struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); int index, qflags; @@ -941,7 +941,7 @@ static int blk_connect(struct XenDevice *xendev) return 0; } =20 -static void blk_disconnect(struct XenDevice *xendev) +static void blk_disconnect(struct XenLegacyDevice *xendev) { struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); =20 @@ -966,7 +966,7 @@ static void blk_disconnect(struct XenDevice *xendev) } } =20 -static int blk_free(struct XenDevice *xendev) +static int blk_free(struct XenLegacyDevice *xendev) { struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); struct ioreq *ioreq; @@ -992,7 +992,7 @@ static int blk_free(struct XenDevice *xendev) return 0; } =20 -static void blk_event(struct XenDevice *xendev) +static void blk_event(struct XenLegacyDevice *xendev) { struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); =20 diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c index 44f7236382..460adc1ba1 100644 --- a/hw/char/xen_console.c +++ b/hw/char/xen_console.c @@ -26,7 +26,7 @@ #include "qapi/error.h" #include "hw/hw.h" #include "chardev/char-fe.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" =20 #include =20 @@ -39,7 +39,7 @@ struct buffer { }; =20 struct XenConsole { - struct XenDevice xendev; /* must be first */ + struct XenLegacyDevice xendev; /* must be first */ struct buffer buffer; char console[XEN_BUFSIZE]; int ring_ref; @@ -173,7 +173,7 @@ static void xencons_send(struct XenConsole *con) =20 /* -------------------------------------------------------------------- */ =20 -static int con_init(struct XenDevice *xendev) +static int con_init(struct XenLegacyDevice *xendev) { struct XenConsole *con =3D container_of(xendev, struct XenConsole, xen= dev); char *type, *dom, label[32]; @@ -222,7 +222,7 @@ static int con_init(struct XenDevice *xendev) return ret; } =20 -static int con_initialise(struct XenDevice *xendev) +static int con_initialise(struct XenLegacyDevice *xendev) { struct XenConsole *con =3D container_of(xendev, struct XenConsole, xen= dev); int limit; @@ -259,7 +259,7 @@ static int con_initialise(struct XenDevice *xendev) return 0; } =20 -static void con_disconnect(struct XenDevice *xendev) +static void con_disconnect(struct XenLegacyDevice *xendev) { struct XenConsole *con =3D container_of(xendev, struct XenConsole, xen= dev); =20 @@ -276,7 +276,7 @@ static void con_disconnect(struct XenDevice *xendev) } } =20 -static void con_event(struct XenDevice *xendev) +static void con_event(struct XenLegacyDevice *xendev) { struct XenConsole *con =3D container_of(xendev, struct XenConsole, xen= dev); =20 diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index 0330dc6f61..6202f1150e 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -30,7 +30,7 @@ #include "hw/hw.h" #include "ui/input.h" #include "ui/console.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" =20 #include #include @@ -46,7 +46,7 @@ /* -------------------------------------------------------------------- */ =20 struct common { - struct XenDevice xendev; /* must be first */ + struct XenLegacyDevice xendev; /* must be first */ void *page; }; =20 @@ -342,14 +342,14 @@ static QemuInputHandler xenfb_rel_mouse =3D { .sync =3D xenfb_mouse_sync, }; =20 -static int input_init(struct XenDevice *xendev) +static int input_init(struct XenLegacyDevice *xendev) { xenstore_write_be_int(xendev, "feature-abs-pointer", 1); xenstore_write_be_int(xendev, "feature-raw-pointer", 1); return 0; } =20 -static int input_initialise(struct XenDevice *xendev) +static int input_initialise(struct XenLegacyDevice *xendev) { struct XenInput *in =3D container_of(xendev, struct XenInput, c.xendev= ); int rc; @@ -361,7 +361,7 @@ static int input_initialise(struct XenDevice *xendev) return 0; } =20 -static void input_connected(struct XenDevice *xendev) +static void input_connected(struct XenLegacyDevice *xendev) { struct XenInput *in =3D container_of(xendev, struct XenInput, c.xendev= ); =20 @@ -395,7 +395,7 @@ static void input_connected(struct XenDevice *xendev) } } =20 -static void input_disconnect(struct XenDevice *xendev) +static void input_disconnect(struct XenLegacyDevice *xendev) { struct XenInput *in =3D container_of(xendev, struct XenInput, c.xendev= ); =20 @@ -410,7 +410,7 @@ static void input_disconnect(struct XenDevice *xendev) common_unbind(&in->c); } =20 -static void input_event(struct XenDevice *xendev) +static void input_event(struct XenLegacyDevice *xendev) { struct XenInput *xenfb =3D container_of(xendev, struct XenInput, c.xen= dev); struct xenkbd_page *page =3D xenfb->c.page; @@ -867,7 +867,7 @@ static void xenfb_handle_events(struct XenFB *xenfb) page->out_cons =3D cons; } =20 -static int fb_init(struct XenDevice *xendev) +static int fb_init(struct XenLegacyDevice *xendev) { #ifdef XENFB_TYPE_RESIZE xenstore_write_be_int(xendev, "feature-resize", 1); @@ -875,7 +875,7 @@ static int fb_init(struct XenDevice *xendev) return 0; } =20 -static int fb_initialise(struct XenDevice *xendev) +static int fb_initialise(struct XenLegacyDevice *xendev) { struct XenFB *fb =3D container_of(xendev, struct XenFB, c.xendev); struct xenfb_page *fb_page; @@ -912,7 +912,7 @@ static int fb_initialise(struct XenDevice *xendev) return 0; } =20 -static void fb_disconnect(struct XenDevice *xendev) +static void fb_disconnect(struct XenLegacyDevice *xendev) { struct XenFB *fb =3D container_of(xendev, struct XenFB, c.xendev); =20 @@ -935,7 +935,8 @@ static void fb_disconnect(struct XenDevice *xendev) fb->bug_trigger =3D 0; } =20 -static void fb_frontend_changed(struct XenDevice *xendev, const char *node) +static void fb_frontend_changed(struct XenLegacyDevice *xendev, + const char *node) { struct XenFB *fb =3D container_of(xendev, struct XenFB, c.xendev); =20 @@ -953,7 +954,7 @@ static void fb_frontend_changed(struct XenDevice *xende= v, const char *node) } } =20 -static void fb_event(struct XenDevice *xendev) +static void fb_event(struct XenLegacyDevice *xendev) { struct XenFB *xenfb =3D container_of(xendev, struct XenFB, c.xendev); =20 diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c index 2143d33b18..6ef31571c8 100644 --- a/hw/i386/xen/xen-hvm.c +++ b/hw/i386/xen/xen-hvm.c @@ -16,7 +16,7 @@ #include "hw/i386/pc.h" #include "hw/i386/apic-msidef.h" #include "hw/xen/xen_common.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" #include "qapi/error.h" #include "qapi/qapi-commands-misc.h" #include "qemu/error-report.h" diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c index 4e4f069a24..9134a7bfef 100644 --- a/hw/i386/xen/xen-mapcache.c +++ b/hw/i386/xen/xen-mapcache.c @@ -14,7 +14,7 @@ =20 #include =20 -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" #include "qemu/bitmap.h" =20 #include diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c index deb7a0c374..16afb54fee 100644 --- a/hw/i386/xen/xen_platform.c +++ b/hw/i386/xen/xen_platform.c @@ -30,7 +30,7 @@ #include "hw/pci/pci.h" #include "hw/irq.h" #include "hw/xen/xen_common.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" #include "trace.h" #include "exec/address-spaces.h" #include "sysemu/block-backend.h" diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c index 46a8dbfc90..37cda8e4be 100644 --- a/hw/net/xen_nic.c +++ b/hw/net/xen_nic.c @@ -28,14 +28,14 @@ #include "net/net.h" #include "net/checksum.h" #include "net/util.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" =20 #include =20 /* ------------------------------------------------------------- */ =20 struct XenNetDev { - struct XenDevice xendev; /* must be first */ + struct XenLegacyDevice xendev; /* must be first */ char *mac; int tx_work; int tx_ring_ref; @@ -276,7 +276,7 @@ static NetClientInfo net_xen_info =3D { .receive =3D net_rx_packet, }; =20 -static int net_init(struct XenDevice *xendev) +static int net_init(struct XenLegacyDevice *xendev) { struct XenNetDev *netdev =3D container_of(xendev, struct XenNetDev, xe= ndev); =20 @@ -308,7 +308,7 @@ static int net_init(struct XenDevice *xendev) return 0; } =20 -static int net_connect(struct XenDevice *xendev) +static int net_connect(struct XenLegacyDevice *xendev) { struct XenNetDev *netdev =3D container_of(xendev, struct XenNetDev, xe= ndev); int rx_copy; @@ -363,7 +363,7 @@ static int net_connect(struct XenDevice *xendev) return 0; } =20 -static void net_disconnect(struct XenDevice *xendev) +static void net_disconnect(struct XenLegacyDevice *xendev) { struct XenNetDev *netdev =3D container_of(xendev, struct XenNetDev, xe= ndev); =20 @@ -379,14 +379,14 @@ static void net_disconnect(struct XenDevice *xendev) } } =20 -static void net_event(struct XenDevice *xendev) +static void net_event(struct XenLegacyDevice *xendev) { struct XenNetDev *netdev =3D container_of(xendev, struct XenNetDev, xe= ndev); net_tx_packets(netdev); qemu_flush_queued_packets(qemu_get_queue(netdev->nic)); } =20 -static int net_free(struct XenDevice *xendev) +static int net_free(struct XenLegacyDevice *xendev) { struct XenNetDev *netdev =3D container_of(xendev, struct XenNetDev, xe= ndev); =20 diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c index f5d5c91094..5eabacba93 100644 --- a/hw/usb/xen-usb.c +++ b/hw/usb/xen-usb.c @@ -27,7 +27,7 @@ #include "qemu/option.h" #include "hw/sysbus.h" #include "hw/usb.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" #include "monitor/qdev.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qstring.h" @@ -99,7 +99,7 @@ struct usbback_hotplug { }; =20 struct usbback_info { - struct XenDevice xendev; /* must be first */ + struct XenLegacyDevice xendev; /* must be first */ USBBus bus; void *urb_sring; void *conn_sring; @@ -142,7 +142,7 @@ static int usbback_gnttab_map(struct usbback_req *usbba= ck_req) unsigned int nr_segs, i, prot; uint32_t ref[USBIF_MAX_SEGMENTS_PER_REQUEST]; struct usbback_info *usbif =3D usbback_req->usbif; - struct XenDevice *xendev =3D &usbif->xendev; + struct XenLegacyDevice *xendev =3D &usbif->xendev; struct usbif_request_segment *seg; void *addr; =20 @@ -220,7 +220,7 @@ static int usbback_gnttab_map(struct usbback_req *usbba= ck_req) =20 static int usbback_init_packet(struct usbback_req *usbback_req) { - struct XenDevice *xendev =3D &usbback_req->usbif->xendev; + struct XenLegacyDevice *xendev =3D &usbback_req->usbif->xendev; USBPacket *packet =3D &usbback_req->packet; USBDevice *dev =3D usbback_req->stub->dev; USBEndpoint *ep; @@ -279,7 +279,7 @@ static void usbback_do_response(struct usbback_req *usb= back_req, int32_t status, { struct usbback_info *usbif; struct usbif_urb_response *res; - struct XenDevice *xendev; + struct XenLegacyDevice *xendev; unsigned int notify; =20 usbif =3D usbback_req->usbif; @@ -824,7 +824,7 @@ static void usbback_process_port(struct usbback_info *u= sbif, unsigned port) g_free(busid); } =20 -static void usbback_disconnect(struct XenDevice *xendev) +static void usbback_disconnect(struct XenLegacyDevice *xendev) { struct usbback_info *usbif; unsigned int i; @@ -853,7 +853,7 @@ static void usbback_disconnect(struct XenDevice *xendev) TR_BUS(xendev, "finished\n"); } =20 -static int usbback_connect(struct XenDevice *xendev) +static int usbback_connect(struct XenLegacyDevice *xendev) { struct usbback_info *usbif; struct usbif_urb_sring *urb_sring; @@ -913,7 +913,8 @@ static int usbback_connect(struct XenDevice *xendev) return 0; } =20 -static void usbback_backend_changed(struct XenDevice *xendev, const char *= node) +static void usbback_backend_changed(struct XenLegacyDevice *xendev, + const char *node) { struct usbback_info *usbif; unsigned int i; @@ -926,7 +927,7 @@ static void usbback_backend_changed(struct XenDevice *x= endev, const char *node) } } =20 -static int usbback_init(struct XenDevice *xendev) +static int usbback_init(struct XenLegacyDevice *xendev) { struct usbback_info *usbif; =20 @@ -1005,7 +1006,7 @@ static USBPortOps xen_usb_port_ops =3D { static USBBusOps xen_usb_bus_ops =3D { }; =20 -static void usbback_alloc(struct XenDevice *xendev) +static void usbback_alloc(struct XenLegacyDevice *xendev) { struct usbback_info *usbif; USBPort *p; @@ -1027,7 +1028,7 @@ static void usbback_alloc(struct XenDevice *xendev) usbif->bh =3D qemu_bh_new(usbback_bh, usbif); } =20 -static int usbback_free(struct XenDevice *xendev) +static int usbback_free(struct XenLegacyDevice *xendev) { struct usbback_info *usbif; struct usbback_req *usbback_req; @@ -1066,7 +1067,7 @@ static int usbback_free(struct XenDevice *xendev) return 0; } =20 -static void usbback_event(struct XenDevice *xendev) +static void usbback_event(struct XenLegacyDevice *xendev) { struct usbback_info *usbif; =20 diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs index 9ea5c73423..3f64a44051 100644 --- a/hw/xen/Makefile.objs +++ b/hw/xen/Makefile.objs @@ -1,5 +1,5 @@ # xen backend driver support -common-obj-$(CONFIG_XEN) +=3D xen_backend.o xen_devconfig.o xen_pvdev.o xe= n-common.o +common-obj-$(CONFIG_XEN) +=3D xen-legacy-backend.o xen_devconfig.o xen_pvd= ev.o xen-common.o =20 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) +=3D xen-host-pci-device.o obj-$(CONFIG_XEN_PCI_PASSTHROUGH) +=3D xen_pt.o xen_pt_config_init.o xen_p= t_graphics.o xen_pt_msi.o diff --git a/hw/xen/xen-common.c b/hw/xen/xen-common.c index d51148b6b3..6a9c8eb50f 100644 --- a/hw/xen/xen-common.c +++ b/hw/xen/xen-common.c @@ -10,7 +10,7 @@ =20 #include "qemu/osdep.h" #include "qemu/error-report.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" #include "chardev/char.h" #include "sysemu/accel.h" #include "migration/misc.h" diff --git a/hw/xen/xen_backend.c b/hw/xen/xen-legacy-backend.c similarity index 89% rename from hw/xen/xen_backend.c rename to hw/xen/xen-legacy-backend.c index 0bc6b1de60..41419763c8 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen-legacy-backend.c @@ -30,7 +30,7 @@ #include "hw/boards.h" #include "qemu/log.h" #include "qapi/error.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" #include "hw/xen/xen_pvdev.h" #include "monitor/qdev.h" =20 @@ -42,49 +42,54 @@ BusState *xen_sysbus; /* ------------------------------------------------------------- */ =20 /* public */ -struct xs_handle *xenstore =3D NULL; +struct xs_handle *xenstore; const char *xen_protocol; =20 /* private */ static bool xen_feature_grant_copy; static int debug; =20 -int xenstore_write_be_str(struct XenDevice *xendev, const char *node, cons= t char *val) +int xenstore_write_be_str(struct XenLegacyDevice *xendev, const char *node, + const char *val) { return xenstore_write_str(xendev->be, node, val); } =20 -int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int = ival) +int xenstore_write_be_int(struct XenLegacyDevice *xendev, const char *node, + int ival) { return xenstore_write_int(xendev->be, node, ival); } =20 -int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, in= t64_t ival) +int xenstore_write_be_int64(struct XenLegacyDevice *xendev, const char *no= de, + int64_t ival) { return xenstore_write_int64(xendev->be, node, ival); } =20 -char *xenstore_read_be_str(struct XenDevice *xendev, const char *node) +char *xenstore_read_be_str(struct XenLegacyDevice *xendev, const char *nod= e) { return xenstore_read_str(xendev->be, node); } =20 -int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *= ival) +int xenstore_read_be_int(struct XenLegacyDevice *xendev, const char *node, + int *ival) { return xenstore_read_int(xendev->be, node, ival); } =20 -char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node) +char *xenstore_read_fe_str(struct XenLegacyDevice *xendev, const char *nod= e) { return xenstore_read_str(xendev->fe, node); } =20 -int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *= ival) +int xenstore_read_fe_int(struct XenLegacyDevice *xendev, const char *node, + int *ival) { return xenstore_read_int(xendev->fe, node, ival); } =20 -int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node, +int xenstore_read_fe_uint64(struct XenLegacyDevice *xendev, const char *no= de, uint64_t *uval) { return xenstore_read_uint64(xendev->fe, node, uval); @@ -92,7 +97,7 @@ int xenstore_read_fe_uint64(struct XenDevice *xendev, con= st char *node, =20 /* ------------------------------------------------------------- */ =20 -int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state) +int xen_be_set_state(struct XenLegacyDevice *xendev, enum xenbus_state sta= te) { int rc; =20 @@ -106,7 +111,7 @@ int xen_be_set_state(struct XenDevice *xendev, enum xen= bus_state state) return 0; } =20 -void xen_be_set_max_grant_refs(struct XenDevice *xendev, +void xen_be_set_max_grant_refs(struct XenLegacyDevice *xendev, unsigned int nr_refs) { assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV); @@ -117,7 +122,7 @@ void xen_be_set_max_grant_refs(struct XenDevice *xendev, } } =20 -void *xen_be_map_grant_refs(struct XenDevice *xendev, uint32_t *refs, +void *xen_be_map_grant_refs(struct XenLegacyDevice *xendev, uint32_t *refs, unsigned int nr_refs, int prot) { void *ptr; @@ -135,7 +140,7 @@ void *xen_be_map_grant_refs(struct XenDevice *xendev, u= int32_t *refs, return ptr; } =20 -void xen_be_unmap_grant_refs(struct XenDevice *xendev, void *ptr, +void xen_be_unmap_grant_refs(struct XenLegacyDevice *xendev, void *ptr, unsigned int nr_refs) { assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV); @@ -146,7 +151,7 @@ void xen_be_unmap_grant_refs(struct XenDevice *xendev, = void *ptr, } } =20 -static int compat_copy_grant_refs(struct XenDevice *xendev, +static int compat_copy_grant_refs(struct XenLegacyDevice *xendev, bool to_domain, XenGrantCopySegment segs[], unsigned int nr_segs) @@ -195,7 +200,7 @@ static int compat_copy_grant_refs(struct XenDevice *xen= dev, return 0; } =20 -int xen_be_copy_grant_refs(struct XenDevice *xendev, +int xen_be_copy_grant_refs(struct XenLegacyDevice *xendev, bool to_domain, XenGrantCopySegment segs[], unsigned int nr_segs) @@ -259,10 +264,11 @@ int xen_be_copy_grant_refs(struct XenDevice *xendev, /* * get xen backend device, allocate a new one if it doesn't exist. */ -static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int = dev, - struct XenDevOps *ops) +static struct XenLegacyDevice *xen_be_get_xendev(const char *type, int dom, + int dev, + struct XenDevOps *ops) { - struct XenDevice *xendev; + struct XenLegacyDevice *xendev; =20 xendev =3D xen_pv_find_xendev(type, dom, dev); if (xendev) { @@ -314,7 +320,8 @@ static struct XenDevice *xen_be_get_xendev(const char *= type, int dom, int dev, * Node specifies the changed field. node =3D NULL means * update all fields (used for initialization). */ -static void xen_be_backend_changed(struct XenDevice *xendev, const char *n= ode) +static void xen_be_backend_changed(struct XenLegacyDevice *xendev, + const char *node) { if (node =3D=3D NULL || strcmp(node, "online") =3D=3D 0) { if (xenstore_read_be_int(xendev, "online", &xendev->online) =3D=3D= -1) { @@ -330,7 +337,8 @@ static void xen_be_backend_changed(struct XenDevice *xe= ndev, const char *node) } } =20 -static void xen_be_frontend_changed(struct XenDevice *xendev, const char *= node) +static void xen_be_frontend_changed(struct XenLegacyDevice *xendev, + const char *node) { int fe_state; =20 @@ -373,7 +381,7 @@ static void xen_be_frontend_changed(struct XenDevice *x= endev, const char *node) * only affects the xendev->be_state variable as xenbus should * already be put into that state by xend. */ -static int xen_be_try_setup(struct XenDevice *xendev) +static int xen_be_try_setup(struct XenLegacyDevice *xendev) { char token[XEN_BUFSIZE]; int be_state; @@ -417,7 +425,7 @@ static int xen_be_try_setup(struct XenDevice *xendev) * * Goes to InitWait on success. */ -static int xen_be_try_init(struct XenDevice *xendev) +static int xen_be_try_init(struct XenLegacyDevice *xendev) { int rc =3D 0; =20 @@ -446,7 +454,7 @@ static int xen_be_try_init(struct XenDevice *xendev) * * Goes to Connected on success. */ -static int xen_be_try_initialise(struct XenDevice *xendev) +static int xen_be_try_initialise(struct XenLegacyDevice *xendev) { int rc =3D 0; =20 @@ -487,7 +495,7 @@ static int xen_be_try_initialise(struct XenDevice *xend= ev) * frontend being Connected. Note that this may be called more * than once since the backend state is not modified. */ -static void xen_be_try_connected(struct XenDevice *xendev) +static void xen_be_try_connected(struct XenLegacyDevice *xendev) { if (!xendev->ops->connected) { return; @@ -510,7 +518,8 @@ static void xen_be_try_connected(struct XenDevice *xend= ev) * * Goes to Closed when done. */ -static void xen_be_disconnect(struct XenDevice *xendev, enum xenbus_state = state) +static void xen_be_disconnect(struct XenLegacyDevice *xendev, + enum xenbus_state state) { if (xendev->be_state !=3D XenbusStateClosing && xendev->be_state !=3D XenbusStateClosed && @@ -529,7 +538,7 @@ static void xen_be_disconnect(struct XenDevice *xendev,= enum xenbus_state state) /* * Try to reset xendev, for reconnection by another frontend instance. */ -static int xen_be_try_reset(struct XenDevice *xendev) +static int xen_be_try_reset(struct XenLegacyDevice *xendev) { if (xendev->fe_state !=3D XenbusStateInitialising) { return -1; @@ -543,7 +552,7 @@ static int xen_be_try_reset(struct XenDevice *xendev) /* * state change dispatcher function */ -void xen_be_check_state(struct XenDevice *xendev) +void xen_be_check_state(struct XenLegacyDevice *xendev) { int rc =3D 0; =20 @@ -587,7 +596,7 @@ void xen_be_check_state(struct XenDevice *xendev) =20 static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops) { - struct XenDevice *xendev; + struct XenLegacyDevice *xendev; char path[XEN_BUFSIZE], token[XEN_BUFSIZE]; char **dev =3D NULL; unsigned int cdev, j; @@ -620,7 +629,7 @@ static int xenstore_scan(const char *type, int dom, str= uct XenDevOps *ops) void xenstore_update_be(char *watch, char *type, int dom, struct XenDevOps *ops) { - struct XenDevice *xendev; + struct XenLegacyDevice *xendev; char path[XEN_BUFSIZE], *bepath; unsigned int len, dev; =20 @@ -628,9 +637,9 @@ void xenstore_update_be(char *watch, char *type, int do= m, if (strncmp(path, watch, len) !=3D 0) { return; } - if (sscanf(watch+len, "/%u/%255s", &dev, path) !=3D 2) { + if (sscanf(watch + len, "/%u/%255s", &dev, path) !=3D 2) { strcpy(path, ""); - if (sscanf(watch+len, "/%u", &dev) !=3D 1) { + if (sscanf(watch + len, "/%u", &dev) !=3D 1) { dev =3D -1; } } @@ -651,7 +660,7 @@ void xenstore_update_be(char *watch, char *type, int do= m, } } =20 -void xenstore_update_fe(char *watch, struct XenDevice *xendev) +void xenstore_update_fe(char *watch, struct XenLegacyDevice *xendev) { char *node; unsigned int len; @@ -753,7 +762,7 @@ void xen_be_register_common(void) #endif } =20 -int xen_be_bind_evtchn(struct XenDevice *xendev) +int xen_be_bind_evtchn(struct XenLegacyDevice *xendev) { if (xendev->local_port !=3D -1) { return 0; @@ -789,7 +798,7 @@ static const TypeInfo xendev_type_info =3D { .name =3D TYPE_XENBACKEND, .parent =3D TYPE_XENSYSDEV, .class_init =3D xendev_class_init, - .instance_size =3D sizeof(struct XenDevice), + .instance_size =3D sizeof(struct XenLegacyDevice), }; =20 static void xen_sysbus_class_init(ObjectClass *klass, void *data) diff --git a/hw/xen/xen_devconfig.c b/hw/xen/xen_devconfig.c index aebc19bd71..1b30bd7691 100644 --- a/hw/xen/xen_devconfig.c +++ b/hw/xen/xen_devconfig.c @@ -1,5 +1,5 @@ #include "qemu/osdep.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" #include "qemu/option.h" #include "sysemu/blockdev.h" =20 diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index 815dc46ba7..5539d56c3a 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -59,7 +59,7 @@ #include "hw/pci/pci.h" #include "hw/xen/xen.h" #include "hw/i386/pc.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" #include "xen_pt.h" #include "qemu/range.h" #include "exec/address-spaces.h" diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c index 9fd953a689..31ec5add1d 100644 --- a/hw/xen/xen_pt_config_init.c +++ b/hw/xen/xen_pt_config_init.c @@ -15,7 +15,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu/timer.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" #include "xen_pt.h" =20 #define XEN_PT_MERGE_VALUE(value, data, val_mask) \ diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c index 60d6b4a556..b69732729b 100644 --- a/hw/xen/xen_pt_graphics.c +++ b/hw/xen/xen_pt_graphics.c @@ -5,7 +5,7 @@ #include "qapi/error.h" #include "xen_pt.h" #include "xen-host-pci-device.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" =20 static unsigned long igd_guest_opregion; static unsigned long igd_host_opregion; diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c index cc514f9157..fb4b887b92 100644 --- a/hw/xen/xen_pt_msi.c +++ b/hw/xen/xen_pt_msi.c @@ -11,7 +11,7 @@ =20 #include "qemu/osdep.h" =20 -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" #include "xen_pt.h" #include "hw/i386/apic-msidef.h" =20 diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c index aed783e844..61de091002 100644 --- a/hw/xen/xen_pvdev.c +++ b/hw/xen/xen_pvdev.c @@ -20,7 +20,7 @@ #include "qemu/osdep.h" #include "qemu/log.h" #include "hw/qdev-core.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" #include "hw/xen/xen_pvdev.h" =20 /* private */ @@ -34,7 +34,7 @@ struct xs_dirs { static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup =3D QTAILQ_HEAD_INITIALIZER(xs_cleanup); =20 -static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs =3D +static QTAILQ_HEAD(XenLegacyDeviceHead, XenLegacyDevice) xendevs =3D QTAILQ_HEAD_INITIALIZER(xendevs); =20 /* ------------------------------------------------------------- */ @@ -195,7 +195,7 @@ const char *xenbus_strstate(enum xenbus_state state) * 2 =3D=3D noisy debug messages (logfile only). * 3 =3D=3D will flood your log (logfile only). */ -void xen_pv_printf(struct XenDevice *xendev, int msg_level, +void xen_pv_printf(struct XenLegacyDevice *xendev, int msg_level, const char *fmt, ...) { va_list args; @@ -230,7 +230,7 @@ void xen_pv_printf(struct XenDevice *xendev, int msg_le= vel, =20 void xen_pv_evtchn_event(void *opaque) { - struct XenDevice *xendev =3D opaque; + struct XenLegacyDevice *xendev =3D opaque; evtchn_port_t port; =20 port =3D xenevtchn_pending(xendev->evtchndev); @@ -247,7 +247,7 @@ void xen_pv_evtchn_event(void *opaque) } } =20 -void xen_pv_unbind_evtchn(struct XenDevice *xendev) +void xen_pv_unbind_evtchn(struct XenLegacyDevice *xendev) { if (xendev->local_port =3D=3D -1) { return; @@ -258,16 +258,16 @@ void xen_pv_unbind_evtchn(struct XenDevice *xendev) xendev->local_port =3D -1; } =20 -int xen_pv_send_notify(struct XenDevice *xendev) +int xen_pv_send_notify(struct XenLegacyDevice *xendev) { return xenevtchn_notify(xendev->evtchndev, xendev->local_port); } =20 /* ------------------------------------------------------------- */ =20 -struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev) +struct XenLegacyDevice *xen_pv_find_xendev(const char *type, int dom, int = dev) { - struct XenDevice *xendev; + struct XenLegacyDevice *xendev; =20 QTAILQ_FOREACH(xendev, &xendevs, next) { if (xendev->dom !=3D dom) { @@ -287,7 +287,7 @@ struct XenDevice *xen_pv_find_xendev(const char *type, = int dom, int dev) /* * release xen backend device. */ -void xen_pv_del_xendev(struct XenDevice *xendev) +void xen_pv_del_xendev(struct XenLegacyDevice *xendev) { if (xendev->ops->free) { xendev->ops->free(xendev); @@ -312,7 +312,7 @@ void xen_pv_del_xendev(struct XenDevice *xendev) qdev_unplug(&xendev->qdev, NULL); } =20 -void xen_pv_insert_xendev(struct XenDevice *xendev) +void xen_pv_insert_xendev(struct XenLegacyDevice *xendev) { QTAILQ_INSERT_TAIL(&xendevs, xendev, next); } diff --git a/hw/xenpv/xen_domainbuild.c b/hw/xenpv/xen_domainbuild.c index 188acaca16..deb28cf596 100644 --- a/hw/xenpv/xen_domainbuild.c +++ b/hw/xenpv/xen_domainbuild.c @@ -1,6 +1,6 @@ #include "qemu/osdep.h" #include "qemu/units.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" #include "xen_domainbuild.h" #include "qemu/timer.h" #include "qemu/log.h" diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c index 44d67b87c4..8c86fb7031 100644 --- a/hw/xenpv/xen_machine_pv.c +++ b/hw/xenpv/xen_machine_pv.c @@ -26,7 +26,7 @@ #include "qemu/error-report.h" #include "hw/hw.h" #include "hw/boards.h" -#include "hw/xen/xen_backend.h" +#include "hw/xen/xen-legacy-backend.h" #include "xen_domainbuild.h" #include "sysemu/block-backend.h" =20 diff --git a/include/hw/xen/xen_backend.h b/include/hw/xen/xen-legacy-backe= nd.h similarity index 61% rename from include/hw/xen/xen_backend.h rename to include/hw/xen/xen-legacy-backend.h index 9c17fdd85d..20cb47b5bf 100644 --- a/include/hw/xen/xen_backend.h +++ b/include/hw/xen/xen-legacy-backend.h @@ -11,7 +11,7 @@ #define TYPE_XENBACKEND "xen-backend" =20 #define XENBACKEND_DEVICE(obj) \ - OBJECT_CHECK(XenDevice, (obj), TYPE_XENBACKEND) + OBJECT_CHECK(XenLegacyDevice, (obj), TYPE_XENBACKEND) =20 /* variables */ extern struct xs_handle *xenstore; @@ -20,32 +20,37 @@ extern DeviceState *xen_sysdev; extern BusState *xen_sysbus; =20 int xenstore_mkdir(char *path, int p); -int xenstore_write_be_str(struct XenDevice *xendev, const char *node, cons= t char *val); -int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int = ival); -int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, in= t64_t ival); -char *xenstore_read_be_str(struct XenDevice *xendev, const char *node); -int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *= ival); -void xenstore_update_fe(char *watch, struct XenDevice *xendev); +int xenstore_write_be_str(struct XenLegacyDevice *xendev, const char *node, + const char *val); +int xenstore_write_be_int(struct XenLegacyDevice *xendev, const char *node, + int ival); +int xenstore_write_be_int64(struct XenLegacyDevice *xendev, const char *no= de, + int64_t ival); +char *xenstore_read_be_str(struct XenLegacyDevice *xendev, const char *nod= e); +int xenstore_read_be_int(struct XenLegacyDevice *xendev, const char *node, + int *ival); +void xenstore_update_fe(char *watch, struct XenLegacyDevice *xendev); void xenstore_update_be(char *watch, char *type, int dom, struct XenDevOps *ops); -char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node); -int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *= ival); -int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node, +char *xenstore_read_fe_str(struct XenLegacyDevice *xendev, const char *nod= e); +int xenstore_read_fe_int(struct XenLegacyDevice *xendev, const char *node, + int *ival); +int xenstore_read_fe_uint64(struct XenLegacyDevice *xendev, const char *no= de, uint64_t *uval); =20 -void xen_be_check_state(struct XenDevice *xendev); +void xen_be_check_state(struct XenLegacyDevice *xendev); =20 /* xen backend driver bits */ int xen_be_init(void); void xen_be_register_common(void); int xen_be_register(const char *type, struct XenDevOps *ops); -int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state); -int xen_be_bind_evtchn(struct XenDevice *xendev); -void xen_be_set_max_grant_refs(struct XenDevice *xendev, +int xen_be_set_state(struct XenLegacyDevice *xendev, enum xenbus_state sta= te); +int xen_be_bind_evtchn(struct XenLegacyDevice *xendev); +void xen_be_set_max_grant_refs(struct XenLegacyDevice *xendev, unsigned int nr_refs); -void *xen_be_map_grant_refs(struct XenDevice *xendev, uint32_t *refs, +void *xen_be_map_grant_refs(struct XenLegacyDevice *xendev, uint32_t *refs, unsigned int nr_refs, int prot); -void xen_be_unmap_grant_refs(struct XenDevice *xendev, void *ptr, +void xen_be_unmap_grant_refs(struct XenLegacyDevice *xendev, void *ptr, unsigned int nr_refs); =20 typedef struct XenGrantCopySegment { @@ -59,17 +64,17 @@ typedef struct XenGrantCopySegment { size_t len; } XenGrantCopySegment; =20 -int xen_be_copy_grant_refs(struct XenDevice *xendev, +int xen_be_copy_grant_refs(struct XenLegacyDevice *xendev, bool to_domain, XenGrantCopySegment segs[], unsigned int nr_segs); =20 -static inline void *xen_be_map_grant_ref(struct XenDevice *xendev, +static inline void *xen_be_map_grant_ref(struct XenLegacyDevice *xendev, uint32_t ref, int prot) { return xen_be_map_grant_refs(xendev, &ref, 1, prot); } =20 -static inline void xen_be_unmap_grant_ref(struct XenDevice *xendev, +static inline void xen_be_unmap_grant_ref(struct XenLegacyDevice *xendev, void *ptr) { return xen_be_unmap_grant_refs(xendev, ptr, 1); diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h index d473e9b34d..83e5174d90 100644 --- a/include/hw/xen/xen_pvdev.h +++ b/include/hw/xen/xen_pvdev.h @@ -6,7 +6,7 @@ =20 #define XEN_BUFSIZE 1024 =20 -struct XenDevice; +struct XenLegacyDevice; =20 /* driver uses grant tables -> open gntdev device (xendev->gnttabdev) */ #define DEVOPS_FLAG_NEED_GNTDEV 1 @@ -16,19 +16,21 @@ struct XenDevice; struct XenDevOps { size_t size; uint32_t flags; - void (*alloc)(struct XenDevice *xendev); - int (*init)(struct XenDevice *xendev); - int (*initialise)(struct XenDevice *xendev); - void (*connected)(struct XenDevice *xendev); - void (*event)(struct XenDevice *xendev); - void (*disconnect)(struct XenDevice *xendev); - int (*free)(struct XenDevice *xendev); - void (*backend_changed)(struct XenDevice *xendev, const char *nod= e); - void (*frontend_changed)(struct XenDevice *xendev, const char *no= de); + void (*alloc)(struct XenLegacyDevice *xendev); + int (*init)(struct XenLegacyDevice *xendev); + int (*initialise)(struct XenLegacyDevice *xendev); + void (*connected)(struct XenLegacyDevice *xendev); + void (*event)(struct XenLegacyDevice *xendev); + void (*disconnect)(struct XenLegacyDevice *xendev); + int (*free)(struct XenLegacyDevice *xendev); + void (*backend_changed)(struct XenLegacyDevice *xendev, + const char *node); + void (*frontend_changed)(struct XenLegacyDevice *xendev, + const char *node); int (*backend_register)(void); }; =20 -struct XenDevice { +struct XenLegacyDevice { DeviceState qdev; const char *type; int dom; @@ -49,7 +51,7 @@ struct XenDevice { xengnttab_handle *gnttabdev; =20 struct XenDevOps *ops; - QTAILQ_ENTRY(XenDevice) next; + QTAILQ_ENTRY(XenLegacyDevice) next; }; =20 /* ------------------------------------------------------------- */ @@ -66,14 +68,14 @@ void xenstore_update(void *unused); const char *xenbus_strstate(enum xenbus_state state); =20 void xen_pv_evtchn_event(void *opaque); -void xen_pv_insert_xendev(struct XenDevice *xendev); -void xen_pv_del_xendev(struct XenDevice *xendev); -struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev); +void xen_pv_insert_xendev(struct XenLegacyDevice *xendev); +void xen_pv_del_xendev(struct XenLegacyDevice *xendev); +struct XenLegacyDevice *xen_pv_find_xendev(const char *type, int dom, int = dev); =20 -void xen_pv_unbind_evtchn(struct XenDevice *xendev); -int xen_pv_send_notify(struct XenDevice *xendev); +void xen_pv_unbind_evtchn(struct XenLegacyDevice *xendev); +int xen_pv_send_notify(struct XenLegacyDevice *xendev); =20 -void xen_pv_printf(struct XenDevice *xendev, int msg_level, +void xen_pv_printf(struct XenLegacyDevice *xendev, int msg_level, const char *fmt, ...) GCC_FMT_ATTR(3, 4); =20 #endif /* QEMU_HW_XEN_PVDEV_H */ --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547128349603982.7503515027779; Thu, 10 Jan 2019 05:52:29 -0800 (PST) Received: from localhost ([127.0.0.1]:53555 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghal2-0006OY-FR for importer@patchew.org; Thu, 10 Jan 2019 08:52:28 -0500 Received: from eggs.gnu.org ([209.51.188.92]:53204) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghaim-000544-16 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghaik-0001gi-5f for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:07 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:11329) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghaij-0001fQ-TC for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:06 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75262377" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:48:56 +0000 Message-ID: <20190110134917.16425-5-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 04/25] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant This patch adds the basic boilerplate for a 'XenBus' object that will act as a parent to 'XenDevice' PV backends. A new 'XenBridge' object is also added to connect XenBus to the system bus. The XenBus object is instantiated by a new xen_bus_init() function called from the same sites as the legacy xen_be_init() function. Subsequent patches will flesh-out the functionality of these objects. Signed-off-by: Paul Durrant Reviewed-by: Anthony Perard Signed-off-by: Anthony PERARD --- hw/i386/xen/xen-hvm.c | 3 + hw/xen/Makefile.objs | 2 +- hw/xen/trace-events | 6 ++ hw/xen/xen-bus.c | 127 ++++++++++++++++++++++++++++++++++++++ hw/xenpv/xen_machine_pv.c | 3 + include/hw/xen/xen-bus.h | 55 +++++++++++++++++ 6 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 hw/xen/xen-bus.c create mode 100644 include/hw/xen/xen-bus.h diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c index 6ef31571c8..497e685d40 100644 --- a/hw/i386/xen/xen-hvm.c +++ b/hw/i386/xen/xen-hvm.c @@ -17,6 +17,7 @@ #include "hw/i386/apic-msidef.h" #include "hw/xen/xen_common.h" #include "hw/xen/xen-legacy-backend.h" +#include "hw/xen/xen-bus.h" #include "qapi/error.h" #include "qapi/qapi-commands-misc.h" #include "qemu/error-report.h" @@ -1484,6 +1485,8 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion = **ram_memory) QLIST_INIT(&state->dev_list); device_listener_register(&state->device_listener); =20 + xen_bus_init(); + /* Initialize backend core & drivers */ if (xen_be_init() !=3D 0) { error_report("xen backend core setup failed"); diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs index 3f64a44051..d9d6d7b4f9 100644 --- a/hw/xen/Makefile.objs +++ b/hw/xen/Makefile.objs @@ -1,5 +1,5 @@ # xen backend driver support -common-obj-$(CONFIG_XEN) +=3D xen-legacy-backend.o xen_devconfig.o xen_pvd= ev.o xen-common.o +common-obj-$(CONFIG_XEN) +=3D xen-legacy-backend.o xen_devconfig.o xen_pvd= ev.o xen-common.o xen-bus.o =20 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) +=3D xen-host-pci-device.o obj-$(CONFIG_XEN_PCI_PASSTHROUGH) +=3D xen_pt.o xen_pt_config_init.o xen_p= t_graphics.o xen_pt_msi.o diff --git a/hw/xen/trace-events b/hw/xen/trace-events index c7e7a3b523..0172cd4e26 100644 --- a/hw/xen/trace-events +++ b/hw/xen/trace-events @@ -12,3 +12,9 @@ xen_unmap_portio_range(uint32_t id, uint64_t start_addr, = uint64_t end_addr) "id: xen_map_pcidev(uint32_t id, uint8_t bus, uint8_t dev, uint8_t func) "id: %= u bdf: %02x.%02x.%02x" xen_unmap_pcidev(uint32_t id, uint8_t bus, uint8_t dev, uint8_t func) "id:= %u bdf: %02x.%02x.%02x" xen_domid_restrict(int err) "err: %u" + +# include/hw/xen/xen-bus.c +xen_bus_realize(void) "" +xen_bus_unrealize(void) "" +xen_device_realize(const char *type) "type: %s" +xen_device_unrealize(const char *type) "type: %s" diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c new file mode 100644 index 0000000000..bc04da748b --- /dev/null +++ b/hw/xen/xen-bus.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2018 Citrix Systems Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "hw/hw.h" +#include "hw/sysbus.h" +#include "hw/xen/xen-bus.h" +#include "qapi/error.h" +#include "trace.h" + +static void xen_bus_unrealize(BusState *bus, Error **errp) +{ + trace_xen_bus_unrealize(); +} + +static void xen_bus_realize(BusState *bus, Error **errp) +{ + trace_xen_bus_realize(); +} + +static void xen_bus_class_init(ObjectClass *class, void *data) +{ + BusClass *bus_class =3D BUS_CLASS(class); + + bus_class->realize =3D xen_bus_realize; + bus_class->unrealize =3D xen_bus_unrealize; +} + +static const TypeInfo xen_bus_type_info =3D { + .name =3D TYPE_XEN_BUS, + .parent =3D TYPE_BUS, + .instance_size =3D sizeof(XenBus), + .class_size =3D sizeof(XenBusClass), + .class_init =3D xen_bus_class_init, + .interfaces =3D (InterfaceInfo[]) { + { TYPE_HOTPLUG_HANDLER }, + { } + }, +}; + +static void xen_device_unrealize(DeviceState *dev, Error **errp) +{ + XenDevice *xendev =3D XEN_DEVICE(dev); + XenDeviceClass *xendev_class =3D XEN_DEVICE_GET_CLASS(xendev); + const char *type =3D object_get_typename(OBJECT(xendev)); + + trace_xen_device_unrealize(type); + + if (xendev_class->unrealize) { + xendev_class->unrealize(xendev, errp); + } +} + +static void xen_device_realize(DeviceState *dev, Error **errp) +{ + XenDevice *xendev =3D XEN_DEVICE(dev); + XenDeviceClass *xendev_class =3D XEN_DEVICE_GET_CLASS(xendev); + const char *type =3D object_get_typename(OBJECT(xendev)); + Error *local_err =3D NULL; + + trace_xen_device_realize(type); + + if (xendev_class->realize) { + xendev_class->realize(xendev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto unrealize; + } + } + + return; + +unrealize: + xen_device_unrealize(dev, &error_abort); +} + +static void xen_device_class_init(ObjectClass *class, void *data) +{ + DeviceClass *dev_class =3D DEVICE_CLASS(class); + + dev_class->realize =3D xen_device_realize; + dev_class->unrealize =3D xen_device_unrealize; + dev_class->bus_type =3D TYPE_XEN_BUS; +} + +static const TypeInfo xen_device_type_info =3D { + .name =3D TYPE_XEN_DEVICE, + .parent =3D TYPE_DEVICE, + .instance_size =3D sizeof(XenDevice), + .abstract =3D true, + .class_size =3D sizeof(XenDeviceClass), + .class_init =3D xen_device_class_init, +}; + +typedef struct XenBridge { + SysBusDevice busdev; +} XenBridge; + +#define TYPE_XEN_BRIDGE "xen-bridge" + +static const TypeInfo xen_bridge_type_info =3D { + .name =3D TYPE_XEN_BRIDGE, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(XenBridge), +}; + +static void xen_register_types(void) +{ + type_register_static(&xen_bridge_type_info); + type_register_static(&xen_bus_type_info); + type_register_static(&xen_device_type_info); +} + +type_init(xen_register_types) + +void xen_bus_init(void) +{ + DeviceState *dev =3D qdev_create(NULL, TYPE_XEN_BRIDGE); + BusState *bus =3D qbus_create(TYPE_XEN_BUS, dev, NULL); + + qdev_init_nofail(dev); + qbus_set_bus_hotplug_handler(bus, &error_abort); +} diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c index 8c86fb7031..608e591bcc 100644 --- a/hw/xenpv/xen_machine_pv.c +++ b/hw/xenpv/xen_machine_pv.c @@ -27,6 +27,7 @@ #include "hw/hw.h" #include "hw/boards.h" #include "hw/xen/xen-legacy-backend.h" +#include "hw/xen/xen-bus.h" #include "xen_domainbuild.h" #include "sysemu/block-backend.h" =20 @@ -93,6 +94,8 @@ static void xen_init_pv(MachineState *machine) xen_config_dev_nic(nd_table + i); } =20 + xen_bus_init(); + /* config cleanup hook */ atexit(xen_config_cleanup); } diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h new file mode 100644 index 0000000000..0cb12464ce --- /dev/null +++ b/include/hw/xen/xen-bus.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018 Citrix Systems Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef HW_XEN_BUS_H +#define HW_XEN_BUS_H + +#include "hw/sysbus.h" + +typedef struct XenDevice { + DeviceState qdev; +} XenDevice; + +typedef void (*XenDeviceRealize)(XenDevice *xendev, Error **errp); +typedef void (*XenDeviceUnrealize)(XenDevice *xendev, Error **errp); + +typedef struct XenDeviceClass { + /*< private >*/ + DeviceClass parent_class; + /*< public >*/ + XenDeviceRealize realize; + XenDeviceUnrealize unrealize; +} XenDeviceClass; + +#define TYPE_XEN_DEVICE "xen-device" +#define XEN_DEVICE(obj) \ + OBJECT_CHECK(XenDevice, (obj), TYPE_XEN_DEVICE) +#define XEN_DEVICE_CLASS(class) \ + OBJECT_CLASS_CHECK(XenDeviceClass, (class), TYPE_XEN_DEVICE) +#define XEN_DEVICE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(XenDeviceClass, (obj), TYPE_XEN_DEVICE) + +typedef struct XenBus { + BusState qbus; +} XenBus; + +typedef struct XenBusClass { + /*< private >*/ + BusClass parent_class; +} XenBusClass; + +#define TYPE_XEN_BUS "xen-bus" +#define XEN_BUS(obj) \ + OBJECT_CHECK(XenBus, (obj), TYPE_XEN_BUS) +#define XEN_BUS_CLASS(class) \ + OBJECT_CLASS_CHECK(XenBusClass, (class), TYPE_XEN_BUS) +#define XEN_BUS_GET_CLASS(obj) \ + OBJECT_GET_CLASS(XenBusClass, (obj), TYPE_XEN_BUS) + +void xen_bus_init(void); + +#endif /* HW_XEN_BUS_H */ --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547128625559590.942641872065; Thu, 10 Jan 2019 05:57:05 -0800 (PST) Received: from localhost ([127.0.0.1]:54849 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghapU-0002Gn-I2 for importer@patchew.org; Thu, 10 Jan 2019 08:57:04 -0500 Received: from eggs.gnu.org ([209.51.188.92]:53172) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghaik-00053Z-D4 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:08 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghaii-0001fH-F5 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:06 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:11315) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghaii-0001eA-2p for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:04 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75262376" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:48:57 +0000 Message-ID: <20190110134917.16425-6-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 05/25] xen: introduce 'xen-block', 'xen-disk' and 'xen-cdrom' 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant This patch adds new XenDevice-s: 'xen-disk' and 'xen-cdrom', both derived from a common 'xen-block' parent type. These will eventually replace the 'xen_disk' (note the underscore rather than hyphen) legacy PV backend but it is illustrative to build up the implementation incrementally, along with the XenBus/XenDevice framework. Subsequent patches will therefore add to these devices' implementation as new features are added to the framework. After this patch has been applied it is possible to instantiate new 'xen-disk' or 'xen-cdrom' devices with a single 'vdev' parameter, which accepts values adhering to the Xen VBD naming scheme [1]. For example, a command-line instantiation of a xen-disk can be done with an argument similar to the following: -device xen-disk,vdev=3Dhda The implementation of the vdev parameter formulates the appropriate VBD number for use in the PV protocol. [1] https://xenbits.xen.org/docs/unstable/man/xen-vbd-interface.7.html Signed-off-by: Paul Durrant Reviewed-by: Anthony Perard Signed-off-by: Anthony PERARD --- MAINTAINERS | 2 +- hw/block/Makefile.objs | 1 + hw/block/trace-events | 8 + hw/block/xen-block.c | 343 +++++++++++++++++++++++++++++++++++++ include/hw/xen/xen-block.h | 73 ++++++++ 5 files changed, 426 insertions(+), 1 deletion(-) create mode 100644 hw/block/xen-block.c create mode 100644 include/hw/xen/xen-block.h diff --git a/MAINTAINERS b/MAINTAINERS index 87f90721b9..7514550c06 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -414,7 +414,7 @@ F: hw/9pfs/xen-9p-backend.c F: hw/char/xen_console.c F: hw/display/xenfb.c F: hw/net/xen_nic.c -F: hw/block/xen_* +F: hw/block/xen* F: hw/xen/ F: hw/xenpv/ F: hw/i386/xen/ diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs index 53ce5751ae..f34813a377 100644 --- a/hw/block/Makefile.objs +++ b/hw/block/Makefile.objs @@ -4,6 +4,7 @@ common-obj-$(CONFIG_SSI_M25P80) +=3D m25p80.o common-obj-$(CONFIG_NAND) +=3D nand.o common-obj-$(CONFIG_PFLASH_CFI01) +=3D pflash_cfi01.o common-obj-$(CONFIG_PFLASH_CFI02) +=3D pflash_cfi02.o +common-obj-$(CONFIG_XEN) +=3D xen-block.o common-obj-$(CONFIG_XEN) +=3D xen_disk.o common-obj-$(CONFIG_ECC) +=3D ecc.o common-obj-$(CONFIG_ONENAND) +=3D onenand.o diff --git a/hw/block/trace-events b/hw/block/trace-events index 335c092450..4afbd62a88 100644 --- a/hw/block/trace-events +++ b/hw/block/trace-events @@ -127,3 +127,11 @@ xen_disk_init(char *name) "%s" xen_disk_connect(char *name) "%s" xen_disk_disconnect(char *name) "%s" xen_disk_free(char *name) "%s" + +# hw/block/xen-block.c +xen_block_realize(const char *type, uint32_t disk, uint32_t partition) "%s= d%up%u" +xen_block_unrealize(const char *type, uint32_t disk, uint32_t partition) "= %s d%up%u" +xen_disk_realize(void) "" +xen_disk_unrealize(void) "" +xen_cdrom_realize(void) "" +xen_cdrom_unrealize(void) "" diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c new file mode 100644 index 0000000000..8e78b6a034 --- /dev/null +++ b/hw/block/xen-block.c @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2018 Citrix Systems Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/cutils.h" +#include "qapi/error.h" +#include "qapi/visitor.h" +#include "hw/hw.h" +#include "hw/xen/xen-block.h" +#include "trace.h" + +static void xen_block_unrealize(XenDevice *xendev, Error **errp) +{ + XenBlockDevice *blockdev =3D XEN_BLOCK_DEVICE(xendev); + XenBlockDeviceClass *blockdev_class =3D + XEN_BLOCK_DEVICE_GET_CLASS(xendev); + const char *type =3D object_get_typename(OBJECT(blockdev)); + XenBlockVdev *vdev =3D &blockdev->props.vdev; + + if (vdev->type =3D=3D XEN_BLOCK_VDEV_TYPE_INVALID) { + return; + } + + trace_xen_block_unrealize(type, vdev->disk, vdev->partition); + + if (blockdev_class->unrealize) { + blockdev_class->unrealize(blockdev, errp); + } +} + +static void xen_block_realize(XenDevice *xendev, Error **errp) +{ + XenBlockDevice *blockdev =3D XEN_BLOCK_DEVICE(xendev); + XenBlockDeviceClass *blockdev_class =3D + XEN_BLOCK_DEVICE_GET_CLASS(xendev); + const char *type =3D object_get_typename(OBJECT(blockdev)); + XenBlockVdev *vdev =3D &blockdev->props.vdev; + Error *local_err =3D NULL; + + if (vdev->type =3D=3D XEN_BLOCK_VDEV_TYPE_INVALID) { + error_setg(errp, "vdev property not set"); + return; + } + + trace_xen_block_realize(type, vdev->disk, vdev->partition); + + if (blockdev_class->realize) { + blockdev_class->realize(blockdev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + } + } +} + +static char *disk_to_vbd_name(unsigned int disk) +{ + char *name, *prefix =3D (disk >=3D 26) ? + disk_to_vbd_name((disk / 26) - 1) : g_strdup(""); + + name =3D g_strdup_printf("%s%c", prefix, 'a' + disk % 26); + g_free(prefix); + + return name; +} + +static void xen_block_get_vdev(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + DeviceState *dev =3D DEVICE(obj); + Property *prop =3D opaque; + XenBlockVdev *vdev =3D qdev_get_prop_ptr(dev, prop); + char *str; + + switch (vdev->type) { + case XEN_BLOCK_VDEV_TYPE_DP: + str =3D g_strdup_printf("d%lup%lu", vdev->disk, vdev->partition); + break; + + case XEN_BLOCK_VDEV_TYPE_XVD: + case XEN_BLOCK_VDEV_TYPE_HD: + case XEN_BLOCK_VDEV_TYPE_SD: { + char *name =3D disk_to_vbd_name(vdev->disk); + + str =3D g_strdup_printf("%s%s%lu", + (vdev->type =3D=3D XEN_BLOCK_VDEV_TYPE_XVD) ? + "xvd" : + (vdev->type =3D=3D XEN_BLOCK_VDEV_TYPE_HD) ? + "hd" : + "sd", + name, vdev->partition); + g_free(name); + break; + } + default: + error_setg(errp, "invalid vdev type"); + return; + } + + visit_type_str(v, name, &str, errp); + g_free(str); +} + +static unsigned int vbd_name_to_disk(const char *name, const char **endp) +{ + unsigned int disk =3D 0; + + while (*name !=3D '\0') { + if (!g_ascii_isalpha(*name) || !g_ascii_islower(*name)) { + break; + } + + disk *=3D 26; + disk +=3D *name++ - 'a' + 1; + } + *endp =3D name; + + return disk - 1; +} + +static void xen_block_set_vdev(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + DeviceState *dev =3D DEVICE(obj); + Property *prop =3D opaque; + XenBlockVdev *vdev =3D qdev_get_prop_ptr(dev, prop); + Error *local_err =3D NULL; + char *str, *p; + const char *end; + + if (dev->realized) { + qdev_prop_set_after_realize(dev, name, errp); + return; + } + + visit_type_str(v, name, &str, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + p =3D strchr(str, 'd'); + if (!p) { + goto invalid; + } + + *p++ =3D '\0'; + if (*str =3D=3D '\0') { + vdev->type =3D XEN_BLOCK_VDEV_TYPE_DP; + } else if (strcmp(str, "xv") =3D=3D 0) { + vdev->type =3D XEN_BLOCK_VDEV_TYPE_XVD; + } else if (strcmp(str, "h") =3D=3D 0) { + vdev->type =3D XEN_BLOCK_VDEV_TYPE_HD; + } else if (strcmp(str, "s") =3D=3D 0) { + vdev->type =3D XEN_BLOCK_VDEV_TYPE_SD; + } else { + goto invalid; + } + + if (vdev->type =3D=3D XEN_BLOCK_VDEV_TYPE_DP) { + if (qemu_strtoul(p, &end, 10, &vdev->disk)) { + goto invalid; + } + + if (*end =3D=3D 'p') { + p =3D (char *) ++end; + if (*end =3D=3D '\0') { + goto invalid; + } + } + } else { + vdev->disk =3D vbd_name_to_disk(p, &end); + } + + if (*end !=3D '\0') { + p =3D (char *)end; + + if (qemu_strtoul(p, &end, 10, &vdev->partition)) { + goto invalid; + } + + if (*end !=3D '\0') { + goto invalid; + } + } else { + vdev->partition =3D 0; + } + + switch (vdev->type) { + case XEN_BLOCK_VDEV_TYPE_DP: + case XEN_BLOCK_VDEV_TYPE_XVD: + if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) { + vdev->number =3D (202 << 8) | (vdev->disk << 4) | + vdev->partition; + } else if (vdev->disk < (1 << 20) && vdev->partition < (1 << 8)) { + vdev->number =3D (1 << 28) | (vdev->disk << 8) | + vdev->partition; + } else { + goto invalid; + } + break; + + case XEN_BLOCK_VDEV_TYPE_HD: + if ((vdev->disk =3D=3D 0 || vdev->disk =3D=3D 1) && + vdev->partition < (1 << 6)) { + vdev->number =3D (3 << 8) | (vdev->disk << 6) | vdev->partitio= n; + } else if ((vdev->disk =3D=3D 2 || vdev->disk =3D=3D 3) && + vdev->partition < (1 << 6)) { + vdev->number =3D (22 << 8) | ((vdev->disk - 2) << 6) | + vdev->partition; + } else { + goto invalid; + } + break; + + case XEN_BLOCK_VDEV_TYPE_SD: + if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) { + vdev->number =3D (8 << 8) | (vdev->disk << 4) | vdev->partitio= n; + } else { + goto invalid; + } + break; + + default: + goto invalid; + } + + g_free(str); + return; + +invalid: + error_setg(errp, "invalid virtual disk specifier"); + + vdev->type =3D XEN_BLOCK_VDEV_TYPE_INVALID; + g_free(str); +} + +/* + * This property deals with 'vdev' names adhering to the Xen VBD naming + * scheme described in: + * + * https://xenbits.xen.org/docs/unstable/man/xen-vbd-interface.7.html + */ +const PropertyInfo xen_block_prop_vdev =3D { + .name =3D "str", + .description =3D "Virtual Disk specifier: d*p*/xvd*/hd*/sd*", + .get =3D xen_block_get_vdev, + .set =3D xen_block_set_vdev, +}; + +static Property xen_block_props[] =3D { + DEFINE_PROP("vdev", XenBlockDevice, props.vdev, + xen_block_prop_vdev, XenBlockVdev), + DEFINE_PROP_END_OF_LIST() +}; + +static void xen_block_class_init(ObjectClass *class, void *data) +{ + DeviceClass *dev_class =3D DEVICE_CLASS(class); + XenDeviceClass *xendev_class =3D XEN_DEVICE_CLASS(class); + + xendev_class->realize =3D xen_block_realize; + xendev_class->unrealize =3D xen_block_unrealize; + + dev_class->props =3D xen_block_props; +} + +static const TypeInfo xen_block_type_info =3D { + .name =3D TYPE_XEN_BLOCK_DEVICE, + .parent =3D TYPE_XEN_DEVICE, + .instance_size =3D sizeof(XenBlockDevice), + .abstract =3D true, + .class_size =3D sizeof(XenBlockDeviceClass), + .class_init =3D xen_block_class_init, +}; + +static void xen_disk_unrealize(XenBlockDevice *blockdev, Error **errp) +{ + trace_xen_disk_unrealize(); +} + +static void xen_disk_realize(XenBlockDevice *blockdev, Error **errp) +{ + trace_xen_disk_realize(); +} + +static void xen_disk_class_init(ObjectClass *class, void *data) +{ + DeviceClass *dev_class =3D DEVICE_CLASS(class); + XenBlockDeviceClass *blockdev_class =3D XEN_BLOCK_DEVICE_CLASS(class); + + blockdev_class->realize =3D xen_disk_realize; + blockdev_class->unrealize =3D xen_disk_unrealize; + + dev_class->desc =3D "Xen Disk Device"; +} + +static const TypeInfo xen_disk_type_info =3D { + .name =3D TYPE_XEN_DISK_DEVICE, + .parent =3D TYPE_XEN_BLOCK_DEVICE, + .instance_size =3D sizeof(XenDiskDevice), + .class_init =3D xen_disk_class_init, +}; + +static void xen_cdrom_unrealize(XenBlockDevice *blockdev, Error **errp) +{ + trace_xen_cdrom_unrealize(); +} + +static void xen_cdrom_realize(XenBlockDevice *blockdev, Error **errp) +{ + trace_xen_cdrom_realize(); +} + +static void xen_cdrom_class_init(ObjectClass *class, void *data) +{ + DeviceClass *dev_class =3D DEVICE_CLASS(class); + XenBlockDeviceClass *blockdev_class =3D XEN_BLOCK_DEVICE_CLASS(class); + + blockdev_class->realize =3D xen_cdrom_realize; + blockdev_class->unrealize =3D xen_cdrom_unrealize; + + dev_class->desc =3D "Xen CD-ROM Device"; +} + +static const TypeInfo xen_cdrom_type_info =3D { + .name =3D TYPE_XEN_CDROM_DEVICE, + .parent =3D TYPE_XEN_BLOCK_DEVICE, + .instance_size =3D sizeof(XenCDRomDevice), + .class_init =3D xen_cdrom_class_init, +}; + +static void xen_block_register_types(void) +{ + type_register_static(&xen_block_type_info); + type_register_static(&xen_disk_type_info); + type_register_static(&xen_cdrom_type_info); +} + +type_init(xen_block_register_types) diff --git a/include/hw/xen/xen-block.h b/include/hw/xen/xen-block.h new file mode 100644 index 0000000000..29413256e9 --- /dev/null +++ b/include/hw/xen/xen-block.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2018 Citrix Systems Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef HW_XEN_BLOCK_H +#define HW_XEN_BLOCK_H + +#include "hw/xen/xen-bus.h" + +typedef enum XenBlockVdevType { + XEN_BLOCK_VDEV_TYPE_INVALID, + XEN_BLOCK_VDEV_TYPE_DP, + XEN_BLOCK_VDEV_TYPE_XVD, + XEN_BLOCK_VDEV_TYPE_HD, + XEN_BLOCK_VDEV_TYPE_SD, + XEN_BLOCK_VDEV_TYPE__MAX +} XenBlockVdevType; + +typedef struct XenBlockVdev { + XenBlockVdevType type; + unsigned long disk; + unsigned long partition; + unsigned long number; +} XenBlockVdev; + +typedef struct XenBlockProperties { + XenBlockVdev vdev; +} XenBlockProperties; + +typedef struct XenBlockDevice { + XenDevice xendev; + XenBlockProperties props; +} XenBlockDevice; + +typedef void (*XenBlockDeviceRealize)(XenBlockDevice *blockdev, Error **er= rp); +typedef void (*XenBlockDeviceUnrealize)(XenBlockDevice *blockdev, Error **= errp); + +typedef struct XenBlockDeviceClass { + /*< private >*/ + XenDeviceClass parent_class; + /*< public >*/ + XenBlockDeviceRealize realize; + XenBlockDeviceUnrealize unrealize; +} XenBlockDeviceClass; + +#define TYPE_XEN_BLOCK_DEVICE "xen-block" +#define XEN_BLOCK_DEVICE(obj) \ + OBJECT_CHECK(XenBlockDevice, (obj), TYPE_XEN_BLOCK_DEVICE) +#define XEN_BLOCK_DEVICE_CLASS(class) \ + OBJECT_CLASS_CHECK(XenBlockDeviceClass, (class), TYPE_XEN_BLOCK_DEVIC= E) +#define XEN_BLOCK_DEVICE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(XenBlockDeviceClass, (obj), TYPE_XEN_BLOCK_DEVICE) + +typedef struct XenDiskDevice { + XenBlockDevice blockdev; +} XenDiskDevice; + +#define TYPE_XEN_DISK_DEVICE "xen-disk" +#define XEN_DISK_DEVICE(obj) \ + OBJECT_CHECK(XenDiskDevice, (obj), TYPE_XEN_DISK_DEVICE) + +typedef struct XenCDRomDevice { + XenBlockDevice blockdev; +} XenCDRomDevice; + +#define TYPE_XEN_CDROM_DEVICE "xen-cdrom" +#define XEN_CDROM_DEVICE(obj) \ + OBJECT_CHECK(XenCDRomDevice, (obj), TYPE_XEN_CDROM_DEVICE) + +#endif /* HW_XEN_BLOCK_H */ --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 15471285657895.793159981084273; Thu, 10 Jan 2019 05:56:05 -0800 (PST) Received: from localhost ([127.0.0.1]:54515 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghaoQ-0001PG-C6 for importer@patchew.org; Thu, 10 Jan 2019 08:55:58 -0500 Received: from eggs.gnu.org ([209.51.188.92]:53216) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghaim-00054D-QT for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghaij-0001gF-ML for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:08 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:11329) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghaij-0001fQ-AN for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:05 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75262367" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:48:58 +0000 Message-ID: <20190110134917.16425-7-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 06/25] xen: create xenstore areas for XenDevice-s 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant This patch adds a new source module, xen-bus-helper.c, which builds on basic libxenstore primitives to provide functions to create (setting permissions appropriately) and destroy xenstore areas, and functions to 'printf' and 'scanf' nodes therein. The main xen-bus code then uses these primitives [1] to initialize and destroy the frontend and backend areas for a XenDevice during realize and unrealize respectively. The 'xen-block' implementation is extended with a 'get_name' method that returns the VBD number. This number is required to 'name' the xenstore areas. NOTE: An exit handler is also added to make sure the xenstore areas are cleaned up if QEMU terminates without devices being unrealized. [1] The 'scanf' functions are actually not yet needed, but they will be needed by code delivered in subsequent patches. Signed-off-by: Paul Durrant Reviewed-by: Anthony Perard Signed-off-by: Anthony PERARD --- hw/block/xen-block.c | 9 + hw/xen/Makefile.objs | 2 +- hw/xen/trace-events | 12 +- hw/xen/xen-bus-helper.c | 150 +++++++++++++++ hw/xen/xen-bus.c | 321 +++++++++++++++++++++++++++++++- include/hw/xen/xen-bus-helper.h | 39 ++++ include/hw/xen/xen-bus.h | 12 ++ 7 files changed, 540 insertions(+), 5 deletions(-) create mode 100644 hw/xen/xen-bus-helper.c create mode 100644 include/hw/xen/xen-bus-helper.h diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c index 8e78b6a034..d27a2865bc 100644 --- a/hw/block/xen-block.c +++ b/hw/block/xen-block.c @@ -13,6 +13,14 @@ #include "hw/xen/xen-block.h" #include "trace.h" =20 +static char *xen_block_get_name(XenDevice *xendev, Error **errp) +{ + XenBlockDevice *blockdev =3D XEN_BLOCK_DEVICE(xendev); + XenBlockVdev *vdev =3D &blockdev->props.vdev; + + return g_strdup_printf("%lu", vdev->number); +} + static void xen_block_unrealize(XenDevice *xendev, Error **errp) { XenBlockDevice *blockdev =3D XEN_BLOCK_DEVICE(xendev); @@ -262,6 +270,7 @@ static void xen_block_class_init(ObjectClass *class, vo= id *data) DeviceClass *dev_class =3D DEVICE_CLASS(class); XenDeviceClass *xendev_class =3D XEN_DEVICE_CLASS(class); =20 + xendev_class->get_name =3D xen_block_get_name; xendev_class->realize =3D xen_block_realize; xendev_class->unrealize =3D xen_block_unrealize; =20 diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs index d9d6d7b4f9..77c0868190 100644 --- a/hw/xen/Makefile.objs +++ b/hw/xen/Makefile.objs @@ -1,5 +1,5 @@ # xen backend driver support -common-obj-$(CONFIG_XEN) +=3D xen-legacy-backend.o xen_devconfig.o xen_pvd= ev.o xen-common.o xen-bus.o +common-obj-$(CONFIG_XEN) +=3D xen-legacy-backend.o xen_devconfig.o xen_pvd= ev.o xen-common.o xen-bus.o xen-bus-helper.o =20 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) +=3D xen-host-pci-device.o obj-$(CONFIG_XEN_PCI_PASSTHROUGH) +=3D xen_pt.o xen_pt_config_init.o xen_p= t_graphics.o xen_pt_msi.o diff --git a/hw/xen/trace-events b/hw/xen/trace-events index 0172cd4e26..75dc226d75 100644 --- a/hw/xen/trace-events +++ b/hw/xen/trace-events @@ -16,5 +16,13 @@ xen_domid_restrict(int err) "err: %u" # include/hw/xen/xen-bus.c xen_bus_realize(void) "" xen_bus_unrealize(void) "" -xen_device_realize(const char *type) "type: %s" -xen_device_unrealize(const char *type) "type: %s" +xen_device_realize(const char *type, char *name) "type: %s name: %s" +xen_device_unrealize(const char *type, char *name) "type: %s name: %s" +xen_device_backend_state(const char *type, char *name, const char *state) = "type: %s name: %s -> %s" +xen_device_frontend_state(const char *type, char *name, const char *state)= "type: %s name: %s -> %s" + +# include/hw/xen/xen-bus-helper.c +xs_node_create(const char *node) "%s" +xs_node_destroy(const char *node) "%s" +xs_node_vprintf(char *path, char *value) "%s %s" +xs_node_vscanf(char *path, char *value) "%s %s" diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c new file mode 100644 index 0000000000..15b3ad8d78 --- /dev/null +++ b/hw/xen/xen-bus-helper.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2018 Citrix Systems Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "hw/hw.h" +#include "hw/sysbus.h" +#include "hw/xen/xen.h" +#include "hw/xen/xen-bus.h" +#include "hw/xen/xen-bus-helper.h" +#include "qapi/error.h" + +#include + +struct xs_state { + enum xenbus_state statenum; + const char *statestr; +}; +#define XS_STATE(state) { state, #state } + +static struct xs_state xs_state[] =3D { + XS_STATE(XenbusStateUnknown), + XS_STATE(XenbusStateInitialising), + XS_STATE(XenbusStateInitWait), + XS_STATE(XenbusStateInitialised), + XS_STATE(XenbusStateConnected), + XS_STATE(XenbusStateClosing), + XS_STATE(XenbusStateClosed), + XS_STATE(XenbusStateReconfiguring), + XS_STATE(XenbusStateReconfigured), +}; + +#undef XS_STATE + +const char *xs_strstate(enum xenbus_state state) +{ + unsigned int i; + + for (i =3D 0; i < ARRAY_SIZE(xs_state); i++) { + if (xs_state[i].statenum =3D=3D state) { + return xs_state[i].statestr; + } + } + + return "INVALID"; +} + +void xs_node_create(struct xs_handle *xsh, xs_transaction_t tid, + const char *node, struct xs_permissions perms[], + unsigned int nr_perms, Error **errp) +{ + trace_xs_node_create(node); + + if (!xs_write(xsh, tid, node, "", 0)) { + error_setg_errno(errp, errno, "failed to create node '%s'", node); + return; + } + + if (!xs_set_permissions(xsh, tid, node, perms, nr_perms)) { + error_setg_errno(errp, errno, "failed to set node '%s' permissions= ", + node); + } +} + +void xs_node_destroy(struct xs_handle *xsh, xs_transaction_t tid, + const char *node, Error **errp) +{ + trace_xs_node_destroy(node); + + if (!xs_rm(xsh, tid, node)) { + error_setg_errno(errp, errno, "failed to destroy node '%s'", node); + } +} + +void xs_node_vprintf(struct xs_handle *xsh, xs_transaction_t tid, + const char *node, const char *key, Error **errp, + const char *fmt, va_list ap) +{ + char *path, *value; + int len; + + path =3D (strlen(node) !=3D 0) ? g_strdup_printf("%s/%s", node, key) : + g_strdup(key); + len =3D g_vasprintf(&value, fmt, ap); + + trace_xs_node_vprintf(path, value); + + if (!xs_write(xsh, tid, path, value, len)) { + error_setg_errno(errp, errno, "failed to write '%s' to '%s'", + value, path); + } + + g_free(value); + g_free(path); +} + +void xs_node_printf(struct xs_handle *xsh, xs_transaction_t tid, + const char *node, const char *key, Error **errp, + const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + xs_node_vprintf(xsh, tid, node, key, errp, fmt, ap); + va_end(ap); +} + +int xs_node_vscanf(struct xs_handle *xsh, xs_transaction_t tid, + const char *node, const char *key, Error **errp, + const char *fmt, va_list ap) +{ + char *path, *value; + int rc; + + path =3D (strlen(node) !=3D 0) ? g_strdup_printf("%s/%s", node, key) : + g_strdup(key); + value =3D xs_read(xsh, tid, path, NULL); + + trace_xs_node_vscanf(path, value); + + if (value) { + rc =3D vsscanf(value, fmt, ap); + } else { + error_setg_errno(errp, errno, "failed to read from '%s'", + path); + rc =3D EOF; + } + + free(value); + g_free(path); + + return rc; +} + +int xs_node_scanf(struct xs_handle *xsh, xs_transaction_t tid, + const char *node, const char *key, Error **errp, + const char *fmt, ...) +{ + va_list ap; + int rc; + + va_start(ap, fmt); + rc =3D xs_node_vscanf(xsh, tid, node, key, errp, fmt, ap); + va_end(ap); + + return rc; +} diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index bc04da748b..843fda26a9 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -8,24 +8,102 @@ #include "qemu/osdep.h" #include "hw/hw.h" #include "hw/sysbus.h" +#include "hw/xen/xen.h" #include "hw/xen/xen-bus.h" +#include "hw/xen/xen-bus-helper.h" +#include "monitor/monitor.h" #include "qapi/error.h" +#include "sysemu/sysemu.h" #include "trace.h" =20 +static char *xen_device_get_backend_path(XenDevice *xendev) +{ + XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); + XenDeviceClass *xendev_class =3D XEN_DEVICE_GET_CLASS(xendev); + const char *type =3D object_get_typename(OBJECT(xendev)); + const char *backend =3D xendev_class->backend; + + if (!backend) { + backend =3D type; + } + + return g_strdup_printf("/local/domain/%u/backend/%s/%u/%s", + xenbus->backend_id, backend, xendev->frontend_i= d, + xendev->name); +} + +static char *xen_device_get_frontend_path(XenDevice *xendev) +{ + XenDeviceClass *xendev_class =3D XEN_DEVICE_GET_CLASS(xendev); + const char *type =3D object_get_typename(OBJECT(xendev)); + const char *device =3D xendev_class->device; + + if (!device) { + device =3D type; + } + + return g_strdup_printf("/local/domain/%u/device/%s/%s", + xendev->frontend_id, device, xendev->name); +} + +static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent) +{ + XenDevice *xendev =3D XEN_DEVICE(dev); + + monitor_printf(mon, "%*sname =3D '%s' frontend_id =3D %u\n", + indent, "", xendev->name, xendev->frontend_id); +} + +static char *xen_bus_get_dev_path(DeviceState *dev) +{ + return xen_device_get_backend_path(XEN_DEVICE(dev)); +} + static void xen_bus_unrealize(BusState *bus, Error **errp) { + XenBus *xenbus =3D XEN_BUS(bus); + trace_xen_bus_unrealize(); + + if (!xenbus->xsh) { + return; + } + + xs_close(xenbus->xsh); } =20 static void xen_bus_realize(BusState *bus, Error **errp) { + XenBus *xenbus =3D XEN_BUS(bus); + unsigned int domid; + trace_xen_bus_realize(); + + xenbus->xsh =3D xs_open(0); + if (!xenbus->xsh) { + error_setg_errno(errp, errno, "failed xs_open"); + goto fail; + } + + if (xs_node_scanf(xenbus->xsh, XBT_NULL, "", /* domain root node */ + "domid", NULL, "%u", &domid) =3D=3D 1) { + xenbus->backend_id =3D domid; + } else { + xenbus->backend_id =3D 0; /* Assume lack of node means dom0 */ + } + + return; + +fail: + xen_bus_unrealize(bus, &error_abort); } =20 static void xen_bus_class_init(ObjectClass *class, void *data) { BusClass *bus_class =3D BUS_CLASS(class); =20 + bus_class->print_dev =3D xen_bus_print_dev; + bus_class->get_dev_path =3D xen_bus_get_dev_path; bus_class->realize =3D xen_bus_realize; bus_class->unrealize =3D xen_bus_unrealize; } @@ -42,27 +120,241 @@ static const TypeInfo xen_bus_type_info =3D { }, }; =20 +static void xen_device_backend_printf(XenDevice *xendev, const char *key, + const char *fmt, ...) +{ + XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); + Error *local_err =3D NULL; + va_list ap; + + g_assert(xenbus->xsh); + + va_start(ap, fmt); + xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->backend_path, key, + &local_err, fmt, ap); + va_end(ap); + + if (local_err) { + error_report_err(local_err); + } +} + +static void xen_device_backend_set_state(XenDevice *xendev, + enum xenbus_state state) +{ + const char *type =3D object_get_typename(OBJECT(xendev)); + + if (xendev->backend_state =3D=3D state) { + return; + } + + trace_xen_device_backend_state(type, xendev->name, + xs_strstate(state)); + + xendev->backend_state =3D state; + xen_device_backend_printf(xendev, "state", "%u", state); +} + +static void xen_device_backend_create(XenDevice *xendev, Error **errp) +{ + XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); + struct xs_permissions perms[2]; + Error *local_err =3D NULL; + + xendev->backend_path =3D xen_device_get_backend_path(xendev); + + perms[0].id =3D xenbus->backend_id; + perms[0].perms =3D XS_PERM_NONE; + perms[1].id =3D xendev->frontend_id; + perms[1].perms =3D XS_PERM_READ; + + g_assert(xenbus->xsh); + + xs_node_create(xenbus->xsh, XBT_NULL, xendev->backend_path, perms, + ARRAY_SIZE(perms), &local_err); + if (local_err) { + error_propagate_prepend(errp, local_err, + "failed to create backend: "); + } +} + +static void xen_device_backend_destroy(XenDevice *xendev) +{ + XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); + Error *local_err =3D NULL; + + if (!xendev->backend_path) { + return; + } + + g_assert(xenbus->xsh); + + xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->backend_path, + &local_err); + g_free(xendev->backend_path); + xendev->backend_path =3D NULL; + + if (local_err) { + error_report_err(local_err); + } +} + +static void xen_device_frontend_printf(XenDevice *xendev, const char *key, + const char *fmt, ...) +{ + XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); + Error *local_err =3D NULL; + va_list ap; + + g_assert(xenbus->xsh); + + va_start(ap, fmt); + xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key, + &local_err, fmt, ap); + va_end(ap); + + if (local_err) { + error_report_err(local_err); + } +} + +static void xen_device_frontend_set_state(XenDevice *xendev, + enum xenbus_state state) +{ + const char *type =3D object_get_typename(OBJECT(xendev)); + + if (xendev->frontend_state =3D=3D state) { + return; + } + + trace_xen_device_frontend_state(type, xendev->name, + xs_strstate(state)); + + xendev->frontend_state =3D state; + xen_device_frontend_printf(xendev, "state", "%u", state); +} + +static void xen_device_frontend_create(XenDevice *xendev, Error **errp) +{ + XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); + struct xs_permissions perms[2]; + Error *local_err =3D NULL; + + xendev->frontend_path =3D xen_device_get_frontend_path(xendev); + + perms[0].id =3D xendev->frontend_id; + perms[0].perms =3D XS_PERM_NONE; + perms[1].id =3D xenbus->backend_id; + perms[1].perms =3D XS_PERM_READ | XS_PERM_WRITE; + + g_assert(xenbus->xsh); + + xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path, perms, + ARRAY_SIZE(perms), &local_err); + if (local_err) { + error_propagate_prepend(errp, local_err, + "failed to create frontend: "); + } +} + +static void xen_device_frontend_destroy(XenDevice *xendev) +{ + XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); + Error *local_err =3D NULL; + + if (!xendev->frontend_path) { + return; + } + + g_assert(xenbus->xsh); + + xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->frontend_path, + &local_err); + g_free(xendev->frontend_path); + xendev->frontend_path =3D NULL; + + if (local_err) { + error_report_err(local_err); + } +} + static void xen_device_unrealize(DeviceState *dev, Error **errp) { XenDevice *xendev =3D XEN_DEVICE(dev); XenDeviceClass *xendev_class =3D XEN_DEVICE_GET_CLASS(xendev); const char *type =3D object_get_typename(OBJECT(xendev)); =20 - trace_xen_device_unrealize(type); + if (!xendev->name) { + return; + } + + trace_xen_device_unrealize(type, xendev->name); + + if (xendev->exit.notify) { + qemu_remove_exit_notifier(&xendev->exit); + xendev->exit.notify =3D NULL; + } =20 if (xendev_class->unrealize) { xendev_class->unrealize(xendev, errp); } + + xen_device_frontend_destroy(xendev); + xen_device_backend_destroy(xendev); + + g_free(xendev->name); + xendev->name =3D NULL; +} + +static void xen_device_exit(Notifier *n, void *data) +{ + XenDevice *xendev =3D container_of(n, XenDevice, exit); + + xen_device_unrealize(DEVICE(xendev), &error_abort); } =20 static void xen_device_realize(DeviceState *dev, Error **errp) { XenDevice *xendev =3D XEN_DEVICE(dev); XenDeviceClass *xendev_class =3D XEN_DEVICE_GET_CLASS(xendev); + XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); const char *type =3D object_get_typename(OBJECT(xendev)); Error *local_err =3D NULL; =20 - trace_xen_device_realize(type); + if (xendev->frontend_id =3D=3D DOMID_INVALID) { + xendev->frontend_id =3D xen_domid; + } + + if (xendev->frontend_id >=3D DOMID_FIRST_RESERVED) { + error_setg(errp, "invalid frontend-id"); + goto unrealize; + } + + if (!xendev_class->get_name) { + error_setg(errp, "get_name method not implemented"); + goto unrealize; + } + + xendev->name =3D xendev_class->get_name(xendev, &local_err); + if (local_err) { + error_propagate_prepend(errp, local_err, + "failed to get device name: "); + goto unrealize; + } + + trace_xen_device_realize(type, xendev->name); + + xen_device_backend_create(xendev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto unrealize; + } + + xen_device_frontend_create(xendev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto unrealize; + } =20 if (xendev_class->realize) { xendev_class->realize(xendev, &local_err); @@ -72,18 +364,43 @@ static void xen_device_realize(DeviceState *dev, Error= **errp) } } =20 + xen_device_backend_printf(xendev, "frontend", "%s", + xendev->frontend_path); + xen_device_backend_printf(xendev, "frontend-id", "%u", + xendev->frontend_id); + xen_device_backend_printf(xendev, "online", "%u", 1); + xen_device_backend_printf(xendev, "hotplug-status", "connected"); + + xen_device_backend_set_state(xendev, XenbusStateInitWait); + + xen_device_frontend_printf(xendev, "backend", "%s", + xendev->backend_path); + xen_device_frontend_printf(xendev, "backend-id", "%u", + xenbus->backend_id); + + xen_device_frontend_set_state(xendev, XenbusStateInitialising); + + xendev->exit.notify =3D xen_device_exit; + qemu_add_exit_notifier(&xendev->exit); return; =20 unrealize: xen_device_unrealize(dev, &error_abort); } =20 +static Property xen_device_props[] =3D { + DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id, + DOMID_INVALID), + DEFINE_PROP_END_OF_LIST() +}; + static void xen_device_class_init(ObjectClass *class, void *data) { DeviceClass *dev_class =3D DEVICE_CLASS(class); =20 dev_class->realize =3D xen_device_realize; dev_class->unrealize =3D xen_device_unrealize; + dev_class->props =3D xen_device_props; dev_class->bus_type =3D TYPE_XEN_BUS; } =20 diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-helpe= r.h new file mode 100644 index 0000000000..5cd9c3d759 --- /dev/null +++ b/include/hw/xen/xen-bus-helper.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Citrix Systems Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef HW_XEN_BUS_HELPER_H +#define HW_XEN_BUS_HELPER_H + +#include "hw/xen/xen_common.h" + +const char *xs_strstate(enum xenbus_state state); + +void xs_node_create(struct xs_handle *xsh, xs_transaction_t tid, + const char *node, struct xs_permissions perms[], + unsigned int nr_perms, Error **errp); +void xs_node_destroy(struct xs_handle *xsh, xs_transaction_t tid, + const char *node, Error **errp); + +/* Write to node/key unless node is empty, in which case write to key */ +void xs_node_vprintf(struct xs_handle *xsh, xs_transaction_t tid, + const char *node, const char *key, Error **errp, + const char *fmt, va_list ap) + GCC_FMT_ATTR(6, 0); +void xs_node_printf(struct xs_handle *xsh, xs_transaction_t tid, + const char *node, const char *key, Error **errp, + const char *fmt, ...) + GCC_FMT_ATTR(6, 7); + +/* Read from node/key unless node is empty, in which case read from key */ +int xs_node_vscanf(struct xs_handle *xsh, xs_transaction_t tid, + const char *node, const char *key, Error **errp, + const char *fmt, va_list ap); +int xs_node_scanf(struct xs_handle *xsh, xs_transaction_t tid, + const char *node, const char *key, Error **errp, + const char *fmt, ...); + +#endif /* HW_XEN_BUS_HELPER_H */ diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h index 0cb12464ce..85a75d8dec 100644 --- a/include/hw/xen/xen-bus.h +++ b/include/hw/xen/xen-bus.h @@ -8,12 +8,19 @@ #ifndef HW_XEN_BUS_H #define HW_XEN_BUS_H =20 +#include "hw/xen/xen_common.h" #include "hw/sysbus.h" =20 typedef struct XenDevice { DeviceState qdev; + domid_t frontend_id; + char *name; + char *backend_path, *frontend_path; + enum xenbus_state backend_state, frontend_state; + Notifier exit; } XenDevice; =20 +typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp); typedef void (*XenDeviceRealize)(XenDevice *xendev, Error **errp); typedef void (*XenDeviceUnrealize)(XenDevice *xendev, Error **errp); =20 @@ -21,6 +28,9 @@ typedef struct XenDeviceClass { /*< private >*/ DeviceClass parent_class; /*< public >*/ + const char *backend; + const char *device; + XenDeviceGetName get_name; XenDeviceRealize realize; XenDeviceUnrealize unrealize; } XenDeviceClass; @@ -35,6 +45,8 @@ typedef struct XenDeviceClass { =20 typedef struct XenBus { BusState qbus; + domid_t backend_id; + struct xs_handle *xsh; } XenBus; =20 typedef struct XenBusClass { --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547128411260236.1561745683781; Thu, 10 Jan 2019 05:53:31 -0800 (PST) Received: from localhost ([127.0.0.1]:53816 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gham2-0007DS-4k for importer@patchew.org; Thu, 10 Jan 2019 08:53:30 -0500 Received: from eggs.gnu.org ([209.51.188.92]:53208) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghaim-000549-7n for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghaij-0001g6-G2 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:08 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:11315) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghaij-0001eA-6s for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:05 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75262366" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:48:59 +0000 Message-ID: <20190110134917.16425-8-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 07/25] xen: add xenstore watcher infrastructure 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant A Xen PV frontend communicates its state to the PV backend by writing to the 'state' key in the frontend area in xenstore. It is therefore necessary for a XenDevice implementation to be notified whenever the value of this key changes. This patch adds code to do this as follows: - an 'fd handler' is registered on the libxenstore handle which will be triggered whenever a 'watch' event occurs - primitives are added to xen-bus-helper to add or remove watch events - a list of Notifier objects is added to XenBus to provide a mechanism to call the appropriate 'watch handler' when its associated event occurs The xen-block implementation is extended with a 'frontend_changed' method, which calls as-yet stub 'connect' and 'disconnect' functions when the relevant frontend state transitions occur. A subsequent patch will supply a full implementation for these functions. Signed-off-by: Paul Durrant Reviewed-by: Anthony Perard Signed-off-by: Anthony PERARD --- hw/block/trace-events | 2 + hw/block/xen-block.c | 70 +++++++++++ hw/xen/trace-events | 6 + hw/xen/xen-bus-helper.c | 34 +++++ hw/xen/xen-bus.c | 211 +++++++++++++++++++++++++++++++- include/hw/xen/xen-bus-helper.h | 6 + include/hw/xen/xen-bus.h | 15 +++ 7 files changed, 342 insertions(+), 2 deletions(-) diff --git a/hw/block/trace-events b/hw/block/trace-events index 4afbd62a88..89e258319c 100644 --- a/hw/block/trace-events +++ b/hw/block/trace-events @@ -130,6 +130,8 @@ xen_disk_free(char *name) "%s" =20 # hw/block/xen-block.c xen_block_realize(const char *type, uint32_t disk, uint32_t partition) "%s= d%up%u" +xen_block_connect(const char *type, uint32_t disk, uint32_t partition) "%s= d%up%u" +xen_block_disconnect(const char *type, uint32_t disk, uint32_t partition) = "%s d%up%u" xen_block_unrealize(const char *type, uint32_t disk, uint32_t partition) "= %s d%up%u" xen_disk_realize(void) "" xen_disk_unrealize(void) "" diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c index d27a2865bc..3a963b0383 100644 --- a/hw/block/xen-block.c +++ b/hw/block/xen-block.c @@ -21,6 +21,24 @@ static char *xen_block_get_name(XenDevice *xendev, Error= **errp) return g_strdup_printf("%lu", vdev->number); } =20 +static void xen_block_disconnect(XenDevice *xendev, Error **errp) +{ + XenBlockDevice *blockdev =3D XEN_BLOCK_DEVICE(xendev); + const char *type =3D object_get_typename(OBJECT(blockdev)); + XenBlockVdev *vdev =3D &blockdev->props.vdev; + + trace_xen_block_disconnect(type, vdev->disk, vdev->partition); +} + +static void xen_block_connect(XenDevice *xendev, Error **errp) +{ + XenBlockDevice *blockdev =3D XEN_BLOCK_DEVICE(xendev); + const char *type =3D object_get_typename(OBJECT(blockdev)); + XenBlockVdev *vdev =3D &blockdev->props.vdev; + + trace_xen_block_connect(type, vdev->disk, vdev->partition); +} + static void xen_block_unrealize(XenDevice *xendev, Error **errp) { XenBlockDevice *blockdev =3D XEN_BLOCK_DEVICE(xendev); @@ -35,6 +53,9 @@ static void xen_block_unrealize(XenDevice *xendev, Error = **errp) =20 trace_xen_block_unrealize(type, vdev->disk, vdev->partition); =20 + /* Disconnect from the frontend in case this has not already happened = */ + xen_block_disconnect(xendev, NULL); + if (blockdev_class->unrealize) { blockdev_class->unrealize(blockdev, errp); } @@ -64,6 +85,54 @@ static void xen_block_realize(XenDevice *xendev, Error *= *errp) } } =20 +static void xen_block_frontend_changed(XenDevice *xendev, + enum xenbus_state frontend_state, + Error **errp) +{ + enum xenbus_state backend_state =3D xen_device_backend_get_state(xende= v); + Error *local_err =3D NULL; + + switch (frontend_state) { + case XenbusStateInitialised: + case XenbusStateConnected: + if (backend_state =3D=3D XenbusStateConnected) { + break; + } + + xen_block_disconnect(xendev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + break; + } + + xen_block_connect(xendev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + break; + } + + xen_device_backend_set_state(xendev, XenbusStateConnected); + break; + + case XenbusStateClosing: + xen_device_backend_set_state(xendev, XenbusStateClosing); + break; + + case XenbusStateClosed: + xen_block_disconnect(xendev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + break; + } + + xen_device_backend_set_state(xendev, XenbusStateClosed); + break; + + default: + break; + } +} + static char *disk_to_vbd_name(unsigned int disk) { char *name, *prefix =3D (disk >=3D 26) ? @@ -272,6 +341,7 @@ static void xen_block_class_init(ObjectClass *class, vo= id *data) =20 xendev_class->get_name =3D xen_block_get_name; xendev_class->realize =3D xen_block_realize; + xendev_class->frontend_changed =3D xen_block_frontend_changed; xendev_class->unrealize =3D xen_block_unrealize; =20 dev_class->props =3D xen_block_props; diff --git a/hw/xen/trace-events b/hw/xen/trace-events index 75dc226d75..22055b5894 100644 --- a/hw/xen/trace-events +++ b/hw/xen/trace-events @@ -16,13 +16,19 @@ xen_domid_restrict(int err) "err: %u" # include/hw/xen/xen-bus.c xen_bus_realize(void) "" xen_bus_unrealize(void) "" +xen_bus_add_watch(const char *node, const char *key, char *token) "node: %= s key: %s token: %s" +xen_bus_remove_watch(const char *node, const char *key, char *token) "node= : %s key: %s token: %s" +xen_bus_watch(const char *token) "token: %s" xen_device_realize(const char *type, char *name) "type: %s name: %s" xen_device_unrealize(const char *type, char *name) "type: %s name: %s" xen_device_backend_state(const char *type, char *name, const char *state) = "type: %s name: %s -> %s" xen_device_frontend_state(const char *type, char *name, const char *state)= "type: %s name: %s -> %s" +xen_device_frontend_changed(const char *type, char *name) "type: %s name: = %s" =20 # include/hw/xen/xen-bus-helper.c xs_node_create(const char *node) "%s" xs_node_destroy(const char *node) "%s" xs_node_vprintf(char *path, char *value) "%s %s" xs_node_vscanf(char *path, char *value) "%s %s" +xs_node_watch(char *path) "%s" +xs_node_unwatch(char *path) "%s" diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c index 15b3ad8d78..5f7a4b2612 100644 --- a/hw/xen/xen-bus-helper.c +++ b/hw/xen/xen-bus-helper.c @@ -148,3 +148,37 @@ int xs_node_scanf(struct xs_handle *xsh, xs_transacti= on_t tid, =20 return rc; } + +void xs_node_watch(struct xs_handle *xsh, const char *node, const char *ke= y, + char *token, Error **errp) +{ + char *path; + + path =3D (strlen(node) !=3D 0) ? g_strdup_printf("%s/%s", node, key) : + g_strdup(key); + + trace_xs_node_watch(path); + + if (!xs_watch(xsh, path, token)) { + error_setg_errno(errp, errno, "failed to watch node '%s'", path); + } + + g_free(path); +} + +void xs_node_unwatch(struct xs_handle *xsh, const char *node, + const char *key, const char *token, Error **errp) +{ + char *path; + + path =3D (strlen(node) !=3D 0) ? g_strdup_printf("%s/%s", node, key) : + g_strdup(key); + + trace_xs_node_unwatch(path); + + if (!xs_unwatch(xsh, path, token)) { + error_setg_errno(errp, errno, "failed to unwatch node '%s'", path); + } + + g_free(path); +} diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index 843fda26a9..5e19592190 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -6,6 +6,8 @@ */ =20 #include "qemu/osdep.h" +#include "qemu/main-loop.h" +#include "qemu/uuid.h" #include "hw/hw.h" #include "hw/sysbus.h" #include "hw/xen/xen.h" @@ -59,6 +61,87 @@ static char *xen_bus_get_dev_path(DeviceState *dev) return xen_device_get_backend_path(XEN_DEVICE(dev)); } =20 +struct XenWatch { + char *node, *key; + char *token; + XenWatchHandler handler; + void *opaque; + Notifier notifier; +}; + +static void watch_notify(Notifier *n, void *data) +{ + XenWatch *watch =3D container_of(n, XenWatch, notifier); + const char *token =3D data; + + if (!strcmp(watch->token, token)) { + watch->handler(watch->opaque); + } +} + +static XenWatch *new_watch(const char *node, const char *key, + XenWatchHandler handler, void *opaque) +{ + XenWatch *watch =3D g_new0(XenWatch, 1); + QemuUUID uuid; + + qemu_uuid_generate(&uuid); + + watch->token =3D qemu_uuid_unparse_strdup(&uuid); + watch->node =3D g_strdup(node); + watch->key =3D g_strdup(key); + watch->handler =3D handler; + watch->opaque =3D opaque; + watch->notifier.notify =3D watch_notify; + + return watch; +} + +static void free_watch(XenWatch *watch) +{ + g_free(watch->token); + g_free(watch->key); + g_free(watch->node); + + g_free(watch); +} + +static XenWatch *xen_bus_add_watch(XenBus *xenbus, const char *node, + const char *key, XenWatchHandler handle= r, + void *opaque, Error **errp) +{ + XenWatch *watch =3D new_watch(node, key, handler, opaque); + Error *local_err =3D NULL; + + trace_xen_bus_add_watch(watch->node, watch->key, watch->token); + + notifier_list_add(&xenbus->watch_notifiers, &watch->notifier); + + xs_node_watch(xenbus->xsh, node, key, watch->token, &local_err); + if (local_err) { + error_propagate(errp, local_err); + + notifier_remove(&watch->notifier); + free_watch(watch); + + return NULL; + } + + return watch; +} + +static void xen_bus_remove_watch(XenBus *xenbus, XenWatch *watch, + Error **errp) +{ + trace_xen_bus_remove_watch(watch->node, watch->key, watch->token); + + xs_node_unwatch(xenbus->xsh, watch->node, watch->key, watch->token, + errp); + + notifier_remove(&watch->notifier); + free_watch(watch); +} + static void xen_bus_unrealize(BusState *bus, Error **errp) { XenBus *xenbus =3D XEN_BUS(bus); @@ -69,9 +152,33 @@ static void xen_bus_unrealize(BusState *bus, Error **er= rp) return; } =20 + qemu_set_fd_handler(xs_fileno(xenbus->xsh), NULL, NULL, NULL); + xs_close(xenbus->xsh); } =20 +static void xen_bus_watch(void *opaque) +{ + XenBus *xenbus =3D opaque; + char **v; + const char *token; + + g_assert(xenbus->xsh); + + v =3D xs_check_watch(xenbus->xsh); + if (!v) { + return; + } + + token =3D v[XS_WATCH_TOKEN]; + + trace_xen_bus_watch(token); + + notifier_list_notify(&xenbus->watch_notifiers, (void *)token); + + free(v); +} + static void xen_bus_realize(BusState *bus, Error **errp) { XenBus *xenbus =3D XEN_BUS(bus); @@ -92,6 +199,9 @@ static void xen_bus_realize(BusState *bus, Error **errp) xenbus->backend_id =3D 0; /* Assume lack of node means dom0 */ } =20 + notifier_list_init(&xenbus->watch_notifiers); + qemu_set_fd_handler(xs_fileno(xenbus->xsh), xen_bus_watch, NULL, + xenbus); return; =20 fail: @@ -139,8 +249,25 @@ static void xen_device_backend_printf(XenDevice *xende= v, const char *key, } } =20 -static void xen_device_backend_set_state(XenDevice *xendev, - enum xenbus_state state) +static int xen_device_backend_scanf(XenDevice *xendev, const char *key, + const char *fmt, ...) +{ + XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); + va_list ap; + int rc; + + g_assert(xenbus->xsh); + + va_start(ap, fmt); + rc =3D xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->backend_path, key, + NULL, fmt, ap); + va_end(ap); + + return rc; +} + +void xen_device_backend_set_state(XenDevice *xendev, + enum xenbus_state state) { const char *type =3D object_get_typename(OBJECT(xendev)); =20 @@ -155,6 +282,11 @@ static void xen_device_backend_set_state(XenDevice *xe= ndev, xen_device_backend_printf(xendev, "state", "%u", state); } =20 +enum xenbus_state xen_device_backend_get_state(XenDevice *xendev) +{ + return xendev->backend_state; +} + static void xen_device_backend_create(XenDevice *xendev, Error **errp) { XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); @@ -218,6 +350,23 @@ static void xen_device_frontend_printf(XenDevice *xend= ev, const char *key, } } =20 +static int xen_device_frontend_scanf(XenDevice *xendev, const char *key, + const char *fmt, ...) +{ + XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); + va_list ap; + int rc; + + g_assert(xenbus->xsh); + + va_start(ap, fmt); + rc =3D xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->frontend_path, ke= y, + NULL, fmt, ap); + va_end(ap); + + return rc; +} + static void xen_device_frontend_set_state(XenDevice *xendev, enum xenbus_state state) { @@ -234,6 +383,50 @@ static void xen_device_frontend_set_state(XenDevice *x= endev, xen_device_frontend_printf(xendev, "state", "%u", state); } =20 +static void xen_device_frontend_changed(void *opaque) +{ + XenDevice *xendev =3D opaque; + XenDeviceClass *xendev_class =3D XEN_DEVICE_GET_CLASS(xendev); + const char *type =3D object_get_typename(OBJECT(xendev)); + enum xenbus_state state; + + trace_xen_device_frontend_changed(type, xendev->name); + + if (xen_device_frontend_scanf(xendev, "state", "%u", &state) !=3D 1) { + state =3D XenbusStateUnknown; + } + + xen_device_frontend_set_state(xendev, state); + + if (xendev_class->frontend_changed) { + Error *local_err =3D NULL; + + xendev_class->frontend_changed(xendev, state, &local_err); + + if (local_err) { + error_reportf_err(local_err, "frontend change error: "); + } + } + + /* + * If a backend is still 'online' then its state should be cycled + * back round to InitWait in order for a new frontend instance to + * connect. This may happen when, for example, a frontend driver is + * re-installed or updated. + */ + if (xendev->backend_state =3D=3D XenbusStateClosed) { + unsigned int online; + + if (xen_device_backend_scanf(xendev, "online", "%u", &online) !=3D= 1) { + online =3D 0; + } + + if (online) { + xen_device_backend_set_state(xendev, XenbusStateInitWait); + } + } +} + static void xen_device_frontend_create(XenDevice *xendev, Error **errp) { XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); @@ -254,6 +447,15 @@ static void xen_device_frontend_create(XenDevice *xend= ev, Error **errp) if (local_err) { error_propagate_prepend(errp, local_err, "failed to create frontend: "); + return; + } + + xendev->frontend_state_watch =3D + xen_bus_add_watch(xenbus, xendev->frontend_path, "state", + xen_device_frontend_changed, xendev, &local_err); + if (local_err) { + error_propagate_prepend(errp, local_err, + "failed to watch frontend state: "); } } =20 @@ -262,6 +464,11 @@ static void xen_device_frontend_destroy(XenDevice *xen= dev) XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); Error *local_err =3D NULL; =20 + if (xendev->frontend_state_watch) { + xen_bus_remove_watch(xenbus, xendev->frontend_state_watch, NULL); + xendev->frontend_state_watch =3D NULL; + } + if (!xendev->frontend_path) { return; } diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-helpe= r.h index 5cd9c3d759..4c0f747445 100644 --- a/include/hw/xen/xen-bus-helper.h +++ b/include/hw/xen/xen-bus-helper.h @@ -36,4 +36,10 @@ int xs_node_scanf(struct xs_handle *xsh, xs_transaction= _t tid, const char *node, const char *key, Error **errp, const char *fmt, ...); =20 +/* Watch node/key unless node is empty, in which case watch key */ +void xs_node_watch(struct xs_handle *xsh, const char *node, const char *ke= y, + char *token, Error **errp); +void xs_node_unwatch(struct xs_handle *xsh, const char *node, const char *= key, + const char *token, Error **errp); + #endif /* HW_XEN_BUS_HELPER_H */ diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h index 85a75d8dec..df73674fcd 100644 --- a/include/hw/xen/xen-bus.h +++ b/include/hw/xen/xen-bus.h @@ -10,6 +10,11 @@ =20 #include "hw/xen/xen_common.h" #include "hw/sysbus.h" +#include "qemu/notify.h" + +typedef void (*XenWatchHandler)(void *opaque); + +typedef struct XenWatch XenWatch; =20 typedef struct XenDevice { DeviceState qdev; @@ -18,10 +23,14 @@ typedef struct XenDevice { char *backend_path, *frontend_path; enum xenbus_state backend_state, frontend_state; Notifier exit; + XenWatch *frontend_state_watch; } XenDevice; =20 typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp); typedef void (*XenDeviceRealize)(XenDevice *xendev, Error **errp); +typedef void (*XenDeviceFrontendChanged)(XenDevice *xendev, + enum xenbus_state frontend_state, + Error **errp); typedef void (*XenDeviceUnrealize)(XenDevice *xendev, Error **errp); =20 typedef struct XenDeviceClass { @@ -32,6 +41,7 @@ typedef struct XenDeviceClass { const char *device; XenDeviceGetName get_name; XenDeviceRealize realize; + XenDeviceFrontendChanged frontend_changed; XenDeviceUnrealize unrealize; } XenDeviceClass; =20 @@ -47,6 +57,7 @@ typedef struct XenBus { BusState qbus; domid_t backend_id; struct xs_handle *xsh; + NotifierList watch_notifiers; } XenBus; =20 typedef struct XenBusClass { @@ -64,4 +75,8 @@ typedef struct XenBusClass { =20 void xen_bus_init(void); =20 +void xen_device_backend_set_state(XenDevice *xendev, + enum xenbus_state state); +enum xenbus_state xen_device_backend_get_state(XenDevice *xendev); + #endif /* HW_XEN_BUS_H */ --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547128500400505.96057380512684; Thu, 10 Jan 2019 05:55:00 -0800 (PST) Received: from localhost ([127.0.0.1]:54205 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghanT-0000Xu-Bt for importer@patchew.org; Thu, 10 Jan 2019 08:54:59 -0500 Received: from eggs.gnu.org ([209.51.188.92]:53175) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghaik-00053c-Hr for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:08 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghaij-0001fs-5d for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:06 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:11318) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghaii-0001ep-U3 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:05 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75262364" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:00 +0000 Message-ID: <20190110134917.16425-9-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 08/25] xen: add grant table interface for XenDevice-s 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant The legacy PV backend infrastructure provides functions to map, unmap and copy pages granted by frontends. Similar functionality will be required by XenDevice implementations so this patch adds the necessary support. Signed-off-by: Paul Durrant Reviewed-by: Anthony Perard Signed-off-by: Anthony PERARD --- hw/xen/xen-bus.c | 146 +++++++++++++++++++++++++++++++++++++++ include/hw/xen/xen-bus.h | 25 +++++++ 2 files changed, 171 insertions(+) diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index 5e19592190..faa9fd3577 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -485,6 +485,138 @@ static void xen_device_frontend_destroy(XenDevice *xe= ndev) } } =20 +void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs, + Error **errp) +{ + if (xengnttab_set_max_grants(xendev->xgth, nr_refs)) { + error_setg_errno(errp, errno, "xengnttab_set_max_grants failed"); + } +} + +void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs, + unsigned int nr_refs, int prot, + Error **errp) +{ + void *map =3D xengnttab_map_domain_grant_refs(xendev->xgth, nr_refs, + xendev->frontend_id, refs, + prot); + + if (!map) { + error_setg_errno(errp, errno, + "xengnttab_map_domain_grant_refs failed"); + } + + return map; +} + +void xen_device_unmap_grant_refs(XenDevice *xendev, void *map, + unsigned int nr_refs, Error **errp) +{ + if (xengnttab_unmap(xendev->xgth, map, nr_refs)) { + error_setg_errno(errp, errno, "xengnttab_unmap failed"); + } +} + +static void compat_copy_grant_refs(XenDevice *xendev, bool to_domain, + XenDeviceGrantCopySegment segs[], + unsigned int nr_segs, Error **errp) +{ + uint32_t *refs =3D g_new(uint32_t, nr_segs); + int prot =3D to_domain ? PROT_WRITE : PROT_READ; + void *map; + unsigned int i; + + for (i =3D 0; i < nr_segs; i++) { + XenDeviceGrantCopySegment *seg =3D &segs[i]; + + refs[i] =3D to_domain ? seg->dest.foreign.ref : + seg->source.foreign.ref; + } + + map =3D xengnttab_map_domain_grant_refs(xendev->xgth, nr_segs, + xendev->frontend_id, refs, + prot); + if (!map) { + error_setg_errno(errp, errno, + "xengnttab_map_domain_grant_refs failed"); + goto done; + } + + for (i =3D 0; i < nr_segs; i++) { + XenDeviceGrantCopySegment *seg =3D &segs[i]; + void *page =3D map + (i * XC_PAGE_SIZE); + + if (to_domain) { + memcpy(page + seg->dest.foreign.offset, seg->source.virt, + seg->len); + } else { + memcpy(seg->dest.virt, page + seg->source.foreign.offset, + seg->len); + } + } + + if (xengnttab_unmap(xendev->xgth, map, nr_segs)) { + error_setg_errno(errp, errno, "xengnttab_unmap failed"); + } + +done: + g_free(refs); +} + +void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain, + XenDeviceGrantCopySegment segs[], + unsigned int nr_segs, Error **errp) +{ + xengnttab_grant_copy_segment_t *xengnttab_segs; + unsigned int i; + + if (!xendev->feature_grant_copy) { + compat_copy_grant_refs(xendev, to_domain, segs, nr_segs, errp); + return; + } + + xengnttab_segs =3D g_new0(xengnttab_grant_copy_segment_t, nr_segs); + + for (i =3D 0; i < nr_segs; i++) { + XenDeviceGrantCopySegment *seg =3D &segs[i]; + xengnttab_grant_copy_segment_t *xengnttab_seg =3D &xengnttab_segs[= i]; + + if (to_domain) { + xengnttab_seg->flags =3D GNTCOPY_dest_gref; + xengnttab_seg->dest.foreign.domid =3D xendev->frontend_id; + xengnttab_seg->dest.foreign.ref =3D seg->dest.foreign.ref; + xengnttab_seg->dest.foreign.offset =3D seg->dest.foreign.offse= t; + xengnttab_seg->source.virt =3D seg->source.virt; + } else { + xengnttab_seg->flags =3D GNTCOPY_source_gref; + xengnttab_seg->source.foreign.domid =3D xendev->frontend_id; + xengnttab_seg->source.foreign.ref =3D seg->source.foreign.ref; + xengnttab_seg->source.foreign.offset =3D + seg->source.foreign.offset; + xengnttab_seg->dest.virt =3D seg->dest.virt; + } + + xengnttab_seg->len =3D seg->len; + } + + if (xengnttab_grant_copy(xendev->xgth, nr_segs, xengnttab_segs)) { + error_setg_errno(errp, errno, "xengnttab_grant_copy failed"); + goto done; + } + + for (i =3D 0; i < nr_segs; i++) { + xengnttab_grant_copy_segment_t *xengnttab_seg =3D &xengnttab_segs[= i]; + + if (xengnttab_seg->status !=3D GNTST_okay) { + error_setg(errp, "xengnttab_grant_copy seg[%u] failed", i); + break; + } + } + +done: + g_free(xengnttab_segs); +} + static void xen_device_unrealize(DeviceState *dev, Error **errp) { XenDevice *xendev =3D XEN_DEVICE(dev); @@ -509,6 +641,11 @@ static void xen_device_unrealize(DeviceState *dev, Err= or **errp) xen_device_frontend_destroy(xendev); xen_device_backend_destroy(xendev); =20 + if (xendev->xgth) { + xengnttab_close(xendev->xgth); + xendev->xgth =3D NULL; + } + g_free(xendev->name); xendev->name =3D NULL; } @@ -551,6 +688,15 @@ static void xen_device_realize(DeviceState *dev, Error= **errp) =20 trace_xen_device_realize(type, xendev->name); =20 + xendev->xgth =3D xengnttab_open(NULL, 0); + if (!xendev->xgth) { + error_setg_errno(errp, errno, "failed xengnttab_open"); + goto unrealize; + } + + xendev->feature_grant_copy =3D + (xengnttab_grant_copy(xendev->xgth, 0, NULL) =3D=3D 0); + xen_device_backend_create(xendev, &local_err); if (local_err) { error_propagate(errp, local_err); diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h index df73674fcd..63a09b67ee 100644 --- a/include/hw/xen/xen-bus.h +++ b/include/hw/xen/xen-bus.h @@ -24,6 +24,8 @@ typedef struct XenDevice { enum xenbus_state backend_state, frontend_state; Notifier exit; XenWatch *frontend_state_watch; + xengnttab_handle *xgth; + bool feature_grant_copy; } XenDevice; =20 typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp); @@ -79,4 +81,27 @@ void xen_device_backend_set_state(XenDevice *xendev, enum xenbus_state state); enum xenbus_state xen_device_backend_get_state(XenDevice *xendev); =20 +void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs, + Error **errp); +void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs, + unsigned int nr_refs, int prot, + Error **errp); +void xen_device_unmap_grant_refs(XenDevice *xendev, void *map, + unsigned int nr_refs, Error **errp); + +typedef struct XenDeviceGrantCopySegment { + union { + void *virt; + struct { + uint32_t ref; + off_t offset; + } foreign; + } source, dest; + size_t len; +} XenDeviceGrantCopySegment; + +void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain, + XenDeviceGrantCopySegment segs[], + unsigned int nr_segs, Error **errp); + #endif /* HW_XEN_BUS_H */ --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547128782337123.99641677595253; Thu, 10 Jan 2019 05:59:42 -0800 (PST) Received: from localhost ([127.0.0.1]:55589 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghas1-00044m-AN for importer@patchew.org; Thu, 10 Jan 2019 08:59:41 -0500 Received: from eggs.gnu.org ([209.51.188.92]:53240) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghaio-00057F-QU for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghaii-0001fi-UF for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:10 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:11315) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghaii-0001eA-MA for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:50:04 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75262363" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:01 +0000 Message-ID: <20190110134917.16425-10-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 09/25] xen: add event channel interface for XenDevice-s 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant The legacy PV backend infrastructure provides functions to bind, unbind and send notifications to event channnels. Similar functionality will be required by XenDevice implementations so this patch adds the necessary support. Signed-off-by: Paul Durrant Reviewed-by: Anthony Perard Signed-off-by: Anthony PERARD --- hw/xen/xen-bus.c | 101 +++++++++++++++++++++++++++++++++++++++ include/hw/xen/xen-bus.h | 18 +++++++ 2 files changed, 119 insertions(+) diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index faa9fd3577..9443f27d44 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -617,6 +617,81 @@ void xen_device_copy_grant_refs(XenDevice *xendev, boo= l to_domain, g_free(xengnttab_segs); } =20 +struct XenEventChannel { + unsigned int local_port; + XenEventHandler handler; + void *opaque; + Notifier notifier; +}; + +static void event_notify(Notifier *n, void *data) +{ + XenEventChannel *channel =3D container_of(n, XenEventChannel, notifier= ); + unsigned long port =3D (unsigned long)data; + + if (port =3D=3D channel->local_port) { + channel->handler(channel->opaque); + } +} + +XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev, + unsigned int port, + XenEventHandler handler, + void *opaque, Error **errp) +{ + XenEventChannel *channel =3D g_new0(XenEventChannel, 1); + + channel->local_port =3D xenevtchn_bind_interdomain(xendev->xeh, + xendev->frontend_id, + port); + if (xendev->local_port < 0) { + error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed"); + + g_free(channel); + return NULL; + } + + channel->handler =3D handler; + channel->opaque =3D opaque; + channel->notifier.notify =3D event_notify; + + notifier_list_add(&xendev->event_notifiers, &channel->notifier); + + return channel; +} + +void xen_device_notify_event_channel(XenDevice *xendev, + XenEventChannel *channel, + Error **errp) +{ + if (!channel) { + error_setg(errp, "bad channel"); + return; + } + + if (xenevtchn_notify(xendev->xeh, channel->local_port) < 0) { + error_setg_errno(errp, errno, "xenevtchn_notify failed"); + } +} + +void xen_device_unbind_event_channel(XenDevice *xendev, + XenEventChannel *channel, + Error **errp) +{ + if (!channel) { + error_setg(errp, "bad channel"); + return; + } + + notifier_remove(&channel->notifier); + + if (xenevtchn_unbind(xendev->xeh, channel->local_port) < 0) { + error_setg_errno(errp, errno, "xenevtchn_unbind failed"); + } + + g_free(channel); +} + static void xen_device_unrealize(DeviceState *dev, Error **errp) { XenDevice *xendev =3D XEN_DEVICE(dev); @@ -641,6 +716,12 @@ static void xen_device_unrealize(DeviceState *dev, Err= or **errp) xen_device_frontend_destroy(xendev); xen_device_backend_destroy(xendev); =20 + if (xendev->xeh) { + qemu_set_fd_handler(xenevtchn_fd(xendev->xeh), NULL, NULL, NULL); + xenevtchn_close(xendev->xeh); + xendev->xeh =3D NULL; + } + if (xendev->xgth) { xengnttab_close(xendev->xgth); xendev->xgth =3D NULL; @@ -657,6 +738,16 @@ static void xen_device_exit(Notifier *n, void *data) xen_device_unrealize(DEVICE(xendev), &error_abort); } =20 +static void xen_device_event(void *opaque) +{ + XenDevice *xendev =3D opaque; + unsigned long port =3D xenevtchn_pending(xendev->xeh); + + notifier_list_notify(&xendev->event_notifiers, (void *)port); + + xenevtchn_unmask(xendev->xeh, port); +} + static void xen_device_realize(DeviceState *dev, Error **errp) { XenDevice *xendev =3D XEN_DEVICE(dev); @@ -697,6 +788,16 @@ static void xen_device_realize(DeviceState *dev, Error= **errp) xendev->feature_grant_copy =3D (xengnttab_grant_copy(xendev->xgth, 0, NULL) =3D=3D 0); =20 + xendev->xeh =3D xenevtchn_open(NULL, 0); + if (!xendev->xeh) { + error_setg_errno(errp, errno, "failed xenevtchn_open"); + goto unrealize; + } + + notifier_list_init(&xendev->event_notifiers); + qemu_set_fd_handler(xenevtchn_fd(xendev->xeh), xen_device_event, NULL, + xendev); + xen_device_backend_create(xendev, &local_err); if (local_err) { error_propagate(errp, local_err); diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h index 63a09b67ee..f83a95cebd 100644 --- a/include/hw/xen/xen-bus.h +++ b/include/hw/xen/xen-bus.h @@ -26,6 +26,9 @@ typedef struct XenDevice { XenWatch *frontend_state_watch; xengnttab_handle *xgth; bool feature_grant_copy; + xenevtchn_handle *xeh; + xenevtchn_port_or_error_t local_port; + NotifierList event_notifiers; } XenDevice; =20 typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp); @@ -104,4 +107,19 @@ void xen_device_copy_grant_refs(XenDevice *xendev, boo= l to_domain, XenDeviceGrantCopySegment segs[], unsigned int nr_segs, Error **errp); =20 +typedef struct XenEventChannel XenEventChannel; + +typedef void (*XenEventHandler)(void *opaque); + +XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev, + unsigned int port, + XenEventHandler handler, + void *opaque, Error **errp); +void xen_device_notify_event_channel(XenDevice *xendev, + XenEventChannel *channel, + Error **errp); +void xen_device_unbind_event_channel(XenDevice *xendev, + XenEventChannel *channel, + Error **errp); + #endif /* HW_XEN_BUS_H */ --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547130494067562.6817185783295; Thu, 10 Jan 2019 06:28:14 -0800 (PST) Received: from localhost ([127.0.0.1]:34954 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghbJc-0001s5-QO for importer@patchew.org; Thu, 10 Jan 2019 09:28:12 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58291) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb57-0006I3-Kc for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghars-0002aw-Kt for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:35 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12073) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gharp-0002X7-Hi for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:30 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263699" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:02 +0000 Message-ID: <20190110134917.16425-11-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 10/25] xen: duplicate xen_disk.c as basis of dataplane/xen-block.c 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant The new xen-block XenDevice implementation requires the same core dataplane as the legacy xen_disk implementation it will eventually replace. This patch therefore copies the legacy xen_disk.c source module into a new dataplane/xen-block.c source module as the basis for the new dataplane and adjusts the MAINTAINERS file accordingly. NOTE: The duplicated code is not yet built. It is simply put into place by this patch (just fixing style violations) such that the modifications that will need to be made to the code are not conflated with code movement, thus making review harder. Signed-off-by: Paul Durrant Acked-by: Anthony Perard Signed-off-by: Anthony PERARD --- MAINTAINERS | 1 + hw/block/dataplane/xen-block.c | 1019 ++++++++++++++++++++++++++++++++ 2 files changed, 1020 insertions(+) create mode 100644 hw/block/dataplane/xen-block.c diff --git a/MAINTAINERS b/MAINTAINERS index 7514550c06..4c98b34853 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -415,6 +415,7 @@ F: hw/char/xen_console.c F: hw/display/xenfb.c F: hw/net/xen_nic.c F: hw/block/xen* +F: hw/block/dataplane/xen* F: hw/xen/ F: hw/xenpv/ F: hw/i386/xen/ diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c new file mode 100644 index 0000000000..9fae50534e --- /dev/null +++ b/hw/block/dataplane/xen-block.c @@ -0,0 +1,1019 @@ +/* + * xen paravirt block device backend + * + * (c) Gerd Hoffmann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Contributions after 2012-01-13 are licensed under the terms of the + * GNU GPL, version 2 or (at your option) any later version. + */ + +#include "qemu/osdep.h" +#include "qemu/units.h" +#include +#include + +#include "hw/hw.h" +#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" + +/* ------------------------------------------------------------- */ + +#define BLOCK_SIZE 512 +#define IOCB_COUNT (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2) + +struct ioreq { + blkif_request_t req; + int16_t status; + + /* parsed request */ + off_t start; + QEMUIOVector v; + void *buf; + size_t size; + int presync; + + /* aio status */ + int aio_inflight; + int aio_errors; + + struct XenBlkDev *blkdev; + QLIST_ENTRY(ioreq) list; + BlockAcctCookie acct; +}; + +#define MAX_RING_PAGE_ORDER 4 + +struct XenBlkDev { + struct XenLegacyDevice xendev; /* must be first */ + char *params; + char *mode; + char *type; + char *dev; + char *devtype; + bool directiosafe; + const char *fileproto; + const char *filename; + unsigned int ring_ref[1 << MAX_RING_PAGE_ORDER]; + unsigned int nr_ring_ref; + void *sring; + int64_t file_blk; + int64_t file_size; + int protocol; + blkif_back_rings_t rings; + int more_work; + + /* request lists */ + QLIST_HEAD(inflight_head, ioreq) inflight; + QLIST_HEAD(finished_head, ioreq) finished; + QLIST_HEAD(freelist_head, ioreq) freelist; + int requests_total; + int requests_inflight; + int requests_finished; + unsigned int max_requests; + + gboolean feature_discard; + + /* qemu block driver */ + DriveInfo *dinfo; + BlockBackend *blk; + QEMUBH *bh; + + IOThread *iothread; + AioContext *ctx; +}; + +/* ------------------------------------------------------------- */ + +static void ioreq_reset(struct ioreq *ioreq) +{ + memset(&ioreq->req, 0, sizeof(ioreq->req)); + ioreq->status =3D 0; + ioreq->start =3D 0; + ioreq->buf =3D NULL; + ioreq->size =3D 0; + ioreq->presync =3D 0; + + ioreq->aio_inflight =3D 0; + ioreq->aio_errors =3D 0; + + ioreq->blkdev =3D NULL; + memset(&ioreq->list, 0, sizeof(ioreq->list)); + memset(&ioreq->acct, 0, sizeof(ioreq->acct)); + + qemu_iovec_reset(&ioreq->v); +} + +static struct ioreq *ioreq_start(struct XenBlkDev *blkdev) +{ + struct ioreq *ioreq =3D NULL; + + if (QLIST_EMPTY(&blkdev->freelist)) { + if (blkdev->requests_total >=3D blkdev->max_requests) { + goto out; + } + /* allocate new struct */ + ioreq =3D g_malloc0(sizeof(*ioreq)); + ioreq->blkdev =3D blkdev; + blkdev->requests_total++; + qemu_iovec_init(&ioreq->v, 1); + } else { + /* get one from freelist */ + ioreq =3D QLIST_FIRST(&blkdev->freelist); + QLIST_REMOVE(ioreq, list); + } + QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list); + blkdev->requests_inflight++; + +out: + return ioreq; +} + +static void ioreq_finish(struct ioreq *ioreq) +{ + struct XenBlkDev *blkdev =3D ioreq->blkdev; + + QLIST_REMOVE(ioreq, list); + QLIST_INSERT_HEAD(&blkdev->finished, ioreq, list); + blkdev->requests_inflight--; + blkdev->requests_finished++; +} + +static void ioreq_release(struct ioreq *ioreq, bool finish) +{ + struct XenBlkDev *blkdev =3D ioreq->blkdev; + + QLIST_REMOVE(ioreq, list); + ioreq_reset(ioreq); + ioreq->blkdev =3D blkdev; + QLIST_INSERT_HEAD(&blkdev->freelist, ioreq, list); + if (finish) { + blkdev->requests_finished--; + } else { + blkdev->requests_inflight--; + } +} + +/* + * translate request into iovec + start offset + * do sanity checks along the way + */ +static int ioreq_parse(struct ioreq *ioreq) +{ + struct XenBlkDev *blkdev =3D ioreq->blkdev; + struct XenLegacyDevice *xendev =3D &blkdev->xendev; + size_t len; + int i; + + xen_pv_printf( + xendev, 3, + "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n", + ioreq->req.operation, ioreq->req.nr_segments, + ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number); + switch (ioreq->req.operation) { + case BLKIF_OP_READ: + break; + case BLKIF_OP_FLUSH_DISKCACHE: + ioreq->presync =3D 1; + if (!ioreq->req.nr_segments) { + return 0; + } + /* fall through */ + case BLKIF_OP_WRITE: + break; + case BLKIF_OP_DISCARD: + return 0; + default: + xen_pv_printf(xendev, 0, "error: unknown operation (%d)\n", + ioreq->req.operation); + goto err; + }; + + if (ioreq->req.operation !=3D BLKIF_OP_READ && blkdev->mode[0] !=3D 'w= ') { + xen_pv_printf(xendev, 0, "error: write req for ro device\n"); + goto err; + } + + ioreq->start =3D ioreq->req.sector_number * blkdev->file_blk; + for (i =3D 0; i < ioreq->req.nr_segments; i++) { + if (i =3D=3D BLKIF_MAX_SEGMENTS_PER_REQUEST) { + xen_pv_printf(xendev, 0, "error: nr_segments too big\n"); + goto err; + } + if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) { + xen_pv_printf(xendev, 0, "error: first > last sector\n"); + goto err; + } + if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >=3D XC_PAGE_SIZE) { + xen_pv_printf(xendev, 0, "error: page crossing\n"); + goto err; + } + + len =3D (ioreq->req.seg[i].last_sect - + ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk; + ioreq->size +=3D len; + } + if (ioreq->start + ioreq->size > blkdev->file_size) { + xen_pv_printf(xendev, 0, "error: access beyond end of file\n"); + goto err; + } + return 0; + +err: + ioreq->status =3D BLKIF_RSP_ERROR; + return -1; +} + +static int ioreq_grant_copy(struct ioreq *ioreq) +{ + struct XenBlkDev *blkdev =3D ioreq->blkdev; + struct XenLegacyDevice *xendev =3D &blkdev->xendev; + XenGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + int i, count, rc; + int64_t file_blk =3D blkdev->file_blk; + bool to_domain =3D (ioreq->req.operation =3D=3D BLKIF_OP_READ); + void *virt =3D ioreq->buf; + + if (ioreq->req.nr_segments =3D=3D 0) { + return 0; + } + + count =3D ioreq->req.nr_segments; + + for (i =3D 0; i < count; i++) { + if (to_domain) { + segs[i].dest.foreign.ref =3D ioreq->req.seg[i].gref; + segs[i].dest.foreign.offset =3D ioreq->req.seg[i].first_sect * + file_blk; + segs[i].source.virt =3D virt; + } else { + segs[i].source.foreign.ref =3D ioreq->req.seg[i].gref; + segs[i].source.foreign.offset =3D ioreq->req.seg[i].first_sect= * + file_blk; + segs[i].dest.virt =3D virt; + } + segs[i].len =3D (ioreq->req.seg[i].last_sect + - ioreq->req.seg[i].first_sect + 1) * file_blk; + virt +=3D segs[i].len; + } + + rc =3D xen_be_copy_grant_refs(xendev, to_domain, segs, count); + + if (rc) { + xen_pv_printf(xendev, 0, + "failed to copy data %d\n", rc); + ioreq->aio_errors++; + return -1; + } + + return rc; +} + +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; + struct XenLegacyDevice *xendev =3D &blkdev->xendev; + + aio_context_acquire(blkdev->ctx); + + if (ret !=3D 0) { + xen_pv_printf(xendev, 0, "%s I/O error\n", + ioreq->req.operation =3D=3D BLKIF_OP_READ ? "read" := "write"); + ioreq->aio_errors++; + } + + ioreq->aio_inflight--; + if (ioreq->presync) { + ioreq->presync =3D 0; + ioreq_runio_qemu_aio(ioreq); + goto done; + } + if (ioreq->aio_inflight > 0) { + goto done; + } + + switch (ioreq->req.operation) { + case BLKIF_OP_READ: + /* in case of failure ioreq->aio_errors is increased */ + if (ret =3D=3D 0) { + ioreq_grant_copy(ioreq); + } + qemu_vfree(ioreq->buf); + break; + case BLKIF_OP_WRITE: + case BLKIF_OP_FLUSH_DISKCACHE: + if (!ioreq->req.nr_segments) { + break; + } + qemu_vfree(ioreq->buf); + break; + default: + break; + } + + ioreq->status =3D ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY; + ioreq_finish(ioreq); + + switch (ioreq->req.operation) { + case BLKIF_OP_WRITE: + case BLKIF_OP_FLUSH_DISKCACHE: + if (!ioreq->req.nr_segments) { + break; + } + case BLKIF_OP_READ: + if (ioreq->status =3D=3D BLKIF_RSP_OKAY) { + block_acct_done(blk_get_stats(blkdev->blk), &ioreq->acct); + } else { + block_acct_failed(blk_get_stats(blkdev->blk), &ioreq->acct); + } + break; + case BLKIF_OP_DISCARD: + default: + break; + } + qemu_bh_schedule(blkdev->bh); + +done: + aio_context_release(blkdev->ctx); +} + +static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_n= umber, + uint64_t nr_sectors) +{ + struct XenBlkDev *blkdev =3D ioreq->blkdev; + int64_t byte_offset; + int byte_chunk; + uint64_t byte_remaining, limit; + uint64_t sec_start =3D sector_number; + uint64_t sec_count =3D nr_sectors; + + /* Wrap around, or overflowing byte limit? */ + if (sec_start + sec_count < sec_count || + sec_start + sec_count > INT64_MAX >> BDRV_SECTOR_BITS) { + return false; + } + + limit =3D BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS; + byte_offset =3D sec_start << BDRV_SECTOR_BITS; + byte_remaining =3D sec_count << BDRV_SECTOR_BITS; + + do { + byte_chunk =3D byte_remaining > limit ? limit : byte_remaining; + ioreq->aio_inflight++; + blk_aio_pdiscard(blkdev->blk, byte_offset, byte_chunk, + qemu_aio_complete, ioreq); + byte_remaining -=3D byte_chunk; + byte_offset +=3D byte_chunk; + } while (byte_remaining > 0); + + return true; +} + +static int ioreq_runio_qemu_aio(struct ioreq *ioreq) +{ + struct XenBlkDev *blkdev =3D ioreq->blkdev; + + ioreq->buf =3D qemu_memalign(XC_PAGE_SIZE, ioreq->size); + if (ioreq->req.nr_segments && + (ioreq->req.operation =3D=3D BLKIF_OP_WRITE || + ioreq->req.operation =3D=3D BLKIF_OP_FLUSH_DISKCACHE) && + ioreq_grant_copy(ioreq)) { + qemu_vfree(ioreq->buf); + goto err; + } + + ioreq->aio_inflight++; + if (ioreq->presync) { + blk_aio_flush(ioreq->blkdev->blk, qemu_aio_complete, ioreq); + return 0; + } + + switch (ioreq->req.operation) { + case BLKIF_OP_READ: + qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size); + block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct, + ioreq->v.size, BLOCK_ACCT_READ); + ioreq->aio_inflight++; + blk_aio_preadv(blkdev->blk, ioreq->start, &ioreq->v, 0, + qemu_aio_complete, ioreq); + break; + case BLKIF_OP_WRITE: + case BLKIF_OP_FLUSH_DISKCACHE: + if (!ioreq->req.nr_segments) { + break; + } + + qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size); + block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct, + ioreq->v.size, + ioreq->req.operation =3D=3D BLKIF_OP_WRITE ? + BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH); + ioreq->aio_inflight++; + blk_aio_pwritev(blkdev->blk, ioreq->start, &ioreq->v, 0, + qemu_aio_complete, ioreq); + break; + case BLKIF_OP_DISCARD: + { + struct blkif_request_discard *req =3D (void *)&ioreq->req; + if (!blk_split_discard(ioreq, req->sector_number, req->nr_sectors)= ) { + goto err; + } + break; + } + default: + /* unknown operation (shouldn't happen -- parse catches this) */ + goto err; + } + + qemu_aio_complete(ioreq, 0); + + return 0; + +err: + ioreq_finish(ioreq); + ioreq->status =3D BLKIF_RSP_ERROR; + return -1; +} + +static int blk_send_response_one(struct ioreq *ioreq) +{ + struct XenBlkDev *blkdev =3D ioreq->blkdev; + int send_notify =3D 0; + int have_requests =3D 0; + blkif_response_t *resp; + + /* Place on the response ring for the relevant domain. */ + switch (blkdev->protocol) { + case BLKIF_PROTOCOL_NATIVE: + resp =3D (blkif_response_t *)RING_GET_RESPONSE( + &blkdev->rings.native, + blkdev->rings.native.rsp_prod_pvt); + break; + case BLKIF_PROTOCOL_X86_32: + resp =3D (blkif_response_t *)RING_GET_RESPONSE( + &blkdev->rings.x86_32_part, + blkdev->rings.x86_32_part.rsp_prod_pvt); + break; + case BLKIF_PROTOCOL_X86_64: + resp =3D (blkif_response_t *)RING_GET_RESPONSE( + &blkdev->rings.x86_64_part, + blkdev->rings.x86_64_part.rsp_prod_pvt); + break; + default: + return 0; + } + + resp->id =3D ioreq->req.id; + resp->operation =3D ioreq->req.operation; + resp->status =3D ioreq->status; + + blkdev->rings.common.rsp_prod_pvt++; + + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notif= y); + if (blkdev->rings.common.rsp_prod_pvt =3D=3D blkdev->rings.common.req_= cons) { + /* + * Tail check for pending requests. Allows frontend to avoid + * notifications if requests are already in flight (lower + * overheads and promotes batching). + */ + RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests= ); + } else if (RING_HAS_UNCONSUMED_REQUESTS(&blkdev->rings.common)) { + have_requests =3D 1; + } + + if (have_requests) { + blkdev->more_work++; + } + return send_notify; +} + +/* walk finished list, send outstanding responses, free requests */ +static void blk_send_response_all(struct XenBlkDev *blkdev) +{ + struct ioreq *ioreq; + int send_notify =3D 0; + + while (!QLIST_EMPTY(&blkdev->finished)) { + ioreq =3D QLIST_FIRST(&blkdev->finished); + send_notify +=3D blk_send_response_one(ioreq); + ioreq_release(ioreq, true); + } + if (send_notify) { + xen_pv_send_notify(&blkdev->xendev); + } +} + +static int blk_get_request(struct XenBlkDev *blkdev, struct ioreq *ioreq, + RING_IDX rc) +{ + switch (blkdev->protocol) { + case BLKIF_PROTOCOL_NATIVE: + memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc), + sizeof(ioreq->req)); + break; + case BLKIF_PROTOCOL_X86_32: + blkif_get_x86_32_req(&ioreq->req, + RING_GET_REQUEST(&blkdev->rings.x86_32_part, = rc)); + break; + case BLKIF_PROTOCOL_X86_64: + blkif_get_x86_64_req(&ioreq->req, + RING_GET_REQUEST(&blkdev->rings.x86_64_part, = rc)); + break; + } + /* Prevent the compiler from accessing the on-ring fields instead. */ + barrier(); + return 0; +} + +static void blk_handle_requests(struct XenBlkDev *blkdev) +{ + RING_IDX rc, rp; + struct ioreq *ioreq; + + blkdev->more_work =3D 0; + + rc =3D blkdev->rings.common.req_cons; + rp =3D blkdev->rings.common.sring->req_prod; + xen_rmb(); /* Ensure we see queued requests up to 'rp'. */ + + blk_send_response_all(blkdev); + while (rc !=3D rp) { + /* pull request from ring */ + if (RING_REQUEST_CONS_OVERFLOW(&blkdev->rings.common, rc)) { + break; + } + ioreq =3D ioreq_start(blkdev); + if (ioreq =3D=3D NULL) { + blkdev->more_work++; + break; + } + blk_get_request(blkdev, ioreq, rc); + blkdev->rings.common.req_cons =3D ++rc; + + /* parse them */ + if (ioreq_parse(ioreq) !=3D 0) { + + switch (ioreq->req.operation) { + case BLKIF_OP_READ: + block_acct_invalid(blk_get_stats(blkdev->blk), + BLOCK_ACCT_READ); + break; + case BLKIF_OP_WRITE: + block_acct_invalid(blk_get_stats(blkdev->blk), + BLOCK_ACCT_WRITE); + break; + case BLKIF_OP_FLUSH_DISKCACHE: + block_acct_invalid(blk_get_stats(blkdev->blk), + BLOCK_ACCT_FLUSH); + default: + break; + }; + + if (blk_send_response_one(ioreq)) { + xen_pv_send_notify(&blkdev->xendev); + } + ioreq_release(ioreq, false); + continue; + } + + ioreq_runio_qemu_aio(ioreq); + } + + if (blkdev->more_work && blkdev->requests_inflight < blkdev->max_reque= sts) { + qemu_bh_schedule(blkdev->bh); + } +} + +/* ------------------------------------------------------------- */ + +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); +} + +static void blk_alloc(struct XenLegacyDevice *xendev) +{ + struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); + Error *err =3D NULL; + + trace_xen_disk_alloc(xendev->name); + + QLIST_INIT(&blkdev->inflight); + QLIST_INIT(&blkdev->finished); + QLIST_INIT(&blkdev->freelist); + + blkdev->iothread =3D iothread_create(xendev->name, &err); + assert(!err); + + blkdev->ctx =3D iothread_get_aio_context(blkdev->iothread); + blkdev->bh =3D aio_bh_new(blkdev->ctx, blk_bh, blkdev); +} + +static void blk_parse_discard(struct XenBlkDev *blkdev) +{ + struct XenLegacyDevice *xendev =3D &blkdev->xendev; + int enable; + + blkdev->feature_discard =3D true; + + if (xenstore_read_be_int(xendev, "discard-enable", &enable) =3D=3D 0) { + blkdev->feature_discard =3D !!enable; + } + + if (blkdev->feature_discard) { + xenstore_write_be_int(xendev, "feature-discard", 1); + } +} + +static int blk_init(struct XenLegacyDevice *xendev) +{ + struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); + int info =3D 0; + char *directiosafe =3D NULL; + + trace_xen_disk_init(xendev->name); + + /* read xenstore entries */ + if (blkdev->params =3D=3D NULL) { + char *h =3D NULL; + blkdev->params =3D xenstore_read_be_str(xendev, "params"); + if (blkdev->params !=3D NULL) { + h =3D strchr(blkdev->params, ':'); + } + if (h !=3D NULL) { + blkdev->fileproto =3D blkdev->params; + blkdev->filename =3D h + 1; + *h =3D 0; + } else { + blkdev->fileproto =3D ""; + blkdev->filename =3D blkdev->params; + } + } + if (!strcmp("aio", blkdev->fileproto)) { + blkdev->fileproto =3D "raw"; + } + if (!strcmp("vhd", blkdev->fileproto)) { + blkdev->fileproto =3D "vpc"; + } + if (blkdev->mode =3D=3D NULL) { + blkdev->mode =3D xenstore_read_be_str(xendev, "mode"); + } + if (blkdev->type =3D=3D NULL) { + blkdev->type =3D xenstore_read_be_str(xendev, "type"); + } + if (blkdev->dev =3D=3D NULL) { + blkdev->dev =3D xenstore_read_be_str(xendev, "dev"); + } + if (blkdev->devtype =3D=3D NULL) { + blkdev->devtype =3D xenstore_read_be_str(xendev, "device-type"); + } + directiosafe =3D xenstore_read_be_str(xendev, "direct-io-safe"); + blkdev->directiosafe =3D (directiosafe && atoi(directiosafe)); + + /* do we have all we need? */ + if (blkdev->params =3D=3D NULL || + blkdev->mode =3D=3D NULL || + blkdev->type =3D=3D NULL || + blkdev->dev =3D=3D NULL) { + goto out_error; + } + + /* read-only ? */ + if (strcmp(blkdev->mode, "w")) { + info |=3D VDISK_READONLY; + } + + /* cdrom ? */ + if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom")) { + info |=3D VDISK_CDROM; + } + + blkdev->file_blk =3D BLOCK_SIZE; + + /* fill info + * blk_connect supplies sector-size and sectors + */ + xenstore_write_be_int(xendev, "feature-flush-cache", 1); + xenstore_write_be_int(xendev, "info", info); + + xenstore_write_be_int(xendev, "max-ring-page-order", + MAX_RING_PAGE_ORDER); + + blk_parse_discard(blkdev); + + g_free(directiosafe); + return 0; + +out_error: + g_free(blkdev->params); + blkdev->params =3D NULL; + g_free(blkdev->mode); + blkdev->mode =3D NULL; + g_free(blkdev->type); + blkdev->type =3D NULL; + g_free(blkdev->dev); + blkdev->dev =3D NULL; + g_free(blkdev->devtype); + blkdev->devtype =3D NULL; + g_free(directiosafe); + blkdev->directiosafe =3D false; + return -1; +} + +static int blk_connect(struct XenLegacyDevice *xendev) +{ + struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); + int index, qflags; + bool readonly =3D true; + bool writethrough =3D true; + int order, ring_ref; + unsigned int ring_size, max_grants; + unsigned int i; + + trace_xen_disk_connect(xendev->name); + + /* read-only ? */ + if (blkdev->directiosafe) { + qflags =3D BDRV_O_NOCACHE | BDRV_O_NATIVE_AIO; + } else { + qflags =3D 0; + writethrough =3D false; + } + if (strcmp(blkdev->mode, "w") =3D=3D 0) { + qflags |=3D BDRV_O_RDWR; + readonly =3D false; + } + if (blkdev->feature_discard) { + qflags |=3D BDRV_O_UNMAP; + } + + /* init qemu block driver */ + index =3D (xendev->dev - 202 * 256) / 16; + blkdev->dinfo =3D drive_get(IF_XEN, 0, index); + if (!blkdev->dinfo) { + Error *local_err =3D NULL; + QDict *options =3D NULL; + + if (strcmp(blkdev->fileproto, "")) { + options =3D qdict_new(); + qdict_put_str(options, "driver", blkdev->fileproto); + } + + /* setup via xenbus -> create new block driver instance */ + xen_pv_printf(xendev, 2, "create new bdrv (xenbus setup)\n"); + blkdev->blk =3D blk_new_open(blkdev->filename, NULL, options, + qflags, &local_err); + if (!blkdev->blk) { + xen_pv_printf(xendev, 0, "error: %s\n", + error_get_pretty(local_err)); + error_free(local_err); + return -1; + } + blk_set_enable_write_cache(blkdev->blk, !writethrough); + } else { + /* setup via qemu cmdline -> already setup for us */ + xen_pv_printf(xendev, 2, + "get configured bdrv (cmdline setup)\n"); + blkdev->blk =3D blk_by_legacy_dinfo(blkdev->dinfo); + if (blk_is_read_only(blkdev->blk) && !readonly) { + xen_pv_printf(xendev, 0, "Unexpected read-only drive"); + blkdev->blk =3D NULL; + return -1; + } + /* blkdev->blk is not create by us, we get a reference + * so we can blk_unref() unconditionally */ + blk_ref(blkdev->blk); + } + blk_attach_dev_legacy(blkdev->blk, blkdev); + blkdev->file_size =3D blk_getlength(blkdev->blk); + if (blkdev->file_size < 0) { + BlockDriverState *bs =3D blk_bs(blkdev->blk); + const char *drv_name =3D bs ? bdrv_get_format_name(bs) : NULL; + xen_pv_printf(xendev, 1, "blk_getlength: %d (%s) | drv %s\n", + (int)blkdev->file_size, strerror(-blkdev->file_size), + drv_name ?: "-"); + blkdev->file_size =3D 0; + } + + xen_pv_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s= \"," + " size %" PRId64 " (%" PRId64 " MB)\n", + blkdev->type, blkdev->fileproto, blkdev->filename, + blkdev->file_size, blkdev->file_size / MiB); + + /* Fill in number of sector size and number of sectors */ + xenstore_write_be_int(xendev, "sector-size", blkdev->file_blk); + xenstore_write_be_int64(xendev, "sectors", + blkdev->file_size / blkdev->file_blk); + + if (xenstore_read_fe_int(xendev, "ring-page-order", + &order) =3D=3D -1) { + blkdev->nr_ring_ref =3D 1; + + if (xenstore_read_fe_int(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(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(xendev, "event-channel", + &xendev->remote_port) =3D=3D -1) { + return -1; + } + + if (!xendev->protocol) { + blkdev->protocol =3D BLKIF_PROTOCOL_NATIVE; + } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_NATIVE) =3D=3D 0)= { + blkdev->protocol =3D BLKIF_PROTOCOL_NATIVE; + } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_32) =3D=3D 0)= { + blkdev->protocol =3D BLKIF_PROTOCOL_X86_32; + } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_64) =3D=3D 0)= { + blkdev->protocol =3D BLKIF_PROTOCOL_X86_64; + } else { + blkdev->protocol =3D BLKIF_PROTOCOL_NATIVE; + } + + 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; + } + + /* Add on the number needed for the ring pages */ + max_grants =3D blkdev->nr_ring_ref; + + xen_be_set_max_grant_refs(xendev, max_grants); + blkdev->sring =3D xen_be_map_grant_refs(xendev, blkdev->ring_ref, + blkdev->nr_ring_ref, + PROT_READ | PROT_WRITE); + if (!blkdev->sring) { + return -1; + } + + switch (blkdev->protocol) { + case BLKIF_PROTOCOL_NATIVE: + { + blkif_sring_t *sring_native =3D blkdev->sring; + 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; + + 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; + + BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, ring_size= ); + break; + } + } + + blk_set_aio_context(blkdev->blk, blkdev->ctx); + + xen_be_bind_evtchn(xendev); + + xen_pv_printf(xendev, 1, "ok: proto %s, nr-ring-ref %u, " + "remote port %d, local port %d\n", + xendev->protocol, blkdev->nr_ring_ref, + xendev->remote_port, xendev->local_port); + return 0; +} + +static void blk_disconnect(struct XenLegacyDevice *xendev) +{ + struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); + + 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(xendev); + + aio_context_release(blkdev->ctx); + + if (blkdev->sring) { + xen_be_unmap_grant_refs(xendev, blkdev->sring, + blkdev->nr_ring_ref); + blkdev->sring =3D NULL; + } +} + +static int blk_free(struct XenLegacyDevice *xendev) +{ + struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); + struct ioreq *ioreq; + + trace_xen_disk_free(xendev->name); + + blk_disconnect(xendev); + + while (!QLIST_EMPTY(&blkdev->freelist)) { + ioreq =3D QLIST_FIRST(&blkdev->freelist); + QLIST_REMOVE(ioreq, list); + qemu_iovec_destroy(&ioreq->v); + g_free(ioreq); + } + + g_free(blkdev->params); + g_free(blkdev->mode); + g_free(blkdev->type); + g_free(blkdev->dev); + g_free(blkdev->devtype); + qemu_bh_delete(blkdev->bh); + iothread_destroy(blkdev->iothread); + return 0; +} + +static void blk_event(struct XenLegacyDevice *xendev) +{ + struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); + + qemu_bh_schedule(blkdev->bh); +} + +struct XenDevOps xen_blkdev_ops =3D { + .flags =3D DEVOPS_FLAG_NEED_GNTDEV, + .size =3D sizeof(struct XenBlkDev), + .alloc =3D blk_alloc, + .init =3D blk_init, + .initialise =3D blk_connect, + .disconnect =3D blk_disconnect, + .event =3D blk_event, + .free =3D blk_free, +}; --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547131171641372.16836596770077; Thu, 10 Jan 2019 06:39:31 -0800 (PST) Received: from localhost ([127.0.0.1]:37708 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghbUY-0002ls-36 for importer@patchew.org; Thu, 10 Jan 2019 09:39:30 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58072) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb5Q-00062k-38 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:35 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gharA-0002Ar-2R for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:58:51 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12008) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghar8-0001xV-Gi for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:58:47 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263629" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:03 +0000 Message-ID: <20190110134917.16425-12-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 11/25] xen: remove unnecessary code from dataplane/xen-block.c 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant Not all of the code duplicated from xen_disk.c is required as the basis for the new dataplane implementation so this patch removes extraneous code, along with the legacy #includes and calls to the legacy xen_pv_printf() function. Error messages are changed to be reported using error_report(). NOTE: The code is still not yet built. Further transformations will be required to make it correctly interface to the new XenBus/XenDevice framework. They will be delivered in a subsequent patch. Signed-off-by: Paul Durrant Acked-by: Anthony Perard Signed-off-by: Anthony PERARD --- hw/block/dataplane/xen-block.c | 429 ++------------------------------- 1 file changed, 23 insertions(+), 406 deletions(-) diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c index 9fae50534e..228472320a 100644 --- a/hw/block/dataplane/xen-block.c +++ b/hw/block/dataplane/xen-block.c @@ -1,45 +1,23 @@ /* - * xen paravirt block device backend + * Copyright (c) 2018 Citrix Systems Inc. + * (c) Gerd Hoffmann * - * (c) Gerd Hoffmann + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; under version 2 of the License. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Contributions after 2012-01-13 are licensed under the terms of the - * GNU GPL, version 2 or (at your option) any later version. + * Contributions after 2012-01-13 are licensed under the terms of the + * GNU GPL, version 2 or (at your option) any later version. */ =20 -#include "qemu/osdep.h" -#include "qemu/units.h" -#include -#include - -#include "hw/hw.h" -#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" - -/* ------------------------------------------------------------- */ - -#define BLOCK_SIZE 512 -#define IOCB_COUNT (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2) - struct ioreq { blkif_request_t req; int16_t status; @@ -101,8 +79,6 @@ struct XenBlkDev { AioContext *ctx; }; =20 -/* ------------------------------------------------------------- */ - static void ioreq_reset(struct ioreq *ioreq) { memset(&ioreq->req, 0, sizeof(ioreq->req)); @@ -183,11 +159,6 @@ static int ioreq_parse(struct ioreq *ioreq) size_t len; int i; =20 - xen_pv_printf( - xendev, 3, - "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n", - ioreq->req.operation, ioreq->req.nr_segments, - ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number); switch (ioreq->req.operation) { case BLKIF_OP_READ: break; @@ -202,28 +173,27 @@ static int ioreq_parse(struct ioreq *ioreq) case BLKIF_OP_DISCARD: return 0; default: - xen_pv_printf(xendev, 0, "error: unknown operation (%d)\n", - ioreq->req.operation); + error_report("error: unknown operation (%d)", ioreq->req.operation= ); goto err; }; =20 if (ioreq->req.operation !=3D BLKIF_OP_READ && blkdev->mode[0] !=3D 'w= ') { - xen_pv_printf(xendev, 0, "error: write req for ro device\n"); + error_report("error: write req for ro device"); goto err; } =20 ioreq->start =3D ioreq->req.sector_number * blkdev->file_blk; for (i =3D 0; i < ioreq->req.nr_segments; i++) { if (i =3D=3D BLKIF_MAX_SEGMENTS_PER_REQUEST) { - xen_pv_printf(xendev, 0, "error: nr_segments too big\n"); + error_report("error: nr_segments too big"); goto err; } if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) { - xen_pv_printf(xendev, 0, "error: first > last sector\n"); + error_report("error: first > last sector"); goto err; } if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >=3D XC_PAGE_SIZE) { - xen_pv_printf(xendev, 0, "error: page crossing\n"); + error_report("error: page crossing"); goto err; } =20 @@ -232,7 +202,7 @@ static int ioreq_parse(struct ioreq *ioreq) ioreq->size +=3D len; } if (ioreq->start + ioreq->size > blkdev->file_size) { - xen_pv_printf(xendev, 0, "error: access beyond end of file\n"); + error_report("error: access beyond end of file"); goto err; } return 0; @@ -278,8 +248,7 @@ static int ioreq_grant_copy(struct ioreq *ioreq) rc =3D xen_be_copy_grant_refs(xendev, to_domain, segs, count); =20 if (rc) { - xen_pv_printf(xendev, 0, - "failed to copy data %d\n", rc); + error_report("failed to copy data %d", rc); ioreq->aio_errors++; return -1; } @@ -298,8 +267,9 @@ static void qemu_aio_complete(void *opaque, int ret) aio_context_acquire(blkdev->ctx); =20 if (ret !=3D 0) { - xen_pv_printf(xendev, 0, "%s I/O error\n", - ioreq->req.operation =3D=3D BLKIF_OP_READ ? "read" := "write"); + error_report("%s I/O error", + ioreq->req.operation =3D=3D BLKIF_OP_READ ? + "read" : "write"); ioreq->aio_errors++; } =20 @@ -605,8 +575,6 @@ static void blk_handle_requests(struct XenBlkDev *blkde= v) } } =20 -/* ------------------------------------------------------------- */ - static void blk_bh(void *opaque) { struct XenBlkDev *blkdev =3D opaque; @@ -634,346 +602,6 @@ static void blk_alloc(struct XenLegacyDevice *xendev) blkdev->bh =3D aio_bh_new(blkdev->ctx, blk_bh, blkdev); } =20 -static void blk_parse_discard(struct XenBlkDev *blkdev) -{ - struct XenLegacyDevice *xendev =3D &blkdev->xendev; - int enable; - - blkdev->feature_discard =3D true; - - if (xenstore_read_be_int(xendev, "discard-enable", &enable) =3D=3D 0) { - blkdev->feature_discard =3D !!enable; - } - - if (blkdev->feature_discard) { - xenstore_write_be_int(xendev, "feature-discard", 1); - } -} - -static int blk_init(struct XenLegacyDevice *xendev) -{ - struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); - int info =3D 0; - char *directiosafe =3D NULL; - - trace_xen_disk_init(xendev->name); - - /* read xenstore entries */ - if (blkdev->params =3D=3D NULL) { - char *h =3D NULL; - blkdev->params =3D xenstore_read_be_str(xendev, "params"); - if (blkdev->params !=3D NULL) { - h =3D strchr(blkdev->params, ':'); - } - if (h !=3D NULL) { - blkdev->fileproto =3D blkdev->params; - blkdev->filename =3D h + 1; - *h =3D 0; - } else { - blkdev->fileproto =3D ""; - blkdev->filename =3D blkdev->params; - } - } - if (!strcmp("aio", blkdev->fileproto)) { - blkdev->fileproto =3D "raw"; - } - if (!strcmp("vhd", blkdev->fileproto)) { - blkdev->fileproto =3D "vpc"; - } - if (blkdev->mode =3D=3D NULL) { - blkdev->mode =3D xenstore_read_be_str(xendev, "mode"); - } - if (blkdev->type =3D=3D NULL) { - blkdev->type =3D xenstore_read_be_str(xendev, "type"); - } - if (blkdev->dev =3D=3D NULL) { - blkdev->dev =3D xenstore_read_be_str(xendev, "dev"); - } - if (blkdev->devtype =3D=3D NULL) { - blkdev->devtype =3D xenstore_read_be_str(xendev, "device-type"); - } - directiosafe =3D xenstore_read_be_str(xendev, "direct-io-safe"); - blkdev->directiosafe =3D (directiosafe && atoi(directiosafe)); - - /* do we have all we need? */ - if (blkdev->params =3D=3D NULL || - blkdev->mode =3D=3D NULL || - blkdev->type =3D=3D NULL || - blkdev->dev =3D=3D NULL) { - goto out_error; - } - - /* read-only ? */ - if (strcmp(blkdev->mode, "w")) { - info |=3D VDISK_READONLY; - } - - /* cdrom ? */ - if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom")) { - info |=3D VDISK_CDROM; - } - - blkdev->file_blk =3D BLOCK_SIZE; - - /* fill info - * blk_connect supplies sector-size and sectors - */ - xenstore_write_be_int(xendev, "feature-flush-cache", 1); - xenstore_write_be_int(xendev, "info", info); - - xenstore_write_be_int(xendev, "max-ring-page-order", - MAX_RING_PAGE_ORDER); - - blk_parse_discard(blkdev); - - g_free(directiosafe); - return 0; - -out_error: - g_free(blkdev->params); - blkdev->params =3D NULL; - g_free(blkdev->mode); - blkdev->mode =3D NULL; - g_free(blkdev->type); - blkdev->type =3D NULL; - g_free(blkdev->dev); - blkdev->dev =3D NULL; - g_free(blkdev->devtype); - blkdev->devtype =3D NULL; - g_free(directiosafe); - blkdev->directiosafe =3D false; - return -1; -} - -static int blk_connect(struct XenLegacyDevice *xendev) -{ - struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); - int index, qflags; - bool readonly =3D true; - bool writethrough =3D true; - int order, ring_ref; - unsigned int ring_size, max_grants; - unsigned int i; - - trace_xen_disk_connect(xendev->name); - - /* read-only ? */ - if (blkdev->directiosafe) { - qflags =3D BDRV_O_NOCACHE | BDRV_O_NATIVE_AIO; - } else { - qflags =3D 0; - writethrough =3D false; - } - if (strcmp(blkdev->mode, "w") =3D=3D 0) { - qflags |=3D BDRV_O_RDWR; - readonly =3D false; - } - if (blkdev->feature_discard) { - qflags |=3D BDRV_O_UNMAP; - } - - /* init qemu block driver */ - index =3D (xendev->dev - 202 * 256) / 16; - blkdev->dinfo =3D drive_get(IF_XEN, 0, index); - if (!blkdev->dinfo) { - Error *local_err =3D NULL; - QDict *options =3D NULL; - - if (strcmp(blkdev->fileproto, "")) { - options =3D qdict_new(); - qdict_put_str(options, "driver", blkdev->fileproto); - } - - /* setup via xenbus -> create new block driver instance */ - xen_pv_printf(xendev, 2, "create new bdrv (xenbus setup)\n"); - blkdev->blk =3D blk_new_open(blkdev->filename, NULL, options, - qflags, &local_err); - if (!blkdev->blk) { - xen_pv_printf(xendev, 0, "error: %s\n", - error_get_pretty(local_err)); - error_free(local_err); - return -1; - } - blk_set_enable_write_cache(blkdev->blk, !writethrough); - } else { - /* setup via qemu cmdline -> already setup for us */ - xen_pv_printf(xendev, 2, - "get configured bdrv (cmdline setup)\n"); - blkdev->blk =3D blk_by_legacy_dinfo(blkdev->dinfo); - if (blk_is_read_only(blkdev->blk) && !readonly) { - xen_pv_printf(xendev, 0, "Unexpected read-only drive"); - blkdev->blk =3D NULL; - return -1; - } - /* blkdev->blk is not create by us, we get a reference - * so we can blk_unref() unconditionally */ - blk_ref(blkdev->blk); - } - blk_attach_dev_legacy(blkdev->blk, blkdev); - blkdev->file_size =3D blk_getlength(blkdev->blk); - if (blkdev->file_size < 0) { - BlockDriverState *bs =3D blk_bs(blkdev->blk); - const char *drv_name =3D bs ? bdrv_get_format_name(bs) : NULL; - xen_pv_printf(xendev, 1, "blk_getlength: %d (%s) | drv %s\n", - (int)blkdev->file_size, strerror(-blkdev->file_size), - drv_name ?: "-"); - blkdev->file_size =3D 0; - } - - xen_pv_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s= \"," - " size %" PRId64 " (%" PRId64 " MB)\n", - blkdev->type, blkdev->fileproto, blkdev->filename, - blkdev->file_size, blkdev->file_size / MiB); - - /* Fill in number of sector size and number of sectors */ - xenstore_write_be_int(xendev, "sector-size", blkdev->file_blk); - xenstore_write_be_int64(xendev, "sectors", - blkdev->file_size / blkdev->file_blk); - - if (xenstore_read_fe_int(xendev, "ring-page-order", - &order) =3D=3D -1) { - blkdev->nr_ring_ref =3D 1; - - if (xenstore_read_fe_int(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(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(xendev, "event-channel", - &xendev->remote_port) =3D=3D -1) { - return -1; - } - - if (!xendev->protocol) { - blkdev->protocol =3D BLKIF_PROTOCOL_NATIVE; - } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_NATIVE) =3D=3D 0)= { - blkdev->protocol =3D BLKIF_PROTOCOL_NATIVE; - } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_32) =3D=3D 0)= { - blkdev->protocol =3D BLKIF_PROTOCOL_X86_32; - } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_64) =3D=3D 0)= { - blkdev->protocol =3D BLKIF_PROTOCOL_X86_64; - } else { - blkdev->protocol =3D BLKIF_PROTOCOL_NATIVE; - } - - 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; - } - - /* Add on the number needed for the ring pages */ - max_grants =3D blkdev->nr_ring_ref; - - xen_be_set_max_grant_refs(xendev, max_grants); - blkdev->sring =3D xen_be_map_grant_refs(xendev, blkdev->ring_ref, - blkdev->nr_ring_ref, - PROT_READ | PROT_WRITE); - if (!blkdev->sring) { - return -1; - } - - switch (blkdev->protocol) { - case BLKIF_PROTOCOL_NATIVE: - { - blkif_sring_t *sring_native =3D blkdev->sring; - 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; - - 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; - - BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, ring_size= ); - break; - } - } - - blk_set_aio_context(blkdev->blk, blkdev->ctx); - - xen_be_bind_evtchn(xendev); - - xen_pv_printf(xendev, 1, "ok: proto %s, nr-ring-ref %u, " - "remote port %d, local port %d\n", - xendev->protocol, blkdev->nr_ring_ref, - xendev->remote_port, xendev->local_port); - return 0; -} - -static void blk_disconnect(struct XenLegacyDevice *xendev) -{ - struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); - - 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(xendev); - - aio_context_release(blkdev->ctx); - - if (blkdev->sring) { - xen_be_unmap_grant_refs(xendev, blkdev->sring, - blkdev->nr_ring_ref); - blkdev->sring =3D NULL; - } -} - static int blk_free(struct XenLegacyDevice *xendev) { struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); @@ -1006,14 +634,3 @@ static void blk_event(struct XenLegacyDevice *xendev) =20 qemu_bh_schedule(blkdev->bh); } - -struct XenDevOps xen_blkdev_ops =3D { - .flags =3D DEVOPS_FLAG_NEED_GNTDEV, - .size =3D sizeof(struct XenBlkDev), - .alloc =3D blk_alloc, - .init =3D blk_init, - .initialise =3D blk_connect, - .disconnect =3D blk_disconnect, - .event =3D blk_event, - .free =3D blk_free, -}; --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547130111093892.0006439859261; Thu, 10 Jan 2019 06:21:51 -0800 (PST) Received: from localhost ([127.0.0.1]:33358 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghbDR-0004gt-T0 for importer@patchew.org; Thu, 10 Jan 2019 09:21:49 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58072) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb52-00062k-Qh for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghasQ-00032U-Gr for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:00:08 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12098) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghasQ-00031h-6K for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:00:06 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263721" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:04 +0000 Message-ID: <20190110134917.16425-13-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 12/25] xen: add header and build dataplane/xen-block.c 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant This patch adds the transformations necessary to get dataplane/xen-block.c to build against the new XenBus/XenDevice framework. MAINTAINERS is also updated due to the introduction of dataplane/xen-block.h. NOTE: Existing data structure names are retained for the moment. These will be modified by subsequent patches. A typedef for XenBlockDataPlane has been added to the header (based on the old struct XenBlkDev name for the moment) so that the old names don't need to leak out of the dataplane code. Signed-off-by: Paul Durrant Reviewed-by: Anthony Perard Signed-off-by: Anthony PERARD --- MAINTAINERS | 1 + hw/block/dataplane/Makefile.objs | 1 + hw/block/dataplane/xen-block.c | 356 ++++++++++++++++++++++--------- hw/block/dataplane/xen-block.h | 29 +++ 4 files changed, 287 insertions(+), 100 deletions(-) create mode 100644 hw/block/dataplane/xen-block.h diff --git a/MAINTAINERS b/MAINTAINERS index 4c98b34853..43b2691b5d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -419,6 +419,7 @@ F: hw/block/dataplane/xen* F: hw/xen/ F: hw/xenpv/ F: hw/i386/xen/ +F: include/hw/block/dataplane/xen* F: include/hw/xen/ F: include/sysemu/xen-mapcache.h =20 diff --git a/hw/block/dataplane/Makefile.objs b/hw/block/dataplane/Makefile= .objs index e786f66421..c6c68dbc00 100644 --- a/hw/block/dataplane/Makefile.objs +++ b/hw/block/dataplane/Makefile.objs @@ -1 +1,2 @@ obj-y +=3D virtio-blk.o +obj-$(CONFIG_XEN) +=3D xen-block.o diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c index 228472320a..ed2b91ffff 100644 --- a/hw/block/dataplane/xen-block.c +++ b/hw/block/dataplane/xen-block.c @@ -18,65 +18,53 @@ * GNU GPL, version 2 or (at your option) any later version. */ =20 +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qapi/error.h" +#include "hw/hw.h" +#include "hw/xen/xen_common.h" +#include "hw/block/xen_blkif.h" +#include "sysemu/block-backend.h" +#include "sysemu/iothread.h" +#include "xen-block.h" + struct ioreq { - blkif_request_t req; - int16_t status; - - /* parsed request */ - off_t start; - QEMUIOVector v; - void *buf; - size_t size; - int presync; - - /* aio status */ - int aio_inflight; - int aio_errors; - - struct XenBlkDev *blkdev; - QLIST_ENTRY(ioreq) list; - BlockAcctCookie acct; + blkif_request_t req; + int16_t status; + off_t start; + QEMUIOVector v; + void *buf; + size_t size; + int presync; + int aio_inflight; + int aio_errors; + struct XenBlkDev *blkdev; + QLIST_ENTRY(ioreq) list; + BlockAcctCookie acct; }; =20 -#define MAX_RING_PAGE_ORDER 4 - struct XenBlkDev { - struct XenLegacyDevice xendev; /* must be first */ - char *params; - char *mode; - char *type; - char *dev; - char *devtype; - bool directiosafe; - const char *fileproto; - const char *filename; - unsigned int ring_ref[1 << MAX_RING_PAGE_ORDER]; - unsigned int nr_ring_ref; - void *sring; - int64_t file_blk; - int64_t file_size; - int protocol; - blkif_back_rings_t rings; - int more_work; - - /* request lists */ + XenDevice *xendev; + XenEventChannel *event_channel; + unsigned int *ring_ref; + unsigned int nr_ring_ref; + void *sring; + int64_t file_blk; + int64_t file_size; + int protocol; + blkif_back_rings_t rings; + int more_work; QLIST_HEAD(inflight_head, ioreq) inflight; QLIST_HEAD(finished_head, ioreq) finished; QLIST_HEAD(freelist_head, ioreq) freelist; - int requests_total; - int requests_inflight; - int requests_finished; - unsigned int max_requests; - - gboolean feature_discard; - - /* qemu block driver */ - DriveInfo *dinfo; - BlockBackend *blk; - QEMUBH *bh; - - IOThread *iothread; - AioContext *ctx; + int requests_total; + int requests_inflight; + int requests_finished; + unsigned int max_requests; + BlockBackend *blk; + QEMUBH *bh; + IOThread *iothread; + AioContext *ctx; }; =20 static void ioreq_reset(struct ioreq *ioreq) @@ -155,7 +143,6 @@ static void ioreq_release(struct ioreq *ioreq, bool fin= ish) static int ioreq_parse(struct ioreq *ioreq) { struct XenBlkDev *blkdev =3D ioreq->blkdev; - struct XenLegacyDevice *xendev =3D &blkdev->xendev; size_t len; int i; =20 @@ -177,7 +164,8 @@ static int ioreq_parse(struct ioreq *ioreq) goto err; }; =20 - if (ioreq->req.operation !=3D BLKIF_OP_READ && blkdev->mode[0] !=3D 'w= ') { + if (ioreq->req.operation !=3D BLKIF_OP_READ && + blk_is_read_only(blkdev->blk)) { error_report("error: write req for ro device"); goto err; } @@ -192,7 +180,7 @@ static int ioreq_parse(struct ioreq *ioreq) error_report("error: first > last sector"); goto err; } - if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >=3D XC_PAGE_SIZE) { + if (ioreq->req.seg[i].last_sect * blkdev->file_blk >=3D XC_PAGE_SI= ZE) { error_report("error: page crossing"); goto err; } @@ -215,12 +203,13 @@ static int ioreq_parse(struct ioreq *ioreq) static int ioreq_grant_copy(struct ioreq *ioreq) { struct XenBlkDev *blkdev =3D ioreq->blkdev; - struct XenLegacyDevice *xendev =3D &blkdev->xendev; - XenGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST]; - int i, count, rc; + XenDevice *xendev =3D blkdev->xendev; + XenDeviceGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + int i, count; int64_t file_blk =3D blkdev->file_blk; bool to_domain =3D (ioreq->req.operation =3D=3D BLKIF_OP_READ); void *virt =3D ioreq->buf; + Error *local_err =3D NULL; =20 if (ioreq->req.nr_segments =3D=3D 0) { return 0; @@ -240,20 +229,21 @@ static int ioreq_grant_copy(struct ioreq *ioreq) file_blk; segs[i].dest.virt =3D virt; } - segs[i].len =3D (ioreq->req.seg[i].last_sect - - ioreq->req.seg[i].first_sect + 1) * file_blk; + segs[i].len =3D (ioreq->req.seg[i].last_sect - + ioreq->req.seg[i].first_sect + 1) * file_blk; virt +=3D segs[i].len; } =20 - rc =3D xen_be_copy_grant_refs(xendev, to_domain, segs, count); + xen_device_copy_grant_refs(xendev, to_domain, segs, count, &local_err); + + if (local_err) { + error_reportf_err(local_err, "failed to copy data: "); =20 - if (rc) { - error_report("failed to copy data %d", rc); ioreq->aio_errors++; return -1; } =20 - return rc; + return 0; } =20 static int ioreq_runio_qemu_aio(struct ioreq *ioreq); @@ -262,7 +252,6 @@ static void qemu_aio_complete(void *opaque, int ret) { struct ioreq *ioreq =3D opaque; struct XenBlkDev *blkdev =3D ioreq->blkdev; - struct XenLegacyDevice *xendev =3D &blkdev->xendev; =20 aio_context_acquire(blkdev->ctx); =20 @@ -340,13 +329,13 @@ static bool blk_split_discard(struct ioreq *ioreq, bl= kif_sector_t sector_number, =20 /* Wrap around, or overflowing byte limit? */ if (sec_start + sec_count < sec_count || - sec_start + sec_count > INT64_MAX >> BDRV_SECTOR_BITS) { + sec_start + sec_count > INT64_MAX / blkdev->file_blk) { return false; } =20 - limit =3D BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS; - byte_offset =3D sec_start << BDRV_SECTOR_BITS; - byte_remaining =3D sec_count << BDRV_SECTOR_BITS; + limit =3D BDRV_REQUEST_MAX_SECTORS * blkdev->file_blk; + byte_offset =3D sec_start * blkdev->file_blk; + byte_remaining =3D sec_count * blkdev->file_blk; =20 do { byte_chunk =3D byte_remaining > limit ? limit : byte_remaining; @@ -428,10 +417,10 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq) =20 static int blk_send_response_one(struct ioreq *ioreq) { - struct XenBlkDev *blkdev =3D ioreq->blkdev; - int send_notify =3D 0; - int have_requests =3D 0; - blkif_response_t *resp; + struct XenBlkDev *blkdev =3D ioreq->blkdev; + int send_notify =3D 0; + int have_requests =3D 0; + blkif_response_t *resp; =20 /* Place on the response ring for the relevant domain. */ switch (blkdev->protocol) { @@ -454,9 +443,9 @@ static int blk_send_response_one(struct ioreq *ioreq) return 0; } =20 - resp->id =3D ioreq->req.id; + resp->id =3D ioreq->req.id; resp->operation =3D ioreq->req.operation; - resp->status =3D ioreq->status; + resp->status =3D ioreq->status; =20 blkdev->rings.common.rsp_prod_pvt++; =20 @@ -490,7 +479,14 @@ static void blk_send_response_all(struct XenBlkDev *bl= kdev) ioreq_release(ioreq, true); } if (send_notify) { - xen_pv_send_notify(&blkdev->xendev); + Error *local_err =3D NULL; + + xen_device_notify_event_channel(blkdev->xendev, + blkdev->event_channel, + &local_err); + if (local_err) { + error_report_err(local_err); + } } } =20 @@ -561,7 +557,14 @@ static void blk_handle_requests(struct XenBlkDev *blkd= ev) }; =20 if (blk_send_response_one(ioreq)) { - xen_pv_send_notify(&blkdev->xendev); + Error *local_err =3D NULL; + + xen_device_notify_event_channel(blkdev->xendev, + blkdev->event_channel, + &local_err); + if (local_err) { + error_report_err(local_err); + } } ioreq_release(ioreq, false); continue; @@ -584,32 +587,47 @@ static void blk_bh(void *opaque) aio_context_release(blkdev->ctx); } =20 -static void blk_alloc(struct XenLegacyDevice *xendev) +static void blk_event(void *opaque) +{ + struct XenBlkDev *blkdev =3D opaque; + + qemu_bh_schedule(blkdev->bh); +} + +struct XenBlkDev *xen_block_dataplane_create(XenDevice *xendev, + BlockConf *conf, + IOThread *iothread) { - struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); - Error *err =3D NULL; + struct XenBlkDev *blkdev =3D g_new0(struct XenBlkDev, 1); =20 - trace_xen_disk_alloc(xendev->name); + blkdev->xendev =3D xendev; + blkdev->file_blk =3D conf->logical_block_size; + blkdev->blk =3D conf->blk; + blkdev->file_size =3D blk_getlength(blkdev->blk); =20 QLIST_INIT(&blkdev->inflight); QLIST_INIT(&blkdev->finished); QLIST_INIT(&blkdev->freelist); =20 - blkdev->iothread =3D iothread_create(xendev->name, &err); - assert(!err); - - blkdev->ctx =3D iothread_get_aio_context(blkdev->iothread); + if (iothread) { + blkdev->iothread =3D iothread; + object_ref(OBJECT(blkdev->iothread)); + blkdev->ctx =3D iothread_get_aio_context(blkdev->iothread); + } else { + blkdev->ctx =3D qemu_get_aio_context(); + } blkdev->bh =3D aio_bh_new(blkdev->ctx, blk_bh, blkdev); + + return blkdev; } =20 -static int blk_free(struct XenLegacyDevice *xendev) +void xen_block_dataplane_destroy(struct XenBlkDev *blkdev) { - struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); struct ioreq *ioreq; =20 - trace_xen_disk_free(xendev->name); - - blk_disconnect(xendev); + if (!blkdev) { + return; + } =20 while (!QLIST_EMPTY(&blkdev->freelist)) { ioreq =3D QLIST_FIRST(&blkdev->freelist); @@ -618,19 +636,157 @@ static int blk_free(struct XenLegacyDevice *xendev) g_free(ioreq); } =20 - g_free(blkdev->params); - g_free(blkdev->mode); - g_free(blkdev->type); - g_free(blkdev->dev); - g_free(blkdev->devtype); qemu_bh_delete(blkdev->bh); - iothread_destroy(blkdev->iothread); - return 0; + if (blkdev->iothread) { + object_unref(OBJECT(blkdev->iothread)); + } + + g_free(blkdev); } =20 -static void blk_event(struct XenLegacyDevice *xendev) + +void xen_block_dataplane_stop(struct XenBlkDev *blkdev) { - struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); + XenDevice *xendev; =20 - qemu_bh_schedule(blkdev->bh); + if (!blkdev) { + return; + } + + aio_context_acquire(blkdev->ctx); + blk_set_aio_context(blkdev->blk, qemu_get_aio_context()); + aio_context_release(blkdev->ctx); + + xendev =3D blkdev->xendev; + + if (blkdev->event_channel) { + Error *local_err =3D NULL; + + xen_device_unbind_event_channel(xendev, blkdev->event_channel, + &local_err); + blkdev->event_channel =3D NULL; + + if (local_err) { + error_report_err(local_err); + } + } + + if (blkdev->sring) { + Error *local_err =3D NULL; + + xen_device_unmap_grant_refs(xendev, blkdev->sring, + blkdev->nr_ring_ref, &local_err); + blkdev->sring =3D NULL; + + if (local_err) { + error_report_err(local_err); + } + } + + g_free(blkdev->ring_ref); + blkdev->ring_ref =3D NULL; +} + +void xen_block_dataplane_start(struct XenBlkDev *blkdev, + const unsigned int ring_ref[], + unsigned int nr_ring_ref, + unsigned int event_channel, + unsigned int protocol, + Error **errp) +{ + XenDevice *xendev =3D blkdev->xendev; + Error *local_err =3D NULL; + unsigned int ring_size; + unsigned int i; + + blkdev->nr_ring_ref =3D nr_ring_ref; + blkdev->ring_ref =3D g_new(unsigned int, nr_ring_ref); + + for (i =3D 0; i < nr_ring_ref; i++) { + blkdev->ring_ref[i] =3D ring_ref[i]; + } + + blkdev->protocol =3D protocol; + + 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: + error_setg(errp, "unknown protocol %u", blkdev->protocol); + return; + } + + xen_device_set_max_grant_refs(xendev, blkdev->nr_ring_ref, + &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto stop; + } + + blkdev->sring =3D xen_device_map_grant_refs(xendev, + blkdev->ring_ref, + blkdev->nr_ring_ref, + PROT_READ | PROT_WRITE, + &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto stop; + } + + switch (blkdev->protocol) { + case BLKIF_PROTOCOL_NATIVE: + { + blkif_sring_t *sring_native =3D blkdev->sring; + + 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; + + 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; + + BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, + ring_size); + break; + } + } + + blkdev->event_channel =3D + xen_device_bind_event_channel(xendev, event_channel, + blk_event, blkdev, + &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto stop; + } + + aio_context_acquire(blkdev->ctx); + blk_set_aio_context(blkdev->blk, blkdev->ctx); + aio_context_release(blkdev->ctx); + return; + +stop: + xen_block_dataplane_stop(blkdev); } diff --git a/hw/block/dataplane/xen-block.h b/hw/block/dataplane/xen-block.h new file mode 100644 index 0000000000..f31da38464 --- /dev/null +++ b/hw/block/dataplane/xen-block.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018 Citrix Systems Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef HW_BLOCK_DATAPLANE_XEN_BLOCK_H +#define HW_BLOCK_DATAPLANE_XEN_BLOCK_H + +#include "hw/block/block.h" +#include "hw/xen/xen-bus.h" +#include "sysemu/iothread.h" + +typedef struct XenBlkDev XenBlockDataPlane; + +XenBlockDataPlane *xen_block_dataplane_create(XenDevice *xendev, + BlockConf *conf, + IOThread *iothread); +void xen_block_dataplane_destroy(XenBlockDataPlane *dataplane); +void xen_block_dataplane_start(XenBlockDataPlane *dataplane, + const unsigned int ring_ref[], + unsigned int nr_ring_ref, + unsigned int event_channel, + unsigned int protocol, + Error **errp); +void xen_block_dataplane_stop(XenBlockDataPlane *dataplane); + +#endif /* HW_BLOCK_DATAPLANE_XEN_BLOCK_H */ --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547129948315551.3909336986717; Thu, 10 Jan 2019 06:19:08 -0800 (PST) Received: from localhost ([127.0.0.1]:60875 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghbAd-0002Wh-Vp for importer@patchew.org; Thu, 10 Jan 2019 09:18:56 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57991) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb59-0005zK-ND for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gharn-0002YL-CY for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:30 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12064) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gharj-0002Ue-8Q for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:24 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263694" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:05 +0000 Message-ID: <20190110134917.16425-14-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 13/25] xen: remove 'XenBlkDev' and 'blkdev' names from dataplane/xen-block 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant This is a purely cosmetic patch that substitutes the old 'struct XenBlkDev' name with 'XenBlockDataPlane' and 'blkdev' field/variable names with 'dataplane', and then does necessary fix-up to adhere to coding style. No functional change. Signed-off-by: Paul Durrant Acked-by: Anthony Perard Signed-off-by: Anthony PERARD --- hw/block/dataplane/xen-block.c | 352 +++++++++++++++++---------------- hw/block/dataplane/xen-block.h | 2 +- 2 files changed, 183 insertions(+), 171 deletions(-) diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c index ed2b91ffff..1ff464973c 100644 --- a/hw/block/dataplane/xen-block.c +++ b/hw/block/dataplane/xen-block.c @@ -38,12 +38,12 @@ struct ioreq { int presync; int aio_inflight; int aio_errors; - struct XenBlkDev *blkdev; + XenBlockDataPlane *dataplane; QLIST_ENTRY(ioreq) list; BlockAcctCookie acct; }; =20 -struct XenBlkDev { +struct XenBlockDataPlane { XenDevice *xendev; XenEventChannel *event_channel; unsigned int *ring_ref; @@ -79,33 +79,33 @@ static void ioreq_reset(struct ioreq *ioreq) ioreq->aio_inflight =3D 0; ioreq->aio_errors =3D 0; =20 - ioreq->blkdev =3D NULL; + ioreq->dataplane =3D NULL; memset(&ioreq->list, 0, sizeof(ioreq->list)); memset(&ioreq->acct, 0, sizeof(ioreq->acct)); =20 qemu_iovec_reset(&ioreq->v); } =20 -static struct ioreq *ioreq_start(struct XenBlkDev *blkdev) +static struct ioreq *ioreq_start(XenBlockDataPlane *dataplane) { struct ioreq *ioreq =3D NULL; =20 - if (QLIST_EMPTY(&blkdev->freelist)) { - if (blkdev->requests_total >=3D blkdev->max_requests) { + if (QLIST_EMPTY(&dataplane->freelist)) { + if (dataplane->requests_total >=3D dataplane->max_requests) { goto out; } /* allocate new struct */ ioreq =3D g_malloc0(sizeof(*ioreq)); - ioreq->blkdev =3D blkdev; - blkdev->requests_total++; + ioreq->dataplane =3D dataplane; + dataplane->requests_total++; qemu_iovec_init(&ioreq->v, 1); } else { /* get one from freelist */ - ioreq =3D QLIST_FIRST(&blkdev->freelist); + ioreq =3D QLIST_FIRST(&dataplane->freelist); QLIST_REMOVE(ioreq, list); } - QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list); - blkdev->requests_inflight++; + QLIST_INSERT_HEAD(&dataplane->inflight, ioreq, list); + dataplane->requests_inflight++; =20 out: return ioreq; @@ -113,26 +113,26 @@ static struct ioreq *ioreq_start(struct XenBlkDev *bl= kdev) =20 static void ioreq_finish(struct ioreq *ioreq) { - struct XenBlkDev *blkdev =3D ioreq->blkdev; + XenBlockDataPlane *dataplane =3D ioreq->dataplane; =20 QLIST_REMOVE(ioreq, list); - QLIST_INSERT_HEAD(&blkdev->finished, ioreq, list); - blkdev->requests_inflight--; - blkdev->requests_finished++; + QLIST_INSERT_HEAD(&dataplane->finished, ioreq, list); + dataplane->requests_inflight--; + dataplane->requests_finished++; } =20 static void ioreq_release(struct ioreq *ioreq, bool finish) { - struct XenBlkDev *blkdev =3D ioreq->blkdev; + XenBlockDataPlane *dataplane =3D ioreq->dataplane; =20 QLIST_REMOVE(ioreq, list); ioreq_reset(ioreq); - ioreq->blkdev =3D blkdev; - QLIST_INSERT_HEAD(&blkdev->freelist, ioreq, list); + ioreq->dataplane =3D dataplane; + QLIST_INSERT_HEAD(&dataplane->freelist, ioreq, list); if (finish) { - blkdev->requests_finished--; + dataplane->requests_finished--; } else { - blkdev->requests_inflight--; + dataplane->requests_inflight--; } } =20 @@ -142,7 +142,7 @@ static void ioreq_release(struct ioreq *ioreq, bool fin= ish) */ static int ioreq_parse(struct ioreq *ioreq) { - struct XenBlkDev *blkdev =3D ioreq->blkdev; + XenBlockDataPlane *dataplane =3D ioreq->dataplane; size_t len; int i; =20 @@ -165,12 +165,12 @@ static int ioreq_parse(struct ioreq *ioreq) }; =20 if (ioreq->req.operation !=3D BLKIF_OP_READ && - blk_is_read_only(blkdev->blk)) { + blk_is_read_only(dataplane->blk)) { error_report("error: write req for ro device"); goto err; } =20 - ioreq->start =3D ioreq->req.sector_number * blkdev->file_blk; + ioreq->start =3D ioreq->req.sector_number * dataplane->file_blk; for (i =3D 0; i < ioreq->req.nr_segments; i++) { if (i =3D=3D BLKIF_MAX_SEGMENTS_PER_REQUEST) { error_report("error: nr_segments too big"); @@ -180,16 +180,16 @@ static int ioreq_parse(struct ioreq *ioreq) error_report("error: first > last sector"); goto err; } - if (ioreq->req.seg[i].last_sect * blkdev->file_blk >=3D XC_PAGE_SI= ZE) { + if (ioreq->req.seg[i].last_sect * dataplane->file_blk >=3D XC_PAGE= _SIZE) { error_report("error: page crossing"); goto err; } =20 len =3D (ioreq->req.seg[i].last_sect - - ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk; + ioreq->req.seg[i].first_sect + 1) * dataplane->file_blk; ioreq->size +=3D len; } - if (ioreq->start + ioreq->size > blkdev->file_size) { + if (ioreq->start + ioreq->size > dataplane->file_size) { error_report("error: access beyond end of file"); goto err; } @@ -202,11 +202,11 @@ static int ioreq_parse(struct ioreq *ioreq) =20 static int ioreq_grant_copy(struct ioreq *ioreq) { - struct XenBlkDev *blkdev =3D ioreq->blkdev; - XenDevice *xendev =3D blkdev->xendev; + XenBlockDataPlane *dataplane =3D ioreq->dataplane; + XenDevice *xendev =3D dataplane->xendev; XenDeviceGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST]; int i, count; - int64_t file_blk =3D blkdev->file_blk; + int64_t file_blk =3D dataplane->file_blk; bool to_domain =3D (ioreq->req.operation =3D=3D BLKIF_OP_READ); void *virt =3D ioreq->buf; Error *local_err =3D NULL; @@ -251,9 +251,9 @@ 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; + XenBlockDataPlane *dataplane =3D ioreq->dataplane; =20 - aio_context_acquire(blkdev->ctx); + aio_context_acquire(dataplane->ctx); =20 if (ret !=3D 0) { error_report("%s I/O error", @@ -302,25 +302,25 @@ 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(blkdev->blk), &ioreq->acct); + block_acct_done(blk_get_stats(dataplane->blk), &ioreq->acct); } else { - block_acct_failed(blk_get_stats(blkdev->blk), &ioreq->acct); + block_acct_failed(blk_get_stats(dataplane->blk), &ioreq->acct); } break; case BLKIF_OP_DISCARD: default: break; } - qemu_bh_schedule(blkdev->bh); + qemu_bh_schedule(dataplane->bh); =20 done: - aio_context_release(blkdev->ctx); + aio_context_release(dataplane->ctx); } =20 static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_n= umber, uint64_t nr_sectors) { - struct XenBlkDev *blkdev =3D ioreq->blkdev; + XenBlockDataPlane *dataplane =3D ioreq->dataplane; int64_t byte_offset; int byte_chunk; uint64_t byte_remaining, limit; @@ -329,18 +329,18 @@ static bool blk_split_discard(struct ioreq *ioreq, bl= kif_sector_t sector_number, =20 /* Wrap around, or overflowing byte limit? */ if (sec_start + sec_count < sec_count || - sec_start + sec_count > INT64_MAX / blkdev->file_blk) { + sec_start + sec_count > INT64_MAX / dataplane->file_blk) { return false; } =20 - limit =3D BDRV_REQUEST_MAX_SECTORS * blkdev->file_blk; - byte_offset =3D sec_start * blkdev->file_blk; - byte_remaining =3D sec_count * blkdev->file_blk; + limit =3D BDRV_REQUEST_MAX_SECTORS * dataplane->file_blk; + byte_offset =3D sec_start * dataplane->file_blk; + byte_remaining =3D sec_count * dataplane->file_blk; =20 do { byte_chunk =3D byte_remaining > limit ? limit : byte_remaining; ioreq->aio_inflight++; - blk_aio_pdiscard(blkdev->blk, byte_offset, byte_chunk, + blk_aio_pdiscard(dataplane->blk, byte_offset, byte_chunk, qemu_aio_complete, ioreq); byte_remaining -=3D byte_chunk; byte_offset +=3D byte_chunk; @@ -351,7 +351,7 @@ static bool blk_split_discard(struct ioreq *ioreq, blki= f_sector_t sector_number, =20 static int ioreq_runio_qemu_aio(struct ioreq *ioreq) { - struct XenBlkDev *blkdev =3D ioreq->blkdev; + XenBlockDataPlane *dataplane =3D ioreq->dataplane; =20 ioreq->buf =3D qemu_memalign(XC_PAGE_SIZE, ioreq->size); if (ioreq->req.nr_segments && @@ -364,17 +364,17 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq) =20 ioreq->aio_inflight++; if (ioreq->presync) { - blk_aio_flush(ioreq->blkdev->blk, qemu_aio_complete, ioreq); + blk_aio_flush(ioreq->dataplane->blk, qemu_aio_complete, ioreq); return 0; } =20 switch (ioreq->req.operation) { case BLKIF_OP_READ: qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size); - block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct, + block_acct_start(blk_get_stats(dataplane->blk), &ioreq->acct, ioreq->v.size, BLOCK_ACCT_READ); ioreq->aio_inflight++; - blk_aio_preadv(blkdev->blk, ioreq->start, &ioreq->v, 0, + blk_aio_preadv(dataplane->blk, ioreq->start, &ioreq->v, 0, qemu_aio_complete, ioreq); break; case BLKIF_OP_WRITE: @@ -384,12 +384,12 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq) } =20 qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size); - block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct, + block_acct_start(blk_get_stats(dataplane->blk), &ioreq->acct, ioreq->v.size, ioreq->req.operation =3D=3D BLKIF_OP_WRITE ? BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH); ioreq->aio_inflight++; - blk_aio_pwritev(blkdev->blk, ioreq->start, &ioreq->v, 0, + blk_aio_pwritev(dataplane->blk, ioreq->start, &ioreq->v, 0, qemu_aio_complete, ioreq); break; case BLKIF_OP_DISCARD: @@ -417,27 +417,27 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq) =20 static int blk_send_response_one(struct ioreq *ioreq) { - struct XenBlkDev *blkdev =3D ioreq->blkdev; + XenBlockDataPlane *dataplane =3D ioreq->dataplane; int send_notify =3D 0; int have_requests =3D 0; blkif_response_t *resp; =20 /* Place on the response ring for the relevant domain. */ - switch (blkdev->protocol) { + switch (dataplane->protocol) { case BLKIF_PROTOCOL_NATIVE: resp =3D (blkif_response_t *)RING_GET_RESPONSE( - &blkdev->rings.native, - blkdev->rings.native.rsp_prod_pvt); + &dataplane->rings.native, + dataplane->rings.native.rsp_prod_pvt); break; case BLKIF_PROTOCOL_X86_32: resp =3D (blkif_response_t *)RING_GET_RESPONSE( - &blkdev->rings.x86_32_part, - blkdev->rings.x86_32_part.rsp_prod_pvt); + &dataplane->rings.x86_32_part, + dataplane->rings.x86_32_part.rsp_prod_pvt); break; case BLKIF_PROTOCOL_X86_64: resp =3D (blkif_response_t *)RING_GET_RESPONSE( - &blkdev->rings.x86_64_part, - blkdev->rings.x86_64_part.rsp_prod_pvt); + &dataplane->rings.x86_64_part, + dataplane->rings.x86_64_part.rsp_prod_pvt); break; default: return 0; @@ -447,42 +447,45 @@ static int blk_send_response_one(struct ioreq *ioreq) resp->operation =3D ioreq->req.operation; resp->status =3D ioreq->status; =20 - blkdev->rings.common.rsp_prod_pvt++; + dataplane->rings.common.rsp_prod_pvt++; =20 - RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notif= y); - if (blkdev->rings.common.rsp_prod_pvt =3D=3D blkdev->rings.common.req_= cons) { + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&dataplane->rings.common, + send_notify); + if (dataplane->rings.common.rsp_prod_pvt =3D=3D + dataplane->rings.common.req_cons) { /* * Tail check for pending requests. Allows frontend to avoid * notifications if requests are already in flight (lower * overheads and promotes batching). */ - RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests= ); - } else if (RING_HAS_UNCONSUMED_REQUESTS(&blkdev->rings.common)) { + RING_FINAL_CHECK_FOR_REQUESTS(&dataplane->rings.common, + have_requests); + } else if (RING_HAS_UNCONSUMED_REQUESTS(&dataplane->rings.common)) { have_requests =3D 1; } =20 if (have_requests) { - blkdev->more_work++; + dataplane->more_work++; } return send_notify; } =20 /* walk finished list, send outstanding responses, free requests */ -static void blk_send_response_all(struct XenBlkDev *blkdev) +static void blk_send_response_all(XenBlockDataPlane *dataplane) { struct ioreq *ioreq; int send_notify =3D 0; =20 - while (!QLIST_EMPTY(&blkdev->finished)) { - ioreq =3D QLIST_FIRST(&blkdev->finished); + while (!QLIST_EMPTY(&dataplane->finished)) { + ioreq =3D QLIST_FIRST(&dataplane->finished); send_notify +=3D blk_send_response_one(ioreq); ioreq_release(ioreq, true); } if (send_notify) { Error *local_err =3D NULL; =20 - xen_device_notify_event_channel(blkdev->xendev, - blkdev->event_channel, + xen_device_notify_event_channel(dataplane->xendev, + dataplane->event_channel, &local_err); if (local_err) { error_report_err(local_err); @@ -490,67 +493,76 @@ static void blk_send_response_all(struct XenBlkDev *b= lkdev) } } =20 -static int blk_get_request(struct XenBlkDev *blkdev, struct ioreq *ioreq, +static int blk_get_request(XenBlockDataPlane *dataplane, struct ioreq *ior= eq, RING_IDX rc) { - switch (blkdev->protocol) { - case BLKIF_PROTOCOL_NATIVE: - memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc), - sizeof(ioreq->req)); + switch (dataplane->protocol) { + case BLKIF_PROTOCOL_NATIVE: { + blkif_request_t *req =3D + RING_GET_REQUEST(&dataplane->rings.native, rc); + + memcpy(&ioreq->req, req, sizeof(ioreq->req)); break; - case BLKIF_PROTOCOL_X86_32: - blkif_get_x86_32_req(&ioreq->req, - RING_GET_REQUEST(&blkdev->rings.x86_32_part, = rc)); + } + case BLKIF_PROTOCOL_X86_32: { + blkif_x86_32_request_t *req =3D + RING_GET_REQUEST(&dataplane->rings.x86_32_part, rc); + + blkif_get_x86_32_req(&ioreq->req, req); break; - case BLKIF_PROTOCOL_X86_64: - blkif_get_x86_64_req(&ioreq->req, - RING_GET_REQUEST(&blkdev->rings.x86_64_part, = rc)); + } + case BLKIF_PROTOCOL_X86_64: { + blkif_x86_64_request_t *req =3D + RING_GET_REQUEST(&dataplane->rings.x86_64_part, rc); + + blkif_get_x86_64_req(&ioreq->req, req); break; } + } /* Prevent the compiler from accessing the on-ring fields instead. */ barrier(); return 0; } =20 -static void blk_handle_requests(struct XenBlkDev *blkdev) +static void blk_handle_requests(XenBlockDataPlane *dataplane) { RING_IDX rc, rp; struct ioreq *ioreq; =20 - blkdev->more_work =3D 0; + dataplane->more_work =3D 0; =20 - rc =3D blkdev->rings.common.req_cons; - rp =3D blkdev->rings.common.sring->req_prod; + rc =3D dataplane->rings.common.req_cons; + rp =3D dataplane->rings.common.sring->req_prod; xen_rmb(); /* Ensure we see queued requests up to 'rp'. */ =20 - blk_send_response_all(blkdev); + blk_send_response_all(dataplane); while (rc !=3D rp) { /* pull request from ring */ - if (RING_REQUEST_CONS_OVERFLOW(&blkdev->rings.common, rc)) { + if (RING_REQUEST_CONS_OVERFLOW(&dataplane->rings.common, rc)) { break; } - ioreq =3D ioreq_start(blkdev); + ioreq =3D ioreq_start(dataplane); if (ioreq =3D=3D NULL) { - blkdev->more_work++; + dataplane->more_work++; break; } - blk_get_request(blkdev, ioreq, rc); - blkdev->rings.common.req_cons =3D ++rc; + blk_get_request(dataplane, ioreq, rc); + dataplane->rings.common.req_cons =3D ++rc; =20 /* parse them */ if (ioreq_parse(ioreq) !=3D 0) { =20 switch (ioreq->req.operation) { case BLKIF_OP_READ: - block_acct_invalid(blk_get_stats(blkdev->blk), + block_acct_invalid(blk_get_stats(dataplane->blk), BLOCK_ACCT_READ); break; case BLKIF_OP_WRITE: - block_acct_invalid(blk_get_stats(blkdev->blk), + block_acct_invalid(blk_get_stats(dataplane->blk), BLOCK_ACCT_WRITE); break; case BLKIF_OP_FLUSH_DISKCACHE: - block_acct_invalid(blk_get_stats(blkdev->blk), + block_acct_invalid(blk_get_stats(dataplane->blk), BLOCK_ACCT_FLUSH); default: break; @@ -559,8 +571,8 @@ static void blk_handle_requests(struct XenBlkDev *blkde= v) if (blk_send_response_one(ioreq)) { Error *local_err =3D NULL; =20 - xen_device_notify_event_channel(blkdev->xendev, - blkdev->event_channel, + xen_device_notify_event_channel(dataplane->xendev, + dataplane->event_channel, &local_err); if (local_err) { error_report_err(local_err); @@ -573,173 +585,173 @@ static void blk_handle_requests(struct XenBlkDev *b= lkdev) ioreq_runio_qemu_aio(ioreq); } =20 - if (blkdev->more_work && blkdev->requests_inflight < blkdev->max_reque= sts) { - qemu_bh_schedule(blkdev->bh); + if (dataplane->more_work && + dataplane->requests_inflight < dataplane->max_requests) { + qemu_bh_schedule(dataplane->bh); } } =20 static void blk_bh(void *opaque) { - struct XenBlkDev *blkdev =3D opaque; + XenBlockDataPlane *dataplane =3D opaque; =20 - aio_context_acquire(blkdev->ctx); - blk_handle_requests(blkdev); - aio_context_release(blkdev->ctx); + aio_context_acquire(dataplane->ctx); + blk_handle_requests(dataplane); + aio_context_release(dataplane->ctx); } =20 static void blk_event(void *opaque) { - struct XenBlkDev *blkdev =3D opaque; + XenBlockDataPlane *dataplane =3D opaque; =20 - qemu_bh_schedule(blkdev->bh); + qemu_bh_schedule(dataplane->bh); } =20 -struct XenBlkDev *xen_block_dataplane_create(XenDevice *xendev, - BlockConf *conf, - IOThread *iothread) +XenBlockDataPlane *xen_block_dataplane_create(XenDevice *xendev, + BlockConf *conf, + IOThread *iothread) { - struct XenBlkDev *blkdev =3D g_new0(struct XenBlkDev, 1); + XenBlockDataPlane *dataplane =3D g_new0(XenBlockDataPlane, 1); =20 - blkdev->xendev =3D xendev; - blkdev->file_blk =3D conf->logical_block_size; - blkdev->blk =3D conf->blk; - blkdev->file_size =3D blk_getlength(blkdev->blk); + dataplane->xendev =3D xendev; + dataplane->file_blk =3D conf->logical_block_size; + dataplane->blk =3D conf->blk; + dataplane->file_size =3D blk_getlength(dataplane->blk); =20 - QLIST_INIT(&blkdev->inflight); - QLIST_INIT(&blkdev->finished); - QLIST_INIT(&blkdev->freelist); + QLIST_INIT(&dataplane->inflight); + QLIST_INIT(&dataplane->finished); + QLIST_INIT(&dataplane->freelist); =20 if (iothread) { - blkdev->iothread =3D iothread; - object_ref(OBJECT(blkdev->iothread)); - blkdev->ctx =3D iothread_get_aio_context(blkdev->iothread); + dataplane->iothread =3D iothread; + object_ref(OBJECT(dataplane->iothread)); + dataplane->ctx =3D iothread_get_aio_context(dataplane->iothread); } else { - blkdev->ctx =3D qemu_get_aio_context(); + dataplane->ctx =3D qemu_get_aio_context(); } - blkdev->bh =3D aio_bh_new(blkdev->ctx, blk_bh, blkdev); + dataplane->bh =3D aio_bh_new(dataplane->ctx, blk_bh, dataplane); =20 - return blkdev; + return dataplane; } =20 -void xen_block_dataplane_destroy(struct XenBlkDev *blkdev) +void xen_block_dataplane_destroy(XenBlockDataPlane *dataplane) { struct ioreq *ioreq; =20 - if (!blkdev) { + if (!dataplane) { return; } =20 - while (!QLIST_EMPTY(&blkdev->freelist)) { - ioreq =3D QLIST_FIRST(&blkdev->freelist); + while (!QLIST_EMPTY(&dataplane->freelist)) { + ioreq =3D QLIST_FIRST(&dataplane->freelist); QLIST_REMOVE(ioreq, list); qemu_iovec_destroy(&ioreq->v); g_free(ioreq); } =20 - qemu_bh_delete(blkdev->bh); - if (blkdev->iothread) { - object_unref(OBJECT(blkdev->iothread)); + qemu_bh_delete(dataplane->bh); + if (dataplane->iothread) { + object_unref(OBJECT(dataplane->iothread)); } =20 - g_free(blkdev); + g_free(dataplane); } =20 - -void xen_block_dataplane_stop(struct XenBlkDev *blkdev) +void xen_block_dataplane_stop(XenBlockDataPlane *dataplane) { XenDevice *xendev; =20 - if (!blkdev) { + if (!dataplane) { return; } =20 - aio_context_acquire(blkdev->ctx); - blk_set_aio_context(blkdev->blk, qemu_get_aio_context()); - aio_context_release(blkdev->ctx); + aio_context_acquire(dataplane->ctx); + blk_set_aio_context(dataplane->blk, qemu_get_aio_context()); + aio_context_release(dataplane->ctx); =20 - xendev =3D blkdev->xendev; + xendev =3D dataplane->xendev; =20 - if (blkdev->event_channel) { + if (dataplane->event_channel) { Error *local_err =3D NULL; =20 - xen_device_unbind_event_channel(xendev, blkdev->event_channel, + xen_device_unbind_event_channel(xendev, dataplane->event_channel, &local_err); - blkdev->event_channel =3D NULL; + dataplane->event_channel =3D NULL; =20 if (local_err) { error_report_err(local_err); } } =20 - if (blkdev->sring) { + if (dataplane->sring) { Error *local_err =3D NULL; =20 - xen_device_unmap_grant_refs(xendev, blkdev->sring, - blkdev->nr_ring_ref, &local_err); - blkdev->sring =3D NULL; + xen_device_unmap_grant_refs(xendev, dataplane->sring, + dataplane->nr_ring_ref, &local_err); + dataplane->sring =3D NULL; =20 if (local_err) { error_report_err(local_err); } } =20 - g_free(blkdev->ring_ref); - blkdev->ring_ref =3D NULL; + g_free(dataplane->ring_ref); + dataplane->ring_ref =3D NULL; } =20 -void xen_block_dataplane_start(struct XenBlkDev *blkdev, +void xen_block_dataplane_start(XenBlockDataPlane *dataplane, const unsigned int ring_ref[], unsigned int nr_ring_ref, unsigned int event_channel, unsigned int protocol, Error **errp) { - XenDevice *xendev =3D blkdev->xendev; + XenDevice *xendev =3D dataplane->xendev; Error *local_err =3D NULL; unsigned int ring_size; unsigned int i; =20 - blkdev->nr_ring_ref =3D nr_ring_ref; - blkdev->ring_ref =3D g_new(unsigned int, nr_ring_ref); + dataplane->nr_ring_ref =3D nr_ring_ref; + dataplane->ring_ref =3D g_new(unsigned int, nr_ring_ref); =20 for (i =3D 0; i < nr_ring_ref; i++) { - blkdev->ring_ref[i] =3D ring_ref[i]; + dataplane->ring_ref[i] =3D ring_ref[i]; } =20 - blkdev->protocol =3D protocol; + dataplane->protocol =3D protocol; =20 - ring_size =3D XC_PAGE_SIZE * blkdev->nr_ring_ref; - switch (blkdev->protocol) { + ring_size =3D XC_PAGE_SIZE * dataplane->nr_ring_ref; + switch (dataplane->protocol) { case BLKIF_PROTOCOL_NATIVE: { - blkdev->max_requests =3D __CONST_RING_SIZE(blkif, ring_size); + dataplane->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= ); + dataplane->max_requests =3D __CONST_RING_SIZE(blkif_x86_32, ring_s= ize); break; } case BLKIF_PROTOCOL_X86_64: { - blkdev->max_requests =3D __CONST_RING_SIZE(blkif_x86_64, ring_size= ); + dataplane->max_requests =3D __CONST_RING_SIZE(blkif_x86_64, ring_s= ize); break; } default: - error_setg(errp, "unknown protocol %u", blkdev->protocol); + error_setg(errp, "unknown protocol %u", dataplane->protocol); return; } =20 - xen_device_set_max_grant_refs(xendev, blkdev->nr_ring_ref, + xen_device_set_max_grant_refs(xendev, dataplane->nr_ring_ref, &local_err); if (local_err) { error_propagate(errp, local_err); goto stop; } =20 - blkdev->sring =3D xen_device_map_grant_refs(xendev, - blkdev->ring_ref, - blkdev->nr_ring_ref, + dataplane->sring =3D xen_device_map_grant_refs(xendev, + dataplane->ring_ref, + dataplane->nr_ring_ref, PROT_READ | PROT_WRITE, &local_err); if (local_err) { @@ -747,46 +759,46 @@ void xen_block_dataplane_start(struct XenBlkDev *blkd= ev, goto stop; } =20 - switch (blkdev->protocol) { + switch (dataplane->protocol) { case BLKIF_PROTOCOL_NATIVE: { - blkif_sring_t *sring_native =3D blkdev->sring; + blkif_sring_t *sring_native =3D dataplane->sring; =20 - BACK_RING_INIT(&blkdev->rings.native, sring_native, ring_size); + BACK_RING_INIT(&dataplane->rings.native, sring_native, ring_size); break; } case BLKIF_PROTOCOL_X86_32: { - blkif_x86_32_sring_t *sring_x86_32 =3D blkdev->sring; + blkif_x86_32_sring_t *sring_x86_32 =3D dataplane->sring; =20 - BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32, + BACK_RING_INIT(&dataplane->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; + blkif_x86_64_sring_t *sring_x86_64 =3D dataplane->sring; =20 - BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, + BACK_RING_INIT(&dataplane->rings.x86_64_part, sring_x86_64, ring_size); break; } } =20 - blkdev->event_channel =3D + dataplane->event_channel =3D xen_device_bind_event_channel(xendev, event_channel, - blk_event, blkdev, + blk_event, dataplane, &local_err); if (local_err) { error_propagate(errp, local_err); goto stop; } =20 - aio_context_acquire(blkdev->ctx); - blk_set_aio_context(blkdev->blk, blkdev->ctx); - aio_context_release(blkdev->ctx); + aio_context_acquire(dataplane->ctx); + blk_set_aio_context(dataplane->blk, dataplane->ctx); + aio_context_release(dataplane->ctx); return; =20 stop: - xen_block_dataplane_stop(blkdev); + xen_block_dataplane_stop(dataplane); } diff --git a/hw/block/dataplane/xen-block.h b/hw/block/dataplane/xen-block.h index f31da38464..d6fa6d26dd 100644 --- a/hw/block/dataplane/xen-block.h +++ b/hw/block/dataplane/xen-block.h @@ -12,7 +12,7 @@ #include "hw/xen/xen-bus.h" #include "sysemu/iothread.h" =20 -typedef struct XenBlkDev XenBlockDataPlane; +typedef struct XenBlockDataPlane XenBlockDataPlane; =20 XenBlockDataPlane *xen_block_dataplane_create(XenDevice *xendev, BlockConf *conf, --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547129845369723.7028651306044; Thu, 10 Jan 2019 06:17:25 -0800 (PST) Received: from localhost ([127.0.0.1]:60535 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb9A-0001Tw-3y for importer@patchew.org; Thu, 10 Jan 2019 09:17:24 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57997) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb52-0005zL-4n for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghasP-00032B-N9 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:00:10 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12098) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghasP-00031h-CC for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:00:05 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263707" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:06 +0000 Message-ID: <20190110134917.16425-15-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 14/25] xen: remove 'ioreq' struct/varable/field names from dataplane/xen-block.c 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant This is a purely cosmetic patch that purges the name 'ioreq' from struct, variable and field names. (This name has been problematic for a long time as 'ioreq' is the name used for generic I/O requests coming from Xen). The patch replaces 'struct ioreq' with a new 'XenBlockRequest' type and 'ioreq' field/variable names with 'request', and then does necessary fix-up to adhere to coding style. Function names are not modified by this patch. They will be dealt with in a subsequent patch. No functional change. Signed-off-by: Paul Durrant Acked-by: Anthony Perard Signed-off-by: Anthony PERARD --- hw/block/dataplane/xen-block.c | 310 +++++++++++++++++---------------- 1 file changed, 156 insertions(+), 154 deletions(-) diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c index 1ff464973c..6788bbf338 100644 --- a/hw/block/dataplane/xen-block.c +++ b/hw/block/dataplane/xen-block.c @@ -28,7 +28,7 @@ #include "sysemu/iothread.h" #include "xen-block.h" =20 -struct ioreq { +typedef struct XenBlockRequest { blkif_request_t req; int16_t status; off_t start; @@ -39,9 +39,9 @@ struct ioreq { int aio_inflight; int aio_errors; XenBlockDataPlane *dataplane; - QLIST_ENTRY(ioreq) list; + QLIST_ENTRY(XenBlockRequest) list; BlockAcctCookie acct; -}; +} XenBlockRequest; =20 struct XenBlockDataPlane { XenDevice *xendev; @@ -54,9 +54,9 @@ struct XenBlockDataPlane { int protocol; blkif_back_rings_t rings; int more_work; - QLIST_HEAD(inflight_head, ioreq) inflight; - QLIST_HEAD(finished_head, ioreq) finished; - QLIST_HEAD(freelist_head, ioreq) freelist; + QLIST_HEAD(inflight_head, XenBlockRequest) inflight; + QLIST_HEAD(finished_head, XenBlockRequest) finished; + QLIST_HEAD(freelist_head, XenBlockRequest) freelist; int requests_total; int requests_inflight; int requests_finished; @@ -67,68 +67,68 @@ struct XenBlockDataPlane { AioContext *ctx; }; =20 -static void ioreq_reset(struct ioreq *ioreq) +static void ioreq_reset(XenBlockRequest *request) { - memset(&ioreq->req, 0, sizeof(ioreq->req)); - ioreq->status =3D 0; - ioreq->start =3D 0; - ioreq->buf =3D NULL; - ioreq->size =3D 0; - ioreq->presync =3D 0; + memset(&request->req, 0, sizeof(request->req)); + request->status =3D 0; + request->start =3D 0; + request->buf =3D NULL; + request->size =3D 0; + request->presync =3D 0; =20 - ioreq->aio_inflight =3D 0; - ioreq->aio_errors =3D 0; + request->aio_inflight =3D 0; + request->aio_errors =3D 0; =20 - ioreq->dataplane =3D NULL; - memset(&ioreq->list, 0, sizeof(ioreq->list)); - memset(&ioreq->acct, 0, sizeof(ioreq->acct)); + request->dataplane =3D NULL; + memset(&request->list, 0, sizeof(request->list)); + memset(&request->acct, 0, sizeof(request->acct)); =20 - qemu_iovec_reset(&ioreq->v); + qemu_iovec_reset(&request->v); } =20 -static struct ioreq *ioreq_start(XenBlockDataPlane *dataplane) +static XenBlockRequest *ioreq_start(XenBlockDataPlane *dataplane) { - struct ioreq *ioreq =3D NULL; + XenBlockRequest *request =3D NULL; =20 if (QLIST_EMPTY(&dataplane->freelist)) { if (dataplane->requests_total >=3D dataplane->max_requests) { goto out; } /* allocate new struct */ - ioreq =3D g_malloc0(sizeof(*ioreq)); - ioreq->dataplane =3D dataplane; + request =3D g_malloc0(sizeof(*request)); + request->dataplane =3D dataplane; dataplane->requests_total++; - qemu_iovec_init(&ioreq->v, 1); + qemu_iovec_init(&request->v, 1); } else { /* get one from freelist */ - ioreq =3D QLIST_FIRST(&dataplane->freelist); - QLIST_REMOVE(ioreq, list); + request =3D QLIST_FIRST(&dataplane->freelist); + QLIST_REMOVE(request, list); } - QLIST_INSERT_HEAD(&dataplane->inflight, ioreq, list); + QLIST_INSERT_HEAD(&dataplane->inflight, request, list); dataplane->requests_inflight++; =20 out: - return ioreq; + return request; } =20 -static void ioreq_finish(struct ioreq *ioreq) +static void ioreq_finish(XenBlockRequest *request) { - XenBlockDataPlane *dataplane =3D ioreq->dataplane; + XenBlockDataPlane *dataplane =3D request->dataplane; =20 - QLIST_REMOVE(ioreq, list); - QLIST_INSERT_HEAD(&dataplane->finished, ioreq, list); + QLIST_REMOVE(request, list); + QLIST_INSERT_HEAD(&dataplane->finished, request, list); dataplane->requests_inflight--; dataplane->requests_finished++; } =20 -static void ioreq_release(struct ioreq *ioreq, bool finish) +static void ioreq_release(XenBlockRequest *request, bool finish) { - XenBlockDataPlane *dataplane =3D ioreq->dataplane; + XenBlockDataPlane *dataplane =3D request->dataplane; =20 - QLIST_REMOVE(ioreq, list); - ioreq_reset(ioreq); - ioreq->dataplane =3D dataplane; - QLIST_INSERT_HEAD(&dataplane->freelist, ioreq, list); + QLIST_REMOVE(request, list); + ioreq_reset(request); + request->dataplane =3D dataplane; + QLIST_INSERT_HEAD(&dataplane->freelist, request, list); if (finish) { dataplane->requests_finished--; } else { @@ -140,18 +140,18 @@ static void ioreq_release(struct ioreq *ioreq, bool f= inish) * translate request into iovec + start offset * do sanity checks along the way */ -static int ioreq_parse(struct ioreq *ioreq) +static int ioreq_parse(XenBlockRequest *request) { - XenBlockDataPlane *dataplane =3D ioreq->dataplane; + XenBlockDataPlane *dataplane =3D request->dataplane; size_t len; int i; =20 - switch (ioreq->req.operation) { + switch (request->req.operation) { case BLKIF_OP_READ: break; case BLKIF_OP_FLUSH_DISKCACHE: - ioreq->presync =3D 1; - if (!ioreq->req.nr_segments) { + request->presync =3D 1; + if (!request->req.nr_segments) { return 0; } /* fall through */ @@ -160,77 +160,78 @@ static int ioreq_parse(struct ioreq *ioreq) case BLKIF_OP_DISCARD: return 0; default: - error_report("error: unknown operation (%d)", ioreq->req.operation= ); + error_report("error: unknown operation (%d)", request->req.operati= on); goto err; }; =20 - if (ioreq->req.operation !=3D BLKIF_OP_READ && + if (request->req.operation !=3D BLKIF_OP_READ && blk_is_read_only(dataplane->blk)) { error_report("error: write req for ro device"); goto err; } =20 - ioreq->start =3D ioreq->req.sector_number * dataplane->file_blk; - for (i =3D 0; i < ioreq->req.nr_segments; i++) { + request->start =3D request->req.sector_number * dataplane->file_blk; + for (i =3D 0; i < request->req.nr_segments; i++) { if (i =3D=3D BLKIF_MAX_SEGMENTS_PER_REQUEST) { error_report("error: nr_segments too big"); goto err; } - if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) { + if (request->req.seg[i].first_sect > request->req.seg[i].last_sect= ) { error_report("error: first > last sector"); goto err; } - if (ioreq->req.seg[i].last_sect * dataplane->file_blk >=3D XC_PAGE= _SIZE) { + if (request->req.seg[i].last_sect * dataplane->file_blk >=3D + XC_PAGE_SIZE) { error_report("error: page crossing"); goto err; } =20 - len =3D (ioreq->req.seg[i].last_sect - - ioreq->req.seg[i].first_sect + 1) * dataplane->file_blk; - ioreq->size +=3D len; + len =3D (request->req.seg[i].last_sect - + request->req.seg[i].first_sect + 1) * dataplane->file_blk; + request->size +=3D len; } - if (ioreq->start + ioreq->size > dataplane->file_size) { + if (request->start + request->size > dataplane->file_size) { error_report("error: access beyond end of file"); goto err; } return 0; =20 err: - ioreq->status =3D BLKIF_RSP_ERROR; + request->status =3D BLKIF_RSP_ERROR; return -1; } =20 -static int ioreq_grant_copy(struct ioreq *ioreq) +static int ioreq_grant_copy(XenBlockRequest *request) { - XenBlockDataPlane *dataplane =3D ioreq->dataplane; + XenBlockDataPlane *dataplane =3D request->dataplane; XenDevice *xendev =3D dataplane->xendev; XenDeviceGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST]; int i, count; int64_t file_blk =3D dataplane->file_blk; - bool to_domain =3D (ioreq->req.operation =3D=3D BLKIF_OP_READ); - void *virt =3D ioreq->buf; + bool to_domain =3D (request->req.operation =3D=3D BLKIF_OP_READ); + void *virt =3D request->buf; Error *local_err =3D NULL; =20 - if (ioreq->req.nr_segments =3D=3D 0) { + if (request->req.nr_segments =3D=3D 0) { return 0; } =20 - count =3D ioreq->req.nr_segments; + count =3D request->req.nr_segments; =20 for (i =3D 0; i < count; i++) { if (to_domain) { - segs[i].dest.foreign.ref =3D ioreq->req.seg[i].gref; - segs[i].dest.foreign.offset =3D ioreq->req.seg[i].first_sect * + segs[i].dest.foreign.ref =3D request->req.seg[i].gref; + segs[i].dest.foreign.offset =3D request->req.seg[i].first_sect= * file_blk; segs[i].source.virt =3D virt; } else { - segs[i].source.foreign.ref =3D ioreq->req.seg[i].gref; - segs[i].source.foreign.offset =3D ioreq->req.seg[i].first_sect= * + segs[i].source.foreign.ref =3D request->req.seg[i].gref; + segs[i].source.foreign.offset =3D request->req.seg[i].first_se= ct * file_blk; segs[i].dest.virt =3D virt; } - segs[i].len =3D (ioreq->req.seg[i].last_sect - - ioreq->req.seg[i].first_sect + 1) * file_blk; + segs[i].len =3D (request->req.seg[i].last_sect - + request->req.seg[i].first_sect + 1) * file_blk; virt +=3D segs[i].len; } =20 @@ -239,72 +240,72 @@ static int ioreq_grant_copy(struct ioreq *ioreq) if (local_err) { error_reportf_err(local_err, "failed to copy data: "); =20 - ioreq->aio_errors++; + request->aio_errors++; return -1; } =20 return 0; } =20 -static int ioreq_runio_qemu_aio(struct ioreq *ioreq); +static int ioreq_runio_qemu_aio(XenBlockRequest *request); =20 static void qemu_aio_complete(void *opaque, int ret) { - struct ioreq *ioreq =3D opaque; - XenBlockDataPlane *dataplane =3D ioreq->dataplane; + XenBlockRequest *request =3D opaque; + XenBlockDataPlane *dataplane =3D request->dataplane; =20 aio_context_acquire(dataplane->ctx); =20 if (ret !=3D 0) { error_report("%s I/O error", - ioreq->req.operation =3D=3D BLKIF_OP_READ ? + request->req.operation =3D=3D BLKIF_OP_READ ? "read" : "write"); - ioreq->aio_errors++; + request->aio_errors++; } =20 - ioreq->aio_inflight--; - if (ioreq->presync) { - ioreq->presync =3D 0; - ioreq_runio_qemu_aio(ioreq); + request->aio_inflight--; + if (request->presync) { + request->presync =3D 0; + ioreq_runio_qemu_aio(request); goto done; } - if (ioreq->aio_inflight > 0) { + if (request->aio_inflight > 0) { goto done; } =20 - switch (ioreq->req.operation) { + switch (request->req.operation) { case BLKIF_OP_READ: - /* in case of failure ioreq->aio_errors is increased */ + /* in case of failure request->aio_errors is increased */ if (ret =3D=3D 0) { - ioreq_grant_copy(ioreq); + ioreq_grant_copy(request); } - qemu_vfree(ioreq->buf); + qemu_vfree(request->buf); break; case BLKIF_OP_WRITE: case BLKIF_OP_FLUSH_DISKCACHE: - if (!ioreq->req.nr_segments) { + if (!request->req.nr_segments) { break; } - qemu_vfree(ioreq->buf); + qemu_vfree(request->buf); break; default: break; } =20 - ioreq->status =3D ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY; - ioreq_finish(ioreq); + request->status =3D request->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_= OKAY; + ioreq_finish(request); =20 - switch (ioreq->req.operation) { + switch (request->req.operation) { case BLKIF_OP_WRITE: case BLKIF_OP_FLUSH_DISKCACHE: - if (!ioreq->req.nr_segments) { + if (!request->req.nr_segments) { break; } case BLKIF_OP_READ: - if (ioreq->status =3D=3D BLKIF_RSP_OKAY) { - block_acct_done(blk_get_stats(dataplane->blk), &ioreq->acct); + if (request->status =3D=3D BLKIF_RSP_OKAY) { + block_acct_done(blk_get_stats(dataplane->blk), &request->acct); } else { - block_acct_failed(blk_get_stats(dataplane->blk), &ioreq->acct); + block_acct_failed(blk_get_stats(dataplane->blk), &request->acc= t); } break; case BLKIF_OP_DISCARD: @@ -317,10 +318,11 @@ static void qemu_aio_complete(void *opaque, int ret) aio_context_release(dataplane->ctx); } =20 -static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_n= umber, +static bool blk_split_discard(XenBlockRequest *request, + blkif_sector_t sector_number, uint64_t nr_sectors) { - XenBlockDataPlane *dataplane =3D ioreq->dataplane; + XenBlockDataPlane *dataplane =3D request->dataplane; int64_t byte_offset; int byte_chunk; uint64_t byte_remaining, limit; @@ -339,9 +341,9 @@ static bool blk_split_discard(struct ioreq *ioreq, blki= f_sector_t sector_number, =20 do { byte_chunk =3D byte_remaining > limit ? limit : byte_remaining; - ioreq->aio_inflight++; + request->aio_inflight++; blk_aio_pdiscard(dataplane->blk, byte_offset, byte_chunk, - qemu_aio_complete, ioreq); + qemu_aio_complete, request); byte_remaining -=3D byte_chunk; byte_offset +=3D byte_chunk; } while (byte_remaining > 0); @@ -349,53 +351,53 @@ static bool blk_split_discard(struct ioreq *ioreq, bl= kif_sector_t sector_number, return true; } =20 -static int ioreq_runio_qemu_aio(struct ioreq *ioreq) +static int ioreq_runio_qemu_aio(XenBlockRequest *request) { - XenBlockDataPlane *dataplane =3D ioreq->dataplane; - - ioreq->buf =3D qemu_memalign(XC_PAGE_SIZE, ioreq->size); - if (ioreq->req.nr_segments && - (ioreq->req.operation =3D=3D BLKIF_OP_WRITE || - ioreq->req.operation =3D=3D BLKIF_OP_FLUSH_DISKCACHE) && - ioreq_grant_copy(ioreq)) { - qemu_vfree(ioreq->buf); + XenBlockDataPlane *dataplane =3D request->dataplane; + + request->buf =3D qemu_memalign(XC_PAGE_SIZE, request->size); + if (request->req.nr_segments && + (request->req.operation =3D=3D BLKIF_OP_WRITE || + request->req.operation =3D=3D BLKIF_OP_FLUSH_DISKCACHE) && + ioreq_grant_copy(request)) { + qemu_vfree(request->buf); goto err; } =20 - ioreq->aio_inflight++; - if (ioreq->presync) { - blk_aio_flush(ioreq->dataplane->blk, qemu_aio_complete, ioreq); + request->aio_inflight++; + if (request->presync) { + blk_aio_flush(request->dataplane->blk, qemu_aio_complete, request); return 0; } =20 - switch (ioreq->req.operation) { + switch (request->req.operation) { case BLKIF_OP_READ: - qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size); - block_acct_start(blk_get_stats(dataplane->blk), &ioreq->acct, - ioreq->v.size, BLOCK_ACCT_READ); - ioreq->aio_inflight++; - blk_aio_preadv(dataplane->blk, ioreq->start, &ioreq->v, 0, - qemu_aio_complete, ioreq); + qemu_iovec_add(&request->v, request->buf, request->size); + block_acct_start(blk_get_stats(dataplane->blk), &request->acct, + request->v.size, BLOCK_ACCT_READ); + request->aio_inflight++; + blk_aio_preadv(dataplane->blk, request->start, &request->v, 0, + qemu_aio_complete, request); break; case BLKIF_OP_WRITE: case BLKIF_OP_FLUSH_DISKCACHE: - if (!ioreq->req.nr_segments) { + if (!request->req.nr_segments) { break; } =20 - qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size); - block_acct_start(blk_get_stats(dataplane->blk), &ioreq->acct, - ioreq->v.size, - ioreq->req.operation =3D=3D BLKIF_OP_WRITE ? + qemu_iovec_add(&request->v, request->buf, request->size); + block_acct_start(blk_get_stats(dataplane->blk), &request->acct, + request->v.size, + request->req.operation =3D=3D BLKIF_OP_WRITE ? BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH); - ioreq->aio_inflight++; - blk_aio_pwritev(dataplane->blk, ioreq->start, &ioreq->v, 0, - qemu_aio_complete, ioreq); + request->aio_inflight++; + blk_aio_pwritev(dataplane->blk, request->start, &request->v, 0, + qemu_aio_complete, request); break; case BLKIF_OP_DISCARD: { - struct blkif_request_discard *req =3D (void *)&ioreq->req; - if (!blk_split_discard(ioreq, req->sector_number, req->nr_sectors)= ) { + struct blkif_request_discard *req =3D (void *)&request->req; + if (!blk_split_discard(request, req->sector_number, req->nr_sector= s)) { goto err; } break; @@ -405,19 +407,19 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq) goto err; } =20 - qemu_aio_complete(ioreq, 0); + qemu_aio_complete(request, 0); =20 return 0; =20 err: - ioreq_finish(ioreq); - ioreq->status =3D BLKIF_RSP_ERROR; + ioreq_finish(request); + request->status =3D BLKIF_RSP_ERROR; return -1; } =20 -static int blk_send_response_one(struct ioreq *ioreq) +static int blk_send_response_one(XenBlockRequest *request) { - XenBlockDataPlane *dataplane =3D ioreq->dataplane; + XenBlockDataPlane *dataplane =3D request->dataplane; int send_notify =3D 0; int have_requests =3D 0; blkif_response_t *resp; @@ -443,9 +445,9 @@ static int blk_send_response_one(struct ioreq *ioreq) return 0; } =20 - resp->id =3D ioreq->req.id; - resp->operation =3D ioreq->req.operation; - resp->status =3D ioreq->status; + resp->id =3D request->req.id; + resp->operation =3D request->req.operation; + resp->status =3D request->status; =20 dataplane->rings.common.rsp_prod_pvt++; =20 @@ -473,13 +475,13 @@ static int blk_send_response_one(struct ioreq *ioreq) /* walk finished list, send outstanding responses, free requests */ static void blk_send_response_all(XenBlockDataPlane *dataplane) { - struct ioreq *ioreq; + XenBlockRequest *request; int send_notify =3D 0; =20 while (!QLIST_EMPTY(&dataplane->finished)) { - ioreq =3D QLIST_FIRST(&dataplane->finished); - send_notify +=3D blk_send_response_one(ioreq); - ioreq_release(ioreq, true); + request =3D QLIST_FIRST(&dataplane->finished); + send_notify +=3D blk_send_response_one(request); + ioreq_release(request, true); } if (send_notify) { Error *local_err =3D NULL; @@ -493,29 +495,29 @@ static void blk_send_response_all(XenBlockDataPlane *= dataplane) } } =20 -static int blk_get_request(XenBlockDataPlane *dataplane, struct ioreq *ior= eq, - RING_IDX rc) +static int blk_get_request(XenBlockDataPlane *dataplane, + XenBlockRequest *request, RING_IDX rc) { switch (dataplane->protocol) { case BLKIF_PROTOCOL_NATIVE: { blkif_request_t *req =3D RING_GET_REQUEST(&dataplane->rings.native, rc); =20 - memcpy(&ioreq->req, req, sizeof(ioreq->req)); + memcpy(&request->req, req, sizeof(request->req)); break; } case BLKIF_PROTOCOL_X86_32: { blkif_x86_32_request_t *req =3D RING_GET_REQUEST(&dataplane->rings.x86_32_part, rc); =20 - blkif_get_x86_32_req(&ioreq->req, req); + blkif_get_x86_32_req(&request->req, req); break; } case BLKIF_PROTOCOL_X86_64: { blkif_x86_64_request_t *req =3D RING_GET_REQUEST(&dataplane->rings.x86_64_part, rc); =20 - blkif_get_x86_64_req(&ioreq->req, req); + blkif_get_x86_64_req(&request->req, req); break; } } @@ -527,7 +529,7 @@ static int blk_get_request(XenBlockDataPlane *dataplane= , struct ioreq *ioreq, static void blk_handle_requests(XenBlockDataPlane *dataplane) { RING_IDX rc, rp; - struct ioreq *ioreq; + XenBlockRequest *request; =20 dataplane->more_work =3D 0; =20 @@ -541,18 +543,18 @@ static void blk_handle_requests(XenBlockDataPlane *da= taplane) if (RING_REQUEST_CONS_OVERFLOW(&dataplane->rings.common, rc)) { break; } - ioreq =3D ioreq_start(dataplane); - if (ioreq =3D=3D NULL) { + request =3D ioreq_start(dataplane); + if (request =3D=3D NULL) { dataplane->more_work++; break; } - blk_get_request(dataplane, ioreq, rc); + blk_get_request(dataplane, request, rc); dataplane->rings.common.req_cons =3D ++rc; =20 /* parse them */ - if (ioreq_parse(ioreq) !=3D 0) { + if (ioreq_parse(request) !=3D 0) { =20 - switch (ioreq->req.operation) { + switch (request->req.operation) { case BLKIF_OP_READ: block_acct_invalid(blk_get_stats(dataplane->blk), BLOCK_ACCT_READ); @@ -568,7 +570,7 @@ static void blk_handle_requests(XenBlockDataPlane *data= plane) break; }; =20 - if (blk_send_response_one(ioreq)) { + if (blk_send_response_one(request)) { Error *local_err =3D NULL; =20 xen_device_notify_event_channel(dataplane->xendev, @@ -578,11 +580,11 @@ static void blk_handle_requests(XenBlockDataPlane *da= taplane) error_report_err(local_err); } } - ioreq_release(ioreq, false); + ioreq_release(request, false); continue; } =20 - ioreq_runio_qemu_aio(ioreq); + ioreq_runio_qemu_aio(request); } =20 if (dataplane->more_work && @@ -636,17 +638,17 @@ XenBlockDataPlane *xen_block_dataplane_create(XenDevi= ce *xendev, =20 void xen_block_dataplane_destroy(XenBlockDataPlane *dataplane) { - struct ioreq *ioreq; + XenBlockRequest *request; =20 if (!dataplane) { return; } =20 while (!QLIST_EMPTY(&dataplane->freelist)) { - ioreq =3D QLIST_FIRST(&dataplane->freelist); - QLIST_REMOVE(ioreq, list); - qemu_iovec_destroy(&ioreq->v); - g_free(ioreq); + request =3D QLIST_FIRST(&dataplane->freelist); + QLIST_REMOVE(request, list); + qemu_iovec_destroy(&request->v); + g_free(request); } =20 qemu_bh_delete(dataplane->bh); --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547130673662136.9609733868624; Thu, 10 Jan 2019 06:31:13 -0800 (PST) Received: from localhost ([127.0.0.1]:35724 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghbMR-00043C-Kp for importer@patchew.org; Thu, 10 Jan 2019 09:31:07 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58408) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb5N-0006SG-4e for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gharH-0002JD-R4 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:58:57 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12008) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gharH-0001xV-I2 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:58:55 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263642" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:07 +0000 Message-ID: <20190110134917.16425-16-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 15/25] xen: purge 'blk' and 'ioreq' from function names in dataplane/xen-block.c 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant This is a purely cosmetic patch that purges remaining use of 'blk' and 'ioreq' in local function names, and then makes sure all functions are prefixed with 'xen_block_'. No functional change. Signed-off-by: Paul Durrant Acked-by: Anthony Perard Signed-off-by: Anthony PERARD --- hw/block/dataplane/xen-block.c | 90 +++++++++++++++++----------------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c index 6788bbf338..8e3965e171 100644 --- a/hw/block/dataplane/xen-block.c +++ b/hw/block/dataplane/xen-block.c @@ -67,7 +67,7 @@ struct XenBlockDataPlane { AioContext *ctx; }; =20 -static void ioreq_reset(XenBlockRequest *request) +static void reset_request(XenBlockRequest *request) { memset(&request->req, 0, sizeof(request->req)); request->status =3D 0; @@ -86,7 +86,7 @@ static void ioreq_reset(XenBlockRequest *request) qemu_iovec_reset(&request->v); } =20 -static XenBlockRequest *ioreq_start(XenBlockDataPlane *dataplane) +static XenBlockRequest *xen_block_start_request(XenBlockDataPlane *datapla= ne) { XenBlockRequest *request =3D NULL; =20 @@ -111,7 +111,7 @@ static XenBlockRequest *ioreq_start(XenBlockDataPlane *= dataplane) return request; } =20 -static void ioreq_finish(XenBlockRequest *request) +static void xen_block_finish_request(XenBlockRequest *request) { XenBlockDataPlane *dataplane =3D request->dataplane; =20 @@ -121,12 +121,12 @@ static void ioreq_finish(XenBlockRequest *request) dataplane->requests_finished++; } =20 -static void ioreq_release(XenBlockRequest *request, bool finish) +static void xen_block_release_request(XenBlockRequest *request, bool finis= h) { XenBlockDataPlane *dataplane =3D request->dataplane; =20 QLIST_REMOVE(request, list); - ioreq_reset(request); + reset_request(request); request->dataplane =3D dataplane; QLIST_INSERT_HEAD(&dataplane->freelist, request, list); if (finish) { @@ -140,7 +140,7 @@ static void ioreq_release(XenBlockRequest *request, boo= l finish) * translate request into iovec + start offset * do sanity checks along the way */ -static int ioreq_parse(XenBlockRequest *request) +static int xen_block_parse_request(XenBlockRequest *request) { XenBlockDataPlane *dataplane =3D request->dataplane; size_t len; @@ -201,7 +201,7 @@ static int ioreq_parse(XenBlockRequest *request) return -1; } =20 -static int ioreq_grant_copy(XenBlockRequest *request) +static int xen_block_copy_request(XenBlockRequest *request) { XenBlockDataPlane *dataplane =3D request->dataplane; XenDevice *xendev =3D dataplane->xendev; @@ -247,9 +247,9 @@ static int ioreq_grant_copy(XenBlockRequest *request) return 0; } =20 -static int ioreq_runio_qemu_aio(XenBlockRequest *request); +static int xen_block_do_aio(XenBlockRequest *request); =20 -static void qemu_aio_complete(void *opaque, int ret) +static void xen_block_complete_aio(void *opaque, int ret) { XenBlockRequest *request =3D opaque; XenBlockDataPlane *dataplane =3D request->dataplane; @@ -266,7 +266,7 @@ static void qemu_aio_complete(void *opaque, int ret) request->aio_inflight--; if (request->presync) { request->presync =3D 0; - ioreq_runio_qemu_aio(request); + xen_block_do_aio(request); goto done; } if (request->aio_inflight > 0) { @@ -277,7 +277,7 @@ static void qemu_aio_complete(void *opaque, int ret) case BLKIF_OP_READ: /* in case of failure request->aio_errors is increased */ if (ret =3D=3D 0) { - ioreq_grant_copy(request); + xen_block_copy_request(request); } qemu_vfree(request->buf); break; @@ -293,7 +293,7 @@ static void qemu_aio_complete(void *opaque, int ret) } =20 request->status =3D request->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_= OKAY; - ioreq_finish(request); + xen_block_finish_request(request); =20 switch (request->req.operation) { case BLKIF_OP_WRITE: @@ -318,9 +318,9 @@ static void qemu_aio_complete(void *opaque, int ret) aio_context_release(dataplane->ctx); } =20 -static bool blk_split_discard(XenBlockRequest *request, - blkif_sector_t sector_number, - uint64_t nr_sectors) +static bool xen_block_split_discard(XenBlockRequest *request, + blkif_sector_t sector_number, + uint64_t nr_sectors) { XenBlockDataPlane *dataplane =3D request->dataplane; int64_t byte_offset; @@ -343,7 +343,7 @@ static bool blk_split_discard(XenBlockRequest *request, byte_chunk =3D byte_remaining > limit ? limit : byte_remaining; request->aio_inflight++; blk_aio_pdiscard(dataplane->blk, byte_offset, byte_chunk, - qemu_aio_complete, request); + xen_block_complete_aio, request); byte_remaining -=3D byte_chunk; byte_offset +=3D byte_chunk; } while (byte_remaining > 0); @@ -351,7 +351,7 @@ static bool blk_split_discard(XenBlockRequest *request, return true; } =20 -static int ioreq_runio_qemu_aio(XenBlockRequest *request) +static int xen_block_do_aio(XenBlockRequest *request) { XenBlockDataPlane *dataplane =3D request->dataplane; =20 @@ -359,14 +359,15 @@ static int ioreq_runio_qemu_aio(XenBlockRequest *requ= est) if (request->req.nr_segments && (request->req.operation =3D=3D BLKIF_OP_WRITE || request->req.operation =3D=3D BLKIF_OP_FLUSH_DISKCACHE) && - ioreq_grant_copy(request)) { + xen_block_copy_request(request)) { qemu_vfree(request->buf); goto err; } =20 request->aio_inflight++; if (request->presync) { - blk_aio_flush(request->dataplane->blk, qemu_aio_complete, request); + blk_aio_flush(request->dataplane->blk, xen_block_complete_aio, + request); return 0; } =20 @@ -377,7 +378,7 @@ static int ioreq_runio_qemu_aio(XenBlockRequest *reques= t) request->v.size, BLOCK_ACCT_READ); request->aio_inflight++; blk_aio_preadv(dataplane->blk, request->start, &request->v, 0, - qemu_aio_complete, request); + xen_block_complete_aio, request); break; case BLKIF_OP_WRITE: case BLKIF_OP_FLUSH_DISKCACHE: @@ -392,12 +393,13 @@ static int ioreq_runio_qemu_aio(XenBlockRequest *requ= est) BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH); request->aio_inflight++; blk_aio_pwritev(dataplane->blk, request->start, &request->v, 0, - qemu_aio_complete, request); + xen_block_complete_aio, request); break; case BLKIF_OP_DISCARD: { struct blkif_request_discard *req =3D (void *)&request->req; - if (!blk_split_discard(request, req->sector_number, req->nr_sector= s)) { + if (!xen_block_split_discard(request, req->sector_number, + req->nr_sectors)) { goto err; } break; @@ -407,17 +409,17 @@ static int ioreq_runio_qemu_aio(XenBlockRequest *requ= est) goto err; } =20 - qemu_aio_complete(request, 0); + xen_block_complete_aio(request, 0); =20 return 0; =20 err: - ioreq_finish(request); + xen_block_finish_request(request); request->status =3D BLKIF_RSP_ERROR; return -1; } =20 -static int blk_send_response_one(XenBlockRequest *request) +static int xen_block_send_response_one(XenBlockRequest *request) { XenBlockDataPlane *dataplane =3D request->dataplane; int send_notify =3D 0; @@ -473,15 +475,15 @@ static int blk_send_response_one(XenBlockRequest *req= uest) } =20 /* walk finished list, send outstanding responses, free requests */ -static void blk_send_response_all(XenBlockDataPlane *dataplane) +static void xen_block_send_response_all(XenBlockDataPlane *dataplane) { XenBlockRequest *request; int send_notify =3D 0; =20 while (!QLIST_EMPTY(&dataplane->finished)) { request =3D QLIST_FIRST(&dataplane->finished); - send_notify +=3D blk_send_response_one(request); - ioreq_release(request, true); + send_notify +=3D xen_block_send_response_one(request); + xen_block_release_request(request, true); } if (send_notify) { Error *local_err =3D NULL; @@ -495,8 +497,8 @@ static void blk_send_response_all(XenBlockDataPlane *da= taplane) } } =20 -static int blk_get_request(XenBlockDataPlane *dataplane, - XenBlockRequest *request, RING_IDX rc) +static int xen_block_get_request(XenBlockDataPlane *dataplane, + XenBlockRequest *request, RING_IDX rc) { switch (dataplane->protocol) { case BLKIF_PROTOCOL_NATIVE: { @@ -526,7 +528,7 @@ static int blk_get_request(XenBlockDataPlane *dataplane, return 0; } =20 -static void blk_handle_requests(XenBlockDataPlane *dataplane) +static void xen_block_handle_requests(XenBlockDataPlane *dataplane) { RING_IDX rc, rp; XenBlockRequest *request; @@ -537,23 +539,22 @@ static void blk_handle_requests(XenBlockDataPlane *da= taplane) rp =3D dataplane->rings.common.sring->req_prod; xen_rmb(); /* Ensure we see queued requests up to 'rp'. */ =20 - blk_send_response_all(dataplane); + xen_block_send_response_all(dataplane); while (rc !=3D rp) { /* pull request from ring */ if (RING_REQUEST_CONS_OVERFLOW(&dataplane->rings.common, rc)) { break; } - request =3D ioreq_start(dataplane); + request =3D xen_block_start_request(dataplane); if (request =3D=3D NULL) { dataplane->more_work++; break; } - blk_get_request(dataplane, request, rc); + xen_block_get_request(dataplane, request, rc); dataplane->rings.common.req_cons =3D ++rc; =20 /* parse them */ - if (ioreq_parse(request) !=3D 0) { - + if (xen_block_parse_request(request) !=3D 0) { switch (request->req.operation) { case BLKIF_OP_READ: block_acct_invalid(blk_get_stats(dataplane->blk), @@ -570,7 +571,7 @@ static void blk_handle_requests(XenBlockDataPlane *data= plane) break; }; =20 - if (blk_send_response_one(request)) { + if (xen_block_send_response_one(request)) { Error *local_err =3D NULL; =20 xen_device_notify_event_channel(dataplane->xendev, @@ -580,11 +581,11 @@ static void blk_handle_requests(XenBlockDataPlane *da= taplane) error_report_err(local_err); } } - ioreq_release(request, false); + xen_block_release_request(request, false); continue; } =20 - ioreq_runio_qemu_aio(request); + xen_block_do_aio(request); } =20 if (dataplane->more_work && @@ -593,16 +594,16 @@ static void blk_handle_requests(XenBlockDataPlane *da= taplane) } } =20 -static void blk_bh(void *opaque) +static void xen_block_dataplane_bh(void *opaque) { XenBlockDataPlane *dataplane =3D opaque; =20 aio_context_acquire(dataplane->ctx); - blk_handle_requests(dataplane); + xen_block_handle_requests(dataplane); aio_context_release(dataplane->ctx); } =20 -static void blk_event(void *opaque) +static void xen_block_dataplane_event(void *opaque) { XenBlockDataPlane *dataplane =3D opaque; =20 @@ -631,7 +632,8 @@ XenBlockDataPlane *xen_block_dataplane_create(XenDevice= *xendev, } else { dataplane->ctx =3D qemu_get_aio_context(); } - dataplane->bh =3D aio_bh_new(dataplane->ctx, blk_bh, dataplane); + dataplane->bh =3D aio_bh_new(dataplane->ctx, xen_block_dataplane_bh, + dataplane); =20 return dataplane; } @@ -789,7 +791,7 @@ void xen_block_dataplane_start(XenBlockDataPlane *datap= lane, =20 dataplane->event_channel =3D xen_device_bind_event_channel(xendev, event_channel, - blk_event, dataplane, + xen_block_dataplane_event, dataplane, &local_err); if (local_err) { error_propagate(errp, local_err); --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547130168725645.2047843679712; Thu, 10 Jan 2019 06:22:48 -0800 (PST) Received: from localhost ([127.0.0.1]:33593 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghbEN-0005R6-Gs for importer@patchew.org; Thu, 10 Jan 2019 09:22:47 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58291) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb5B-0006I3-H4 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gharU-0002Qn-Py for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:11 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12049) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gharU-0002QK-Ec for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:08 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263679" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:08 +0000 Message-ID: <20190110134917.16425-17-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 16/25] xen: add implementations of xen-block connect and disconnect functions... 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant ...and wire in the dataplane. This patch adds the remaining code to make the xen-block XenDevice functional. The parameters that a block frontend expects to find are populated in the backend xenstore area, and the 'ring-ref' and 'event-channel' values specified in the frontend xenstore area are mapped/bound and used to set up the dataplane. Signed-off-by: Paul Durrant Reviewed-by: Anthony Perard Signed-off-by: Anthony PERARD --- hw/block/xen-block.c | 166 ++++++++++++++++++++++++++++++++ hw/xen/trace-events | 3 + hw/xen/xen-bus.c | 187 ++++++++++++++++++++++++++++++++----- include/hw/xen/xen-block.h | 9 ++ include/hw/xen/xen-bus.h | 14 ++- 5 files changed, 353 insertions(+), 26 deletions(-) diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c index 3a963b0383..a7c37c185a 100644 --- a/hw/block/xen-block.c +++ b/hw/block/xen-block.c @@ -10,7 +10,13 @@ #include "qapi/error.h" #include "qapi/visitor.h" #include "hw/hw.h" +#include "hw/xen/xen_common.h" +#include "hw/block/xen_blkif.h" #include "hw/xen/xen-block.h" +#include "sysemu/blockdev.h" +#include "sysemu/block-backend.h" +#include "sysemu/iothread.h" +#include "dataplane/xen-block.h" #include "trace.h" =20 static char *xen_block_get_name(XenDevice *xendev, Error **errp) @@ -28,6 +34,8 @@ static void xen_block_disconnect(XenDevice *xendev, Error= **errp) XenBlockVdev *vdev =3D &blockdev->props.vdev; =20 trace_xen_block_disconnect(type, vdev->disk, vdev->partition); + + xen_block_dataplane_stop(blockdev->dataplane); } =20 static void xen_block_connect(XenDevice *xendev, Error **errp) @@ -35,8 +43,72 @@ static void xen_block_connect(XenDevice *xendev, Error *= *errp) XenBlockDevice *blockdev =3D XEN_BLOCK_DEVICE(xendev); const char *type =3D object_get_typename(OBJECT(blockdev)); XenBlockVdev *vdev =3D &blockdev->props.vdev; + unsigned int order, nr_ring_ref, *ring_ref, event_channel, protocol; + char *str; =20 trace_xen_block_connect(type, vdev->disk, vdev->partition); + + if (xen_device_frontend_scanf(xendev, "ring-page-order", "%u", + &order) !=3D 1) { + nr_ring_ref =3D 1; + ring_ref =3D g_new(unsigned int, nr_ring_ref); + + if (xen_device_frontend_scanf(xendev, "ring-ref", "%u", + &ring_ref[0]) !=3D 1) { + error_setg(errp, "failed to read ring-ref"); + g_free(ring_ref); + return; + } + } else if (order <=3D blockdev->props.max_ring_page_order) { + unsigned int i; + + nr_ring_ref =3D 1 << order; + ring_ref =3D g_new(unsigned int, nr_ring_ref); + + for (i =3D 0; i < nr_ring_ref; i++) { + const char *key =3D g_strdup_printf("ring-ref%u", i); + + if (xen_device_frontend_scanf(xendev, key, "%u", + &ring_ref[i]) !=3D 1) { + error_setg(errp, "failed to read %s", key); + g_free((gpointer)key); + g_free(ring_ref); + return; + } + + g_free((gpointer)key); + } + } else { + error_setg(errp, "invalid ring-page-order (%d)", order); + return; + } + + if (xen_device_frontend_scanf(xendev, "event-channel", "%u", + &event_channel) !=3D 1) { + error_setg(errp, "failed to read event-channel"); + g_free(ring_ref); + return; + } + + if (xen_device_frontend_scanf(xendev, "protocol", "%ms", + &str) !=3D 1) { + protocol =3D BLKIF_PROTOCOL_NATIVE; + } else { + if (strcmp(str, XEN_IO_PROTO_ABI_X86_32) =3D=3D 0) { + protocol =3D BLKIF_PROTOCOL_X86_32; + } else if (strcmp(str, XEN_IO_PROTO_ABI_X86_64) =3D=3D 0) { + protocol =3D BLKIF_PROTOCOL_X86_64; + } else { + protocol =3D BLKIF_PROTOCOL_NATIVE; + } + + free(str); + } + + xen_block_dataplane_start(blockdev->dataplane, ring_ref, nr_ring_ref, + event_channel, protocol, errp); + + g_free(ring_ref); } =20 static void xen_block_unrealize(XenDevice *xendev, Error **errp) @@ -56,6 +128,9 @@ static void xen_block_unrealize(XenDevice *xendev, Error= **errp) /* Disconnect from the frontend in case this has not already happened = */ xen_block_disconnect(xendev, NULL); =20 + xen_block_dataplane_destroy(blockdev->dataplane); + blockdev->dataplane =3D NULL; + if (blockdev_class->unrealize) { blockdev_class->unrealize(blockdev, errp); } @@ -68,6 +143,7 @@ static void xen_block_realize(XenDevice *xendev, Error *= *errp) XEN_BLOCK_DEVICE_GET_CLASS(xendev); const char *type =3D object_get_typename(OBJECT(blockdev)); XenBlockVdev *vdev =3D &blockdev->props.vdev; + BlockConf *conf =3D &blockdev->props.conf; Error *local_err =3D NULL; =20 if (vdev->type =3D=3D XEN_BLOCK_VDEV_TYPE_INVALID) { @@ -81,8 +157,62 @@ static void xen_block_realize(XenDevice *xendev, Error = **errp) blockdev_class->realize(blockdev, &local_err); if (local_err) { error_propagate(errp, local_err); + return; } } + + /* + * The blkif protocol does not deal with removable media, so it must + * always be present, even for CDRom devices. + */ + assert(conf->blk); + if (!blk_is_inserted(conf->blk)) { + error_setg(errp, "device needs media, but drive is empty"); + return; + } + + if (!blkconf_apply_backend_options(conf, blockdev->info & VDISK_READON= LY, + false, errp)) { + return; + } + + if (!(blockdev->info & VDISK_CDROM) && + !blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) { + return; + } + + blkconf_blocksizes(conf); + + if (conf->logical_block_size > conf->physical_block_size) { + error_setg( + errp, "logical_block_size > physical_block_size not supported"= ); + return; + } + + blk_set_guest_block_size(conf->blk, conf->logical_block_size); + + if (conf->discard_granularity > 0) { + xen_device_backend_printf(xendev, "feature-discard", "%u", 1); + } + + xen_device_backend_printf(xendev, "feature-flush-cache", "%u", 1); + xen_device_backend_printf(xendev, "max-ring-page-order", "%u", + blockdev->props.max_ring_page_order); + xen_device_backend_printf(xendev, "info", "%u", blockdev->info); + + xen_device_frontend_printf(xendev, "virtual-device", "%lu", + vdev->number); + xen_device_frontend_printf(xendev, "device-type", "%s", + blockdev->device_type); + + xen_device_backend_printf(xendev, "sector-size", "%u", + conf->logical_block_size); + xen_device_backend_printf(xendev, "sectors", "%lu", + blk_getlength(conf->blk) / + conf->logical_block_size); + + blockdev->dataplane =3D + xen_block_dataplane_create(xendev, conf, blockdev->props.iothread); } =20 static void xen_block_frontend_changed(XenDevice *xendev, @@ -331,6 +461,11 @@ const PropertyInfo xen_block_prop_vdev =3D { static Property xen_block_props[] =3D { DEFINE_PROP("vdev", XenBlockDevice, props.vdev, xen_block_prop_vdev, XenBlockVdev), + DEFINE_BLOCK_PROPERTIES(XenBlockDevice, props.conf), + DEFINE_PROP_UINT32("max-ring-page-order", XenBlockDevice, + props.max_ring_page_order, 4), + DEFINE_PROP_LINK("iothread", XenBlockDevice, props.iothread, + TYPE_IOTHREAD, IOThread *), DEFINE_PROP_END_OF_LIST() }; =20 @@ -339,6 +474,7 @@ static void xen_block_class_init(ObjectClass *class, vo= id *data) DeviceClass *dev_class =3D DEVICE_CLASS(class); XenDeviceClass *xendev_class =3D XEN_DEVICE_CLASS(class); =20 + xendev_class->device =3D "vbd"; xendev_class->get_name =3D xen_block_get_name; xendev_class->realize =3D xen_block_realize; xendev_class->frontend_changed =3D xen_block_frontend_changed; @@ -363,7 +499,18 @@ static void xen_disk_unrealize(XenBlockDevice *blockde= v, Error **errp) =20 static void xen_disk_realize(XenBlockDevice *blockdev, Error **errp) { + BlockConf *conf =3D &blockdev->props.conf; + trace_xen_disk_realize(); + + blockdev->device_type =3D "disk"; + + if (!conf->blk) { + error_setg(errp, "drive property not set"); + return; + } + + blockdev->info =3D blk_is_read_only(conf->blk) ? VDISK_READONLY : 0; } =20 static void xen_disk_class_init(ObjectClass *class, void *data) @@ -391,7 +538,26 @@ static void xen_cdrom_unrealize(XenBlockDevice *blockd= ev, Error **errp) =20 static void xen_cdrom_realize(XenBlockDevice *blockdev, Error **errp) { + BlockConf *conf =3D &blockdev->props.conf; + trace_xen_cdrom_realize(); + + blockdev->device_type =3D "cdrom"; + + if (!conf->blk) { + int rc; + + /* Set up an empty drive */ + conf->blk =3D blk_new(0, BLK_PERM_ALL); + + rc =3D blk_attach_dev(conf->blk, DEVICE(blockdev)); + if (!rc) { + error_setg_errno(errp, -rc, "failed to create drive"); + return; + } + } + + blockdev->info =3D VDISK_READONLY | VDISK_CDROM; } =20 static void xen_cdrom_class_init(ObjectClass *class, void *data) diff --git a/hw/xen/trace-events b/hw/xen/trace-events index 22055b5894..d4651bdb30 100644 --- a/hw/xen/trace-events +++ b/hw/xen/trace-events @@ -22,8 +22,11 @@ xen_bus_watch(const char *token) "token: %s" xen_device_realize(const char *type, char *name) "type: %s name: %s" xen_device_unrealize(const char *type, char *name) "type: %s name: %s" xen_device_backend_state(const char *type, char *name, const char *state) = "type: %s name: %s -> %s" +xen_device_backend_online(const char *type, char *name, bool online) "type= : %s name: %s -> %u" +xen_device_backend_changed(const char *type, char *name) "type: %s name: %= s" xen_device_frontend_state(const char *type, char *name, const char *state)= "type: %s name: %s -> %s" xen_device_frontend_changed(const char *type, char *name) "type: %s name: = %s" +xen_device_unplug(const char *type, char *name) "type: %s name: %s" =20 # include/hw/xen/xen-bus-helper.c xs_node_create(const char *node) "%s" diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index 9443f27d44..a22aa49921 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -48,6 +48,54 @@ static char *xen_device_get_frontend_path(XenDevice *xen= dev) xendev->frontend_id, device, xendev->name); } =20 +static void xen_device_unplug(XenDevice *xendev, Error **errp) +{ + XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); + const char *type =3D object_get_typename(OBJECT(xendev)); + Error *local_err =3D NULL; + xs_transaction_t tid; + + trace_xen_device_unplug(type, xendev->name); + + /* Mimic the way the Xen toolstack does an unplug */ +again: + tid =3D xs_transaction_start(xenbus->xsh); + if (tid =3D=3D XBT_NULL) { + error_setg_errno(errp, errno, "failed xs_transaction_start"); + return; + } + + xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "online", + &local_err, "%u", 0); + if (local_err) { + goto abort; + } + + xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "state", + &local_err, "%u", XenbusStateClosing); + if (local_err) { + goto abort; + } + + if (!xs_transaction_end(xenbus->xsh, tid, false)) { + if (errno =3D=3D EAGAIN) { + goto again; + } + + error_setg_errno(errp, errno, "failed xs_transaction_end"); + } + + return; + +abort: + /* + * We only abort if there is already a failure so ignore any error + * from ending the transaction. + */ + xs_transaction_end(xenbus->xsh, tid, true); + error_propagate(errp, local_err); +} + static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent) { XenDevice *xendev =3D XEN_DEVICE(dev); @@ -208,14 +256,26 @@ static void xen_bus_realize(BusState *bus, Error **er= rp) xen_bus_unrealize(bus, &error_abort); } =20 +static void xen_bus_unplug_request(HotplugHandler *hotplug, + DeviceState *dev, + Error **errp) +{ + XenDevice *xendev =3D XEN_DEVICE(dev); + + xen_device_unplug(xendev, errp); +} + static void xen_bus_class_init(ObjectClass *class, void *data) { BusClass *bus_class =3D BUS_CLASS(class); + HotplugHandlerClass *hotplug_class =3D HOTPLUG_HANDLER_CLASS(class); =20 bus_class->print_dev =3D xen_bus_print_dev; bus_class->get_dev_path =3D xen_bus_get_dev_path; bus_class->realize =3D xen_bus_realize; bus_class->unrealize =3D xen_bus_unrealize; + + hotplug_class->unplug_request =3D xen_bus_unplug_request; } =20 static const TypeInfo xen_bus_type_info =3D { @@ -230,8 +290,8 @@ static const TypeInfo xen_bus_type_info =3D { }, }; =20 -static void xen_device_backend_printf(XenDevice *xendev, const char *key, - const char *fmt, ...) +void xen_device_backend_printf(XenDevice *xendev, const char *key, + const char *fmt, ...) { XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); Error *local_err =3D NULL; @@ -287,6 +347,70 @@ enum xenbus_state xen_device_backend_get_state(XenDevi= ce *xendev) return xendev->backend_state; } =20 +static void xen_device_backend_set_online(XenDevice *xendev, bool online) +{ + const char *type =3D object_get_typename(OBJECT(xendev)); + + if (xendev->backend_online =3D=3D online) { + return; + } + + trace_xen_device_backend_online(type, xendev->name, online); + + xendev->backend_online =3D online; + xen_device_backend_printf(xendev, "online", "%u", online); +} + +static void xen_device_backend_changed(void *opaque) +{ + XenDevice *xendev =3D opaque; + const char *type =3D object_get_typename(OBJECT(xendev)); + enum xenbus_state state; + unsigned int online; + + trace_xen_device_backend_changed(type, xendev->name); + + if (xen_device_backend_scanf(xendev, "state", "%u", &state) !=3D 1) { + state =3D XenbusStateUnknown; + } + + xen_device_backend_set_state(xendev, state); + + if (xen_device_backend_scanf(xendev, "online", "%u", &online) !=3D 1) { + online =3D 0; + } + + xen_device_backend_set_online(xendev, !!online); + + /* + * If the toolstack (or unplug request callback) has set the backend + * state to Closing, but there is no active frontend (i.e. the + * state is not Connected) then set the backend state to Closed. + */ + if (xendev->backend_state =3D=3D XenbusStateClosing && + xendev->frontend_state !=3D XenbusStateConnected) { + xen_device_backend_set_state(xendev, XenbusStateClosed); + } + + /* + * If a backend is still 'online' then its state should be cycled + * back round to InitWait in order for a new frontend instance to + * connect. This may happen when, for example, a frontend driver is + * re-installed or updated. + * If a backend is not 'online' then the device should be destroyed. + */ + if (xendev->backend_online && + xendev->backend_state =3D=3D XenbusStateClosed) { + xen_device_backend_set_state(xendev, XenbusStateInitWait); + } else if (!xendev->backend_online && + (xendev->backend_state =3D=3D XenbusStateClosed || + xendev->backend_state =3D=3D XenbusStateInitialising || + xendev->backend_state =3D=3D XenbusStateInitWait || + xendev->backend_state =3D=3D XenbusStateUnknown)) { + object_unparent(OBJECT(xendev)); + } +} + static void xen_device_backend_create(XenDevice *xendev, Error **errp) { XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); @@ -307,6 +431,27 @@ static void xen_device_backend_create(XenDevice *xende= v, Error **errp) if (local_err) { error_propagate_prepend(errp, local_err, "failed to create backend: "); + return; + } + + xendev->backend_state_watch =3D + xen_bus_add_watch(xenbus, xendev->backend_path, + "state", xen_device_backend_changed, + xendev, &local_err); + if (local_err) { + error_propagate_prepend(errp, local_err, + "failed to watch backend state: "); + return; + } + + xendev->backend_online_watch =3D + xen_bus_add_watch(xenbus, xendev->backend_path, + "online", xen_device_backend_changed, + xendev, &local_err); + if (local_err) { + error_propagate_prepend(errp, local_err, + "failed to watch backend online: "); + return; } } =20 @@ -315,6 +460,16 @@ static void xen_device_backend_destroy(XenDevice *xend= ev) XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); Error *local_err =3D NULL; =20 + if (xendev->backend_online_watch) { + xen_bus_remove_watch(xenbus, xendev->backend_online_watch, NULL); + xendev->backend_online_watch =3D NULL; + } + + if (xendev->backend_state_watch) { + xen_bus_remove_watch(xenbus, xendev->backend_state_watch, NULL); + xendev->backend_state_watch =3D NULL; + } + if (!xendev->backend_path) { return; } @@ -331,8 +486,8 @@ static void xen_device_backend_destroy(XenDevice *xende= v) } } =20 -static void xen_device_frontend_printf(XenDevice *xendev, const char *key, - const char *fmt, ...) +void xen_device_frontend_printf(XenDevice *xendev, const char *key, + const char *fmt, ...) { XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); Error *local_err =3D NULL; @@ -350,8 +505,8 @@ static void xen_device_frontend_printf(XenDevice *xende= v, const char *key, } } =20 -static int xen_device_frontend_scanf(XenDevice *xendev, const char *key, - const char *fmt, ...) +int xen_device_frontend_scanf(XenDevice *xendev, const char *key, + const char *fmt, ...) { XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); va_list ap; @@ -407,24 +562,6 @@ static void xen_device_frontend_changed(void *opaque) error_reportf_err(local_err, "frontend change error: "); } } - - /* - * If a backend is still 'online' then its state should be cycled - * back round to InitWait in order for a new frontend instance to - * connect. This may happen when, for example, a frontend driver is - * re-installed or updated. - */ - if (xendev->backend_state =3D=3D XenbusStateClosed) { - unsigned int online; - - if (xen_device_backend_scanf(xendev, "online", "%u", &online) !=3D= 1) { - online =3D 0; - } - - if (online) { - xen_device_backend_set_state(xendev, XenbusStateInitWait); - } - } } =20 static void xen_device_frontend_create(XenDevice *xendev, Error **errp) @@ -822,9 +959,9 @@ static void xen_device_realize(DeviceState *dev, Error = **errp) xendev->frontend_path); xen_device_backend_printf(xendev, "frontend-id", "%u", xendev->frontend_id); - xen_device_backend_printf(xendev, "online", "%u", 1); xen_device_backend_printf(xendev, "hotplug-status", "connected"); =20 + xen_device_backend_set_online(xendev, true); xen_device_backend_set_state(xendev, XenbusStateInitWait); =20 xen_device_frontend_printf(xendev, "backend", "%s", diff --git a/include/hw/xen/xen-block.h b/include/hw/xen/xen-block.h index 29413256e9..c4223f9be1 100644 --- a/include/hw/xen/xen-block.h +++ b/include/hw/xen/xen-block.h @@ -9,6 +9,9 @@ #define HW_XEN_BLOCK_H =20 #include "hw/xen/xen-bus.h" +#include "hw/block/block.h" +#include "hw/block/dataplane/xen-block.h" +#include "sysemu/iothread.h" =20 typedef enum XenBlockVdevType { XEN_BLOCK_VDEV_TYPE_INVALID, @@ -28,11 +31,17 @@ typedef struct XenBlockVdev { =20 typedef struct XenBlockProperties { XenBlockVdev vdev; + BlockConf conf; + unsigned int max_ring_page_order; + IOThread *iothread; } XenBlockProperties; =20 typedef struct XenBlockDevice { XenDevice xendev; XenBlockProperties props; + const char *device_type; + unsigned int info; + XenBlockDataPlane *dataplane; } XenBlockDevice; =20 typedef void (*XenBlockDeviceRealize)(XenBlockDevice *blockdev, Error **er= rp); diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h index f83a95cebd..0834cb3a7e 100644 --- a/include/hw/xen/xen-bus.h +++ b/include/hw/xen/xen-bus.h @@ -23,7 +23,9 @@ typedef struct XenDevice { char *backend_path, *frontend_path; enum xenbus_state backend_state, frontend_state; Notifier exit; - XenWatch *frontend_state_watch; + XenWatch *backend_state_watch, *frontend_state_watch; + bool backend_online; + XenWatch *backend_online_watch; xengnttab_handle *xgth; bool feature_grant_copy; xenevtchn_handle *xeh; @@ -84,6 +86,16 @@ void xen_device_backend_set_state(XenDevice *xendev, enum xenbus_state state); enum xenbus_state xen_device_backend_get_state(XenDevice *xendev); =20 +void xen_device_backend_printf(XenDevice *xendev, const char *key, + const char *fmt, ...) + GCC_FMT_ATTR(3, 4); +void xen_device_frontend_printf(XenDevice *xendev, const char *key, + const char *fmt, ...) + GCC_FMT_ATTR(3, 4); + +int xen_device_frontend_scanf(XenDevice *xendev, const char *key, + const char *fmt, ...); + void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs, Error **errp); void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs, --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 154713031077115.3869114357243; Thu, 10 Jan 2019 06:25:10 -0800 (PST) Received: from localhost ([127.0.0.1]:34151 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghbGZ-0007Vj-Gq for importer@patchew.org; Thu, 10 Jan 2019 09:25:03 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57997) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb58-0005zL-5c for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghars-0002aZ-JB for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:34 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12075) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gharp-0002Xf-Hi for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:30 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263702" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:09 +0000 Message-ID: <20190110134917.16425-18-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 17/25] xen: add a mechanism to automatically create XenDevice-s... 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant ...that maintains compatibility with existing Xen toolstacks. Xen toolstacks instantiate PV backends by simply writing information into xenstore and expecting a backend implementation to be watching for this. This patch adds a new 'xen-backend' module to allow individual XenDevice implementations to register create and destroy functions. The creator will be called when a tool-stack instantiates a new backend in this way, and the destructor will then be called after the resulting XenDevice object is unrealized. To support this it is also necessary to add new watchers into the XenBus implementation to handle enumeration of new backends and also destruction of XenDevice-s when the toolstack sets the backend 'online' key to 0. NOTE: This patch only adds the framework. A subsequent patch will add a creator function for xen-block devices. Signed-off-by: Paul Durrant Reviewed-by: Anthony Perard Signed-off-by: Anthony PERARD --- hw/xen/Makefile.objs | 2 +- hw/xen/trace-events | 3 + hw/xen/xen-backend.c | 165 +++++++++++++++++++++++++++++++++++ hw/xen/xen-bus.c | 164 +++++++++++++++++++++++++++++++++- include/hw/xen/xen-backend.h | 39 +++++++++ include/hw/xen/xen-bus.h | 1 + include/qemu/module.h | 3 + 7 files changed, 375 insertions(+), 2 deletions(-) create mode 100644 hw/xen/xen-backend.c create mode 100644 include/hw/xen/xen-backend.h diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs index 77c0868190..84df60a928 100644 --- a/hw/xen/Makefile.objs +++ b/hw/xen/Makefile.objs @@ -1,5 +1,5 @@ # xen backend driver support -common-obj-$(CONFIG_XEN) +=3D xen-legacy-backend.o xen_devconfig.o xen_pvd= ev.o xen-common.o xen-bus.o xen-bus-helper.o +common-obj-$(CONFIG_XEN) +=3D xen-legacy-backend.o xen_devconfig.o xen_pvd= ev.o xen-common.o xen-bus.o xen-bus-helper.o xen-backend.o =20 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) +=3D xen-host-pci-device.o obj-$(CONFIG_XEN_PCI_PASSTHROUGH) +=3D xen_pt.o xen_pt_config_init.o xen_p= t_graphics.o xen_pt_msi.o diff --git a/hw/xen/trace-events b/hw/xen/trace-events index d4651bdb30..f6944624b2 100644 --- a/hw/xen/trace-events +++ b/hw/xen/trace-events @@ -16,6 +16,9 @@ xen_domid_restrict(int err) "err: %u" # include/hw/xen/xen-bus.c xen_bus_realize(void) "" xen_bus_unrealize(void) "" +xen_bus_enumerate(void) "" +xen_bus_type_enumerate(const char *type) "type: %s" +xen_bus_backend_create(const char *type, const char *path) "type: %s path:= %s" xen_bus_add_watch(const char *node, const char *key, char *token) "node: %= s key: %s token: %s" xen_bus_remove_watch(const char *node, const char *key, char *token) "node= : %s key: %s token: %s" xen_bus_watch(const char *token) "token: %s" diff --git a/hw/xen/xen-backend.c b/hw/xen/xen-backend.c new file mode 100644 index 0000000000..da065f81b7 --- /dev/null +++ b/hw/xen/xen-backend.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2018 Citrix Systems Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qapi/error.h" +#include "hw/xen/xen-backend.h" +#include "hw/xen/xen-bus.h" + +typedef struct XenBackendImpl { + const char *type; + XenBackendDeviceCreate create; + XenBackendDeviceDestroy destroy; +} XenBackendImpl; + +struct XenBackendInstance { + QLIST_ENTRY(XenBackendInstance) entry; + const XenBackendImpl *impl; + XenBus *xenbus; + char *name; + XenDevice *xendev; +}; + +static GHashTable *xen_backend_table_get(void) +{ + static GHashTable *table; + + if (table =3D=3D NULL) { + table =3D g_hash_table_new(g_str_hash, g_str_equal); + } + + return table; +} + +static void xen_backend_table_add(XenBackendImpl *impl) +{ + g_hash_table_insert(xen_backend_table_get(), (void *)impl->type, impl); +} + +static const XenBackendImpl *xen_backend_table_lookup(const char *type) +{ + return g_hash_table_lookup(xen_backend_table_get(), type); +} + +void xen_backend_register(const XenBackendInfo *info) +{ + XenBackendImpl *impl =3D g_new0(XenBackendImpl, 1); + + g_assert(info->type); + + if (xen_backend_table_lookup(info->type)) { + error_report("attempt to register duplicate Xen backend type '%s'", + info->type); + abort(); + } + + if (!info->create) { + error_report("backend type '%s' has no creator", info->type); + abort(); + } + + impl->type =3D info->type; + impl->create =3D info->create; + impl->destroy =3D info->destroy; + + xen_backend_table_add(impl); +} + +static QLIST_HEAD(, XenBackendInstance) backend_list; + +static void xen_backend_list_add(XenBackendInstance *backend) +{ + QLIST_INSERT_HEAD(&backend_list, backend, entry); +} + +static XenBackendInstance *xen_backend_list_find(XenDevice *xendev) +{ + XenBackendInstance *backend; + + QLIST_FOREACH(backend, &backend_list, entry) { + if (backend->xendev =3D=3D xendev) { + return backend; + } + } + + return NULL; +} + +static void xen_backend_list_remove(XenBackendInstance *backend) +{ + QLIST_REMOVE(backend, entry); +} + +void xen_backend_device_create(XenBus *xenbus, const char *type, + const char *name, QDict *opts, Error **errp) +{ + const XenBackendImpl *impl =3D xen_backend_table_lookup(type); + XenBackendInstance *backend; + Error *local_error =3D NULL; + + if (!impl) { + return; + } + + backend =3D g_new0(XenBackendInstance, 1); + backend->xenbus =3D xenbus; + backend->name =3D g_strdup(name); + + impl->create(backend, opts, &local_error); + if (local_error) { + error_propagate(errp, local_error); + g_free(backend->name); + g_free(backend); + return; + } + + backend->impl =3D impl; + xen_backend_list_add(backend); +} + +XenBus *xen_backend_get_bus(XenBackendInstance *backend) +{ + return backend->xenbus; +} + +const char *xen_backend_get_name(XenBackendInstance *backend) +{ + return backend->name; +} + +void xen_backend_set_device(XenBackendInstance *backend, + XenDevice *xendev) +{ + g_assert(!backend->xendev); + backend->xendev =3D xendev; +} + +XenDevice *xen_backend_get_device(XenBackendInstance *backend) +{ + return backend->xendev; +} + + +bool xen_backend_try_device_destroy(XenDevice *xendev, Error **errp) +{ + XenBackendInstance *backend =3D xen_backend_list_find(xendev); + const XenBackendImpl *impl; + + if (!backend) { + return false; + } + + impl =3D backend->impl; + impl->destroy(backend, errp); + + xen_backend_list_remove(backend); + g_free(backend->name); + g_free(backend); + + return true; +} diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index a22aa49921..f90bcf2342 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -11,10 +11,12 @@ #include "hw/hw.h" #include "hw/sysbus.h" #include "hw/xen/xen.h" +#include "hw/xen/xen-backend.h" #include "hw/xen/xen-bus.h" #include "hw/xen/xen-bus-helper.h" #include "monitor/monitor.h" #include "qapi/error.h" +#include "qapi/qmp/qdict.h" #include "sysemu/sysemu.h" #include "trace.h" =20 @@ -190,12 +192,151 @@ static void xen_bus_remove_watch(XenBus *xenbus, Xen= Watch *watch, free_watch(watch); } =20 +static void xen_bus_backend_create(XenBus *xenbus, const char *type, + const char *name, char *path, + Error **errp) +{ + xs_transaction_t tid; + char **key; + QDict *opts; + unsigned int i, n; + Error *local_err =3D NULL; + + trace_xen_bus_backend_create(type, path); + +again: + tid =3D xs_transaction_start(xenbus->xsh); + if (tid =3D=3D XBT_NULL) { + error_setg(errp, "failed xs_transaction_start"); + return; + } + + key =3D xs_directory(xenbus->xsh, tid, path, &n); + if (!key) { + if (!xs_transaction_end(xenbus->xsh, tid, true)) { + error_setg_errno(errp, errno, "failed xs_transaction_end"); + } + return; + } + + opts =3D qdict_new(); + for (i =3D 0; i < n; i++) { + char *val; + + /* + * Assume anything found in the xenstore backend area, other than + * the keys created for a generic XenDevice, are parameters + * to be used to configure the backend. + */ + if (!strcmp(key[i], "state") || + !strcmp(key[i], "online") || + !strcmp(key[i], "frontend") || + !strcmp(key[i], "frontend-id") || + !strcmp(key[i], "hotplug-status")) + continue; + + if (xs_node_scanf(xenbus->xsh, tid, path, key[i], NULL, "%ms", + &val) =3D=3D 1) { + qdict_put_str(opts, key[i], val); + free(val); + } + } + + free(key); + + if (!xs_transaction_end(xenbus->xsh, tid, false)) { + qobject_unref(opts); + + if (errno =3D=3D EAGAIN) { + goto again; + } + + error_setg_errno(errp, errno, "failed xs_transaction_end"); + return; + } + + xen_backend_device_create(xenbus, type, name, opts, &local_err); + qobject_unref(opts); + + if (local_err) { + error_propagate_prepend(errp, local_err, + "failed to create '%s' device '%s': ", + type, name); + } +} + +static void xen_bus_type_enumerate(XenBus *xenbus, const char *type) +{ + char *domain_path =3D g_strdup_printf("backend/%s/%u", type, xen_domid= ); + char **backend; + unsigned int i, n; + + trace_xen_bus_type_enumerate(type); + + backend =3D xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n); + if (!backend) { + goto out; + } + + for (i =3D 0; i < n; i++) { + char *backend_path =3D g_strdup_printf("%s/%s", domain_path, + backend[i]); + enum xenbus_state backend_state; + + if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "state", + NULL, "%u", &backend_state) !=3D 1) + backend_state =3D XenbusStateUnknown; + + if (backend_state =3D=3D XenbusStateInitialising) { + Error *local_err =3D NULL; + + xen_bus_backend_create(xenbus, type, backend[i], backend_path, + &local_err); + if (local_err) { + error_report_err(local_err); + } + } + + g_free(backend_path); + } + + free(backend); + +out: + g_free(domain_path); +} + +static void xen_bus_enumerate(void *opaque) +{ + XenBus *xenbus =3D opaque; + char **type; + unsigned int i, n; + + trace_xen_bus_enumerate(); + + type =3D xs_directory(xenbus->xsh, XBT_NULL, "backend", &n); + if (!type) { + return; + } + + for (i =3D 0; i < n; i++) { + xen_bus_type_enumerate(xenbus, type[i]); + } + + free(type); +} + static void xen_bus_unrealize(BusState *bus, Error **errp) { XenBus *xenbus =3D XEN_BUS(bus); =20 trace_xen_bus_unrealize(); =20 + if (xenbus->backend_watch) { + xen_bus_remove_watch(xenbus, xenbus->backend_watch, NULL); + xenbus->backend_watch =3D NULL; + } + if (!xenbus->xsh) { return; } @@ -231,6 +372,7 @@ static void xen_bus_realize(BusState *bus, Error **errp) { XenBus *xenbus =3D XEN_BUS(bus); unsigned int domid; + Error *local_err =3D NULL; =20 trace_xen_bus_realize(); =20 @@ -250,6 +392,18 @@ static void xen_bus_realize(BusState *bus, Error **err= p) notifier_list_init(&xenbus->watch_notifiers); qemu_set_fd_handler(xs_fileno(xenbus->xsh), xen_bus_watch, NULL, xenbus); + + module_call_init(MODULE_INIT_XEN_BACKEND); + + xenbus->backend_watch =3D + xen_bus_add_watch(xenbus, "", /* domain root node */ + "backend", xen_bus_enumerate, xenbus, &local_err= ); + if (local_err) { + /* This need not be treated as a hard error so don't propagate */ + error_reportf_err(local_err, + "failed to set up enumeration watch: "); + } + return; =20 fail: @@ -407,7 +561,15 @@ static void xen_device_backend_changed(void *opaque) xendev->backend_state =3D=3D XenbusStateInitialising || xendev->backend_state =3D=3D XenbusStateInitWait || xendev->backend_state =3D=3D XenbusStateUnknown)) { - object_unparent(OBJECT(xendev)); + Error *local_err =3D NULL; + + if (!xen_backend_try_device_destroy(xendev, &local_err)) { + object_unparent(OBJECT(xendev)); + } + + if (local_err) { + error_report_err(local_err); + } } } =20 diff --git a/include/hw/xen/xen-backend.h b/include/hw/xen/xen-backend.h new file mode 100644 index 0000000000..010d712638 --- /dev/null +++ b/include/hw/xen/xen-backend.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Citrix Systems Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef HW_XEN_BACKEND_H +#define HW_XEN_BACKEND_H + +#include "hw/xen/xen-bus.h" + +typedef struct XenBackendInstance XenBackendInstance; + +typedef void (*XenBackendDeviceCreate)(XenBackendInstance *backend, + QDict *opts, Error **errp); +typedef void (*XenBackendDeviceDestroy)(XenBackendInstance *backend, + Error **errp); + +typedef struct XenBackendInfo { + const char *type; + XenBackendDeviceCreate create; + XenBackendDeviceDestroy destroy; +} XenBackendInfo; + +XenBus *xen_backend_get_bus(XenBackendInstance *backend); +const char *xen_backend_get_name(XenBackendInstance *backend); + +void xen_backend_set_device(XenBackendInstance *backend, + XenDevice *xendevice); +XenDevice *xen_backend_get_device(XenBackendInstance *backend); + +void xen_backend_register(const XenBackendInfo *info); + +void xen_backend_device_create(XenBus *xenbus, const char *type, + const char *name, QDict *opts, Error **errp= ); +bool xen_backend_try_device_destroy(XenDevice *xendev, Error **errp); + +#endif /* HW_XEN_BACKEND_H */ diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h index 0834cb3a7e..e55a5de5f1 100644 --- a/include/hw/xen/xen-bus.h +++ b/include/hw/xen/xen-bus.h @@ -65,6 +65,7 @@ typedef struct XenBus { domid_t backend_id; struct xs_handle *xsh; NotifierList watch_notifiers; + XenWatch *backend_watch; } XenBus; =20 typedef struct XenBusClass { diff --git a/include/qemu/module.h b/include/qemu/module.h index 54300ab6e5..55dd2beea8 100644 --- a/include/qemu/module.h +++ b/include/qemu/module.h @@ -44,6 +44,7 @@ typedef enum { MODULE_INIT_OPTS, MODULE_INIT_QOM, MODULE_INIT_TRACE, + MODULE_INIT_XEN_BACKEND, MODULE_INIT_MAX } module_init_type; =20 @@ -51,6 +52,8 @@ typedef enum { #define opts_init(function) module_init(function, MODULE_INIT_OPTS) #define type_init(function) module_init(function, MODULE_INIT_QOM) #define trace_init(function) module_init(function, MODULE_INIT_TRACE) +#define xen_backend_init(function) module_init(function, \ + MODULE_INIT_XEN_BACKEND) =20 #define block_module_load_one(lib) module_load_one("block-", lib) #define ui_module_load_one(lib) module_load_one("ui-", lib) --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547130895063515.7258505754955; Thu, 10 Jan 2019 06:34:55 -0800 (PST) Received: from localhost ([127.0.0.1]:36532 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghbQ0-00074S-B3 for importer@patchew.org; Thu, 10 Jan 2019 09:34:48 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57991) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb5N-0005zK-PW for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gharH-0002Iy-Fi for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:58:57 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12015) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gharF-0002Dz-Ob for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:58:55 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263638" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:10 +0000 Message-ID: <20190110134917.16425-19-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 18/25] xen: automatically create XenBlockDevice-s 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant This patch adds create and destroy function for XenBlockDevice-s so that they can be created automatically when the Xen toolstack instantiates a new PV backend via xenstore. When the XenBlockDevice is created this way it is also necessary to create a 'drive' which matches the configuration that the Xen toolstack has written into xenstore. This is done by formulating the parameters necessary for each 'blockdev' layer of the drive and then using qmp_blockdev_add() to create the layers. Also, for compatibility with the legacy 'xen_disk' implementation, an iothread is automatically created for the new XenBlockDevice. This, like the driver layers, will be destroyed after the XenBlockDevice is unrealized. The legacy backend scan for 'qdisk' is removed by this patch, which makes the 'xen_disk' code is redundant. The code will be removed by a subsequent patch. Signed-off-by: Paul Durrant Reviewed-by: Anthony PERARD Signed-off-by: Anthony PERARD --- hw/block/trace-events | 4 + hw/block/xen-block.c | 375 ++++++++++++++++++++++++++++++++++++ hw/xen/xen-legacy-backend.c | 1 - include/hw/xen/xen-block.h | 12 ++ 4 files changed, 391 insertions(+), 1 deletion(-) diff --git a/hw/block/trace-events b/hw/block/trace-events index 89e258319c..55e5a5500c 100644 --- a/hw/block/trace-events +++ b/hw/block/trace-events @@ -137,3 +137,7 @@ xen_disk_realize(void) "" xen_disk_unrealize(void) "" xen_cdrom_realize(void) "" xen_cdrom_unrealize(void) "" +xen_block_blockdev_add(char *str) "%s" +xen_block_blockdev_del(const char *node_name) "%s" +xen_block_device_create(unsigned int number) "%u" +xen_block_device_destroy(unsigned int number) "%u" diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c index a7c37c185a..be28b63442 100644 --- a/hw/block/xen-block.c +++ b/hw/block/xen-block.c @@ -7,12 +7,20 @@ =20 #include "qemu/osdep.h" #include "qemu/cutils.h" +#include "qemu/option.h" #include "qapi/error.h" +#include "qapi/qapi-commands-block-core.h" +#include "qapi/qapi-commands-misc.h" +#include "qapi/qapi-visit-block-core.h" +#include "qapi/qobject-input-visitor.h" #include "qapi/visitor.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp/qstring.h" #include "hw/hw.h" #include "hw/xen/xen_common.h" #include "hw/block/xen_blkif.h" #include "hw/xen/xen-block.h" +#include "hw/xen/xen-backend.h" #include "sysemu/blockdev.h" #include "sysemu/block-backend.h" #include "sysemu/iothread.h" @@ -474,6 +482,7 @@ static void xen_block_class_init(ObjectClass *class, vo= id *data) DeviceClass *dev_class =3D DEVICE_CLASS(class); XenDeviceClass *xendev_class =3D XEN_DEVICE_CLASS(class); =20 + xendev_class->backend =3D "qdisk"; xendev_class->device =3D "vbd"; xendev_class->get_name =3D xen_block_get_name; xendev_class->realize =3D xen_block_realize; @@ -586,3 +595,369 @@ static void xen_block_register_types(void) } =20 type_init(xen_block_register_types) + +static void xen_block_blockdev_del(const char *node_name, Error **errp) +{ + trace_xen_block_blockdev_del(node_name); + + qmp_blockdev_del(node_name, errp); +} + +static char *xen_block_blockdev_add(const char *id, QDict *qdict, + Error **errp) +{ + const char *driver =3D qdict_get_try_str(qdict, "driver"); + BlockdevOptions *options =3D NULL; + Error *local_err =3D NULL; + char *node_name; + Visitor *v; + + if (!driver) { + error_setg(errp, "no 'driver' parameter"); + return NULL; + } + + node_name =3D g_strdup_printf("%s-%s", id, driver); + qdict_put_str(qdict, "node-name", node_name); + + trace_xen_block_blockdev_add(node_name); + + v =3D qobject_input_visitor_new(QOBJECT(qdict)); + visit_type_BlockdevOptions(v, NULL, &options, &local_err); + visit_free(v); + + if (local_err) { + error_propagate(errp, local_err); + goto fail; + } + + qmp_blockdev_add(options, &local_err); + + if (local_err) { + error_propagate(errp, local_err); + goto fail; + } + + qapi_free_BlockdevOptions(options); + + return node_name; + +fail: + if (options) { + qapi_free_BlockdevOptions(options); + } + g_free(node_name); + + return NULL; +} + +static void xen_block_drive_destroy(XenBlockDrive *drive, Error **errp) +{ + char *node_name =3D drive->node_name; + + if (node_name) { + Error *local_err =3D NULL; + + xen_block_blockdev_del(node_name, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + g_free(node_name); + drive->node_name =3D NULL; + } + g_free(drive->id); + g_free(drive); +} + +static XenBlockDrive *xen_block_drive_create(const char *id, + const char *device_type, + QDict *opts, Error **errp) +{ + const char *params =3D qdict_get_try_str(opts, "params"); + const char *mode =3D qdict_get_try_str(opts, "mode"); + const char *direct_io_safe =3D qdict_get_try_str(opts, "direct-io-safe= "); + const char *discard_enable =3D qdict_get_try_str(opts, "discard-enable= "); + char *driver =3D NULL; + char *filename =3D NULL; + XenBlockDrive *drive =3D NULL; + Error *local_err =3D NULL; + QDict *file_layer; + QDict *driver_layer; + + if (params) { + char **v =3D g_strsplit(params, ":", 2); + + if (v[1] =3D=3D NULL) { + filename =3D g_strdup(v[0]); + driver =3D g_strdup("raw"); + } else { + if (strcmp(v[0], "aio") =3D=3D 0) { + driver =3D g_strdup("raw"); + } else if (strcmp(v[0], "vhd") =3D=3D 0) { + driver =3D g_strdup("vpc"); + } else { + driver =3D g_strdup(v[0]); + } + filename =3D g_strdup(v[1]); + } + + g_strfreev(v); + } + + if (!filename) { + error_setg(errp, "no filename"); + goto done; + } + assert(driver); + + drive =3D g_new0(XenBlockDrive, 1); + drive->id =3D g_strdup(id); + + file_layer =3D qdict_new(); + + qdict_put_str(file_layer, "driver", "file"); + qdict_put_str(file_layer, "filename", filename); + + if (mode && *mode !=3D 'w') { + qdict_put_bool(file_layer, "read-only", true); + } + + if (direct_io_safe) { + unsigned long value; + + if (!qemu_strtoul(direct_io_safe, NULL, 2, &value) && !!value) { + QDict *cache_qdict =3D qdict_new(); + + qdict_put_bool(cache_qdict, "direct", true); + qdict_put_obj(file_layer, "cache", QOBJECT(cache_qdict)); + + qdict_put_str(file_layer, "aio", "native"); + } + } + + if (discard_enable) { + unsigned long value; + + if (!qemu_strtoul(discard_enable, NULL, 2, &value) && !!value) { + qdict_put_str(file_layer, "discard", "unmap"); + } + } + + /* + * It is necessary to turn file locking off as an emulated device + * may have already opened the same image file. + */ + qdict_put_str(file_layer, "locking", "off"); + + driver_layer =3D qdict_new(); + + qdict_put_str(driver_layer, "driver", driver); + qdict_put_obj(driver_layer, "file", QOBJECT(file_layer)); + + g_assert(!drive->node_name); + drive->node_name =3D xen_block_blockdev_add(drive->id, driver_layer, + &local_err); + +done: + g_free(driver); + g_free(filename); + + if (local_err) { + error_propagate(errp, local_err); + xen_block_drive_destroy(drive, NULL); + return NULL; + } + + return drive; +} + +static const char *xen_block_drive_get_node_name(XenBlockDrive *drive) +{ + return drive->node_name ? drive->node_name : ""; +} + +static void xen_block_iothread_destroy(XenBlockIOThread *iothread, + Error **errp) +{ + qmp_object_del(iothread->id, errp); + + g_free(iothread->id); + g_free(iothread); +} + +static XenBlockIOThread *xen_block_iothread_create(const char *id, + Error **errp) +{ + XenBlockIOThread *iothread =3D g_new(XenBlockIOThread, 1); + Error *local_err =3D NULL; + + iothread->id =3D g_strdup(id); + + qmp_object_add(TYPE_IOTHREAD, id, false, NULL, &local_err); + if (local_err) { + error_propagate(errp, local_err); + + g_free(iothread->id); + g_free(iothread); + return NULL; + } + + return iothread; +} + +static void xen_block_device_create(XenBackendInstance *backend, + QDict *opts, Error **errp) +{ + XenBus *xenbus =3D xen_backend_get_bus(backend); + const char *name =3D xen_backend_get_name(backend); + unsigned long number; + const char *vdev, *device_type; + XenBlockDrive *drive =3D NULL; + XenBlockIOThread *iothread =3D NULL; + XenDevice *xendev =3D NULL; + Error *local_err =3D NULL; + const char *type; + XenBlockDevice *blockdev; + + if (qemu_strtoul(name, NULL, 10, &number)) { + error_setg(errp, "failed to parse name '%s'", name); + goto fail; + } + + trace_xen_block_device_create(number); + + vdev =3D qdict_get_try_str(opts, "dev"); + if (!vdev) { + error_setg(errp, "no dev parameter"); + goto fail; + } + + device_type =3D qdict_get_try_str(opts, "device-type"); + if (!device_type) { + error_setg(errp, "no device-type parameter"); + goto fail; + } + + if (!strcmp(device_type, "disk")) { + type =3D TYPE_XEN_DISK_DEVICE; + } else if (!strcmp(device_type, "cdrom")) { + type =3D TYPE_XEN_CDROM_DEVICE; + } else { + error_setg(errp, "invalid device-type parameter '%s'", device_type= ); + goto fail; + } + + drive =3D xen_block_drive_create(vdev, device_type, opts, &local_err); + if (!drive) { + error_propagate_prepend(errp, local_err, "failed to create drive: = "); + goto fail; + } + + iothread =3D xen_block_iothread_create(vdev, &local_err); + if (local_err) { + error_propagate_prepend(errp, local_err, + "failed to create iothread: "); + goto fail; + } + + xendev =3D XEN_DEVICE(qdev_create(BUS(xenbus), type)); + blockdev =3D XEN_BLOCK_DEVICE(xendev); + + object_property_set_str(OBJECT(xendev), vdev, "vdev", &local_err); + if (local_err) { + error_propagate_prepend(errp, local_err, "failed to set 'vdev': "); + goto fail; + } + + object_property_set_str(OBJECT(xendev), + xen_block_drive_get_node_name(drive), "drive", + &local_err); + if (local_err) { + error_propagate_prepend(errp, local_err, "failed to set 'drive': "= ); + goto fail; + } + + object_property_set_str(OBJECT(xendev), iothread->id, "iothread", + &local_err); + if (local_err) { + error_propagate_prepend(errp, local_err, + "failed to set 'iothread': "); + goto fail; + } + + blockdev->iothread =3D iothread; + blockdev->drive =3D drive; + + object_property_set_bool(OBJECT(xendev), true, "realized", &local_err); + if (local_err) { + error_propagate_prepend(errp, local_err, + "realization of device %s failed: ", + type); + goto fail; + } + + xen_backend_set_device(backend, xendev); + return; + +fail: + if (xendev) { + object_unparent(OBJECT(xendev)); + } + + if (iothread) { + xen_block_iothread_destroy(iothread, NULL); + } + + if (drive) { + xen_block_drive_destroy(drive, NULL); + } +} + +static void xen_block_device_destroy(XenBackendInstance *backend, + Error **errp) +{ + XenDevice *xendev =3D xen_backend_get_device(backend); + XenBlockDevice *blockdev =3D XEN_BLOCK_DEVICE(xendev); + XenBlockVdev *vdev =3D &blockdev->props.vdev; + XenBlockDrive *drive =3D blockdev->drive; + XenBlockIOThread *iothread =3D blockdev->iothread; + + trace_xen_block_device_destroy(vdev->number); + + object_unparent(OBJECT(xendev)); + + if (iothread) { + Error *local_err =3D NULL; + + xen_block_iothread_destroy(iothread, &local_err); + if (local_err) { + error_propagate_prepend(errp, local_err, + "failed to destroy iothread: "); + return; + } + } + + if (drive) { + Error *local_err =3D NULL; + + xen_block_drive_destroy(drive, &local_err); + if (local_err) { + error_propagate_prepend(errp, local_err, + "failed to destroy drive: "); + } + } +} + +static const XenBackendInfo xen_block_backend_info =3D { + .type =3D "qdisk", + .create =3D xen_block_device_create, + .destroy =3D xen_block_device_destroy, +}; + +static void xen_block_register_backend(void) +{ + xen_backend_register(&xen_block_backend_info); +} + +xen_backend_init(xen_block_register_backend); diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c index 41419763c8..36fd1e9b09 100644 --- a/hw/xen/xen-legacy-backend.c +++ b/hw/xen/xen-legacy-backend.c @@ -753,7 +753,6 @@ void xen_be_register_common(void) =20 xen_be_register("console", &xen_console_ops); xen_be_register("vkbd", &xen_kbdmouse_ops); - xen_be_register("qdisk", &xen_blkdev_ops); #ifdef CONFIG_VIRTFS xen_be_register("9pfs", &xen_9pfs_ops); #endif diff --git a/include/hw/xen/xen-block.h b/include/hw/xen/xen-block.h index c4223f9be1..11d351b4b3 100644 --- a/include/hw/xen/xen-block.h +++ b/include/hw/xen/xen-block.h @@ -29,6 +29,7 @@ typedef struct XenBlockVdev { unsigned long number; } XenBlockVdev; =20 + typedef struct XenBlockProperties { XenBlockVdev vdev; BlockConf conf; @@ -36,12 +37,23 @@ typedef struct XenBlockProperties { IOThread *iothread; } XenBlockProperties; =20 +typedef struct XenBlockDrive { + char *id; + char *node_name; +} XenBlockDrive; + +typedef struct XenBlockIOThread { + char *id; +} XenBlockIOThread; + typedef struct XenBlockDevice { XenDevice xendev; XenBlockProperties props; const char *device_type; unsigned int info; XenBlockDataPlane *dataplane; + XenBlockDrive *drive; + XenBlockIOThread *iothread; } XenBlockDevice; =20 typedef void (*XenBlockDeviceRealize)(XenBlockDevice *blockdev, Error **er= rp); --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547129897930256.01207728787904; Thu, 10 Jan 2019 06:18:17 -0800 (PST) Received: from localhost ([127.0.0.1]:60745 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghbA0-00027E-QM for importer@patchew.org; Thu, 10 Jan 2019 09:18:16 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57991) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb52-0005zK-FE for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghasS-00033Q-Ke for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:00:10 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12098) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghasS-00031h-B2 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:00:08 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263730" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:11 +0000 Message-ID: <20190110134917.16425-20-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 19/25] MAINTAINERS: add myself as a Xen maintainer 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant I have made many significant contributions to the Xen code in QEMU, particularly the recent patches introducing a new PV device framework. I intend to make further significant contributions, porting other PV back- ends to the new framework with the intent of eventually removing the legacy code. It therefore seems reasonable that I become a maintainer of the Xen code. Signed-off-by: Paul Durrant Acked-by: Anthony Perard Acked-by: Stefano Stabellini Signed-off-by: Anthony PERARD --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 43b2691b5d..2a1520dee7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -407,6 +407,7 @@ Guest CPU Cores (Xen): X86 M: Stefano Stabellini M: Anthony Perard +M: Paul Durrant L: xen-devel@lists.xenproject.org S: Supported F: */xen* --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547130444749993.5702272265886; Thu, 10 Jan 2019 06:27:24 -0800 (PST) Received: from localhost ([127.0.0.1]:34762 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghbIp-0001Iv-95 for importer@patchew.org; Thu, 10 Jan 2019 09:27:23 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58408) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb5A-0006SG-2b for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gharW-0002RI-8x for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:13 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12049) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gharV-0002QK-Ot for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:10 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263681" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:12 +0000 Message-ID: <20190110134917.16425-21-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 20/25] xen: remove the legacy 'xen_disk' backend 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 , xen-devel@lists.xenproject.org, Paul Durrant Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paul Durrant This backend has now been replaced by the 'xen-qdisk' XenDevice. Signed-off-by: Paul Durrant Acked-by: Anthony Perard Signed-off-by: Anthony PERARD --- hw/block/Makefile.objs | 1 - hw/block/xen_disk.c | 1011 ---------------------------------------- 2 files changed, 1012 deletions(-) delete mode 100644 hw/block/xen_disk.c diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs index f34813a377..e206b8e712 100644 --- a/hw/block/Makefile.objs +++ b/hw/block/Makefile.objs @@ -5,7 +5,6 @@ common-obj-$(CONFIG_NAND) +=3D nand.o common-obj-$(CONFIG_PFLASH_CFI01) +=3D pflash_cfi01.o common-obj-$(CONFIG_PFLASH_CFI02) +=3D pflash_cfi02.o common-obj-$(CONFIG_XEN) +=3D xen-block.o -common-obj-$(CONFIG_XEN) +=3D xen_disk.o common-obj-$(CONFIG_ECC) +=3D ecc.o common-obj-$(CONFIG_ONENAND) +=3D onenand.o common-obj-$(CONFIG_NVME_PCI) +=3D nvme.o diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c deleted file mode 100644 index 75fe55f2ae..0000000000 --- a/hw/block/xen_disk.c +++ /dev/null @@ -1,1011 +0,0 @@ -/* - * xen paravirt block device backend - * - * (c) Gerd Hoffmann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; under version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Contributions after 2012-01-13 are licensed under the terms of the - * GNU GPL, version 2 or (at your option) any later version. - */ - -#include "qemu/osdep.h" -#include "qemu/units.h" -#include -#include - -#include "hw/hw.h" -#include "hw/xen/xen-legacy-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" - -/* ------------------------------------------------------------- */ - -#define BLOCK_SIZE 512 -#define IOCB_COUNT (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2) - -struct ioreq { - blkif_request_t req; - int16_t status; - - /* parsed request */ - off_t start; - QEMUIOVector v; - void *buf; - size_t size; - int presync; - - /* aio status */ - int aio_inflight; - int aio_errors; - - struct XenBlkDev *blkdev; - QLIST_ENTRY(ioreq) list; - BlockAcctCookie acct; -}; - -#define MAX_RING_PAGE_ORDER 4 - -struct XenBlkDev { - struct XenLegacyDevice xendev; /* must be first */ - char *params; - char *mode; - char *type; - char *dev; - char *devtype; - bool directiosafe; - const char *fileproto; - const char *filename; - unsigned int ring_ref[1 << MAX_RING_PAGE_ORDER]; - unsigned int nr_ring_ref; - void *sring; - int64_t file_blk; - int64_t file_size; - int protocol; - blkif_back_rings_t rings; - int more_work; - - /* request lists */ - QLIST_HEAD(inflight_head, ioreq) inflight; - QLIST_HEAD(finished_head, ioreq) finished; - QLIST_HEAD(freelist_head, ioreq) freelist; - int requests_total; - int requests_inflight; - int requests_finished; - unsigned int max_requests; - - gboolean feature_discard; - - /* qemu block driver */ - DriveInfo *dinfo; - BlockBackend *blk; - QEMUBH *bh; - - IOThread *iothread; - AioContext *ctx; -}; - -/* ------------------------------------------------------------- */ - -static void ioreq_reset(struct ioreq *ioreq) -{ - memset(&ioreq->req, 0, sizeof(ioreq->req)); - ioreq->status =3D 0; - ioreq->start =3D 0; - ioreq->buf =3D NULL; - ioreq->size =3D 0; - ioreq->presync =3D 0; - - ioreq->aio_inflight =3D 0; - ioreq->aio_errors =3D 0; - - ioreq->blkdev =3D NULL; - memset(&ioreq->list, 0, sizeof(ioreq->list)); - memset(&ioreq->acct, 0, sizeof(ioreq->acct)); - - qemu_iovec_reset(&ioreq->v); -} - -static struct ioreq *ioreq_start(struct XenBlkDev *blkdev) -{ - struct ioreq *ioreq =3D NULL; - - if (QLIST_EMPTY(&blkdev->freelist)) { - if (blkdev->requests_total >=3D blkdev->max_requests) { - goto out; - } - /* allocate new struct */ - ioreq =3D g_malloc0(sizeof(*ioreq)); - ioreq->blkdev =3D blkdev; - blkdev->requests_total++; - qemu_iovec_init(&ioreq->v, 1); - } else { - /* get one from freelist */ - ioreq =3D QLIST_FIRST(&blkdev->freelist); - QLIST_REMOVE(ioreq, list); - } - QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list); - blkdev->requests_inflight++; - -out: - return ioreq; -} - -static void ioreq_finish(struct ioreq *ioreq) -{ - struct XenBlkDev *blkdev =3D ioreq->blkdev; - - QLIST_REMOVE(ioreq, list); - QLIST_INSERT_HEAD(&blkdev->finished, ioreq, list); - blkdev->requests_inflight--; - blkdev->requests_finished++; -} - -static void ioreq_release(struct ioreq *ioreq, bool finish) -{ - struct XenBlkDev *blkdev =3D ioreq->blkdev; - - QLIST_REMOVE(ioreq, list); - ioreq_reset(ioreq); - ioreq->blkdev =3D blkdev; - QLIST_INSERT_HEAD(&blkdev->freelist, ioreq, list); - if (finish) { - blkdev->requests_finished--; - } else { - blkdev->requests_inflight--; - } -} - -/* - * translate request into iovec + start offset - * do sanity checks along the way - */ -static int ioreq_parse(struct ioreq *ioreq) -{ - struct XenBlkDev *blkdev =3D ioreq->blkdev; - struct XenLegacyDevice *xendev =3D &blkdev->xendev; - size_t len; - int i; - - xen_pv_printf(xendev, 3, - "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId= 64 "\n", - ioreq->req.operation, ioreq->req.nr_segments, - ioreq->req.handle, ioreq->req.id, ioreq->req.sector_numb= er); - switch (ioreq->req.operation) { - case BLKIF_OP_READ: - break; - case BLKIF_OP_FLUSH_DISKCACHE: - ioreq->presync =3D 1; - if (!ioreq->req.nr_segments) { - return 0; - } - /* fall through */ - case BLKIF_OP_WRITE: - break; - case BLKIF_OP_DISCARD: - return 0; - default: - xen_pv_printf(xendev, 0, "error: unknown operation (%d)\n", - ioreq->req.operation); - goto err; - }; - - if (ioreq->req.operation !=3D BLKIF_OP_READ && blkdev->mode[0] !=3D 'w= ') { - xen_pv_printf(xendev, 0, "error: write req for ro device\n"); - goto err; - } - - ioreq->start =3D ioreq->req.sector_number * blkdev->file_blk; - for (i =3D 0; i < ioreq->req.nr_segments; i++) { - if (i =3D=3D BLKIF_MAX_SEGMENTS_PER_REQUEST) { - xen_pv_printf(xendev, 0, "error: nr_segments too big\n"); - goto err; - } - if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) { - xen_pv_printf(xendev, 0, "error: first > last sector\n"); - goto err; - } - if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >=3D XC_PAGE_SIZE) { - xen_pv_printf(xendev, 0, "error: page crossing\n"); - goto err; - } - - len =3D (ioreq->req.seg[i].last_sect - ioreq->req.seg[i].first_sec= t + 1) * blkdev->file_blk; - ioreq->size +=3D len; - } - if (ioreq->start + ioreq->size > blkdev->file_size) { - xen_pv_printf(xendev, 0, "error: access beyond end of file\n"); - goto err; - } - return 0; - -err: - ioreq->status =3D BLKIF_RSP_ERROR; - return -1; -} - -static int ioreq_grant_copy(struct ioreq *ioreq) -{ - struct XenBlkDev *blkdev =3D ioreq->blkdev; - struct XenLegacyDevice *xendev =3D &blkdev->xendev; - XenGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST]; - int i, count, rc; - int64_t file_blk =3D blkdev->file_blk; - bool to_domain =3D (ioreq->req.operation =3D=3D BLKIF_OP_READ); - void *virt =3D ioreq->buf; - - if (ioreq->req.nr_segments =3D=3D 0) { - return 0; - } - - count =3D ioreq->req.nr_segments; - - for (i =3D 0; i < count; i++) { - if (to_domain) { - segs[i].dest.foreign.ref =3D ioreq->req.seg[i].gref; - segs[i].dest.foreign.offset =3D ioreq->req.seg[i].first_sect *= file_blk; - segs[i].source.virt =3D virt; - } else { - segs[i].source.foreign.ref =3D ioreq->req.seg[i].gref; - segs[i].source.foreign.offset =3D ioreq->req.seg[i].first_sect= * file_blk; - segs[i].dest.virt =3D virt; - } - segs[i].len =3D (ioreq->req.seg[i].last_sect - - ioreq->req.seg[i].first_sect + 1) * file_blk; - virt +=3D segs[i].len; - } - - rc =3D xen_be_copy_grant_refs(xendev, to_domain, segs, count); - - if (rc) { - xen_pv_printf(xendev, 0, - "failed to copy data %d\n", rc); - ioreq->aio_errors++; - return -1; - } - - return rc; -} - -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; - struct XenLegacyDevice *xendev =3D &blkdev->xendev; - - aio_context_acquire(blkdev->ctx); - - if (ret !=3D 0) { - xen_pv_printf(xendev, 0, "%s I/O error\n", - ioreq->req.operation =3D=3D BLKIF_OP_READ ? "read" := "write"); - ioreq->aio_errors++; - } - - ioreq->aio_inflight--; - if (ioreq->presync) { - ioreq->presync =3D 0; - ioreq_runio_qemu_aio(ioreq); - goto done; - } - if (ioreq->aio_inflight > 0) { - goto done; - } - - switch (ioreq->req.operation) { - case BLKIF_OP_READ: - /* in case of failure ioreq->aio_errors is increased */ - if (ret =3D=3D 0) { - ioreq_grant_copy(ioreq); - } - qemu_vfree(ioreq->buf); - break; - case BLKIF_OP_WRITE: - case BLKIF_OP_FLUSH_DISKCACHE: - if (!ioreq->req.nr_segments) { - break; - } - qemu_vfree(ioreq->buf); - break; - default: - break; - } - - ioreq->status =3D ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY; - ioreq_finish(ioreq); - - switch (ioreq->req.operation) { - case BLKIF_OP_WRITE: - case BLKIF_OP_FLUSH_DISKCACHE: - if (!ioreq->req.nr_segments) { - break; - } - case BLKIF_OP_READ: - if (ioreq->status =3D=3D BLKIF_RSP_OKAY) { - block_acct_done(blk_get_stats(blkdev->blk), &ioreq->acct); - } else { - block_acct_failed(blk_get_stats(blkdev->blk), &ioreq->acct); - } - break; - case BLKIF_OP_DISCARD: - default: - break; - } - qemu_bh_schedule(blkdev->bh); - -done: - aio_context_release(blkdev->ctx); -} - -static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_n= umber, - uint64_t nr_sectors) -{ - struct XenBlkDev *blkdev =3D ioreq->blkdev; - int64_t byte_offset; - int byte_chunk; - uint64_t byte_remaining, limit; - uint64_t sec_start =3D sector_number; - uint64_t sec_count =3D nr_sectors; - - /* Wrap around, or overflowing byte limit? */ - if (sec_start + sec_count < sec_count || - sec_start + sec_count > INT64_MAX >> BDRV_SECTOR_BITS) { - return false; - } - - limit =3D BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS; - byte_offset =3D sec_start << BDRV_SECTOR_BITS; - byte_remaining =3D sec_count << BDRV_SECTOR_BITS; - - do { - byte_chunk =3D byte_remaining > limit ? limit : byte_remaining; - ioreq->aio_inflight++; - blk_aio_pdiscard(blkdev->blk, byte_offset, byte_chunk, - qemu_aio_complete, ioreq); - byte_remaining -=3D byte_chunk; - byte_offset +=3D byte_chunk; - } while (byte_remaining > 0); - - return true; -} - -static int ioreq_runio_qemu_aio(struct ioreq *ioreq) -{ - struct XenBlkDev *blkdev =3D ioreq->blkdev; - - ioreq->buf =3D qemu_memalign(XC_PAGE_SIZE, ioreq->size); - if (ioreq->req.nr_segments && - (ioreq->req.operation =3D=3D BLKIF_OP_WRITE || - ioreq->req.operation =3D=3D BLKIF_OP_FLUSH_DISKCACHE) && - ioreq_grant_copy(ioreq)) { - qemu_vfree(ioreq->buf); - goto err; - } - - ioreq->aio_inflight++; - if (ioreq->presync) { - blk_aio_flush(ioreq->blkdev->blk, qemu_aio_complete, ioreq); - return 0; - } - - switch (ioreq->req.operation) { - case BLKIF_OP_READ: - qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size); - block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct, - ioreq->v.size, BLOCK_ACCT_READ); - ioreq->aio_inflight++; - blk_aio_preadv(blkdev->blk, ioreq->start, &ioreq->v, 0, - qemu_aio_complete, ioreq); - break; - case BLKIF_OP_WRITE: - case BLKIF_OP_FLUSH_DISKCACHE: - if (!ioreq->req.nr_segments) { - break; - } - - qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size); - block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct, - ioreq->v.size, - ioreq->req.operation =3D=3D BLKIF_OP_WRITE ? - BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH); - ioreq->aio_inflight++; - blk_aio_pwritev(blkdev->blk, ioreq->start, &ioreq->v, 0, - qemu_aio_complete, ioreq); - break; - case BLKIF_OP_DISCARD: - { - struct blkif_request_discard *req =3D (void *)&ioreq->req; - if (!blk_split_discard(ioreq, req->sector_number, req->nr_sectors)= ) { - goto err; - } - break; - } - default: - /* unknown operation (shouldn't happen -- parse catches this) */ - goto err; - } - - qemu_aio_complete(ioreq, 0); - - return 0; - -err: - ioreq_finish(ioreq); - ioreq->status =3D BLKIF_RSP_ERROR; - return -1; -} - -static int blk_send_response_one(struct ioreq *ioreq) -{ - struct XenBlkDev *blkdev =3D ioreq->blkdev; - int send_notify =3D 0; - int have_requests =3D 0; - blkif_response_t *resp; - - /* Place on the response ring for the relevant domain. */ - switch (blkdev->protocol) { - case BLKIF_PROTOCOL_NATIVE: - resp =3D (blkif_response_t *) RING_GET_RESPONSE(&blkdev->rings.nat= ive, - blkdev->rings.native.rsp_prod_pvt); - break; - case BLKIF_PROTOCOL_X86_32: - resp =3D (blkif_response_t *) RING_GET_RESPONSE(&blkdev->rings.x86= _32_part, - blkdev->rings.x86_32_part.rsp_prod_pvt); - break; - case BLKIF_PROTOCOL_X86_64: - resp =3D (blkif_response_t *) RING_GET_RESPONSE(&blkdev->rings.x86= _64_part, - blkdev->rings.x86_64_part.rsp_prod_pvt); - break; - default: - return 0; - } - - resp->id =3D ioreq->req.id; - resp->operation =3D ioreq->req.operation; - resp->status =3D ioreq->status; - - blkdev->rings.common.rsp_prod_pvt++; - - RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notif= y); - if (blkdev->rings.common.rsp_prod_pvt =3D=3D blkdev->rings.common.req_= cons) { - /* - * Tail check for pending requests. Allows frontend to avoid - * notifications if requests are already in flight (lower - * overheads and promotes batching). - */ - RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests= ); - } else if (RING_HAS_UNCONSUMED_REQUESTS(&blkdev->rings.common)) { - have_requests =3D 1; - } - - if (have_requests) { - blkdev->more_work++; - } - return send_notify; -} - -/* walk finished list, send outstanding responses, free requests */ -static void blk_send_response_all(struct XenBlkDev *blkdev) -{ - struct ioreq *ioreq; - int send_notify =3D 0; - - while (!QLIST_EMPTY(&blkdev->finished)) { - ioreq =3D QLIST_FIRST(&blkdev->finished); - send_notify +=3D blk_send_response_one(ioreq); - ioreq_release(ioreq, true); - } - if (send_notify) { - xen_pv_send_notify(&blkdev->xendev); - } -} - -static int blk_get_request(struct XenBlkDev *blkdev, struct ioreq *ioreq, = RING_IDX rc) -{ - switch (blkdev->protocol) { - case BLKIF_PROTOCOL_NATIVE: - memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc), - sizeof(ioreq->req)); - break; - case BLKIF_PROTOCOL_X86_32: - blkif_get_x86_32_req(&ioreq->req, - RING_GET_REQUEST(&blkdev->rings.x86_32_part, = rc)); - break; - case BLKIF_PROTOCOL_X86_64: - blkif_get_x86_64_req(&ioreq->req, - RING_GET_REQUEST(&blkdev->rings.x86_64_part, = rc)); - break; - } - /* Prevent the compiler from accessing the on-ring fields instead. */ - barrier(); - return 0; -} - -static void blk_handle_requests(struct XenBlkDev *blkdev) -{ - RING_IDX rc, rp; - struct ioreq *ioreq; - - blkdev->more_work =3D 0; - - rc =3D blkdev->rings.common.req_cons; - rp =3D blkdev->rings.common.sring->req_prod; - xen_rmb(); /* Ensure we see queued requests up to 'rp'. */ - - blk_send_response_all(blkdev); - while (rc !=3D rp) { - /* pull request from ring */ - if (RING_REQUEST_CONS_OVERFLOW(&blkdev->rings.common, rc)) { - break; - } - ioreq =3D ioreq_start(blkdev); - if (ioreq =3D=3D NULL) { - blkdev->more_work++; - break; - } - blk_get_request(blkdev, ioreq, rc); - blkdev->rings.common.req_cons =3D ++rc; - - /* parse them */ - if (ioreq_parse(ioreq) !=3D 0) { - - switch (ioreq->req.operation) { - case BLKIF_OP_READ: - block_acct_invalid(blk_get_stats(blkdev->blk), - BLOCK_ACCT_READ); - break; - case BLKIF_OP_WRITE: - block_acct_invalid(blk_get_stats(blkdev->blk), - BLOCK_ACCT_WRITE); - break; - case BLKIF_OP_FLUSH_DISKCACHE: - block_acct_invalid(blk_get_stats(blkdev->blk), - BLOCK_ACCT_FLUSH); - default: - break; - }; - - if (blk_send_response_one(ioreq)) { - xen_pv_send_notify(&blkdev->xendev); - } - ioreq_release(ioreq, false); - continue; - } - - ioreq_runio_qemu_aio(ioreq); - } - - if (blkdev->more_work && blkdev->requests_inflight < blkdev->max_reque= sts) { - qemu_bh_schedule(blkdev->bh); - } -} - -/* ------------------------------------------------------------- */ - -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); -} - -static void blk_alloc(struct XenLegacyDevice *xendev) -{ - struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); - Error *err =3D NULL; - - trace_xen_disk_alloc(xendev->name); - - QLIST_INIT(&blkdev->inflight); - QLIST_INIT(&blkdev->finished); - QLIST_INIT(&blkdev->freelist); - - blkdev->iothread =3D iothread_create(xendev->name, &err); - assert(!err); - - blkdev->ctx =3D iothread_get_aio_context(blkdev->iothread); - blkdev->bh =3D aio_bh_new(blkdev->ctx, blk_bh, blkdev); -} - -static void blk_parse_discard(struct XenBlkDev *blkdev) -{ - struct XenLegacyDevice *xendev =3D &blkdev->xendev; - int enable; - - blkdev->feature_discard =3D true; - - if (xenstore_read_be_int(xendev, "discard-enable", &enable) =3D=3D 0) { - blkdev->feature_discard =3D !!enable; - } - - if (blkdev->feature_discard) { - xenstore_write_be_int(xendev, "feature-discard", 1); - } -} - -static int blk_init(struct XenLegacyDevice *xendev) -{ - struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); - int info =3D 0; - char *directiosafe =3D NULL; - - trace_xen_disk_init(xendev->name); - - /* read xenstore entries */ - if (blkdev->params =3D=3D NULL) { - char *h =3D NULL; - blkdev->params =3D xenstore_read_be_str(xendev, "params"); - if (blkdev->params !=3D NULL) { - h =3D strchr(blkdev->params, ':'); - } - if (h !=3D NULL) { - blkdev->fileproto =3D blkdev->params; - blkdev->filename =3D h+1; - *h =3D 0; - } else { - blkdev->fileproto =3D ""; - blkdev->filename =3D blkdev->params; - } - } - if (!strcmp("aio", blkdev->fileproto)) { - blkdev->fileproto =3D "raw"; - } - if (!strcmp("vhd", blkdev->fileproto)) { - blkdev->fileproto =3D "vpc"; - } - if (blkdev->mode =3D=3D NULL) { - blkdev->mode =3D xenstore_read_be_str(xendev, "mode"); - } - if (blkdev->type =3D=3D NULL) { - blkdev->type =3D xenstore_read_be_str(xendev, "type"); - } - if (blkdev->dev =3D=3D NULL) { - blkdev->dev =3D xenstore_read_be_str(xendev, "dev"); - } - if (blkdev->devtype =3D=3D NULL) { - blkdev->devtype =3D xenstore_read_be_str(xendev, "device-type"); - } - directiosafe =3D xenstore_read_be_str(xendev, "direct-io-safe"); - blkdev->directiosafe =3D (directiosafe && atoi(directiosafe)); - - /* do we have all we need? */ - if (blkdev->params =3D=3D NULL || - blkdev->mode =3D=3D NULL || - blkdev->type =3D=3D NULL || - blkdev->dev =3D=3D NULL) { - goto out_error; - } - - /* read-only ? */ - if (strcmp(blkdev->mode, "w")) { - info |=3D VDISK_READONLY; - } - - /* cdrom ? */ - if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom")) { - info |=3D VDISK_CDROM; - } - - blkdev->file_blk =3D BLOCK_SIZE; - - /* fill info - * blk_connect supplies sector-size and sectors - */ - xenstore_write_be_int(xendev, "feature-flush-cache", 1); - xenstore_write_be_int(xendev, "info", info); - - xenstore_write_be_int(xendev, "max-ring-page-order", - MAX_RING_PAGE_ORDER); - - blk_parse_discard(blkdev); - - g_free(directiosafe); - return 0; - -out_error: - g_free(blkdev->params); - blkdev->params =3D NULL; - g_free(blkdev->mode); - blkdev->mode =3D NULL; - g_free(blkdev->type); - blkdev->type =3D NULL; - g_free(blkdev->dev); - blkdev->dev =3D NULL; - g_free(blkdev->devtype); - blkdev->devtype =3D NULL; - g_free(directiosafe); - blkdev->directiosafe =3D false; - return -1; -} - -static int blk_connect(struct XenLegacyDevice *xendev) -{ - struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); - int index, qflags; - bool readonly =3D true; - bool writethrough =3D true; - int order, ring_ref; - unsigned int ring_size, max_grants; - unsigned int i; - - trace_xen_disk_connect(xendev->name); - - /* read-only ? */ - if (blkdev->directiosafe) { - qflags =3D BDRV_O_NOCACHE | BDRV_O_NATIVE_AIO; - } else { - qflags =3D 0; - writethrough =3D false; - } - if (strcmp(blkdev->mode, "w") =3D=3D 0) { - qflags |=3D BDRV_O_RDWR; - readonly =3D false; - } - if (blkdev->feature_discard) { - qflags |=3D BDRV_O_UNMAP; - } - - /* init qemu block driver */ - index =3D (xendev->dev - 202 * 256) / 16; - blkdev->dinfo =3D drive_get(IF_XEN, 0, index); - if (!blkdev->dinfo) { - Error *local_err =3D NULL; - QDict *options =3D NULL; - - if (strcmp(blkdev->fileproto, "")) { - options =3D qdict_new(); - qdict_put_str(options, "driver", blkdev->fileproto); - } - - /* setup via xenbus -> create new block driver instance */ - xen_pv_printf(xendev, 2, "create new bdrv (xenbus setup)\n"); - blkdev->blk =3D blk_new_open(blkdev->filename, NULL, options, - qflags, &local_err); - if (!blkdev->blk) { - xen_pv_printf(xendev, 0, "error: %s\n", - error_get_pretty(local_err)); - error_free(local_err); - return -1; - } - blk_set_enable_write_cache(blkdev->blk, !writethrough); - } else { - /* setup via qemu cmdline -> already setup for us */ - xen_pv_printf(xendev, 2, - "get configured bdrv (cmdline setup)\n"); - blkdev->blk =3D blk_by_legacy_dinfo(blkdev->dinfo); - if (blk_is_read_only(blkdev->blk) && !readonly) { - xen_pv_printf(xendev, 0, "Unexpected read-only drive"); - blkdev->blk =3D NULL; - return -1; - } - /* blkdev->blk is not create by us, we get a reference - * so we can blk_unref() unconditionally */ - blk_ref(blkdev->blk); - } - blk_attach_dev_legacy(blkdev->blk, blkdev); - blkdev->file_size =3D blk_getlength(blkdev->blk); - if (blkdev->file_size < 0) { - BlockDriverState *bs =3D blk_bs(blkdev->blk); - const char *drv_name =3D bs ? bdrv_get_format_name(bs) : NULL; - xen_pv_printf(xendev, 1, "blk_getlength: %d (%s) | drv %s\n", - (int)blkdev->file_size, strerror(-blkdev->file_size), - drv_name ?: "-"); - blkdev->file_size =3D 0; - } - - xen_pv_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s= \"," - " size %" PRId64 " (%" PRId64 " MB)\n", - blkdev->type, blkdev->fileproto, blkdev->filename, - blkdev->file_size, blkdev->file_size / MiB); - - /* Fill in number of sector size and number of sectors */ - xenstore_write_be_int(xendev, "sector-size", blkdev->file_blk); - xenstore_write_be_int64(xendev, "sectors", - blkdev->file_size / blkdev->file_blk); - - if (xenstore_read_fe_int(xendev, "ring-page-order", - &order) =3D=3D -1) { - blkdev->nr_ring_ref =3D 1; - - if (xenstore_read_fe_int(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(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(xendev, "event-channel", - &xendev->remote_port) =3D=3D -1) { - return -1; - } - - if (!xendev->protocol) { - blkdev->protocol =3D BLKIF_PROTOCOL_NATIVE; - } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_NATIVE) =3D=3D 0)= { - blkdev->protocol =3D BLKIF_PROTOCOL_NATIVE; - } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_32) =3D=3D 0)= { - blkdev->protocol =3D BLKIF_PROTOCOL_X86_32; - } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_64) =3D=3D 0)= { - blkdev->protocol =3D BLKIF_PROTOCOL_X86_64; - } else { - blkdev->protocol =3D BLKIF_PROTOCOL_NATIVE; - } - - 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; - } - - /* Add on the number needed for the ring pages */ - max_grants =3D blkdev->nr_ring_ref; - - xen_be_set_max_grant_refs(xendev, max_grants); - blkdev->sring =3D xen_be_map_grant_refs(xendev, blkdev->ring_ref, - blkdev->nr_ring_ref, - PROT_READ | PROT_WRITE); - if (!blkdev->sring) { - return -1; - } - - switch (blkdev->protocol) { - case BLKIF_PROTOCOL_NATIVE: - { - blkif_sring_t *sring_native =3D blkdev->sring; - 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; - - 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; - - BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, ring_size= ); - break; - } - } - - blk_set_aio_context(blkdev->blk, blkdev->ctx); - - xen_be_bind_evtchn(xendev); - - xen_pv_printf(xendev, 1, "ok: proto %s, nr-ring-ref %u, " - "remote port %d, local port %d\n", - xendev->protocol, blkdev->nr_ring_ref, - xendev->remote_port, xendev->local_port); - return 0; -} - -static void blk_disconnect(struct XenLegacyDevice *xendev) -{ - struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); - - 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(xendev); - - aio_context_release(blkdev->ctx); - - if (blkdev->sring) { - xen_be_unmap_grant_refs(xendev, blkdev->sring, - blkdev->nr_ring_ref); - blkdev->sring =3D NULL; - } -} - -static int blk_free(struct XenLegacyDevice *xendev) -{ - struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); - struct ioreq *ioreq; - - trace_xen_disk_free(xendev->name); - - blk_disconnect(xendev); - - while (!QLIST_EMPTY(&blkdev->freelist)) { - ioreq =3D QLIST_FIRST(&blkdev->freelist); - QLIST_REMOVE(ioreq, list); - qemu_iovec_destroy(&ioreq->v); - g_free(ioreq); - } - - g_free(blkdev->params); - g_free(blkdev->mode); - g_free(blkdev->type); - g_free(blkdev->dev); - g_free(blkdev->devtype); - qemu_bh_delete(blkdev->bh); - iothread_destroy(blkdev->iothread); - return 0; -} - -static void blk_event(struct XenLegacyDevice *xendev) -{ - struct XenBlkDev *blkdev =3D container_of(xendev, struct XenBlkDev, xe= ndev); - - qemu_bh_schedule(blkdev->bh); -} - -struct XenDevOps xen_blkdev_ops =3D { - .flags =3D DEVOPS_FLAG_NEED_GNTDEV, - .size =3D sizeof(struct XenBlkDev), - .alloc =3D blk_alloc, - .init =3D blk_init, - .initialise =3D blk_connect, - .disconnect =3D blk_disconnect, - .event =3D blk_event, - .free =3D blk_free, -}; --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547130358254238.31375097292562; Thu, 10 Jan 2019 06:25:58 -0800 (PST) Received: from localhost ([127.0.0.1]:34401 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghbHR-00008W-2P for importer@patchew.org; Thu, 10 Jan 2019 09:25:57 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58072) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb5I-00062k-Vn for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gharM-0002LV-8v for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:02 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12008) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gharL-0001xV-SA for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:00 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263664" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:13 +0000 Message-ID: <20190110134917.16425-22-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 21/25] Remove broken Xen PV domain builder 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 , xen-devel@lists.xenproject.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" It is broken since Xen 4.9 [1] and it will not build in Xen 4.12. Also, it is not built by default since QEMU 2.6. [1] https://lists.xenproject.org/archives/html/xen-devel/2018-09/msg00313.h= tml Signed-off-by: Anthony PERARD Acked-by: Stefano Stabellini --- configure | 17 -- hw/xenpv/Makefile.objs | 2 - hw/xenpv/xen_domainbuild.c | 299 ------------------------------------ hw/xenpv/xen_domainbuild.h | 13 -- hw/xenpv/xen_machine_pv.c | 14 -- include/hw/xen/xen.h | 1 - include/hw/xen/xen_common.h | 18 --- qemu-options.hx | 8 - vl.c | 7 - 9 files changed, 379 deletions(-) delete mode 100644 hw/xenpv/xen_domainbuild.c delete mode 100644 hw/xenpv/xen_domainbuild.h diff --git a/configure b/configure index 8049b71eef..ba2b5f24c4 100755 --- a/configure +++ b/configure @@ -357,7 +357,6 @@ vnc_png=3D"" xkbcommon=3D"" xen=3D"" xen_ctrl_version=3D"" -xen_pv_domain_build=3D"no" xen_pci_passthrough=3D"" linux_aio=3D"" cap_ng=3D"" @@ -1122,10 +1121,6 @@ for opt do ;; --enable-xen-pci-passthrough) xen_pci_passthrough=3D"yes" ;; - --disable-xen-pv-domain-build) xen_pv_domain_build=3D"no" - ;; - --enable-xen-pv-domain-build) xen_pv_domain_build=3D"yes" - ;; --disable-brlapi) brlapi=3D"no" ;; --enable-brlapi) brlapi=3D"yes" @@ -1688,8 +1683,6 @@ Advanced options (experts only): --tls-priority default TLS protocol/cipher priority string --enable-gprof QEMU profiling with gprof --enable-profiler profiler support - --enable-xen-pv-domain-build - xen pv domain builder --enable-debug-stack-usage track the maximum stack usage of stacks created= by qemu_alloc_stack =20 @@ -2681,12 +2674,6 @@ if test "$xen_pci_passthrough" !=3D "no"; then fi fi =20 -if test "$xen_pv_domain_build" =3D "yes" && - test "$xen" !=3D "yes"; then - error_exit "User requested Xen PV domain builder support" \ - "which requires Xen support." -fi - ########################################## # Windows Hypervisor Platform accelerator (WHPX) check if test "$whpx" !=3D "no" ; then @@ -6072,7 +6059,6 @@ fi echo "xen support $xen" if test "$xen" =3D "yes" ; then echo "xen ctrl version $xen_ctrl_version" - echo "pv dom build $xen_pv_domain_build" fi echo "brlapi support $brlapi" echo "bluez support $bluez" @@ -6542,9 +6528,6 @@ fi if test "$xen" =3D "yes" ; then echo "CONFIG_XEN_BACKEND=3Dy" >> $config_host_mak echo "CONFIG_XEN_CTRL_INTERFACE_VERSION=3D$xen_ctrl_version" >> $config_= host_mak - if test "$xen_pv_domain_build" =3D "yes" ; then - echo "CONFIG_XEN_PV_DOMAIN_BUILD=3Dy" >> $config_host_mak - fi fi if test "$linux_aio" =3D "yes" ; then echo "CONFIG_LINUX_AIO=3Dy" >> $config_host_mak diff --git a/hw/xenpv/Makefile.objs b/hw/xenpv/Makefile.objs index bbf5873fd1..8bfa4586ab 100644 --- a/hw/xenpv/Makefile.objs +++ b/hw/xenpv/Makefile.objs @@ -1,4 +1,2 @@ # Xen PV machine support obj-$(CONFIG_XEN) +=3D xen_machine_pv.o -# Xen PV machine builder support -obj-$(CONFIG_XEN_PV_DOMAIN_BUILD) +=3D xen_domainbuild.o diff --git a/hw/xenpv/xen_domainbuild.c b/hw/xenpv/xen_domainbuild.c deleted file mode 100644 index deb28cf596..0000000000 --- a/hw/xenpv/xen_domainbuild.c +++ /dev/null @@ -1,299 +0,0 @@ -#include "qemu/osdep.h" -#include "qemu/units.h" -#include "hw/xen/xen-legacy-backend.h" -#include "xen_domainbuild.h" -#include "qemu/timer.h" -#include "qemu/log.h" - -#include - -static int xenstore_domain_mkdir(char *path) -{ - struct xs_permissions perms_ro[] =3D {{ - .id =3D 0, /* set owner: dom0 */ - },{ - .id =3D xen_domid, - .perms =3D XS_PERM_READ, - }}; - struct xs_permissions perms_rw[] =3D {{ - .id =3D 0, /* set owner: dom0 */ - },{ - .id =3D xen_domid, - .perms =3D XS_PERM_READ | XS_PERM_WRITE, - }}; - const char *writable[] =3D { "device", "control", "error", NULL }; - char subpath[256]; - int i; - - if (!xs_mkdir(xenstore, 0, path)) { - fprintf(stderr, "%s: xs_mkdir %s: failed\n", __func__, path); - return -1; - } - if (!xs_set_permissions(xenstore, 0, path, perms_ro, 2)) { - fprintf(stderr, "%s: xs_set_permissions failed\n", __func__); - return -1; - } - - for (i =3D 0; writable[i]; i++) { - snprintf(subpath, sizeof(subpath), "%s/%s", path, writable[i]); - if (!xs_mkdir(xenstore, 0, subpath)) { - fprintf(stderr, "%s: xs_mkdir %s: failed\n", __func__, subpath= ); - return -1; - } - if (!xs_set_permissions(xenstore, 0, subpath, perms_rw, 2)) { - fprintf(stderr, "%s: xs_set_permissions failed\n", __func__); - return -1; - } - } - return 0; -} - -int xenstore_domain_init1(const char *kernel, const char *ramdisk, - const char *cmdline) -{ - char *dom, uuid_string[42], vm[256], path[256]; - int i; - - qemu_uuid_unparse(&qemu_uuid, uuid_string); - dom =3D xs_get_domain_path(xenstore, xen_domid); - snprintf(vm, sizeof(vm), "/vm/%s", uuid_string); - - xenstore_domain_mkdir(dom); - - xenstore_write_str(vm, "image/ostype", "linux"); - if (kernel) - xenstore_write_str(vm, "image/kernel", kernel); - if (ramdisk) - xenstore_write_str(vm, "image/ramdisk", ramdisk); - if (cmdline) - xenstore_write_str(vm, "image/cmdline", cmdline); - - /* name + id */ - xenstore_write_str(vm, "name", qemu_name ? qemu_name : "no-name"); - xenstore_write_str(vm, "uuid", uuid_string); - xenstore_write_str(dom, "name", qemu_name ? qemu_name : "no-name"); - xenstore_write_int(dom, "domid", xen_domid); - xenstore_write_str(dom, "vm", vm); - - /* memory */ - xenstore_write_int(dom, "memory/target", ram_size / KiB); - xenstore_write_int(vm, "memory", ram_size / MiB); - xenstore_write_int(vm, "maxmem", ram_size / MiB); - - /* cpus */ - for (i =3D 0; i < smp_cpus; i++) { - snprintf(path, sizeof(path), "cpu/%d/availability",i); - xenstore_write_str(dom, path, "online"); - } - xenstore_write_int(vm, "vcpu_avail", smp_cpus); - xenstore_write_int(vm, "vcpus", smp_cpus); - - /* vnc password */ - xenstore_write_str(vm, "vncpassword", "" /* FIXME */); - - free(dom); - return 0; -} - -int xenstore_domain_init2(int xenstore_port, int xenstore_mfn, - int console_port, int console_mfn) -{ - char *dom; - - dom =3D xs_get_domain_path(xenstore, xen_domid); - - /* signal new domain */ - xs_introduce_domain(xenstore, - xen_domid, - xenstore_mfn, - xenstore_port); - - /* xenstore */ - xenstore_write_int(dom, "store/ring-ref", xenstore_mfn); - xenstore_write_int(dom, "store/port", xenstore_port); - - /* console */ - xenstore_write_str(dom, "console/type", "ioemu"); - xenstore_write_int(dom, "console/limit", 128 * KiB); - xenstore_write_int(dom, "console/ring-ref", console_mfn); - xenstore_write_int(dom, "console/port", console_port); - xen_config_dev_console(0); - - free(dom); - return 0; -} - -/* ------------------------------------------------------------- */ - -static QEMUTimer *xen_poll; - -/* check domain state once per second */ -static void xen_domain_poll(void *opaque) -{ - struct xc_dominfo info; - int rc; - - rc =3D xc_domain_getinfo(xen_xc, xen_domid, 1, &info); - if ((rc !=3D 1) || (info.domid !=3D xen_domid)) { - qemu_log("xen: domain %d is gone\n", xen_domid); - goto quit; - } - if (info.dying) { - qemu_log("xen: domain %d is dying (%s%s)\n", xen_domid, - info.crashed ? "crashed" : "", - info.shutdown ? "shutdown" : ""); - goto quit; - } - - timer_mod(xen_poll, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000); - return; - -quit: - qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); -} - -static int xen_domain_watcher(void) -{ - int qemu_running =3D 1; - int fd[2], i, n, rc; - char byte; - - if (pipe(fd) !=3D 0) { - qemu_log("%s: Huh? pipe error: %s\n", __func__, strerror(errno)); - return -1; - } - if (fork() !=3D 0) - return 0; /* not child */ - - /* close all file handles, except stdio/out/err, - * our watch pipe and the xen interface handle */ - n =3D getdtablesize(); - for (i =3D 3; i < n; i++) { - if (i =3D=3D fd[0]) - continue; - close(i); - } - - /* - * Reopen xc interface, since the original is unsafe after fork - * and was closed above. - */ - xen_xc =3D xc_interface_open(0, 0, 0); - - /* ignore term signals */ - signal(SIGINT, SIG_IGN); - signal(SIGTERM, SIG_IGN); - - /* wait for qemu exiting */ - while (qemu_running) { - rc =3D read(fd[0], &byte, 1); - switch (rc) { - case -1: - if (errno =3D=3D EINTR) - continue; - qemu_log("%s: Huh? read error: %s\n", __func__, strerror(errno= )); - qemu_running =3D 0; - break; - case 0: - /* EOF -> qemu exited */ - qemu_running =3D 0; - break; - default: - qemu_log("%s: Huh? data on the watch pipe?\n", __func__); - break; - } - } - - /* cleanup */ - qemu_log("%s: destroy domain %d\n", __func__, xen_domid); - xc_domain_destroy(xen_xc, xen_domid); - _exit(0); -} - -/* normal cleanup */ -static void xen_domain_cleanup(void) -{ - char *dom; - - dom =3D xs_get_domain_path(xenstore, xen_domid); - if (dom) { - xs_rm(xenstore, 0, dom); - free(dom); - } - xs_release_domain(xenstore, xen_domid); -} - -int xen_domain_build_pv(const char *kernel, const char *ramdisk, - const char *cmdline) -{ - uint32_t ssidref =3D 0; - uint32_t flags =3D 0; - xen_domain_handle_t uuid; - unsigned int xenstore_port =3D 0, console_port =3D 0; - unsigned long xenstore_mfn =3D 0, console_mfn =3D 0; - int rc; - - memcpy(uuid, &qemu_uuid, sizeof(uuid)); - rc =3D xen_domain_create(xen_xc, ssidref, uuid, flags, &xen_domid); - if (rc < 0) { - fprintf(stderr, "xen: xc_domain_create() failed\n"); - goto err; - } - qemu_log("xen: created domain %d\n", xen_domid); - atexit(xen_domain_cleanup); - if (xen_domain_watcher() =3D=3D -1) { - goto err; - } - - xenstore_domain_init1(kernel, ramdisk, cmdline); - - rc =3D xc_domain_max_vcpus(xen_xc, xen_domid, smp_cpus); - if (rc < 0) { - fprintf(stderr, "xen: xc_domain_max_vcpus() failed\n"); - goto err; - } - -#if 0 - rc =3D xc_domain_setcpuweight(xen_xc, xen_domid, 256); - if (rc < 0) { - fprintf(stderr, "xen: xc_domain_setcpuweight() failed\n"); - goto err; - } -#endif - - rc =3D xc_domain_setmaxmem(xen_xc, xen_domid, ram_size / KiB); - if (rc < 0) { - fprintf(stderr, "xen: xc_domain_setmaxmem() failed\n"); - goto err; - } - - xenstore_port =3D xc_evtchn_alloc_unbound(xen_xc, xen_domid, 0); - console_port =3D xc_evtchn_alloc_unbound(xen_xc, xen_domid, 0); - - rc =3D xc_linux_build(xen_xc, xen_domid, ram_size / MiB, - kernel, ramdisk, cmdline, - 0, flags, - xenstore_port, &xenstore_mfn, - console_port, &console_mfn); - if (rc < 0) { - fprintf(stderr, "xen: xc_linux_build() failed\n"); - goto err; - } - - xenstore_domain_init2(xenstore_port, xenstore_mfn, - console_port, console_mfn); - - qemu_log("xen: unpausing domain %d\n", xen_domid); - rc =3D xc_domain_unpause(xen_xc, xen_domid); - if (rc < 0) { - fprintf(stderr, "xen: xc_domain_unpause() failed\n"); - goto err; - } - - xen_poll =3D timer_new_ms(QEMU_CLOCK_REALTIME, xen_domain_poll, NULL); - timer_mod(xen_poll, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000); - return 0; - -err: - return -1; -} diff --git a/hw/xenpv/xen_domainbuild.h b/hw/xenpv/xen_domainbuild.h deleted file mode 100644 index 652d9b410f..0000000000 --- a/hw/xenpv/xen_domainbuild.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef QEMU_HW_XEN_DOMAINBUILD_H -#define QEMU_HW_XEN_DOMAINBUILD_H - -#include "hw/xen/xen_common.h" - -int xenstore_domain_init1(const char *kernel, const char *ramdisk, - const char *cmdline); -int xenstore_domain_init2(int xenstore_port, int xenstore_mfn, - int console_port, int console_mfn); -int xen_domain_build_pv(const char *kernel, const char *ramdisk, - const char *cmdline); - -#endif /* QEMU_HW_XEN_DOMAINBUILD_H */ diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c index 608e591bcc..8d68fef25e 100644 --- a/hw/xenpv/xen_machine_pv.c +++ b/hw/xenpv/xen_machine_pv.c @@ -28,7 +28,6 @@ #include "hw/boards.h" #include "hw/xen/xen-legacy-backend.h" #include "hw/xen/xen-bus.h" -#include "xen_domainbuild.h" #include "sysemu/block-backend.h" =20 static void xen_init_pv(MachineState *machine) @@ -46,19 +45,6 @@ static void xen_init_pv(MachineState *machine) case XEN_ATTACH: /* nothing to do, xend handles everything */ break; -#ifdef CONFIG_XEN_PV_DOMAIN_BUILD - case XEN_CREATE: { - const char *kernel_filename =3D machine->kernel_filename; - const char *kernel_cmdline =3D machine->kernel_cmdline; - const char *initrd_filename =3D machine->initrd_filename; - if (xen_domain_build_pv(kernel_filename, initrd_filename, - kernel_cmdline) < 0) { - error_report("xen pv domain creation failed"); - exit(1); - } - break; - } -#endif case XEN_EMULATE: error_report("xen emulation not implemented (yet)"); exit(1); diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h index 7efcdaa8fe..978aaa31fb 100644 --- a/include/hw/xen/xen.h +++ b/include/hw/xen/xen.h @@ -15,7 +15,6 @@ /* xen-machine.c */ enum xen_mode { XEN_EMULATE =3D 0, // xen emulation, using xenner (default) - XEN_CREATE, // create xen domain XEN_ATTACH // attach to xen domain created by xend }; =20 diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h index 93f631e5bf..2b91d199a1 100644 --- a/include/hw/xen/xen_common.h +++ b/include/hw/xen/xen_common.h @@ -661,24 +661,6 @@ static inline int xen_set_ioreq_server_state(domid_t d= om, =20 #endif =20 -#ifdef CONFIG_XEN_PV_DOMAIN_BUILD -#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 40700 -static inline int xen_domain_create(xc_interface *xc, uint32_t ssidref, - xen_domain_handle_t handle, uint32_t f= lags, - uint32_t *pdomid) -{ - return xc_domain_create(xc, ssidref, handle, flags, pdomid); -} -#else -static inline int xen_domain_create(xc_interface *xc, uint32_t ssidref, - xen_domain_handle_t handle, uint32_t f= lags, - uint32_t *pdomid) -{ - return xc_domain_create(xc, ssidref, handle, flags, pdomid, NULL); -} -#endif -#endif - /* Xen before 4.8 */ =20 #if CONFIG_XEN_CTRL_INTERFACE_VERSION < 40800 diff --git a/qemu-options.hx b/qemu-options.hx index d4f3564b78..7c323c9406 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3394,10 +3394,6 @@ ETEXI =20 DEF("xen-domid", HAS_ARG, QEMU_OPTION_xen_domid, "-xen-domid id specify xen guest domain id\n", QEMU_ARCH_ALL) -DEF("xen-create", 0, QEMU_OPTION_xen_create, - "-xen-create create domain using xen hypercalls, bypassing xend\n" - " warning: should not be used when xend is in use\n", - QEMU_ARCH_ALL) DEF("xen-attach", 0, QEMU_OPTION_xen_attach, "-xen-attach attach to existing xen domain\n" " xend will use this when starting QEMU\n", @@ -3411,10 +3407,6 @@ STEXI @item -xen-domid @var{id} @findex -xen-domid Specify xen guest domain @var{id} (XEN only). -@item -xen-create -@findex -xen-create -Create domain using xen hypercalls, bypassing xend. -Warning: should not be used when xend is in use (XEN only). @item -xen-attach @findex -xen-attach Attach to existing xen domain. diff --git a/vl.c b/vl.c index 064872cc98..d3f74c051c 100644 --- a/vl.c +++ b/vl.c @@ -3856,13 +3856,6 @@ int main(int argc, char **argv, char **envp) } xen_domid =3D atoi(optarg); break; - case QEMU_OPTION_xen_create: - if (!(xen_available())) { - error_report("Option not supported for this target"); - exit(1); - } - xen_mode =3D XEN_CREATE; - break; case QEMU_OPTION_xen_attach: if (!(xen_available())) { error_report("Option not supported for this target"); --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547130982222660.6276516739497; Thu, 10 Jan 2019 06:36:22 -0800 (PST) Received: from localhost ([127.0.0.1]:36937 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghbRR-0000Lx-Ez for importer@patchew.org; Thu, 10 Jan 2019 09:36:17 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58291) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb5P-0006I3-84 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gharD-0002Ep-Kp for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:58:53 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12008) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gharB-0001xV-NH for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:58:51 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263636" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:14 +0000 Message-ID: <20190110134917.16425-23-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 22/25] xen: Replace few mentions of xend by libxl 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 , xen-devel@lists.xenproject.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" xend have been replaced by libxenlight (libxl) for many Xen releases now. Signed-off-by: Anthony PERARD Acked-by: Stefano Stabellini --- hw/xenpv/xen_machine_pv.c | 2 +- include/hw/xen/xen.h | 2 +- qemu-options.hx | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c index 8d68fef25e..dcaf2a01a3 100644 --- a/hw/xenpv/xen_machine_pv.c +++ b/hw/xenpv/xen_machine_pv.c @@ -43,7 +43,7 @@ static void xen_init_pv(MachineState *machine) =20 switch (xen_mode) { case XEN_ATTACH: - /* nothing to do, xend handles everything */ + /* nothing to do, libxl handles everything */ break; case XEN_EMULATE: error_report("xen emulation not implemented (yet)"); diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h index 978aaa31fb..ba039c146d 100644 --- a/include/hw/xen/xen.h +++ b/include/hw/xen/xen.h @@ -15,7 +15,7 @@ /* xen-machine.c */ enum xen_mode { XEN_EMULATE =3D 0, // xen emulation, using xenner (default) - XEN_ATTACH // attach to xen domain created by xend + XEN_ATTACH // attach to xen domain created by libxl }; =20 extern uint32_t xen_domid; diff --git a/qemu-options.hx b/qemu-options.hx index 7c323c9406..521511ec13 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3396,7 +3396,7 @@ DEF("xen-domid", HAS_ARG, QEMU_OPTION_xen_domid, "-xen-domid id specify xen guest domain id\n", QEMU_ARCH_ALL) DEF("xen-attach", 0, QEMU_OPTION_xen_attach, "-xen-attach attach to existing xen domain\n" - " xend will use this when starting QEMU\n", + " libxl will use this when starting QEMU\n", QEMU_ARCH_ALL) DEF("xen-domid-restrict", 0, QEMU_OPTION_xen_domid_restrict, "-xen-domid-restrict restrict set of available xen operations\n" @@ -3410,7 +3410,7 @@ Specify xen guest domain @var{id} (XEN only). @item -xen-attach @findex -xen-attach Attach to existing xen domain. -xend will use this when starting QEMU (XEN only). +libxl will use this when starting QEMU (XEN only). @findex -xen-domid-restrict Restrict set of available xen operations to specified domain id (XEN only). ETEXI --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547130066216538.987391689634; Thu, 10 Jan 2019 06:21:06 -0800 (PST) Received: from localhost ([127.0.0.1]:33179 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghbCi-00047k-Rg for importer@patchew.org; Thu, 10 Jan 2019 09:21:04 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57997) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb5A-0005zL-Hy for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gharW-0002Rf-Q3 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:11 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12049) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gharW-0002QK-Fn for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:10 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263686" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:15 +0000 Message-ID: <20190110134917.16425-24-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 23/25] xen-block: improve batching behaviour 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 , xen-devel@lists.xenproject.org, Paul Durrant , Tim Smith Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Tim Smith When I/O consists of many small requests, performance is improved by batching them together in a single io_submit() call. When there are relatively few requests, the extra overhead is not worth it. This introduces a check to start batching I/O requests via blk_io_plug()/ blk_io_unplug() in an amount proportional to the number which were already in flight at the time we started reading the ring. Signed-off-by: Tim Smith Re-based and commit comment adjusted. Signed-off-by: Paul Durrant Acked-by: Anthony PERARD Signed-off-by: Anthony PERARD --- hw/block/dataplane/xen-block.c | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c index 8e3965e171..acd23a74a8 100644 --- a/hw/block/dataplane/xen-block.c +++ b/hw/block/dataplane/xen-block.c @@ -528,10 +528,18 @@ static int xen_block_get_request(XenBlockDataPlane *d= ataplane, return 0; } =20 +/* + * Threshold of in-flight requests above which we will start using + * blk_io_plug()/blk_io_unplug() to batch requests. + */ +#define IO_PLUG_THRESHOLD 1 + static void xen_block_handle_requests(XenBlockDataPlane *dataplane) { RING_IDX rc, rp; XenBlockRequest *request; + int inflight_atstart =3D dataplane->requests_inflight; + int batched =3D 0; =20 dataplane->more_work =3D 0; =20 @@ -540,6 +548,18 @@ static void xen_block_handle_requests(XenBlockDataPlan= e *dataplane) xen_rmb(); /* Ensure we see queued requests up to 'rp'. */ =20 xen_block_send_response_all(dataplane); + /* + * If there was more than IO_PLUG_THRESHOLD requests in flight + * when we got here, this is an indication that there the bottleneck + * is below us, so it's worth beginning to batch up I/O requests + * rather than submitting them immediately. The maximum number + * of requests we're willing to batch is the number already in + * flight, so it can grow up to max_requests when the bottleneck + * is below us. + */ + if (inflight_atstart > IO_PLUG_THRESHOLD) { + blk_io_plug(dataplane->blk); + } while (rc !=3D rp) { /* pull request from ring */ if (RING_REQUEST_CONS_OVERFLOW(&dataplane->rings.common, rc)) { @@ -585,7 +605,22 @@ static void xen_block_handle_requests(XenBlockDataPlan= e *dataplane) continue; } =20 + if (inflight_atstart > IO_PLUG_THRESHOLD && + batched >=3D inflight_atstart) { + blk_io_unplug(dataplane->blk); + } xen_block_do_aio(request); + if (inflight_atstart > IO_PLUG_THRESHOLD) { + if (batched >=3D inflight_atstart) { + blk_io_plug(dataplane->blk); + batched =3D 0; + } else { + batched++; + } + } + } + if (inflight_atstart > IO_PLUG_THRESHOLD) { + blk_io_unplug(dataplane->blk); } =20 if (dataplane->more_work && --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547130264123581.8383040391017; Thu, 10 Jan 2019 06:24:24 -0800 (PST) Received: from localhost ([127.0.0.1]:33949 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghbFp-0006qG-Mb for importer@patchew.org; Thu, 10 Jan 2019 09:24:17 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57997) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb5B-0005zL-T4 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gharN-0002Ly-Ky for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:03 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12008) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gharN-0001xV-9N for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:59:01 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263668" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:16 +0000 Message-ID: <20190110134917.16425-25-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 24/25] xen-block: improve response latency 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 , xen-devel@lists.xenproject.org, Paul Durrant , Tim Smith Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Tim Smith If the I/O ring is full, the guest cannot send any more requests until some responses are sent. Only sending all available responses just before checking for new work does not leave much time for the guest to supply new work, so this will cause stalls if the ring gets full. Also, not completing reads as soon as possible adds latency to the guest. To alleviate that, complete IO requests as soon as they come back. xen_block_send_response() already returns a value indicating whether a notify should be sent, which is all the batching we need. Signed-off-by: Tim Smith Re-based and commit comment adjusted. Signed-off-by: Paul Durrant Acked-by: Anthony PERARD Signed-off-by: Anthony PERARD --- hw/block/dataplane/xen-block.c | 56 +++++++++++----------------------- 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c index acd23a74a8..35bfccfba7 100644 --- a/hw/block/dataplane/xen-block.c +++ b/hw/block/dataplane/xen-block.c @@ -55,11 +55,9 @@ struct XenBlockDataPlane { blkif_back_rings_t rings; int more_work; QLIST_HEAD(inflight_head, XenBlockRequest) inflight; - QLIST_HEAD(finished_head, XenBlockRequest) finished; QLIST_HEAD(freelist_head, XenBlockRequest) freelist; int requests_total; int requests_inflight; - int requests_finished; unsigned int max_requests; BlockBackend *blk; QEMUBH *bh; @@ -116,12 +114,10 @@ static void xen_block_finish_request(XenBlockRequest = *request) XenBlockDataPlane *dataplane =3D request->dataplane; =20 QLIST_REMOVE(request, list); - QLIST_INSERT_HEAD(&dataplane->finished, request, list); dataplane->requests_inflight--; - dataplane->requests_finished++; } =20 -static void xen_block_release_request(XenBlockRequest *request, bool finis= h) +static void xen_block_release_request(XenBlockRequest *request) { XenBlockDataPlane *dataplane =3D request->dataplane; =20 @@ -129,11 +125,7 @@ static void xen_block_release_request(XenBlockRequest = *request, bool finish) reset_request(request); request->dataplane =3D dataplane; QLIST_INSERT_HEAD(&dataplane->freelist, request, list); - if (finish) { - dataplane->requests_finished--; - } else { - dataplane->requests_inflight--; - } + dataplane->requests_inflight--; } =20 /* @@ -248,6 +240,7 @@ static int xen_block_copy_request(XenBlockRequest *requ= est) } =20 static int xen_block_do_aio(XenBlockRequest *request); +static int xen_block_send_response(XenBlockRequest *request); =20 static void xen_block_complete_aio(void *opaque, int ret) { @@ -312,6 +305,18 @@ static void xen_block_complete_aio(void *opaque, int r= et) default: break; } + if (xen_block_send_response(request)) { + Error *local_err =3D NULL; + + xen_device_notify_event_channel(dataplane->xendev, + dataplane->event_channel, + &local_err); + if (local_err) { + error_report_err(local_err); + } + } + xen_block_release_request(request); + qemu_bh_schedule(dataplane->bh); =20 done: @@ -419,7 +424,7 @@ static int xen_block_do_aio(XenBlockRequest *request) return -1; } =20 -static int xen_block_send_response_one(XenBlockRequest *request) +static int xen_block_send_response(XenBlockRequest *request) { XenBlockDataPlane *dataplane =3D request->dataplane; int send_notify =3D 0; @@ -474,29 +479,6 @@ static int xen_block_send_response_one(XenBlockRequest= *request) return send_notify; } =20 -/* walk finished list, send outstanding responses, free requests */ -static void xen_block_send_response_all(XenBlockDataPlane *dataplane) -{ - XenBlockRequest *request; - int send_notify =3D 0; - - while (!QLIST_EMPTY(&dataplane->finished)) { - request =3D QLIST_FIRST(&dataplane->finished); - send_notify +=3D xen_block_send_response_one(request); - xen_block_release_request(request, true); - } - if (send_notify) { - Error *local_err =3D NULL; - - xen_device_notify_event_channel(dataplane->xendev, - dataplane->event_channel, - &local_err); - if (local_err) { - error_report_err(local_err); - } - } -} - static int xen_block_get_request(XenBlockDataPlane *dataplane, XenBlockRequest *request, RING_IDX rc) { @@ -547,7 +529,6 @@ static void xen_block_handle_requests(XenBlockDataPlane= *dataplane) rp =3D dataplane->rings.common.sring->req_prod; xen_rmb(); /* Ensure we see queued requests up to 'rp'. */ =20 - xen_block_send_response_all(dataplane); /* * If there was more than IO_PLUG_THRESHOLD requests in flight * when we got here, this is an indication that there the bottleneck @@ -591,7 +572,7 @@ static void xen_block_handle_requests(XenBlockDataPlane= *dataplane) break; }; =20 - if (xen_block_send_response_one(request)) { + if (xen_block_send_response(request)) { Error *local_err =3D NULL; =20 xen_device_notify_event_channel(dataplane->xendev, @@ -601,7 +582,7 @@ static void xen_block_handle_requests(XenBlockDataPlane= *dataplane) error_report_err(local_err); } } - xen_block_release_request(request, false); + xen_block_release_request(request); continue; } =20 @@ -657,7 +638,6 @@ XenBlockDataPlane *xen_block_dataplane_create(XenDevice= *xendev, dataplane->file_size =3D blk_getlength(dataplane->blk); =20 QLIST_INIT(&dataplane->inflight); - QLIST_INIT(&dataplane->finished); QLIST_INIT(&dataplane->freelist); =20 if (iothread) { --=20 Anthony PERARD From nobody Fri Apr 19 23:43:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547130700019560.0505703717286; Thu, 10 Jan 2019 06:31:40 -0800 (PST) Received: from localhost ([127.0.0.1]:35839 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghbMw-0004QO-NJ for importer@patchew.org; Thu, 10 Jan 2019 09:31:38 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58546) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghb5L-0006cH-0m for qemu-devel@nongnu.org; Thu, 10 Jan 2019 09:13:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gharK-0002Km-7G for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:58:58 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:12008) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gharJ-0001xV-Vr for qemu-devel@nongnu.org; Thu, 10 Jan 2019 08:58:58 -0500 X-IronPort-AV: E=Sophos;i="5.56,461,1539648000"; d="scan'208";a="75263660" From: Anthony PERARD To: Date: Thu, 10 Jan 2019 13:49:17 +0000 Message-ID: <20190110134917.16425-26-anthony.perard@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com> References: <20190110134917.16425-1-anthony.perard@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PULL 25/25] xen-block: avoid repeated memory allocation 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 , xen-devel@lists.xenproject.org, Paul Durrant , Tim Smith Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Tim Smith The xen-block dataplane currently allocates memory to hold the data for each request as that request is used, and frees it afterwards. Because it requires page-aligned blocks, this interacts poorly with non-page- aligned allocations and balloons the heap. Instead, allocate the maximum possible buffer size required for the protocol, which is BLKIF_MAX_SEGMENTS_PER_REQUEST (currently 11) pages when the request structure is created, and keep that buffer until it is destroyed. Since the requests are re-used via a free list, this should actually improve memory usage. Signed-off-by: Tim Smith Re-based and commit comment adjusted. Signed-off-by: Paul Durrant Acked-by: Anthony PERARD Signed-off-by: Anthony PERARD --- hw/block/dataplane/xen-block.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c index 35bfccfba7..d0d8905a33 100644 --- a/hw/block/dataplane/xen-block.c +++ b/hw/block/dataplane/xen-block.c @@ -70,7 +70,6 @@ static void reset_request(XenBlockRequest *request) memset(&request->req, 0, sizeof(request->req)); request->status =3D 0; request->start =3D 0; - request->buf =3D NULL; request->size =3D 0; request->presync =3D 0; =20 @@ -95,6 +94,14 @@ static XenBlockRequest *xen_block_start_request(XenBlock= DataPlane *dataplane) /* allocate new struct */ request =3D g_malloc0(sizeof(*request)); request->dataplane =3D dataplane; + /* + * We cannot need more pages per requests than this, and since we + * re-use requests, allocate the memory once here. It will be freed + * xen_block_dataplane_destroy() when the request list is freed. + */ + request->buf =3D qemu_memalign(XC_PAGE_SIZE, + BLKIF_MAX_SEGMENTS_PER_REQUEST * + XC_PAGE_SIZE); dataplane->requests_total++; qemu_iovec_init(&request->v, 1); } else { @@ -272,14 +279,12 @@ static void xen_block_complete_aio(void *opaque, int = ret) if (ret =3D=3D 0) { xen_block_copy_request(request); } - qemu_vfree(request->buf); break; case BLKIF_OP_WRITE: case BLKIF_OP_FLUSH_DISKCACHE: if (!request->req.nr_segments) { break; } - qemu_vfree(request->buf); break; default: break; @@ -360,12 +365,10 @@ static int xen_block_do_aio(XenBlockRequest *request) { XenBlockDataPlane *dataplane =3D request->dataplane; =20 - request->buf =3D qemu_memalign(XC_PAGE_SIZE, request->size); if (request->req.nr_segments && (request->req.operation =3D=3D BLKIF_OP_WRITE || request->req.operation =3D=3D BLKIF_OP_FLUSH_DISKCACHE) && xen_block_copy_request(request)) { - qemu_vfree(request->buf); goto err; } =20 @@ -665,6 +668,7 @@ void xen_block_dataplane_destroy(XenBlockDataPlane *dat= aplane) request =3D QLIST_FIRST(&dataplane->freelist); QLIST_REMOVE(request, list); qemu_iovec_destroy(&request->v); + qemu_vfree(request->buf); g_free(request); } =20 --=20 Anthony PERARD