|
|
c313de |
From 7888472ef1d57d992995a16dc7c9ba0fe18562a8 Mon Sep 17 00:00:00 2001
|
|
|
c313de |
Message-Id: <7888472ef1d57d992995a16dc7c9ba0fe18562a8@dist-git>
|
|
|
c313de |
From: Yi Min Zhao <zyimin@linux.ibm.com>
|
|
|
c313de |
Date: Mon, 8 Apr 2019 10:57:22 +0200
|
|
|
c313de |
Subject: [PATCH] conf: Introduce address caching for PCI extensions
|
|
|
c313de |
MIME-Version: 1.0
|
|
|
c313de |
Content-Type: text/plain; charset=UTF-8
|
|
|
c313de |
Content-Transfer-Encoding: 8bit
|
|
|
c313de |
|
|
|
c313de |
This patch provides a caching mechanism for the device address
|
|
|
c313de |
extensions uid and fid on S390. For efficient sparse address allocation,
|
|
|
c313de |
we introduce two hash tables for uid/fid which hold the address set
|
|
|
c313de |
information per domain. Also in order to improve performance of
|
|
|
c313de |
searching available value, we introduce our own callbacks for the two
|
|
|
c313de |
hashtables. In this way, uid/fid is saved in hash key and hash value
|
|
|
c313de |
could be any non-NULL pointer due to no operation on hash value. That is
|
|
|
c313de |
also the reason why we don't introduce hash value free callback.
|
|
|
c313de |
|
|
|
c313de |
Signed-off-by: Yi Min Zhao <zyimin@linux.ibm.com>
|
|
|
c313de |
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
|
|
|
c313de |
Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
|
|
|
c313de |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
c313de |
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
|
|
|
c313de |
|
|
|
c313de |
(cherry picked from commit 28831e1f1ec001882e907f03f7618f7c00ebc98d)
|
|
|
c313de |
|
|
|
c313de |
https://bugzilla.redhat.com/show_bug.cgi?id=1508149
|
|
|
c313de |
|
|
|
c313de |
Conflicts:
|
|
|
c313de |
|
|
|
c313de |
* src/conf/domain_addr.h
|
|
|
c313de |
+ context
|
|
|
c313de |
- missing b72183223f3b
|
|
|
c313de |
|
|
|
c313de |
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
|
|
|
c313de |
Message-Id: <20190408085732.28684-6-abologna@redhat.com>
|
|
|
c313de |
Reviewed-by: Laine Stump <laine@redhat.com>
|
|
|
c313de |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
c313de |
---
|
|
|
c313de |
src/bhyve/bhyve_device.c | 3 +-
|
|
|
c313de |
src/conf/domain_addr.c | 93 +++++++++++++++++++++++++++++++++-
|
|
|
c313de |
src/conf/domain_addr.h | 10 +++-
|
|
|
c313de |
src/qemu/qemu_domain_address.c | 6 ++-
|
|
|
c313de |
4 files changed, 108 insertions(+), 4 deletions(-)
|
|
|
c313de |
|
|
|
c313de |
diff --git a/src/bhyve/bhyve_device.c b/src/bhyve/bhyve_device.c
|
|
|
c313de |
index 03aa6c93bd..8f0862b0b6 100644
|
|
|
c313de |
--- a/src/bhyve/bhyve_device.c
|
|
|
c313de |
+++ b/src/bhyve/bhyve_device.c
|
|
|
c313de |
@@ -71,7 +71,8 @@ bhyveDomainPCIAddressSetCreate(virDomainDefPtr def, unsigned int nbuses)
|
|
|
c313de |
{
|
|
|
c313de |
virDomainPCIAddressSetPtr addrs;
|
|
|
c313de |
|
|
|
c313de |
- if ((addrs = virDomainPCIAddressSetAlloc(nbuses)) == NULL)
|
|
|
c313de |
+ if ((addrs = virDomainPCIAddressSetAlloc(nbuses,
|
|
|
c313de |
+ VIR_PCI_ADDRESS_EXTENSION_NONE)) == NULL)
|
|
|
c313de |
return NULL;
|
|
|
c313de |
|
|
|
c313de |
if (virDomainPCIAddressBusSetModel(&addrs->buses[0],
|
|
|
c313de |
diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
|
|
|
c313de |
index 39f22b82eb..3e33549c3d 100644
|
|
|
c313de |
--- a/src/conf/domain_addr.c
|
|
|
c313de |
+++ b/src/conf/domain_addr.c
|
|
|
c313de |
@@ -27,6 +27,7 @@
|
|
|
c313de |
#include "virlog.h"
|
|
|
c313de |
#include "virstring.h"
|
|
|
c313de |
#include "domain_addr.h"
|
|
|
c313de |
+#include "virhashcode.h"
|
|
|
c313de |
|
|
|
c313de |
#define VIR_FROM_THIS VIR_FROM_DOMAIN
|
|
|
c313de |
|
|
|
c313de |
@@ -741,8 +742,93 @@ virDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs,
|
|
|
c313de |
addrs->buses[addr->bus].slot[addr->slot].functions &= ~(1 << addr->function);
|
|
|
c313de |
}
|
|
|
c313de |
|
|
|
c313de |
+
|
|
|
c313de |
+static uint32_t
|
|
|
c313de |
+virZPCIAddrKeyCode(const void *name,
|
|
|
c313de |
+ uint32_t seed)
|
|
|
c313de |
+{
|
|
|
c313de |
+ unsigned int value = *((unsigned int *)name);
|
|
|
c313de |
+ return virHashCodeGen(&value, sizeof(value), seed);
|
|
|
c313de |
+}
|
|
|
c313de |
+
|
|
|
c313de |
+
|
|
|
c313de |
+static bool
|
|
|
c313de |
+virZPCIAddrKeyEqual(const void *namea,
|
|
|
c313de |
+ const void *nameb)
|
|
|
c313de |
+{
|
|
|
c313de |
+ return *((unsigned int *)namea) == *((unsigned int *)nameb);
|
|
|
c313de |
+}
|
|
|
c313de |
+
|
|
|
c313de |
+
|
|
|
c313de |
+static void *
|
|
|
c313de |
+virZPCIAddrKeyCopy(const void *name)
|
|
|
c313de |
+{
|
|
|
c313de |
+ unsigned int *copy;
|
|
|
c313de |
+
|
|
|
c313de |
+ if (VIR_ALLOC(copy) < 0)
|
|
|
c313de |
+ return NULL;
|
|
|
c313de |
+
|
|
|
c313de |
+ *copy = *((unsigned int *)name);
|
|
|
c313de |
+ return (void *)copy;
|
|
|
c313de |
+}
|
|
|
c313de |
+
|
|
|
c313de |
+
|
|
|
c313de |
+static void
|
|
|
c313de |
+virZPCIAddrKeyFree(void *name)
|
|
|
c313de |
+{
|
|
|
c313de |
+ VIR_FREE(name);
|
|
|
c313de |
+}
|
|
|
c313de |
+
|
|
|
c313de |
+
|
|
|
c313de |
+static void
|
|
|
c313de |
+virDomainPCIAddressSetExtensionFree(virDomainPCIAddressSetPtr addrs)
|
|
|
c313de |
+{
|
|
|
c313de |
+ if (!addrs || !addrs->zpciIds)
|
|
|
c313de |
+ return;
|
|
|
c313de |
+
|
|
|
c313de |
+ virHashFree(addrs->zpciIds->uids);
|
|
|
c313de |
+ virHashFree(addrs->zpciIds->fids);
|
|
|
c313de |
+ VIR_FREE(addrs->zpciIds);
|
|
|
c313de |
+}
|
|
|
c313de |
+
|
|
|
c313de |
+
|
|
|
c313de |
+static int
|
|
|
c313de |
+virDomainPCIAddressSetExtensionAlloc(virDomainPCIAddressSetPtr addrs,
|
|
|
c313de |
+ virPCIDeviceAddressExtensionFlags extFlags)
|
|
|
c313de |
+{
|
|
|
c313de |
+ if (extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) {
|
|
|
c313de |
+ if (addrs->zpciIds)
|
|
|
c313de |
+ return 0;
|
|
|
c313de |
+
|
|
|
c313de |
+ if (VIR_ALLOC(addrs->zpciIds) < 0)
|
|
|
c313de |
+ return -1;
|
|
|
c313de |
+
|
|
|
c313de |
+ if (!(addrs->zpciIds->uids = virHashCreateFull(10, NULL,
|
|
|
c313de |
+ virZPCIAddrKeyCode,
|
|
|
c313de |
+ virZPCIAddrKeyEqual,
|
|
|
c313de |
+ virZPCIAddrKeyCopy,
|
|
|
c313de |
+ virZPCIAddrKeyFree)))
|
|
|
c313de |
+ goto error;
|
|
|
c313de |
+
|
|
|
c313de |
+ if (!(addrs->zpciIds->fids = virHashCreateFull(10, NULL,
|
|
|
c313de |
+ virZPCIAddrKeyCode,
|
|
|
c313de |
+ virZPCIAddrKeyEqual,
|
|
|
c313de |
+ virZPCIAddrKeyCopy,
|
|
|
c313de |
+ virZPCIAddrKeyFree)))
|
|
|
c313de |
+ goto error;
|
|
|
c313de |
+ }
|
|
|
c313de |
+
|
|
|
c313de |
+ return 0;
|
|
|
c313de |
+
|
|
|
c313de |
+ error:
|
|
|
c313de |
+ virDomainPCIAddressSetExtensionFree(addrs);
|
|
|
c313de |
+ return -1;
|
|
|
c313de |
+}
|
|
|
c313de |
+
|
|
|
c313de |
+
|
|
|
c313de |
virDomainPCIAddressSetPtr
|
|
|
c313de |
-virDomainPCIAddressSetAlloc(unsigned int nbuses)
|
|
|
c313de |
+virDomainPCIAddressSetAlloc(unsigned int nbuses,
|
|
|
c313de |
+ virPCIDeviceAddressExtensionFlags extFlags)
|
|
|
c313de |
{
|
|
|
c313de |
virDomainPCIAddressSetPtr addrs;
|
|
|
c313de |
|
|
|
c313de |
@@ -753,6 +839,10 @@ virDomainPCIAddressSetAlloc(unsigned int nbuses)
|
|
|
c313de |
goto error;
|
|
|
c313de |
|
|
|
c313de |
addrs->nbuses = nbuses;
|
|
|
c313de |
+
|
|
|
c313de |
+ if (virDomainPCIAddressSetExtensionAlloc(addrs, extFlags) < 0)
|
|
|
c313de |
+ goto error;
|
|
|
c313de |
+
|
|
|
c313de |
return addrs;
|
|
|
c313de |
|
|
|
c313de |
error:
|
|
|
c313de |
@@ -767,6 +857,7 @@ virDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs)
|
|
|
c313de |
if (!addrs)
|
|
|
c313de |
return;
|
|
|
c313de |
|
|
|
c313de |
+ virDomainPCIAddressSetExtensionFree(addrs);
|
|
|
c313de |
VIR_FREE(addrs->buses);
|
|
|
c313de |
VIR_FREE(addrs);
|
|
|
c313de |
}
|
|
|
c313de |
diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h
|
|
|
c313de |
index fd06008e26..b01e6b9d20 100644
|
|
|
c313de |
--- a/src/conf/domain_addr.h
|
|
|
c313de |
+++ b/src/conf/domain_addr.h
|
|
|
c313de |
@@ -116,6 +116,12 @@ typedef struct {
|
|
|
c313de |
} virDomainPCIAddressBus;
|
|
|
c313de |
typedef virDomainPCIAddressBus *virDomainPCIAddressBusPtr;
|
|
|
c313de |
|
|
|
c313de |
+typedef struct {
|
|
|
c313de |
+ virHashTablePtr uids;
|
|
|
c313de |
+ virHashTablePtr fids;
|
|
|
c313de |
+} virDomainZPCIAddressIds;
|
|
|
c313de |
+typedef virDomainZPCIAddressIds *virDomainZPCIAddressIdsPtr;
|
|
|
c313de |
+
|
|
|
c313de |
struct _virDomainPCIAddressSet {
|
|
|
c313de |
virDomainPCIAddressBus *buses;
|
|
|
c313de |
size_t nbuses;
|
|
|
c313de |
@@ -125,6 +131,7 @@ struct _virDomainPCIAddressSet {
|
|
|
c313de |
bool areMultipleRootsSupported;
|
|
|
c313de |
/* If true, the guest can use the pcie-to-pci-bridge controller */
|
|
|
c313de |
bool isPCIeToPCIBridgeSupported;
|
|
|
c313de |
+ virDomainZPCIAddressIdsPtr zpciIds;
|
|
|
c313de |
};
|
|
|
c313de |
typedef struct _virDomainPCIAddressSet virDomainPCIAddressSet;
|
|
|
c313de |
typedef virDomainPCIAddressSet *virDomainPCIAddressSetPtr;
|
|
|
c313de |
@@ -132,7 +139,8 @@ typedef virDomainPCIAddressSet *virDomainPCIAddressSetPtr;
|
|
|
c313de |
char *virDomainPCIAddressAsString(virPCIDeviceAddressPtr addr)
|
|
|
c313de |
ATTRIBUTE_NONNULL(1);
|
|
|
c313de |
|
|
|
c313de |
-virDomainPCIAddressSetPtr virDomainPCIAddressSetAlloc(unsigned int nbuses);
|
|
|
c313de |
+virDomainPCIAddressSetPtr virDomainPCIAddressSetAlloc(unsigned int nbuses,
|
|
|
c313de |
+ virPCIDeviceAddressExtensionFlags extFlags);
|
|
|
c313de |
|
|
|
c313de |
void virDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs);
|
|
|
c313de |
|
|
|
c313de |
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
|
|
|
c313de |
index 3d01d14b46..ba870d56b1 100644
|
|
|
c313de |
--- a/src/qemu/qemu_domain_address.c
|
|
|
c313de |
+++ b/src/qemu/qemu_domain_address.c
|
|
|
c313de |
@@ -1508,8 +1508,12 @@ qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
|
|
|
c313de |
size_t i;
|
|
|
c313de |
bool hasPCIeRoot = false;
|
|
|
c313de |
virDomainControllerModelPCI defaultModel;
|
|
|
c313de |
+ virPCIDeviceAddressExtensionFlags extFlags = VIR_PCI_ADDRESS_EXTENSION_NONE;
|
|
|
c313de |
|
|
|
c313de |
- if ((addrs = virDomainPCIAddressSetAlloc(nbuses)) == NULL)
|
|
|
c313de |
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_ZPCI))
|
|
|
c313de |
+ extFlags |= VIR_PCI_ADDRESS_EXTENSION_ZPCI;
|
|
|
c313de |
+
|
|
|
c313de |
+ if ((addrs = virDomainPCIAddressSetAlloc(nbuses, extFlags)) == NULL)
|
|
|
c313de |
return NULL;
|
|
|
c313de |
|
|
|
c313de |
addrs->dryRun = dryRun;
|
|
|
c313de |
--
|
|
|
c313de |
2.22.0
|
|
|
c313de |
|