From: James Bottomley <James.Bottomley@steeleye.com>
To: PARISC list <parisc-linux@lists.parisc-linux.org>
Cc: parisc-linux-cvs@lists.parisc-linux.org
Subject: [parisc-linux] Re: [parisc-linux-cvs] linux-2.6 jejb
Date: 06 Apr 2004 16:37:15 -0500 [thread overview]
Message-ID: <1081287436.1837.43.camel@mulgrave> (raw)
In-Reply-To: <20040406213446.CB675494194@palinux.hppa>
On Tue, 2004-04-06 at 16:34, James Bottomley wrote:
> CVSROOT: /var/cvs
> Module name: linux-2.6
> Changes by: jejb 04/04/06 15:34:46
>
> Modified files:
> . : Makefile
> arch/parisc/kernel: cache.c
>
> Log message:
> Fix flush_dcache_page
Index: arch/parisc/kernel/cache.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/cache.c,v
retrieving revision 1.6
diff -u -r1.6 cache.c
--- a/arch/parisc/kernel/cache.c 5 Apr 2004 02:47:39 -0000 1.6
+++ b/arch/parisc/kernel/cache.c 6 Apr 2004 21:30:44 -0000
@@ -227,6 +227,32 @@
disable_sr_hashing_asm(srhash_type);
}
+/* Simple function to work out if we have an existing address translation
+ * for a user space vma. */
+static inline int translation_exists(struct vm_area_struct *vma,
+ unsigned long addr)
+{
+ pgd_t *pgd = pgd_offset(vma->vm_mm, addr);
+ pmd_t *pmd;
+ pte_t *pte;
+
+ if(pgd_none(*pgd))
+ return 0;
+
+ pmd = pmd_offset(pgd, addr);
+ if(pmd_none(*pmd) || pmd_bad(*pmd))
+ return 0;
+
+ pte = pte_offset_map(pmd, addr);
+
+ /* The PA flush mappings show up as pte_none, but they're
+ * valid none the less */
+ if(pte_none(*pte) && ((pte_val(*pte) & _PAGE_FLUSH) == 0))
+ return 0;
+ return 1;
+}
+
+
void __flush_dcache_page(struct page *page)
{
struct mm_struct *mm = current->active_mm;
@@ -237,19 +263,15 @@
if (!page->mapping)
return;
- /* check shared list first if it's not empty...it's usually
- * the shortest */
+
+ /* We have ensured in arch_get_unmapped_area() that all shared
+ * mappings are mapped at equivalent addresses, so we only need
+ * to flush one for them all to become coherent */
list_for_each(l, &page->mapping->i_mmap_shared) {
struct vm_area_struct *mpnt;
- unsigned long off;
+ unsigned long off, addr;
- anyvma = mpnt = list_entry(l, struct vm_area_struct, shared);
-
- /*
- * If this VMA is not in our MM, we can ignore it.
- */
- if (mpnt->vm_mm != mm)
- continue;
+ mpnt = list_entry(l, struct vm_area_struct, shared);
if (page->index < mpnt->vm_pgoff)
continue;
@@ -258,25 +280,51 @@
if (off >= (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT)
continue;
- flush_cache_page(mpnt, mpnt->vm_start + (off << PAGE_SHIFT));
+ addr = mpnt->vm_start + (off << PAGE_SHIFT);
+
+ /* flush instructions produce non access tlb misses.
+ * On PA, we nullify these instructions rather than
+ * taking a page fault if the pte doesn't exist, so we
+ * have to find a congruent address with an existing
+ * translation */
+
+ if (!translation_exists(mpnt, addr))
+ continue;
+
+ anyvma = mpnt;
+
+ /*
+ * We try first to find a page in our current user process
+ */
+ if (mpnt->vm_mm != mm)
+ continue;
+
+
+ flush_cache_page(mpnt, addr);
/* All user shared mappings should be equivalently mapped,
* so once we've flushed one we should be ok
*/
- return;
+ goto flush_unshared;
}
- /* then check private mapping list for read only shared mappings
- * which are flagged by VM_MAYSHARE */
- list_for_each(l, &page->mapping->i_mmap) {
- struct vm_area_struct *mpnt;
- unsigned long off;
+ /* OK, shared page but not in our current process' address space */
+ if (anyvma) {
+ unsigned long addr = anyvma->vm_start
+ + ((page->index - anyvma->vm_pgoff) << PAGE_SHIFT);
+ flush_cache_page(anyvma, addr);
+ }
- anyvma = mpnt = list_entry(l, struct vm_area_struct, shared);
+ flush_unshared:
+ /* Private mappings will not have congruent addresses, so we
+ * have to flush each of them individually to make the change
+ * in the kernel page visible */
+ list_for_each(l, &page->mapping->i_mmap) {
+ struct vm_area_struct *mpnt;
+ unsigned long off, addr;
- if (mpnt->vm_mm != mm || !(mpnt->vm_flags & VM_MAYSHARE))
- continue;
+ mpnt = list_entry(l, struct vm_area_struct, shared);
if (page->index < mpnt->vm_pgoff)
continue;
@@ -285,20 +333,15 @@
if (off >= (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT)
continue;
- flush_cache_page(mpnt, mpnt->vm_start + (off << PAGE_SHIFT));
+ addr = mpnt->vm_start + (off << PAGE_SHIFT);
- /* All user shared mappings should be equivalently mapped,
- * so once we've flushed one we should be ok
- */
- return;
- }
- /* This is the problem case. We failed to find the page to be
- * flushed in the current vma thus we have to flush it in some
- * other user process */
- if (likely(anyvma)) {
- unsigned long addr = anyvma->vm_start
- + ((page->index - anyvma->vm_pgoff) << PAGE_SHIFT);
- flush_user_cache_page_non_current(anyvma, addr);
+ /* This is just for speed. If the page translation isn't
+ * there there's no point exciting the nadtlb handler into
+ * a nullification frenzy */
+ if(!translation_exists(mpnt, addr))
+ continue;
+
+ flush_cache_page(mpnt, addr);
}
}
EXPORT_SYMBOL(__flush_dcache_page);
next parent reply other threads:[~2004-04-06 21:37 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20040406213446.CB675494194@palinux.hppa>
2004-04-06 21:37 ` James Bottomley [this message]
[not found] <20040505204811.27F0C4945E4@palinux.hppa>
2004-05-05 20:50 ` [parisc-linux] Re: [parisc-linux-cvs] linux-2.6 jejb James Bottomley
2004-05-06 5:05 ` Randolph Chung
2004-05-06 5:22 ` Randolph Chung
2004-05-06 9:33 ` M. Grabert
2004-05-06 13:25 ` Kyle McMartin
[not found] <20040502161601.DC7C24945C7@palinux.hppa>
2004-05-03 20:51 ` James Bottomley
[not found] <20040501200312.40BB74945E1@palinux.hppa>
2004-05-01 20:09 ` James Bottomley
2004-05-03 8:57 ` Joel Soete
[not found] <20040501160556.D07DC4945CA@palinux.hppa>
2004-05-01 16:13 ` James Bottomley
[not found] <20040430162037.9D2B94945CD@palinux.hppa>
2004-04-30 16:25 ` James Bottomley
[not found] <20040427171140.706074945BD@palinux.hppa>
2004-04-27 17:15 ` James Bottomley
[not found] <20040425145051.10F5C4942B8@palinux.hppa>
2004-04-25 14:55 ` James Bottomley
[not found] <20040414174535.81173494194@palinux.hppa>
2004-04-14 17:53 ` James Bottomley
[not found] <20040412154800.D31F6494194@palinux.hppa>
2004-04-12 15:55 ` James Bottomley
[not found] <20040407004901.031D3494194@palinux.hppa>
2004-04-07 0:54 ` James Bottomley
2004-04-08 6:15 ` Joel Soete
2004-04-08 12:36 ` James Bottomley
[not found] <20040405174131.84BF1494194@palinux.hppa>
2004-04-06 13:21 ` Carlos O'Donell
2004-04-06 14:18 ` James Bottomley
2004-04-06 15:40 ` Randolph Chung
[not found] <20040405024740.9330F494194@palinux.hppa>
2004-04-05 2:49 ` James Bottomley
2004-04-05 2:54 ` James Bottomley
[not found] <20040320210116.7A727494553@palinux.hppa>
2004-03-20 21:04 ` James Bottomley
2004-03-20 21:10 ` Helge Deller
2004-03-20 21:13 ` Helge Deller
[not found] <20040228212407.DB126494190@palinux.hppa>
2004-02-28 22:21 ` Joel Soete
2004-02-28 22:42 ` James Bottomley
2004-02-29 9:39 ` Joel Soete
2004-03-04 16:39 ` Joel Soete
2004-02-06 7:31 [parisc-linux] " Joel Soete
2004-02-06 17:50 ` Grant Grundler
2004-02-06 18:06 ` bame
2004-02-06 19:16 ` Randolph Chung
2004-02-06 17:08 ` Joel Soete
2004-02-07 6:40 ` Randolph Chung
2004-02-09 7:26 ` Joel Soete
[not found] <20040204182455.1CC11494191@palinux.hppa>
2004-02-05 9:20 ` [parisc-linux] " Randolph Chung
2004-02-05 15:19 ` James Bottomley
2004-02-05 15:29 ` [parisc-linux] " Joel Soete
2004-02-05 20:31 ` Randolph Chung
2004-02-05 18:49 ` Joel Soete
[not found] <20040113155603.CBCC249425A@palinux.hppa>
2004-01-13 15:58 ` [parisc-linux] " James Bottomley
[not found] <20030924175431.D51BC49408B@palinux.hppa>
2003-09-24 18:01 ` James Bottomley
[not found] <20030919010356.148684940A4@palinux.hppa>
2003-09-19 1:06 ` James Bottomley
2003-09-19 11:24 ` Randolph Chung
2003-09-19 14:02 ` James Bottomley
2003-09-19 18:24 ` Jim Hull
[not found] <20030903200300.8B7B7494064@palinux.hppa>
2003-09-03 20:07 ` James Bottomley
[not found] <20030903165113.138BF494064@palinux.hppa>
2003-09-03 16:56 ` James Bottomley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1081287436.1837.43.camel@mulgrave \
--to=james.bottomley@steeleye.com \
--cc=parisc-linux-cvs@lists.parisc-linux.org \
--cc=parisc-linux@lists.parisc-linux.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.