On 05/12/2016 04:09 PM, Gavin Shan wrote:
On Thu, May 12, 2016 at 03:47:09PM +1000, Alexey Kardashevskiy wrote:
The pnv_pci_init_ioda_phb() helper allocates a blob to store auxilary
data such PE and M32/M64 segment allocation maps; this single blob has few
partitions, size of each is derived from the PE number -
phb->ioda.total_pe_num.

It was assumed that the minimum PE number is 8, however it is 4 for NPU
so the pe_alloc part was missing in the allocated blob.
It was invisible till recently as we were not tracking used M64 segments
and NPUs do not use M32 segments so the phb->ioda.m32_segmap
(which was pointing to the same address as phb->ioda.pe_alloc)
has never been written to leaving the pe_alloc memory intact.

After 401203ac2d "powerpc/powernv: Track M64 segment consumption"
the pe_alloc gets corrupted and PE allocation cannot work.
This fixes the issue by enforcing the minimum PE number to 8.


As I said offline yesterday, the issue exists from day-1 when NPU PHB
is supported. I don't think it's related to 401203ac2d. Without the logic
tracking M64 segments, the PE# bitmap still can be corrupted when writting
to M32 segment map. It's confusing to mention a unrelated commit in the
changelog.


The bug exists from day 1. The actual corruption started happening from 401203ac2d, it could be happening before but it was not.


Since the issue exists from day-1 when NPU PHB is supported, is a stable
tag needed?

Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru>

With above parts fixed:

Reviewed-by: Gavin Shan <gws...@linux.vnet.ibm.com>

---
arch/powerpc/platforms/powernv/pci-ioda.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 6cda2a8..d0d32c2 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -3507,7 +3507,8 @@ static void __init pnv_pci_init_ioda_phb(struct 
device_node *np,
                                PNV_IODA1_DMA32_SEGSIZE;

        /* Allocate aux data & arrays. We don't have IO ports on PHB3 */
-       size = _ALIGN_UP(phb->ioda.total_pe_num / 8, sizeof(unsigned long));
+       size = _ALIGN_UP(max_t(unsigned, phb->ioda.total_pe_num, 8) / 8,
+                       sizeof(unsigned long));
        m64map_off = size;
        size += phb->ioda.total_pe_num * sizeof(phb->ioda.m64_segmap[0]);
        m32map_off = size;
--
2.5.0.rc3




--
Alexey
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to