Linux PARISC architecture development
 help / color / mirror / Atom feed
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);

       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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox