qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Cornelia Huck <cornelia.huck@de.ibm.com>
To: qemu-devel@nongnu.org
Cc: borntraeger@de.ibm.com, agraf@suse.de, jfrei@linux.vnet.ibm.com,
	Pierre Morel <pmorel@linux.vnet.ibm.com>,
	Cornelia Huck <cornelia.huck@de.ibm.com>
Subject: [Qemu-devel] [PATCH 06/11] s390x/pci: change the device array to a list
Date: Wed, 11 Jan 2017 10:37:37 +0100	[thread overview]
Message-ID: <20170111093742.21946-7-cornelia.huck@de.ibm.com> (raw)
In-Reply-To: <20170111093742.21946-1-cornelia.huck@de.ibm.com>

From: Pierre Morel <pmorel@linux.vnet.ibm.com>

In order to support a greater number of devices we use a QTAILQ
list of devices instead of a limited array.

This leads us to change:
- every lookup function s390_pci_find_xxx() for QTAILQ
- the FH_MASK_INDEX to index up to 65536 devices

Signed-off-by: Pierre Morel <pmorel@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/s390-pci-bus.c | 100 ++++++++++++++++++++++++------------------------
 hw/s390x/s390-pci-bus.h |   7 +++-
 2 files changed, 56 insertions(+), 51 deletions(-)

diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 04a4c3508e..dfca006bde 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -93,33 +93,24 @@ int chsc_sei_nt2_have_event(void)
 
 S390PCIBusDevice *s390_pci_find_next_avail_dev(S390PCIBusDevice *pbdev)
 {
-    int idx = 0;
-    S390PCIBusDevice *dev = NULL;
     S390pciState *s = s390_get_phb();
+    S390PCIBusDevice *ret = pbdev ? QTAILQ_NEXT(pbdev, link) :
+        QTAILQ_FIRST(&s->zpci_devs);
 
-    if (pbdev) {
-        idx = (pbdev->fh & FH_MASK_INDEX) + 1;
+    while (ret && ret->state == ZPCI_FS_RESERVED) {
+        ret = QTAILQ_NEXT(ret, link);
     }
 
-    for (; idx < PCI_SLOT_MAX; idx++) {
-        dev = s->pbdev[idx];
-        if (dev && dev->state != ZPCI_FS_RESERVED) {
-            return dev;
-        }
-    }
-
-    return NULL;
+    return ret;
 }
 
 S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid)
 {
     S390PCIBusDevice *pbdev;
-    int i;
     S390pciState *s = s390_get_phb();
 
-    for (i = 0; i < PCI_SLOT_MAX; i++) {
-        pbdev = s->pbdev[i];
-        if (pbdev && pbdev->fid == fid) {
+    QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) {
+        if (pbdev->fid == fid) {
             return pbdev;
         }
     }
@@ -203,16 +194,10 @@ out:
 
 static S390PCIBusDevice *s390_pci_find_dev_by_uid(uint16_t uid)
 {
-    int i;
     S390PCIBusDevice *pbdev;
     S390pciState *s = s390_get_phb();
 
-    for (i = 0; i < PCI_SLOT_MAX; i++) {
-        pbdev = s->pbdev[i];
-        if (!pbdev) {
-            continue;
-        }
-
+    QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) {
         if (pbdev->uid == uid) {
             return pbdev;
         }
@@ -223,7 +208,6 @@ static S390PCIBusDevice *s390_pci_find_dev_by_uid(uint16_t uid)
 
 static S390PCIBusDevice *s390_pci_find_dev_by_target(const char *target)
 {
-    int i;
     S390PCIBusDevice *pbdev;
     S390pciState *s = s390_get_phb();
 
@@ -231,12 +215,7 @@ static S390PCIBusDevice *s390_pci_find_dev_by_target(const char *target)
         return NULL;
     }
 
-    for (i = 0; i < PCI_SLOT_MAX; i++) {
-        pbdev = s->pbdev[i];
-        if (!pbdev) {
-            continue;
-        }
-
+    QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) {
         if (!strcmp(pbdev->target, target)) {
             return pbdev;
         }
@@ -247,9 +226,16 @@ static S390PCIBusDevice *s390_pci_find_dev_by_target(const char *target)
 
 S390PCIBusDevice *s390_pci_find_dev_by_idx(uint32_t idx)
 {
+    S390PCIBusDevice *pbdev;
     S390pciState *s = s390_get_phb();
 
-    return s->pbdev[idx & FH_MASK_INDEX];
+    QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) {
+        if (pbdev->idx == idx) {
+            return pbdev;
+        }
+    }
+
+    return NULL;
 }
 
 S390PCIBusDevice *s390_pci_find_dev_by_fh(uint32_t fh)
@@ -257,9 +243,10 @@ S390PCIBusDevice *s390_pci_find_dev_by_fh(uint32_t fh)
     S390pciState *s = s390_get_phb();
     S390PCIBusDevice *pbdev;
 
-    pbdev = s->pbdev[fh & FH_MASK_INDEX];
-    if (pbdev && pbdev->fh == fh) {
-        return pbdev;
+    QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) {
+        if (pbdev->fh == fh) {
+            return pbdev;
+        }
     }
 
     return NULL;
@@ -600,6 +587,7 @@ static int s390_pcihost_init(SysBusDevice *dev)
     s->iommu_table = g_hash_table_new_full(g_int64_hash, g_int64_equal,
                                            NULL, g_free);
     QTAILQ_INIT(&s->pending_sei);
+    QTAILQ_INIT(&s->zpci_devs);
     return 0;
 }
 
@@ -667,6 +655,25 @@ static S390PCIBusDevice *s390_pci_device_new(const char *target)
     return S390_PCI_DEVICE(dev);
 }
 
+static bool s390_pci_alloc_idx(S390PCIBusDevice *pbdev)
+{
+    uint32_t idx;
+    S390pciState *s = s390_get_phb();
+
+    idx = s->next_idx;
+    while (s390_pci_find_dev_by_idx(idx)) {
+        idx = (idx + 1) & FH_MASK_INDEX;
+        if (idx == s->next_idx) {
+            return false;
+        }
+    }
+
+    pbdev->idx = idx;
+    s->next_idx = (idx + 1) & FH_MASK_INDEX;
+
+    return true;
+}
+
 static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
                                   DeviceState *dev, Error **errp)
 {
@@ -714,18 +721,14 @@ static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
                                          pbdev->fh, pbdev->fid);
         }
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) {
-        int idx;
-
         pbdev = S390_PCI_DEVICE(dev);
-        for (idx = 0; idx < PCI_SLOT_MAX; idx++) {
-            if (!s->pbdev[idx]) {
-                s->pbdev[idx] = pbdev;
-                pbdev->fh = idx;
-                return;
-            }
-        }
 
-        error_setg(errp, "no slot for plugging zpci device");
+        if (!s390_pci_alloc_idx(pbdev)) {
+            error_setg(errp, "no slot for plugging zpci device");
+            return;
+        }
+        pbdev->fh = pbdev->idx;
+        QTAILQ_INSERT_TAIL(&s->zpci_devs, pbdev, link);
     }
 }
 
@@ -751,16 +754,15 @@ static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,
 {
     PCIDevice *pci_dev = NULL;
     PCIBus *bus;
-    int32_t devfn, i;
+    int32_t devfn;
     S390PCIBusDevice *pbdev = NULL;
     S390pciState *s = s390_get_phb();
 
     if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
         pci_dev = PCI_DEVICE(dev);
 
-        for (i = 0 ; i < PCI_SLOT_MAX; i++) {
-            if (s->pbdev[i] && s->pbdev[i]->pdev == pci_dev) {
-                pbdev = s->pbdev[i];
+        QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) {
+            if (pbdev->pdev == pci_dev) {
                 break;
             }
         }
@@ -803,7 +805,7 @@ static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,
     pbdev->state = ZPCI_FS_RESERVED;
 out:
     pbdev->fid = 0;
-    s->pbdev[pbdev->fh & FH_MASK_INDEX] = NULL;
+    QTAILQ_REMOVE(&s->zpci_devs, pbdev, link);
     object_unparent(OBJECT(pbdev));
 }
 
diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
index fe108e9330..1bd37ad821 100644
--- a/hw/s390x/s390-pci-bus.h
+++ b/hw/s390x/s390-pci-bus.h
@@ -27,7 +27,7 @@
 #define FH_MASK_ENABLE   0x80000000
 #define FH_MASK_INSTANCE 0x7f000000
 #define FH_MASK_SHM      0x00ff0000
-#define FH_MASK_INDEX    0x0000001f
+#define FH_MASK_INDEX    0x0000ffff
 #define FH_SHM_VFIO      0x00010000
 #define FH_SHM_EMUL      0x00020000
 #define S390_PCIPT_ADAPTER 2
@@ -285,6 +285,7 @@ typedef struct S390PCIBusDevice {
     ZpciState state;
     char *target;
     uint16_t uid;
+    uint32_t idx;
     uint32_t fh;
     uint32_t fid;
     bool fid_defined;
@@ -299,6 +300,7 @@ typedef struct S390PCIBusDevice {
     IndAddr *summary_ind;
     IndAddr *indicator;
     QEMUTimer *release_timer;
+    QTAILQ_ENTRY(S390PCIBusDevice) link;
 } S390PCIBusDevice;
 
 typedef struct S390PCIBus {
@@ -307,10 +309,11 @@ typedef struct S390PCIBus {
 
 typedef struct S390pciState {
     PCIHostState parent_obj;
+    uint32_t next_idx;
     S390PCIBus *bus;
-    S390PCIBusDevice *pbdev[PCI_SLOT_MAX];
     GHashTable *iommu_table;
     QTAILQ_HEAD(, SeiContainer) pending_sei;
+    QTAILQ_HEAD(, S390PCIBusDevice) zpci_devs;
 } S390pciState;
 
 int chsc_sei_nt2_get_event(void *res);
-- 
2.11.0

  parent reply	other threads:[~2017-01-11  9:38 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-11  9:37 [Qemu-devel] [PATCH 00/11] s390x patches for 2.9 Cornelia Huck
2017-01-11  9:37 ` [Qemu-devel] [PATCH 01/11] s390x: remove double compat statement Cornelia Huck
2017-01-11  9:37 ` [Qemu-devel] [PATCH 02/11] s390x: add compat machine for 2.9 Cornelia Huck
2017-01-11  9:37 ` [Qemu-devel] [PATCH 03/11] s390x/kvm: use kvm_gsi_routing_enabled in flic Cornelia Huck
2017-01-11  9:37 ` [Qemu-devel] [PATCH 04/11] s390x/pci: make S390PCIIOMMU inherit Object Cornelia Huck
2017-01-11  9:37 ` [Qemu-devel] [PATCH 05/11] s390x/pci: dynamically allocate iommu Cornelia Huck
2017-01-11  9:37 ` Cornelia Huck [this message]
2017-01-11  9:37 ` [Qemu-devel] [PATCH 07/11] s390x/pci: optimize calling s390_get_phb() Cornelia Huck
2017-01-11  9:37 ` [Qemu-devel] [PATCH 08/11] s390x/pci: PCI multibus bridge handling Cornelia Huck
2017-01-11  9:37 ` [Qemu-devel] [PATCH 09/11] s390x/pci: use hashtable to look up zpci via fh Cornelia Huck
2017-01-11  9:37 ` [Qemu-devel] [PATCH 10/11] s390x/pci: handle PCIBridge bus number Cornelia Huck
2017-01-11  9:37 ` [Qemu-devel] [PATCH 11/11] s390x/pci: merge msix init functions Cornelia Huck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170111093742.21946-7-cornelia.huck@de.ibm.com \
    --to=cornelia.huck@de.ibm.com \
    --cc=agraf@suse.de \
    --cc=borntraeger@de.ibm.com \
    --cc=jfrei@linux.vnet.ibm.com \
    --cc=pmorel@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).