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: Yi Min Zhao <zyimin@linux.vnet.ibm.com> Reviewed-by: Pierre Morel <pmorel@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
This commit is contained in:
parent
3fc92a24f3
commit
df8dd91b99
@ -227,25 +227,16 @@ 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) {
|
||||
return pbdev;
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user