From patchwork Wed Dec 23 08:38:10 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Pietrek, Markus" X-Patchwork-Id: 69468 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id nBN8cbe7022909 for ; Wed, 23 Dec 2009 08:38:37 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754379AbZLWIiU (ORCPT ); Wed, 23 Dec 2009 03:38:20 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754376AbZLWIiS (ORCPT ); Wed, 23 Dec 2009 03:38:18 -0500 Received: from mail3.emtrion.de ([80.150.99.69]:19705 "EHLO mail3.emtrion.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754321AbZLWIiP convert rfc822-to-8bit (ORCPT ); Wed, 23 Dec 2009 03:38:15 -0500 Received: from BMK019S01.emtrion.local ([::1]) by BMK019S01.emtrion.local ([fe80::4a1:cedc:cab6:e9ce%10]) with mapi; Wed, 23 Dec 2009 09:38:12 +0100 From: "Pietrek, Markus" To: Matt Fleming CC: "linux-sh@vger.kernel.org" Date: Wed, 23 Dec 2009 09:38:10 +0100 Subject: AW: Probably cache synchronization issue on SH7723 Thread-Topic: Probably cache synchronization issue on SH7723 Thread-Index: AcqDJsJbFHi+w5X8SLWehLtdknz5cwAgciuA Message-ID: <95F51F4B902CAC40AF459205F6322F0133E18561CD@BMK019S01.emtrion.local> References: <20091204064759.GA13603@linux-sh.org> <95F51F4B902CAC40AF459205F6322F0133E18561C7@BMK019S01.emtrion.local> <20091222165150.GA7254@console-pimps.org> In-Reply-To: <20091222165150.GA7254@console-pimps.org> Accept-Language: de-DE Content-Language: de-DE X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: de-DE x-tm-as-product-ver: SMEX-8.0.0.1307-6.000.1038-17086.005 x-tm-as-result: No--51.340700-8.000000-31 x-tm-as-user-approved-sender: No x-tm-as-user-blocked-sender: No MIME-Version: 1.0 Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c index e9415d3..054bb8a 100644 --- a/arch/sh/mm/cache.c +++ b/arch/sh/mm/cache.c @@ -126,8 +126,10 @@ void __update_cache(struct vm_area_struct *vma, { struct page *page; unsigned long pfn = pte_pfn(pte); + /* flush any dirty data page before using it as a code page */ + int exec = (vma != NULL) ? (vma->vm_flags & VM_EXEC) : 1; - if (!boot_cpu_data.dcache.n_aliases) + if (!boot_cpu_data.dcache.n_aliases && !exec) return; page = pfn_to_page(pfn); @@ -136,7 +138,7 @@ void __update_cache(struct vm_area_struct *vma, if (dirty) { unsigned long addr = (unsigned long)page_address(page); - if (pages_do_alias(addr, address & PAGE_MASK)) + if (exec || pages_do_alias(addr, address & PAGE_MASK)) __flush_purge_region((void *)addr, PAGE_SIZE); } } Best regards, Markus Pietrek -----Ursprüngliche Nachricht----- Von: Matt Fleming [mailto:matt@console-pimps.org] Gesendet: Dienstag, 22. Dezember 2009 17:52 An: Pietrek, Markus Cc: linux-sh@vger.kernel.org Betreff: Re: Probably cache synchronization issue on SH7723 On Tue, Dec 22, 2009 at 05:18:16PM +0100, Pietrek, Markus wrote: > Hi, > > Lacking some understanding of the caching system I'm not sure why in > update_cache() some dirty pages are skipped. The following patch fixes > my problem, but I'm not sure about any negative side effects. Interesting! Good investigative work. It's an optimisation so that we don't flush the dcache more than we need to. There shouldn't be any negative side effects of your patch, it's just a bit inefficient. Having looked at the MIPS __update_cache() function I'm wondering if the bug is that we should be flushing the cache if the page is executable. Could you try this patch? diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c index e9415d3..8460bbf 100644 --- a/arch/sh/mm/cache.c +++ b/arch/sh/mm/cache.c @@ -126,8 +126,9 @@ void __update_cache(struct vm_area_struct *vma, { struct page *page; unsigned long pfn = pte_pfn(pte); + int exec = (vma->vm_flags & VM_EXEC); - if (!boot_cpu_data.dcache.n_aliases) + if (!boot_cpu_data.dcache.n_aliases && !exec) return; page = pfn_to_page(pfn); @@ -136,7 +137,7 @@ void __update_cache(struct vm_area_struct *vma, if (dirty) { unsigned long addr = (unsigned long)page_address(page); - if (pages_do_alias(addr, address & PAGE_MASK)) + if (exec || pages_do_alias(addr, address & PAGE_MASK)) __flush_purge_region((void *)addr, PAGE_SIZE); } }