From patchwork Wed Jan 11 09:37:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cornelia Huck X-Patchwork-Id: 9509721 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B139B60231 for ; Wed, 11 Jan 2017 09:54:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A9F3928584 for ; Wed, 11 Jan 2017 09:54:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9E54228596; Wed, 11 Jan 2017 09:54:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E015C28584 for ; Wed, 11 Jan 2017 09:54:26 +0000 (UTC) Received: from localhost ([::1]:52731 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cRFbt-0007mi-DK for patchwork-qemu-devel@patchwork.kernel.org; Wed, 11 Jan 2017 04:54:25 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45093) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cRFM1-0000dE-2Z for qemu-devel@nongnu.org; Wed, 11 Jan 2017 04:38:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cRFLz-0000nT-Mt for qemu-devel@nongnu.org; Wed, 11 Jan 2017 04:38:01 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:56883) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cRFLz-0000mJ-Cv for qemu-devel@nongnu.org; Wed, 11 Jan 2017 04:37:59 -0500 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id v0B9XhPk050146 for ; Wed, 11 Jan 2017 04:37:58 -0500 Received: from e06smtp12.uk.ibm.com (e06smtp12.uk.ibm.com [195.75.94.108]) by mx0a-001b2d01.pphosted.com with ESMTP id 27wfccfbbs-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Wed, 11 Jan 2017 04:37:58 -0500 Received: from localhost by e06smtp12.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 11 Jan 2017 09:37:55 -0000 Received: from d06dlp03.portsmouth.uk.ibm.com (9.149.20.15) by e06smtp12.uk.ibm.com (192.168.101.142) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 11 Jan 2017 09:37:53 -0000 Received: from b06cxnps4075.portsmouth.uk.ibm.com (d06relay12.portsmouth.uk.ibm.com [9.149.109.197]) by d06dlp03.portsmouth.uk.ibm.com (Postfix) with ESMTP id 6520E1B08023; Wed, 11 Jan 2017 09:40:34 +0000 (GMT) Received: from d06av24.portsmouth.uk.ibm.com (d06av24.portsmouth.uk.ibm.com [9.149.105.60]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v0B9br7Q3997952; Wed, 11 Jan 2017 09:37:53 GMT Received: from d06av24.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id CD84442049; Wed, 11 Jan 2017 08:35:48 +0000 (GMT) Received: from d06av24.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9676842045; Wed, 11 Jan 2017 08:35:48 +0000 (GMT) Received: from gondolin.boeblingen.de.ibm.com (unknown [9.152.224.55]) by d06av24.portsmouth.uk.ibm.com (Postfix) with ESMTPS; Wed, 11 Jan 2017 08:35:48 +0000 (GMT) From: Cornelia Huck To: qemu-devel@nongnu.org Date: Wed, 11 Jan 2017 10:37:37 +0100 X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170111093742.21946-1-cornelia.huck@de.ibm.com> References: <20170111093742.21946-1-cornelia.huck@de.ibm.com> X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 17011109-0008-0000-0000-000003CE3918 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17011109-0009-0000-0000-00001C0E0182 Message-Id: <20170111093742.21946-7-cornelia.huck@de.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-01-11_08:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=3 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1612050000 definitions=main-1701110135 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.156.1 Subject: [Qemu-devel] [PATCH 06/11] s390x/pci: change the device array to a list X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Cornelia Huck , borntraeger@de.ibm.com, jfrei@linux.vnet.ibm.com, Pierre Morel , agraf@suse.de Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Pierre Morel 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 Signed-off-by: Cornelia Huck --- 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);