Linux MIPS Architecture development
 help / color / mirror / Atom feed
* problems on D-cache alias in 2.4.22
@ 2004-05-13  6:52 wuming
  2004-05-14  7:45 ` Peter Horton
  0 siblings, 1 reply; 19+ messages in thread
From: wuming @ 2004-05-13  6:52 UTC (permalink / raw)
  To: linux-mips

 I am developing in linux-2.4.22 on the machine with virtual address
indexed and physical
address tagged. But when I compile some application programs, I met the
following error:

cc1: internal compiler error: Segmentation fault

I have searched about this error from internet, it's due to some
hardware fault or
a wrong pte fault handler. Because my machine have D-cache aliasing, so
I think
this error should be due to a wrong pte fault handler. After my painful
kernel hacking,
I found some strange problems and it's in function __update_cache( ):

void __update_cache(struct vm_area_struct *vma, unsigned long address,
pte_t pte)
{
unsigned long addr;
struct page *page;

if (!cpu_has_dc_aliases)
return;

page = pte_page(pte);

/*This printk is added by myself*/
printk("<1>valid page:%d\tpage mapping:0x%p\tpage flags:%d\n",\
VALID_PAGE(page), page->mapping, (page->flags & (1UL << PG_dcache_dirty)));

if (VALID_PAGE(page) && page->mapping &&
(page->flags & (1UL << PG_dcache_dirty))) {
if (pages_do_alias((unsigned long) page_address(page), address &
PAGE_MASK)) {
addr = (unsigned long) page_address(page);
flush_data_cache_page(addr);
}
ClearPageDcacheDirty(page);
}
}

When my kernel is running, I found the condition "page->mapping" and
"(page->flags & (1UL << PG_dcache_dirty))"
will never be true at the same time. so the function
flush_data_cache_page( ) will never be called.
Then I commented the two condition, the compiler error disappeared.
I do not understand the phenomenon very clearly, so I need some help.

^ permalink raw reply	[flat|nested] 19+ messages in thread
* RE: problems on D-cache alias in 2.4.22
@ 2004-05-13 22:05 Bob Breuer
  2004-05-13 22:05 ` Bob Breuer
  2004-05-14  2:59 ` wuming
  0 siblings, 2 replies; 19+ messages in thread
From: Bob Breuer @ 2004-05-13 22:05 UTC (permalink / raw)
  To: linux-mips


> -----Original Message-----
> Date: Thu, 13 May 2004 14:52:53 +0800
> From: wuming <wuming@ict.ac.cn>
> Subject: problems on D-cache alias in 2.4.22
> 
>  I am developing in linux-2.4.22 on the machine with virtual address
> indexed and physical
> address tagged. But when I compile some application programs, 
> I met the
> following error:
> 
> cc1: internal compiler error: Segmentation fault
> 
> I have searched about this error from internet, it's due to some
> hardware fault or
> a wrong pte fault handler. Because my machine have D-cache 
> aliasing, so
> I think
> this error should be due to a wrong pte fault handler. After 
> my painful
> kernel hacking,
> I found some strange problems and it's in function __update_cache( ):
> 
> void __update_cache(struct vm_area_struct *vma, unsigned long address,
> pte_t pte)
> {
> unsigned long addr;
> struct page *page;
> 
> if (!cpu_has_dc_aliases)
> return;
> 
> page = pte_page(pte);
> 
> /*This printk is added by myself*/
> printk("<1>valid page:%d\tpage mapping:0x%p\tpage flags:%d\n",\
> VALID_PAGE(page), page->mapping, (page->flags & (1UL << 
> PG_dcache_dirty)));
> 
> if (VALID_PAGE(page) && page->mapping &&
> (page->flags & (1UL << PG_dcache_dirty))) {
> if (pages_do_alias((unsigned long) page_address(page), address &
> PAGE_MASK)) {
> addr = (unsigned long) page_address(page);
> flush_data_cache_page(addr);
> }
> ClearPageDcacheDirty(page);
> }
> }
> 
> When my kernel is running, I found the condition "page->mapping" and
> "(page->flags & (1UL << PG_dcache_dirty))"
> will never be true at the same time. so the function
> flush_data_cache_page( ) will never be called.
> Then I commented the two condition, the compiler error disappeared.
> I do not understand the phenomenon very clearly, so I need some help.
> 
> 

I am having a similar problem with 2.4.26 on an NEC VR5500 with a 32k
2-way cache.  This is with a 32 bit little-endian kernel, and an ext2
filesystem on an ide hard drive in pio mode.

Removing just the check for PG_dcache_dirty fixes the problem for me.

Along the way, I found a bogus check for cache aliases in c-r4k.c.  In
the ld_mmu_r4xx0 function, it has the check:
    if (c->dcache.sets * c->dcache.ways > PAGE_SIZE)
which will never work for a 32k cache.

Bob Breuer

^ permalink raw reply	[flat|nested] 19+ messages in thread
* RE: problems on D-cache alias in 2.4.22
@ 2004-05-18 18:17 Bob Breuer
  2004-05-18 18:17 ` Bob Breuer
                   ` (3 more replies)
  0 siblings, 4 replies; 19+ messages in thread
From: Bob Breuer @ 2004-05-18 18:17 UTC (permalink / raw)
  To: linux-mips

[-- Attachment #1: Type: text/plain, Size: 1393 bytes --]


> -----Original Message-----
> From: linux-mips-bounce@linux-mips.org
> [mailto:linux-mips-bounce@linux-mips.org]On Behalf Of Peter Horton
> Sent: Friday, May 14, 2004 2:53 AM
> To: wuming
> Cc: linux-mips@linux-mips.org
> Subject: Re: problems on D-cache alias in 2.4.22
> 
> 
> wuming wrote:
> 
...
> > at last, when I replaced flush_page_to_ram( ) with 
> flush_dcache_page( ),
> > the internal compiler error disappeared.
> >
...
> 
> This is probably just hiding your problem. flush_page_to_ram() is not 
> used anymore.
> 
> P.
> 
> 

Changing that same place also fixes my problem.  However, I came across
the mips cobalt patches and after applying a variation of the IDE cache
fix from there, that also fixes the problem.  So it would seem that this
is the same problem as already fixed in the cobalt patch, but showing up
on non-cobalt hardware.

flush_page_to_ram() was made useless around the release of 2.4.21.  I
suspect that this was broken at that time, seeing how it is broken in
2.4.22 and 2.4.26.  From browsing the debian-mips mailing list archives,
it appears that they have not had a stable mips kernel since 2.4.19,
could this bug be the cause?  Are the recent Debian mips kernels still
unstable?

Would anyone with an unstable 2.4.2x kernel be willing to try one of the
attached patches to see if the situation improves?

Bob

[-- Attachment #2: cache_alias_fix1.diff --]
[-- Type: application/octet-stream, Size: 480 bytes --]

Index: mm/filemap.c
===================================================================
RCS file: /home/cvs/linux/mm/filemap.c,v
retrieving revision 1.74.2.14
diff -u -r1.74.2.14 filemap.c
--- mm/filemap.c	20 Feb 2004 01:22:21 -0000	1.74.2.14
+++ mm/filemap.c	18 May 2004 17:18:26 -0000
@@ -2111,7 +2111,7 @@
 	 * and possibly copy it over to another page..
 	 */
 	mark_page_accessed(page);
-	flush_page_to_ram(page);
+	flush_dcache_page(page);
 	return page;
 
 no_cached_page:

[-- Attachment #3: cache_alias_fix2.diff --]
[-- Type: application/octet-stream, Size: 1543 bytes --]

Index: include/asm-mips/ide.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/ide.h,v
retrieving revision 1.11.2.7
diff -u -r1.11.2.7 ide.h
--- include/asm-mips/ide.h	15 Jul 2003 15:08:33 -0000	1.11.2.7
+++ include/asm-mips/ide.h	18 May 2004 17:57:44 -0000
@@ -69,6 +69,49 @@
 #endif
 
 #include <asm-generic/ide_iops.h>
+#include <asm/r4kcache.h>
+
+static inline void __flush_dcache_range(unsigned long start, unsigned long end)
+{
+	unsigned long dc_size, dc_line, addr;
+
+	dc_size = current_cpu_data.dcache.waysize;
+	dc_line = current_cpu_data.dcache.linesz;
+
+	addr = start & ~(dc_line - 1);
+	end += dc_line - 1;
+
+	if (end - addr < dc_size)
+		for (; addr < end; addr += dc_line)
+			flush_dcache_line(addr);
+	else {
+		/* flush all of dcache */
+		addr = KSEG0;
+		end = addr + dc_size;
+		for (; addr < end; addr += dc_line)
+			flush_dcache_line_indexed(addr);
+	}
+}
+
+#undef insw
+#undef insl
+#undef __ide_insw
+#undef __ide_insl
+
+static inline void __ide_insw(unsigned long port, void *addr, u32 count)
+{
+	__insw(port, addr, count);
+	__flush_dcache_range((unsigned long)addr, (unsigned long)addr + count*2);
+}
+
+static inline void __ide_insl(unsigned long port, void *addr, u32 count)
+{
+	__insl(port, addr, count);
+	__flush_dcache_range((unsigned long)addr, (unsigned long)addr + count*4);
+}
+
+#define insw(port, addr, count) __ide_insw(port, addr, count)
+#define insl(port, addr, count) __ide_insl(port, addr, count)
 
 #endif /* __KERNEL__ */
 

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2004-05-18 23:29 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-05-13  6:52 problems on D-cache alias in 2.4.22 wuming
2004-05-14  7:45 ` Peter Horton
  -- strict thread matches above, loose matches on Subject: below --
2004-05-13 22:05 Bob Breuer
2004-05-13 22:05 ` Bob Breuer
2004-05-14  2:59 ` wuming
2004-05-14  7:52   ` Peter Horton
2004-05-15  0:12   ` Ralf Baechle
2004-05-15 12:31     ` Fuxin Zhang
2004-05-18 18:17 Bob Breuer
2004-05-18 18:17 ` Bob Breuer
2004-05-18 18:45 ` Jun Sun
2004-05-18 19:10   ` Peter Horton
2004-05-18 19:50     ` Ralf Baechle
2004-05-18 18:24       ` Alan Cox
2004-05-18 21:21       ` Peter Horton
2004-05-18 22:25     ` Jun Sun
2004-05-18 23:29       ` Peter Horton
2004-05-18 20:02 ` Ralf Baechle
2004-05-18 20:10 ` Thiemo Seufer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox