summaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/powernv
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2016-05-20 09:41:30 +0300
committerMichael Ellerman <mpe@ellerman.id.au>2016-06-21 08:30:53 +0300
commit9fcd6f4a2b264f15071ab5e2d61ac2d9125ebc1d (patch)
treeb7bc9d19a231716dcddd9b47a4d02a1c2d9a7add /arch/powerpc/platforms/powernv
parentc127562ae1d85c7f79192ace0431f97add8f83ea (diff)
downloadlinux-9fcd6f4a2b264f15071ab5e2d61ac2d9125ebc1d.tar.xz
powerpc/powernv: Allocate PE# in reverse order
PE number for one particular PE can be allocated dynamically or reserved according to the consumed M64 (64-bits prefetchable) segments of the PE. The M64 segment can't be remapped to arbitrary PE, meaning the PE number is determined according to the index of the consumed M64 segment. As below figure shows, M64 resource grows from low to high end, meaning the PE (number) reserved according to M64 segment grows from low to high end as well, so does the dynamically allocated PE number. It will lead to conflict: PE number (M64 segment) reserved by dynamic allocation is required by hot added PCI adapter at later point. It fails the PCI hotplug because of the PE number can't be reserved based on the index of the consumed M64 segment. +---+---+---+---+---+--------------------------------+-----+ | 0 | 1 | 2 | 3 | 4 | ....... | 255 | +---+---+---+---+---+--------------------------------+-----+ PE number for dynamic allocation -----------------> PE number reserved for M64 segment -----------------> To resolve above conflicts, this forces the PE number to be allocated dynamically in reverse order. With this patch applied, the PE numbers are reserved in ascending order, but allocated dynamically in reverse order. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/platforms/powernv')
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 393d32401f4f..e82097316602 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -141,16 +141,14 @@ static void pnv_ioda_reserve_pe(struct pnv_phb *phb, int pe_no)
static struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb *phb)
{
- unsigned long pe;
+ unsigned long pe = phb->ioda.total_pe_num - 1;
- do {
- pe = find_next_zero_bit(phb->ioda.pe_alloc,
- phb->ioda.total_pe_num, 0);
- if (pe >= phb->ioda.total_pe_num)
- return NULL;
- } while(test_and_set_bit(pe, phb->ioda.pe_alloc));
+ for (pe = phb->ioda.total_pe_num - 1; pe >= 0; pe--) {
+ if (!test_and_set_bit(pe, phb->ioda.pe_alloc))
+ return pnv_ioda_init_pe(phb, pe);
+ }
- return pnv_ioda_init_pe(phb, pe);
+ return NULL;
}
static void pnv_ioda_free_pe(struct pnv_ioda_pe *pe)