Subject: RE: problems on D-cache alias in 2.4.22

From: "Bob Breuer" <[email-masked]>
Date: Thu, 13 May 2004 17:05:52 -0500

> -----Original Message-----
> Date: Thu, 13 May 2004 14:52:53 +0800
> From: wuming <[email-masked]>
> 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

---

From: wuming <[email-masked]>
Date: Fri, 14 May 2004 10:59:13 +0800

>which will never work for a 32k cache.
I have understood the phenomenon, and I think this is a kernel's bug.
The real wrong place is not the judgement for condition "PG_dcache_dirty"
in function __update_cache( ).
in file mm/filemap.c and function filemap_nopage( ):
......
success:
        /*
         * Try read-ahead for sequential areas.
         */
        if (VM_SequentialReadHint(area))
                nopage_sequential_readahead(area, pgoff, size);
                                                                               
        /*
         * Found the page and have a reference on it, need to check sharing
         * and possibly copy it over to another page..
         */
        mark_page_accessed(page);
        flush_page_to_ram(page);
        return page;
......

flush_page_to_ram( ) has not been used for a long time, and in kernel 2.4.22
"include/asm-mips/cacheflush.h"
#define flush_page_to_ram(page)         do { } while (0)

so the mapped page has not been flushed to ram, and the user space will not
know the latest data in the page.
the flush_page_to_ram( ) should be replaced by flush_dcache_page( ),
and if the flush_dcache_page( ) does not really flush the cache, it will set
the PG_dcache_dirty, and the real flush will be postponed to 
__update_cache( ).
and if there is not the flush_dcache_page( ) here, no one will set the 
PG_dcache_dirty,
and __update_cache( ) will not flush the page too, so the D-cache 
aliasing happens.

at last, when I replaced flush_page_to_ram( ) with flush_dcache_page( ),
the internal compiler error disappeared.

I hope your problem will be solved by this way too. God bless you! :-)

---

From: Peter Horton <[email-masked]>
Date: Fri, 14 May 2004 08:52:42 +0100

> I hope your problem will be solved by this way too. God bless you! :-)

This is probably just hiding your problem. flush_page_to_ram() is not 
used anymore.

P.

---

From: Ralf Baechle <[email-masked]>
Date: Sat, 15 May 2004 02:12:55 +0200

Wuming,

what kind of filesystem or storage are you using?

  Ralf

---

From: Fuxin Zhang <[email-masked]>
Date: Sat, 15 May 2004 08:31:35 -0400

We are using ide disk with ext3 filesystem, DMA is on( PIIX4 chip),but 
it seems PIO/DMA
does not affect the failures.