[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v2 4/4] xen: Fix map/unmap of pcidev to ioreq server



> -----Original Message-----
> From: Don Slutz [mailto:dslutz@xxxxxxxxxxx]
> Sent: 09 June 2015 14:51
> To: Paul Durrant; Slutz, Donald Christopher; qemu-devel@xxxxxxxxxx; xen-
> devel@xxxxxxxxxxxxx
> Cc: Michael S. Tsirkin; Stefano Stabellini; Don Slutz
> Subject: Re: [PATCH v2 4/4] xen: Fix map/unmap of pcidev to ioreq server
> 
> On 06/09/15 05:05, Paul Durrant wrote:
> >> -----Original Message-----
> >> From: Don Slutz [mailto:dslutz@xxxxxxxxxxx]
> >> Sent: 08 June 2015 22:19
> >> To: qemu-devel@xxxxxxxxxx; xen-devel@xxxxxxxxxxxxx
> >> Cc: Michael S. Tsirkin; Paul Durrant; Stefano Stabellini; Don Slutz; Don 
> >> Slutz
> >> Subject: [PATCH v2 4/4] xen: Fix map/unmap of pcidev to ioreq server
> >>
> >> The commit 707ff80021ccd7a68f4b3d2c44eebf87efbb41c4 added usage of
> >> xc_hvm_map_pcidev_from_ioreq_server() and
> >> xc_hvm_unmap_pcidev_from_ioreq_server().  These routines only
> >> correctly work if the PCI BDF of a PCI device is unique.  The 3
> >> parts (bus, device, and function) of a PCI BDF are not required to
> >> be unique.
> >>
> >> The PCI BDF is accessed in QEMU:
> >>   bus        pci_bus_num()
> >>   device     PCI_SLOT()
> >>   function   PCI_FUNC()
> >>
> >> Add a hash table to track the current set of PCI BDFs and only call
> >> on xc_hvm_map_pcidev_from_ioreq_server() and
> >> xc_hvm_unmap_pcidev_from_ioreq_server() when needed.
> >>
> >
> > This seems to imply that the devices are being realized multiple times
> without being unrealized?
> 
> Not directly.  The devices are not being "realized" in QEMU terms.  The
> PCI to PCI brige is changing state, and the BDF for all PCI devices on
> the secondary bus changes when the PCI config named
> PCI_SECONDARY_BUS on
> the PCI to PCI bridge is changed.  This is what patch #2 is all about.
> 
> > Is that really the case?
> >
> 
> That is what it looks like to Xen.  But the device listener callbacks
> are not called.

Then what's calling xc_hvm_map_pcidev_from_ioreq_server()? I don't understand 
why you are having to introduce this to avoid duplicate calls?

  Paul

> 
>    -Don Slutz
> 
> >   Paul
> >
> >> Also fix the PCI BDF default stderr trace output: bus is seperated
> >> by ':', and function is only 1 digit.
> >>
> >> Here is an example of stderr trace output:
> >>
> >> xen_map_pcidev id: 1 bdf: 00:00.0
> >> xen_map_pcidev id: 1 bdf: 00:01.0
> >> xen_map_pcidev id: 1 bdf: 00:01.1
> >> xen_map_pcidev id: 1 bdf: 00:01.3
> >> xen_map_pcidev id: 1 bdf: 00:02.0
> >> xen_map_pcidev id: 1 bdf: 00:03.0
> >> xen_map_pcidev id: 1 bdf: 00:04.0
> >> xen_map_pcidev id: 1 bdf: 00:05.0
> >> xen_map_pcidev id: 1 bdf: 00:11.0
> >> xen_map_pcidev id: 1 bdf: 00:15.0
> >> xen_map_pcidev id: 1 bdf: 00:16.0
> >> xen_map_pcidev id: 1 bdf: 00:17.0
> >> xen_map_pcidev id: 1 bdf: 00:18.0
> >> xen_map_pcidev_dup id: 1 bdf: 00:01.0 dup: 2
> >> xen_map_pcidev_dup id: 1 bdf: 00:01.0 dup: 3
> >> xen_map_pcidev_dup id: 1 bdf: 00:03.0 dup: 2
> >> xen_map_pcidev_dup id: 1 bdf: 00:03.0 dup: 3
> >> xen_map_pcidev_dup id: 1 bdf: 00:04.0 dup: 2
> >> xen_unmap_pcidev_dup id: 1 bdf: 00:03.0 dup: 2
> >> xen_map_pcidev id: 1 bdf: ff:03.0
> >> xen_unmap_pcidev id: 1 bdf: 00:17.0
> >> xen_map_pcidev id: 1 bdf: ff:17.0
> >> xen_unmap_pcidev_dup id: 1 bdf: 00:01.0 dup: 2
> >> xen_map_pcidev id: 1 bdf: ff:01.0
> >> xen_unmap_pcidev_dup id: 1 bdf: 00:03.0 dup: 1
> >> xen_map_pcidev_dup id: 1 bdf: ff:03.0 dup: 2
> >> xen_unmap_pcidev_dup id: 1 bdf: 00:04.0 dup: 1
> >> xen_map_pcidev id: 1 bdf: ff:04.0
> >> xen_unmap_pcidev_dup id: 1 bdf: ff:03.0 dup: 1
> >> xen_map_pcidev id: 1 bdf: 01:03.0
> >> xen_unmap_pcidev id: 1 bdf: ff:17.0
> >> xen_map_pcidev id: 1 bdf: 01:17.0
> >> xen_unmap_pcidev_dup id: 1 bdf: 00:01.0 dup: 1
> >> xen_map_pcidev_dup id: 1 bdf: ff:01.0 dup: 2
> >> xen_unmap_pcidev_dup id: 1 bdf: ff:01.0 dup: 1
> >> xen_map_pcidev id: 1 bdf: 02:01.0
> >> xen_unmap_pcidev id: 1 bdf: ff:01.0
> >> xen_map_pcidev id: 1 bdf: 03:01.0
> >> xen_unmap_pcidev id: 1 bdf: ff:03.0
> >> xen_map_pcidev id: 1 bdf: 03:03.0
> >> xen_unmap_pcidev id: 1 bdf: ff:04.0
> >> xen_map_pcidev id: 1 bdf: 03:04.0
> >> xen_unmap_pcidev id: 1 bdf: 00:04.0
> >> xen_unmap_pcidev id: 1 bdf: 00:05.0
> >> xen_unmap_pcidev id: 1 bdf: 01:03.0
> >> xen_map_pcidev_dup id: 1 bdf: 00:03.0 dup: 2
> >> xen_unmap_pcidev id: 1 bdf: 01:17.0
> >> xen_map_pcidev id: 1 bdf: 00:17.0
> >> xen_unmap_pcidev id: 1 bdf: 03:01.0
> >> xen_map_pcidev_dup id: 1 bdf: 00:01.0 dup: 2
> >> xen_unmap_pcidev id: 1 bdf: 03:03.0
> >> xen_map_pcidev_dup id: 1 bdf: 00:03.0 dup: 3
> >> xen_unmap_pcidev id: 1 bdf: 03:04.0
> >> xen_map_pcidev id: 1 bdf: 00:04.0
> >> xen_unmap_pcidev_dup id: 1 bdf: 00:03.0 dup: 2
> >> xen_map_pcidev id: 1 bdf: 01:03.0
> >> xen_unmap_pcidev id: 1 bdf: 00:17.0
> >> xen_map_pcidev id: 1 bdf: 01:17.0
> >> xen_unmap_pcidev id: 1 bdf: 02:01.0
> >> xen_map_pcidev_dup id: 1 bdf: 00:01.0 dup: 3
> >> xen_unmap_pcidev_dup id: 1 bdf: 00:01.0 dup: 2
> >> xen_map_pcidev id: 1 bdf: 02:01.0
> >> xen_unmap_pcidev_dup id: 1 bdf: 00:01.0 dup: 1
> >> xen_map_pcidev id: 1 bdf: 03:01.0
> >> xen_unmap_pcidev_dup id: 1 bdf: 00:03.0 dup: 1
> >> xen_map_pcidev id: 1 bdf: 03:03.0
> >> xen_unmap_pcidev id: 1 bdf: 00:04.0
> >> xen_map_pcidev id: 1 bdf: 03:04.0
> >>
> >> Signed-off-by: Don Slutz <dslutz@xxxxxxxxxxx>
> >> CC: Don Slutz <don.slutz@xxxxxxxxx>
> >> ---
> >>  include/hw/xen/xen_common.h | 53
> >> +++++++++++++++++++++++++++++++++++----------
> >>  trace-events                |  6 +++--
> >>  xen-hvm.c                   | 15 ++++++++-----
> >>  3 files changed, 55 insertions(+), 19 deletions(-)
> >>
> >> diff --git a/include/hw/xen/xen_common.h
> >> b/include/hw/xen/xen_common.h
> >> index 6579b78..260ee58 100644
> >> --- a/include/hw/xen/xen_common.h
> >> +++ b/include/hw/xen/xen_common.h
> >> @@ -223,12 +223,14 @@ static inline void xen_unmap_io_section(XenXC
> xc,
> >> domid_t dom,
> >>
> >>  static inline void xen_map_pcidev(XenXC xc, domid_t dom,
> >>                                    ioservid_t ioservid,
> >> +                                  GHashTable *pci_bdf,
> >>                                    PCIDevice *pci_dev)
> >>  {
> >>  }
> >>
> >>  static inline void xen_unmap_pcidev(XenXC xc, domid_t dom,
> >>                                      ioservid_t ioservid,
> >> +                                    GHashTable *pci_bdf,
> >>                                      PCIDevice *pci_dev,
> >>                                      uint8_t oldbus)
> >>  {
> >> @@ -346,27 +348,54 @@ static inline void xen_unmap_io_section(XenXC
> xc,
> >> domid_t dom,
> >>
> >>  static inline void xen_map_pcidev(XenXC xc, domid_t dom,
> >>                                    ioservid_t ioservid,
> >> +                                  GHashTable *pci_bdf,
> >>                                    PCIDevice *pci_dev)
> >>  {
> >> -    trace_xen_map_pcidev(ioservid, pci_bus_num(pci_dev->bus),
> >> -                         PCI_SLOT(pci_dev->devfn), 
> >> PCI_FUNC(pci_dev->devfn));
> >> -    xc_hvm_map_pcidev_to_ioreq_server(xc, dom, ioservid,
> >> -                                      0, pci_bus_num(pci_dev->bus),
> >> -                                      PCI_SLOT(pci_dev->devfn),
> >> -                                      PCI_FUNC(pci_dev->devfn));
> >> +    gpointer bdf_key = GINT_TO_POINTER((pci_bus_num(pci_dev->bus)
> <<
> >> 8) |
> >> +                                       pci_dev->devfn);
> >> +    gint bdf_cnt = GPOINTER_TO_INT(g_hash_table_lookup(pci_bdf,
> >> bdf_key));
> >> +
> >> +    if (!bdf_cnt) {
> >> +        trace_xen_map_pcidev(ioservid, pci_bus_num(pci_dev->bus),
> >> +                             PCI_SLOT(pci_dev->devfn),
> >> +                             PCI_FUNC(pci_dev->devfn));
> >> +        g_hash_table_insert(pci_bdf, bdf_key, GINT_TO_POINTER(1));
> >> +        xc_hvm_map_pcidev_to_ioreq_server(xc, dom, ioservid,
> >> +                                          0, pci_bus_num(pci_dev->bus),
> >> +                                          PCI_SLOT(pci_dev->devfn),
> >> +                                          PCI_FUNC(pci_dev->devfn));
> >> +    } else {
> >> +        trace_xen_map_pcidev_dup(ioservid, pci_bus_num(pci_dev->bus),
> >> +                                 PCI_SLOT(pci_dev->devfn),
> >> +                                 PCI_FUNC(pci_dev->devfn),
> >> +                                 bdf_cnt + 1);
> >> +        g_hash_table_replace(pci_bdf, bdf_key,
> GINT_TO_POINTER(bdf_cnt +
> >> 1));
> >> +    }
> >>  }
> >>
> >>  static inline void xen_unmap_pcidev(XenXC xc, domid_t dom,
> >>                                      ioservid_t ioservid,
> >> +                                    GHashTable *pci_bdf,
> >>                                      PCIDevice *pci_dev,
> >>                                      uint8_t oldbus)
> >>  {
> >> -    trace_xen_unmap_pcidev(ioservid, oldbus,
> >> -                           PCI_SLOT(pci_dev->devfn), 
> >> PCI_FUNC(pci_dev->devfn));
> >> -    xc_hvm_unmap_pcidev_from_ioreq_server(xc, dom, ioservid,
> >> -                                          0, oldbus,
> >> -                                          PCI_SLOT(pci_dev->devfn),
> >> -                                          PCI_FUNC(pci_dev->devfn));
> >> +    gpointer bdf_key = GINT_TO_POINTER((oldbus << 8) | pci_dev-
> >devfn);
> >> +    gint bdf_cnt = GPOINTER_TO_INT(g_hash_table_lookup(pci_bdf,
> >> bdf_key));
> >> +
> >> +    if (bdf_cnt == 1) {
> >> +        trace_xen_unmap_pcidev(ioservid, oldbus,
> >> +                               PCI_SLOT(pci_dev->devfn),
> >> +                               PCI_FUNC(pci_dev->devfn));
> >> +        g_hash_table_remove(pci_bdf, bdf_key);
> >> +        xc_hvm_unmap_pcidev_from_ioreq_server(xc, dom, ioservid,
> >> +                                              0, oldbus,
> >> +                                              PCI_SLOT(pci_dev->devfn),
> >> +                                              PCI_FUNC(pci_dev->devfn));
> >> +    } else {
> >> +        trace_xen_unmap_pcidev_dup(ioservid, oldbus, PCI_SLOT(pci_dev-
> >>> devfn),
> >> +                                   PCI_FUNC(pci_dev->devfn), bdf_cnt - 1);
> >> +        g_hash_table_replace(pci_bdf, bdf_key,
> GINT_TO_POINTER(bdf_cnt -
> >> 1));
> >> +    }
> >>  }
> >>
> >>  static inline int xen_create_ioreq_server(XenXC xc, domid_t dom,
> >> diff --git a/trace-events b/trace-events
> >> index a589650..58deeaf 100644
> >> --- a/trace-events
> >> +++ b/trace-events
> >> @@ -930,8 +930,10 @@ xen_map_mmio_range(uint32_t id, uint64_t
> >> start_addr, uint64_t end_addr) "id: %u
> >>  xen_unmap_mmio_range(uint32_t id, uint64_t start_addr, uint64_t
> >> end_addr) "id: %u start: %#"PRIx64" end: %#"PRIx64
> >>  xen_map_portio_range(uint32_t id, uint64_t start_addr, uint64_t
> end_addr)
> >> "id: %u start: %#"PRIx64" end: %#"PRIx64
> >>  xen_unmap_portio_range(uint32_t id, uint64_t start_addr, uint64_t
> >> end_addr) "id: %u start: %#"PRIx64" end: %#"PRIx64
> >> -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_map_pcidev(uint32_t id, uint8_t bus, uint8_t dev, uint8_t func) "id:
> %u
> >> bdf: %02x:%02x.%x"
> >> +xen_map_pcidev_dup(uint32_t id, uint8_t bus, uint8_t dev, uint8_t
> func,
> >> int dup) "id: %u bdf: %02x:%02x.%x dup: %d"
> >> +xen_unmap_pcidev(uint32_t id, uint8_t bus, uint8_t dev, uint8_t func)
> "id:
> >> %u bdf: %02x:%02x.%x"
> >> +xen_unmap_pcidev_dup(uint32_t id, uint8_t bus, uint8_t dev, uint8_t
> func,
> >> int dup) "id: %u bdf: %02x:%02x.%x dup: %d"
> >>
> >>  # xen-mapcache.c
> >>  xen_map_cache(uint64_t phys_addr) "want %#"PRIx64
> >> diff --git a/xen-hvm.c b/xen-hvm.c
> >> index 7b6d8f1..f041909 100644
> >> --- a/xen-hvm.c
> >> +++ b/xen-hvm.c
> >> @@ -123,6 +123,7 @@ typedef struct XenIOState {
> >>      MemoryListener memory_listener;
> >>      MemoryListener io_listener;
> >>      DeviceListener device_listener;
> >> +    GHashTable *pci_bdf;
> >>      QLIST_HEAD(, XenPhysmap) physmap;
> >>      hwaddr free_phys_offset;
> >>      const XenPhysmap *log_for_dirtybit;
> >> @@ -578,7 +579,8 @@ static void xen_device_realize(DeviceListener
> >> *listener,
> >>      if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
> >>          PCIDevice *pci_dev = PCI_DEVICE(dev);
> >>
> >> -        xen_map_pcidev(xen_xc, xen_domid, state->ioservid, pci_dev);
> >> +        xen_map_pcidev(xen_xc, xen_domid, state->ioservid, state-
> >pci_bdf,
> >> +                       pci_dev);
> >>      }
> >>  }
> >>
> >> @@ -590,8 +592,8 @@ static void xen_device_unrealize(DeviceListener
> >> *listener,
> >>      if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
> >>          PCIDevice *pci_dev = PCI_DEVICE(dev);
> >>
> >> -        xen_unmap_pcidev(xen_xc, xen_domid, state->ioservid, pci_dev,
> >> -                         pci_bus_num(pci_dev->bus));
> >> +        xen_unmap_pcidev(xen_xc, xen_domid, state->ioservid, state-
> >>> pci_bdf,
> >> +                         pci_dev, pci_bus_num(pci_dev->bus));
> >>      }
> >>  }
> >>
> >> @@ -600,8 +602,10 @@ static void
> >> xen_device_change_pci_bus_num(DeviceListener *listener,
> >>  {
> >>      XenIOState *state = container_of(listener, XenIOState,
> device_listener);
> >>
> >> -    xen_unmap_pcidev(xen_xc, xen_domid, state->ioservid, pci_dev,
> >> oldbus);
> >> -    xen_map_pcidev(xen_xc, xen_domid, state->ioservid, pci_dev);
> >> +    xen_unmap_pcidev(xen_xc, xen_domid, state->ioservid, state-
> >pci_bdf,
> >> +                     pci_dev, oldbus);
> >> +    xen_map_pcidev(xen_xc, xen_domid, state->ioservid, state-
> >pci_bdf,
> >> +                   pci_dev);
> >>  }
> >>
> >>  static void xen_sync_dirty_bitmap(XenIOState *state,
> >> @@ -1318,6 +1322,7 @@ int xen_hvm_init(ram_addr_t
> >> *below_4g_mem_size, ram_addr_t *above_4g_mem_size,
> >>      memory_listener_register(&state->io_listener, &address_space_io);
> >>
> >>      state->device_listener = xen_device_listener;
> >> +    state->pci_bdf = g_hash_table_new(NULL, NULL);
> >>      device_listener_register(&state->device_listener);
> >>
> >>      /* Initialize backend core & drivers */
> >> --
> >> 1.8.4
> >

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.