[Top] [All Lists]

RE: file corruption with highmem kernel

To: "Ralf Baechle" <>
Subject: RE: file corruption with highmem kernel
From: "Anoop P.A." <>
Date: Fri, 6 Aug 2010 03:12:00 -0700
Cc: "linux-mips" <>
In-reply-to: <>
Original-recipient: rfc822;
References: <> <> <>
Thread-index: Acs0y8bnYm14g7FHRaW+W2PRh1m8QQAgmpOA
Thread-topic: file corruption with highmem kernel
> Since you're running on an RM9000 class CPU, why don't just use a
> kernel?  Highmem is just so f*cking insane that you want to avoid it
> French kisses from a zombie suffering ebola.  If you have DMA
> then you may consider reusing ZONE_DMA.
[Anoop P.A.] I understand that I am working on 64 bit kernel in
parallel, DMA issue made me concentrate on highmem support as immediate
> small 32-bit system that didn't need highmem or went 64-bit right away
> the gaps in the code while well known were never fixed up ...

[Anoop P.A.] I presume with decreased value of RAM, more 32 bit machines
will come with bulk of memory pretty soon to the world of highmem

> I'm a bit surprised that the patch posted actually made things work
> for you since it entirely avoids flushing of highmem pages.  The code
> it
> was originally written using page_address() will perform cacheflushes
> for highmem pages as well - but only for highmem pages are actually
> mapped.  That is your code will flush less pages than the existing

[Anoop P.A.] I confirmed it, calling __dma_sync for highmem map address
occasionally causes memory corruption ( reports bus error , segmentation
fault etc..) .

Blowing entire scache (I understand it is pain) for highmem pages fixed
my file corruption issue

--- linux-2.6.18/arch/mips/mm/dma-noncoherent.c 2006-08-23
23:16:07.000000000 +0530
+++ linux-2.6.18/arch/mips/mm/dma-noncoherent.c 2010-08-06
20:48:36.000000000 +0530
@@ -15,6 +15,7 @@
 #include <asm/cache.h>
 #include <asm/io.h>
+#include <asm/r4kcache.h>
  * Warning on the terminology - Linux calls an uncached area coherent;
@@ -131,13 +132,21 @@
        for (i = 0; i < nents; i++, sg++) {
                unsigned long addr;
+               if (!PageHighMem(sg->page))
+               {
+                               addr = (unsigned
long)page_address(sg->page) + sg->offset;
+                               __dma_sync(addr, sg->length, direction);
+               }
+               else
+               { 
+               /*blasting entire cache for all the highmem page's might
be over head 
+                 But __dma_sync is failing for mapped highmem pages, so
this is the 
+                 easiest solution for time being*/
+                       blast_scache32(); /*RM9000 sc_line=32 */ 
+               }
-               addr = (unsigned long) page_address(sg->page);
-               if (addr) {
-                       __dma_sync(addr + sg->offset, sg->length,
-                       sg->dma_address =
+               sg->dma_address = (dma_addr_t)page_to_phys(sg->page)
                                          + sg->offset;
-               }
        return nents;


<Prev in Thread] Current Thread [Next in Thread>