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. #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> int main(int argc, char **argv) { int fd; struct stat st; volatile unsigned char *buf; unsigned char dat, dat2; fd = open(argv[1], O_RDONLY); fstat(fd, &st); 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); munmap(buf, st.st_size); close(fd); return 0; } 'dat' and 'dat2' should be same value, of course. But sometimes they differ. 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. Documentation/cachetlb.txt says: 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 cacheflush() call. 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.. */ mark_page_accessed(page); + flush_dcache_page(page); flush_page_to_ram(page); return page; --- Atsushi Nemoto