RE: file corruption with highmem kernel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> 
> Since you're running on an RM9000 class CPU, why don't just use a
64-bit
> kernel?  Highmem is just so f*cking insane that you want to avoid it
like
> French kisses from a zombie suffering ebola.  If you have DMA
restrictions
> 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
option.
 
> small 32-bit system that didn't need highmem or went 64-bit right away
so
> 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
better
> for you since it entirely avoids flushing of highmem pages.  The code
as
> it
> was originally written using page_address() will perform cacheflushes
> for highmem pages as well - but only for highmem pages are actually
are
> mapped.  That is your code will flush less pages than the existing
code.

[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,
direction);
-			sg->dma_address =
(dma_addr_t)page_to_phys(sg->page)
+		sg->dma_address = (dma_addr_t)page_to_phys(sg->page)
 					  + sg->offset;
-		}
 	}
 
 	return nents;


Thanks
Anoop



[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux