> > 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