Commit df8dd91b authored by Yi Min Zhao's avatar Yi Min Zhao Committed by Cornelia Huck
Browse files

s390x/pci: use hashtable to look up zpci via fh



After PCI multibus is supported, more than 32 PCI devices could be
plugged. The current implementation of s390_pci_find_dev_by_fh()
appears low performance if there's a huge number of PCI devices
plugged. Therefore we introduce a hashtable using idx as key to store
zpci device's pointer on account of translating fh to idx very easily.

Signed-off-by: default avatarYi Min Zhao <zyimin@linux.vnet.ibm.com>
Reviewed-by: default avatarPierre Morel <pmorel@linux.vnet.ibm.com>
Signed-off-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
parent 3fc92a24
Loading
Loading
Loading
Loading
+8 −14
Original line number Diff line number Diff line
@@ -227,26 +227,17 @@ static S390PCIBusDevice *s390_pci_find_dev_by_target(S390pciState *s,

S390PCIBusDevice *s390_pci_find_dev_by_idx(S390pciState *s, uint32_t idx)
{
    S390PCIBusDevice *pbdev;

    QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) {
        if (pbdev->idx == idx) {
            return pbdev;
        }
    }

    return NULL;
    return g_hash_table_lookup(s->zpci_table, &idx);
}

S390PCIBusDevice *s390_pci_find_dev_by_fh(S390pciState *s, uint32_t fh)
{
    S390PCIBusDevice *pbdev;
    uint32_t idx = FH_MASK_INDEX & fh;
    S390PCIBusDevice *pbdev = s390_pci_find_dev_by_idx(s, idx);

    QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) {
        if (pbdev->fh == fh) {
    if (pbdev && pbdev->fh == fh) {
        return pbdev;
    }
    }

    return NULL;
}
@@ -584,6 +575,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);
    s->zpci_table = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, NULL);
    QTAILQ_INIT(&s->pending_sei);
    QTAILQ_INIT(&s->zpci_devs);
    return 0;
@@ -735,6 +727,7 @@ static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
        }
        pbdev->fh = pbdev->idx;
        QTAILQ_INSERT_TAIL(&s->zpci_devs, pbdev, link);
        g_hash_table_insert(s->zpci_table, &pbdev->idx, pbdev);
    }
}

@@ -815,6 +808,7 @@ static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,
out:
    pbdev->fid = 0;
    QTAILQ_REMOVE(&s->zpci_devs, pbdev, link);
    g_hash_table_remove(s->zpci_table, &pbdev->idx);
    object_unparent(OBJECT(pbdev));
}

+1 −0
Original line number Diff line number Diff line
@@ -312,6 +312,7 @@ typedef struct S390pciState {
    uint32_t next_idx;
    S390PCIBus *bus;
    GHashTable *iommu_table;
    GHashTable *zpci_table;
    QTAILQ_HEAD(, SeiContainer) pending_sei;
    QTAILQ_HEAD(, S390PCIBusDevice) zpci_devs;
} S390pciState;