lkml.org 
[lkml]   [2011]   [Jan]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH RESEND 1/6] MIPS: sync after cacheflush
    Date
    On processors with deep write buffers, it is likely that many cycles
    will pass between a CACHE instruction and the time the data actually
    gets written out to DRAM. Add a SYNC instruction to ensure that the
    buffers get emptied before the flush functions return.

    Actual problem seen in the wild:

    1) dma_alloc_coherent() allocates cached memory

    2) memset() is called to clear the new pages

    3) dma_cache_wback_inv() is called to flush the zero data out to memory

    4) dma_alloc_coherent() returns an uncached (kseg1) pointer to the
    freshly allocated pages

    5) Caller writes data through the kseg1 pointer

    6) Buffered writeback data finally gets flushed out to DRAM

    7) Part of caller's data is inexplicably zeroed out

    This patch adds SYNC between steps 3 and 4, which fixed the problem.

    Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
    ---
    arch/mips/mm/c-r4k.c | 4 ++++
    1 files changed, 4 insertions(+), 0 deletions(-)

    diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
    index b4923a7..dc5d9c4 100644
    --- a/arch/mips/mm/c-r4k.c
    +++ b/arch/mips/mm/c-r4k.c
    @@ -604,6 +604,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
    r4k_blast_scache();
    else
    blast_scache_range(addr, addr + size);
    + __sync();
    return;
    }

    @@ -620,6 +621,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
    }

    bc_wback_inv(addr, size);
    + __sync();
    }

    static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
    @@ -647,6 +649,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
    (addr + size - 1) & almask);
    blast_inv_scache_range(addr, addr + size);
    }
    + __sync();
    return;
    }

    @@ -663,6 +666,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
    }

    bc_inv(addr, size);
    + __sync();
    }
    #endif /* CONFIG_DMA_NONCOHERENT */

    --
    1.7.0.4


    \
     
     \ /
      Last update: 2011-01-06 08:47    [W:0.023 / U:149.528 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site