From: Paul M. <pau...@ti...> - 2002-10-30 16:46:15
|
This looks like more of a problem of flush_page_to_ram() not doing its job. If we look at DaveM's cache/tlb flushing docs, we see the following: flush_page_to_ram(struct page *page) The physical page 'page' is about to be place into the user address space of a process. If it is possible for stores done recently by the kernel into this physical page, to not be visible to an arbitrary mapping in userspace, you must flush this page from the D-cache. If the D-cache is writeback in nature, the dirty data (if any) for this physical page must be written back to main memory before the cache lines are invalidated. This looks pretty straightforward in nature, and for this application, I think we'd be better off simply aliasing flush_page_to_ram() to flush_dcache_page(). At least it looks like it'll do the Right Thing(tm) more often then not that way (with potentially a few extra dcache flushes..). I've attached a patch that does this for HEAD and restructure, which I'll push in if no one has any objections. On Wed, 2002-10-30 at 00:52, SUGIOKA Toshinobu wrote: > On my SH7750S (200MHz, 128MB) board, user land application > causes segmentation fault and/or unaligned access randomly when > very high memory load with swap on. >=20 > You could easily reproduce with 'stress' program. > http://weather.ou.edu/~apw/projects/stress/ >=20 > Following patch fixes this problem, but I'm not sure if this is correct. > Does anyone else encountered this problem? >=20 > --- mm/memory.c~ Thu Apr 11 17:57:49 2002 > +++ mm/memory.c Wed Oct 30 14:30:21 2002 > @@ -1170,6 +1170,7 @@ > pte =3D pte_mkdirty(pte_mkwrite(pte)); > unlock_page(page); >=20 > + flush_dcache_page(page); > flush_page_to_ram(page); > flush_icache_page(vma, page); > set_pte(page_table, pte); >=20 Regards, --=20 Paul Mundt pau...@ti... TimeSys Corporation 2002-10-30 Paul Mundt <le...@li...> * arch/sh/mm/cache-sh4.c (flush_page_to_ram): Added, as an alias to flush_dcache_page(). =09 * include/asm-sh/cacheflush.h (flush_page_to_ram): Moved to an extern reference. Index: arch/sh/mm/cache-sh4.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/cache-sh4.c,v retrieving revision 1.1.1.1.4.2 diff -u -r1.1.1.1.4.2 cache-sh4.c --- arch/sh/mm/cache-sh4.c 27 Oct 2002 21:22:50 -0000 1.1.1.1.4.2 +++ arch/sh/mm/cache-sh4.c 30 Oct 2002 16:37:40 -0000 @@ -249,6 +249,9 @@ } } =20 +void flush_page_to_ram(struct page *page) + __attribute__ ((alias("flush_dcache_page"))); + static inline void flush_icache_all(void) { unsigned long flags; Index: include/asm-sh/cacheflush.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/linuxsh/linux/include/asm-sh/cacheflush.h,v retrieving revision 1.1.2.1 diff -u -r1.1.2.1 cacheflush.h --- include/asm-sh/cacheflush.h 27 Oct 2002 20:10:27 -0000 1.1.2.1 +++ include/asm-sh/cacheflush.h 30 Oct 2002 16:37:56 -0000 @@ -44,13 +44,13 @@ unsigned long end); extern void flush_cache_page(struct vm_area_struct *vma, unsigned long add= r); extern void flush_dcache_page(struct page *pg); +extern void flush_page_to_ram(struct page *pg); extern void flush_icache_range(unsigned long start, unsigned long end); extern void flush_cache_sigtramp(unsigned long addr); extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, unsigned long addr, int len); =20 -#define flush_page_to_ram(page) do { } while (0) #define flush_icache_page(vma,pg) do { } while (0) =20 /* Initialization of P3 area for copy_user_page */ |