I noticed that reading from file with mmap sometimes return wrong data
on 2.4 kernel.
This is a test program to reproduce the problem.
int main(int argc, char **argv)
struct stat st;
volatile unsigned char *buf;
unsigned char dat, dat2;
fd = open(argv, O_RDONLY);
buf = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
dat = *buf;
cacheflush(0, 0, 0); // flush cache all
dat2 = *buf;
printf("dat %x dat2 %x\n", dat, dat2);
'dat' and 'dat2' should be same value, of course. But sometimes they
This problem often happens when I read a file in IDE disk (using PIO)
just after mounted. I saw same problem on a mtd JFFS2 partition a
while ago. I suppose it is not a filesystem/driver problem.
After calling cacheflush(), it returns correct data. And I checked
the virtual/physical address return by the mmap and found they had
different 'color' when the problem happens. So it seems to be a
virtual aliasing problem.
void flush_dcache_page(struct page *page)
Any time the kernel writes to a page cache page, _OR_
the kernel is about to read from a page cache page and
user space shared/writable mappings of this page potentially
exist, this routine is called.
But flush_dcache_page() did not called between the mmap() call and the
Tracing the code path on the page fault, I noticed filemap_nopage()
uses old flush_page_to_ram() interface. I suppose flush_dcache_page()
should be called in same place. Is this a correct fix?
--- linux-2.4.25/mm/filemap.c Wed Feb 18 22:36:32 2004
+++ linux/mm/filemap.c Thu Mar 25 21:19:29 2004
@@ -2111,6 +2111,7 @@
* and possibly copy it over to another page..