linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Christoph Lameter <clameter@sgi.com>
To: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: hugh@veritas.com, linux-kernel@vger.kernel.org,
	linux-mm@kvack.org, akpm@osdl.org
Subject: Read/Write migration entries: Make mprotect() convert write migration entries to read
Date: Thu, 20 Apr 2006 13:18:52 -0700 (PDT)	[thread overview]
Message-ID: <Pine.LNX.4.64.0604201317220.19049@schroedinger.engr.sgi.com> (raw)
In-Reply-To: <20060419123911.3bd22ab3.kamezawa.hiroyu@jp.fujitsu.com>

1. Introduce a new function make_migration_entry() to
   isolate common code between copy_pte_range and change_pte_range.

2. Modify change_pte_range() to check for a migration entry.
   If a write migration entry is found and there is a request for
   a READ permissions then change the migration entry.

I am a bit concerned about the check of newprot. Are there other
values than PAGE_READONLY that indicate read only access?

Signed-off-by: Christoph Lameter <clameter@sgi.com>

Index: linux-2.6.17-rc1-mm3/mm/memory.c
===================================================================
--- linux-2.6.17-rc1-mm3.orig/mm/memory.c	2006-04-18 11:09:23.252982000 -0700
+++ linux-2.6.17-rc1-mm3/mm/memory.c	2006-04-20 12:22:50.626800376 -0700
@@ -447,14 +447,11 @@
 			}
 			if (is_migration_entry(entry) &&
 					is_cow_mapping(vm_flags)) {
-				page = migration_entry_to_page(entry);
-
 				/*
 				 * COW mappings require pages in both parent
-				*  and child to be set to read.
+				 * and child to be set to read.
 				 */
-				entry = make_migration_entry(page,
-						SWP_MIGRATION_READ);
+				make_migration_entry_read(&entry);
 				pte = swp_entry_to_pte(entry);
 				set_pte_at(src_mm, addr, src_pte, pte);
 			}
Index: linux-2.6.17-rc1-mm3/mm/mprotect.c
===================================================================
--- linux-2.6.17-rc1-mm3.orig/mm/mprotect.c	2006-04-18 11:12:30.614603000 -0700
+++ linux-2.6.17-rc1-mm3/mm/mprotect.c	2006-04-20 12:17:03.771210036 -0700
@@ -19,6 +19,8 @@
 #include <linux/mempolicy.h>
 #include <linux/personality.h>
 #include <linux/syscalls.h>
+#include <linux/swap.h>
+#include <linux/swapops.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -28,22 +30,35 @@
 static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
 		unsigned long addr, unsigned long end, pgprot_t newprot)
 {
-	pte_t *pte;
+	pte_t *pte, oldpte;
 	spinlock_t *ptl;
 
 	pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
 	do {
-		if (pte_present(*pte)) {
+		oldpte = *pte;
+		if (pte_present(oldpte)) {
 			pte_t ptent;
 
 			/* Avoid an SMP race with hardware updated dirty/clean
 			 * bits by wiping the pte and then setting the new pte
 			 * into place.
 			 */
-			ptent = pte_modify(ptep_get_and_clear(mm, addr, pte), newprot);
+			ptent = pte_modify(ptep_get_and_clear(mm, addr, pte),
+								newprot);
 			set_pte_at(mm, addr, pte, ptent);
 			lazy_mmu_prot_update(ptent);
+		} else
+		if (!pte_file(oldpte) && pgprot_val(newprot) ==
+						 pgprot_val(PAGE_READONLY)) {
+			swp_entry_t entry = pte_to_swp_entry(oldpte);
+
+			if (is_write_migration_entry(entry)) {
+				make_migration_entry_read(&entry);
+				set_pte_at(mm, addr, pte,
+					swp_entry_to_pte(entry));
+			}
 		}
+
 	} while (pte++, addr += PAGE_SIZE, addr != end);
 	pte_unmap_unlock(pte - 1, ptl);
 }
Index: linux-2.6.17-rc1-mm3/include/linux/swapops.h
===================================================================
--- linux-2.6.17-rc1-mm3.orig/include/linux/swapops.h	2006-04-18 10:58:33.675573000 -0700
+++ linux-2.6.17-rc1-mm3/include/linux/swapops.h	2006-04-20 12:00:29.279539838 -0700
@@ -98,6 +98,11 @@
 	return p;
 }
 
+static inline void make_migration_entry_read(swp_entry_t *entry)
+{
+	*entry = swp_entry(SWP_MIGRATION_READ, swp_offset(*entry));
+}
+
 extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
 					unsigned long address);
 #else
@@ -105,6 +110,7 @@
 #define make_migration_entry(page, write) swp_entry(0, 0)
 #define is_migration_entry(swp) 0
 #define migration_entry_to_page(swp) NULL
+static inline void make_migration_entry_read(entryp) { }
 static inline void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
 					 unsigned long address) { }
 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

      parent reply	other threads:[~2006-04-20 20:18 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-04-18 18:21 Read/Write migration entries: Implement correct behavior in copy_one_pte Christoph Lameter
2006-04-19  0:50 ` KAMEZAWA Hiroyuki
2006-04-19  1:27   ` Christoph Lameter
2006-04-19  3:39     ` KAMEZAWA Hiroyuki
2006-04-20 20:17       ` Christoph Lameter
2006-04-20 20:18       ` Christoph Lameter [this message]

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=Pine.LNX.4.64.0604201317220.19049@schroedinger.engr.sgi.com \
    --to=clameter@sgi.com \
    --cc=akpm@osdl.org \
    --cc=hugh@veritas.com \
    --cc=kamezawa.hiroyu@jp.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.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;
as well as URLs for NNTP newsgroup(s).