ACK: [SRU][F][G][PATCH v3 1/1] s390/pci: Fix zpci_alloc_domain() over allocation
Frank Heimes
frank.heimes at canonical.com
Wed May 13 10:02:28 UTC 2020
Yes of course - done.
(Sorry, some of the tickets were opened when the dev. of 'groovy' was not
opened, and I forgot to adjust the nominations later ...)
BR, Frank
On Wed, May 13, 2020 at 11:56 AM Kleber Souza <kleber.souza at canonical.com>
wrote:
> On 13.05.20 11:54, Kleber Souza wrote:
> > On 06.05.20 09:21, frank.heimes at canonical.com wrote:
> >> From: Niklas Schnelle <schnelle at linux.ibm.com>
> >>
> >> BugLink: https://bugs.launchpad.net/bugs/1874057
>
> Hi Frank,
>
> I forgot to mention, can you please fix the nominations on the bug report?
>
>
> Thanks,
> Kleber
>
> >>
> >> Until now zpci_alloc_domain() only prevented more than
> >> CONFIG_PCI_NR_FUNCTIONS from being added when using automatic domain
> >> allocation. When explicit UIDs were defined UIDs above
> >> CONFIG_PCI_NR_FUNCTIONS were not counted at all.
> >> When more PCI functions are added this could lead to various errors
> >> including under sized IRQ vectors and similar issues.
> >>
> >> Fix this by explicitly tracking the number of allocated domains.
> >>
> >> Signed-off-by: Niklas Schnelle <schnelle at linux.ibm.com>
> >> Reviewed-by: Pierre Morel <pmorel at linux.ibm.com>
> >> Signed-off-by: Vasily Gorbik <gor at linux.ibm.com>
> >> (backported from commit 969ae01bab2fe938b4c8324836038b5ac1c78fac)
> >> Signed-off-by: Frank Heimes <frank.heimes at canonical.com>
> >
> >
> > Acked-by: Kleber Sacilotto de Souza <kleber.souza at canonical.com>
> >
> >> ---
> >> arch/s390/include/asm/pci.h | 1 +
> >> arch/s390/pci/pci.c | 34 ++++++++++++++++++++--------------
> >> 2 files changed, 21 insertions(+), 14 deletions(-)
> >>
> >> diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
> >> index 6087a4e9b2bf..7850e8c8c79a 100644
> >> --- a/arch/s390/include/asm/pci.h
> >> +++ b/arch/s390/include/asm/pci.h
> >> @@ -28,6 +28,7 @@ int pci_proc_domain(struct pci_bus *);
> >>
> >> #define ZPCI_NR_DMA_SPACES 1
> >> #define ZPCI_NR_DEVICES CONFIG_PCI_NR_FUNCTIONS
> >> +#define ZPCI_DOMAIN_BITMAP_SIZE (1 << 16)
> >>
> >> /* PCI Function Controls */
> >> #define ZPCI_FC_FN_ENABLED 0x80
> >> diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
> >> index 6105b1b6e49b..0af46683dd66 100644
> >> --- a/arch/s390/pci/pci.c
> >> +++ b/arch/s390/pci/pci.c
> >> @@ -39,8 +39,9 @@
> >> static LIST_HEAD(zpci_list);
> >> static DEFINE_SPINLOCK(zpci_list_lock);
> >>
> >> -static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES);
> >> +static DECLARE_BITMAP(zpci_domain, ZPCI_DOMAIN_BITMAP_SIZE);
> >> static DEFINE_SPINLOCK(zpci_domain_lock);
> >> +static unsigned int zpci_num_domains_allocated;
> >>
> >> #define ZPCI_IOMAP_ENTRIES \
> >> min(((unsigned long) ZPCI_NR_DEVICES * PCI_BAR_COUNT / 2), \
> >> @@ -651,39 +652,44 @@ struct dev_pm_ops pcibios_pm_ops = {
> >>
> >> static int zpci_alloc_domain(struct zpci_dev *zdev)
> >> {
> >> + spin_lock(&zpci_domain_lock);
> >> + if (zpci_num_domains_allocated > (ZPCI_NR_DEVICES - 1)) {
> >> + spin_unlock(&zpci_domain_lock);
> >> + pr_err("Adding PCI function %08x failed because the
> configured limit of %d is reached\n",
> >> + zdev->fid, ZPCI_NR_DEVICES);
> >> + return -ENOSPC;
> >> + }
> >> +
> >> if (zpci_unique_uid) {
> >> zdev->domain = (u16) zdev->uid;
> >> - if (zdev->domain >= ZPCI_NR_DEVICES)
> >> - return 0;
> >> -
> >> - spin_lock(&zpci_domain_lock);
> >> if (test_bit(zdev->domain, zpci_domain)) {
> >> spin_unlock(&zpci_domain_lock);
> >> + pr_err("Adding PCI function %08x failed because
> domain %04x is already assigned\n",
> >> + zdev->fid, zdev->domain);
> >> return -EEXIST;
> >> }
> >> set_bit(zdev->domain, zpci_domain);
> >> + zpci_num_domains_allocated++;
> >> spin_unlock(&zpci_domain_lock);
> >> return 0;
> >> }
> >> -
> >> - spin_lock(&zpci_domain_lock);
> >> + /*
> >> + * We can always auto allocate domains below ZPCI_NR_DEVICES.
> >> + * There is either a free domain or we have reached the maximum in
> >> + * which case we would have bailed earlier.
> >> + */
> >> zdev->domain = find_first_zero_bit(zpci_domain, ZPCI_NR_DEVICES);
> >> - if (zdev->domain == ZPCI_NR_DEVICES) {
> >> - spin_unlock(&zpci_domain_lock);
> >> - return -ENOSPC;
> >> - }
> >> set_bit(zdev->domain, zpci_domain);
> >> + zpci_num_domains_allocated++;
> >> spin_unlock(&zpci_domain_lock);
> >> return 0;
> >> }
> >>
> >> static void zpci_free_domain(struct zpci_dev *zdev)
> >> {
> >> - if (zdev->domain >= ZPCI_NR_DEVICES)
> >> - return;
> >> -
> >> spin_lock(&zpci_domain_lock);
> >> clear_bit(zdev->domain, zpci_domain);
> >> + zpci_num_domains_allocated--;
> >> spin_unlock(&zpci_domain_lock);
> >> }
> >>
> >>
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20200513/0f5c040b/attachment.html>
More information about the kernel-team
mailing list