linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
To: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: cl@linux-foundation.org, "linux-mm@kvack.org" <linux-mm@kvack.org>
Subject: [RFC MM 3/4] add mm version number
Date: Fri, 13 Nov 2009 16:40:29 +0900	[thread overview]
Message-ID: <20091113164029.e7e8bcea.kamezawa.hiroyu@jp.fujitsu.com> (raw)
In-Reply-To: <20091113163544.d92561c7.kamezawa.hiroyu@jp.fujitsu.com>


Add logical timestamp to mm_struct, which is incremented always
mmap_sem(write) is got and released. By this, it works like seqlock's
counter and indicates mm_struct is modified or not.

And this adds vma_cache to each thread. Each thread remember the last
faulted vma and grab reference count. Correctness of cache is checked by
mm->generation timestamp. (mm struct's vma cache is not very good
if mm is shared, I think)

Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
---
 arch/x86/mm/fault.c       |   18 ++++++++++++++++--
 fs/exec.c                 |    4 ++++
 include/linux/init_task.h |    1 +
 include/linux/mm_types.h  |   11 ++++++++++-
 include/linux/sched.h     |    4 ++++
 kernel/exit.c             |    3 +++
 kernel/fork.c             |    5 ++++-
 7 files changed, 42 insertions(+), 4 deletions(-)

Index: mmotm-2.6.32-Nov2/include/linux/mm_types.h
===================================================================
--- mmotm-2.6.32-Nov2.orig/include/linux/mm_types.h
+++ mmotm-2.6.32-Nov2/include/linux/mm_types.h
@@ -216,6 +216,7 @@ struct mm_struct {
 	atomic_t mm_users;			/* How many users with user space? */
 	atomic_t mm_count;			/* How many references to "struct mm_struct" (users count as 1) */
 	int map_count;				/* number of VMAs */
+	unsigned int generation;		/* logical timestamp of last modification */
 	struct rw_semaphore sem;
 	spinlock_t page_table_lock;		/* Protects page tables and some counters */
 
@@ -308,16 +309,21 @@ static inline int mm_reader_trylock(stru
 static inline void mm_writer_lock(struct mm_struct *mm)
 {
 	down_write(&mm->sem);
+	mm->generation++;
 }
 
 static inline void mm_writer_unlock(struct mm_struct *mm)
 {
+	mm->generation++;
 	up_write(&mm->sem);
 }
 
 static inline int mm_writer_trylock(struct mm_struct *mm)
 {
-	return down_write_trylock(&mm->sem);
+	int ret = down_write_trylock(&mm->sem);
+	if (!ret)
+		mm->generation++;
+	return ret;
 }
 
 static inline int mm_locked(struct mm_struct *mm)
@@ -327,17 +333,20 @@ static inline int mm_locked(struct mm_st
 
 static inline void mm_writer_to_reader_lock(struct mm_struct *mm)
 {
+	mm->generation++;
 	downgrade_write(&mm->sem);
 }
 
 static inline void mm_writer_lock_nested(struct mm_struct *mm, int x)
 {
 	down_write_nested(&mm->sem, x);
+	mm->generation++;
 }
 
 static inline void mm_lock_init(struct mm_struct *mm)
 {
 	init_rwsem(&mm->sem);
+	mm->generation = 0;
 }
 
 static inline void mm_lock_prefetch(struct mm_struct *mm)
Index: mmotm-2.6.32-Nov2/arch/x86/mm/fault.c
===================================================================
--- mmotm-2.6.32-Nov2.orig/arch/x86/mm/fault.c
+++ mmotm-2.6.32-Nov2/arch/x86/mm/fault.c
@@ -952,6 +952,7 @@ do_page_fault(struct pt_regs *regs, unsi
 	struct mm_struct *mm;
 	int write;
 	int fault;
+	int cachehit = 0;
 
 	tsk = current;
 	mm = tsk->mm;
@@ -1071,8 +1072,13 @@ do_page_fault(struct pt_regs *regs, unsi
 		 */
 		might_sleep();
 	}
-
-	vma = find_vma(mm, address);
+	if ((mm->generation == current->mm_generation) && current->vma_cache) {
+		vma = current->vma_cache;
+		if ((vma->vm_start <= address) && (address < vma->vm_end))
+			cachehit = 1;
+	}
+	if (!cachehit)
+		vma = find_vma(mm, address);
 	if (unlikely(!vma)) {
 		bad_area(regs, error_code, address);
 		return;
@@ -1133,6 +1139,14 @@ good_area:
 		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
 				     regs, address);
 	}
+	/* cache information */
+	if (!cachehit) {
+		if (current->vma_cache)
+			vma_put(current->vma_cache);
+		current->vma_cache = vma;
+		current->mm_generation = mm->generation;
+		vma_get(vma);
+	}
 
 	check_v8086_mode(regs, address, tsk);
 
Index: mmotm-2.6.32-Nov2/include/linux/sched.h
===================================================================
--- mmotm-2.6.32-Nov2.orig/include/linux/sched.h
+++ mmotm-2.6.32-Nov2/include/linux/sched.h
@@ -1370,6 +1370,10 @@ struct task_struct {
 /* hung task detection */
 	unsigned long last_switch_count;
 #endif
+/* For relaxing per-thread page fault, information is cached.*/
+	struct vm_area_struct *vma_cache;
+	unsigned int mm_generation;
+
 /* CPU-specific state of this task */
 	struct thread_struct thread;
 /* filesystem information */
Index: mmotm-2.6.32-Nov2/kernel/fork.c
===================================================================
--- mmotm-2.6.32-Nov2.orig/kernel/fork.c
+++ mmotm-2.6.32-Nov2/kernel/fork.c
@@ -264,6 +264,9 @@ static struct task_struct *dup_task_stru
 #endif
 	tsk->splice_pipe = NULL;
 
+	tsk->vma_cache = NULL;
+	tsk->mm_generation = 0;
+
 	account_kernel_stack(ti, 1);
 
 	return tsk;
@@ -289,7 +292,7 @@ static int dup_mmap(struct mm_struct *mm
 	 * Not linked in yet - no deadlock potential:
 	 */
 	mm_writer_lock_nested(mm, SINGLE_DEPTH_NESTING);
-
+	mm->generation = 0;
 	mm->locked_vm = 0;
 	mm->mmap = NULL;
 	mm->mmap_cache = NULL;
Index: mmotm-2.6.32-Nov2/kernel/exit.c
===================================================================
--- mmotm-2.6.32-Nov2.orig/kernel/exit.c
+++ mmotm-2.6.32-Nov2/kernel/exit.c
@@ -645,6 +645,9 @@ static void exit_mm(struct task_struct *
 	struct mm_struct *mm = tsk->mm;
 	struct core_state *core_state;
 
+	if (tsk->vma_cache)
+		vma_put(tsk->vma_cache);
+
 	mm_release(tsk, mm);
 	if (!mm)
 		return;
Index: mmotm-2.6.32-Nov2/fs/exec.c
===================================================================
--- mmotm-2.6.32-Nov2.orig/fs/exec.c
+++ mmotm-2.6.32-Nov2/fs/exec.c
@@ -720,6 +720,10 @@ static int exec_mmap(struct mm_struct *m
 			return -EINTR;
 		}
 	}
+	if (tsk->vma_cache) {
+		vma_put(tsk->vma_cache);
+		tsk->vma_cache = NULL;
+	}
 	task_lock(tsk);
 	active_mm = tsk->active_mm;
 	tsk->mm = mm;
Index: mmotm-2.6.32-Nov2/include/linux/init_task.h
===================================================================
--- mmotm-2.6.32-Nov2.orig/include/linux/init_task.h
+++ mmotm-2.6.32-Nov2/include/linux/init_task.h
@@ -156,6 +156,7 @@ extern struct cred init_cred;
 		 __MUTEX_INITIALIZER(tsk.cred_guard_mutex),		\
 	.comm		= "swapper",					\
 	.thread		= INIT_THREAD,					\
+	.vma_cache	= NULL,						\
 	.fs		= &init_fs,					\
 	.files		= &init_files,					\
 	.signal		= &init_signals,				\

--
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:[~2009-11-13  7:43 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-13  7:35 [RFC MM] speculative page fault KAMEZAWA Hiroyuki
2009-11-13  7:37 ` [RFC MM 1/4] mm accessor (updated) KAMEZAWA Hiroyuki
2009-11-13  7:38 ` [RFC MM 2/4] refcnt for vm_area_struct KAMEZAWA Hiroyuki
2009-11-13  7:40 ` KAMEZAWA Hiroyuki [this message]
2009-11-13 15:27   ` [RFC MM 3/4] add mm version number Minchan Kim
2009-11-13 16:26     ` KAMEZAWA Hiroyuki
2009-11-13  7:41 ` [RFC MM 4/4] speculative page fault KAMEZAWA Hiroyuki
2009-11-13 15:59   ` Minchan Kim
2009-11-13 16:28     ` KAMEZAWA Hiroyuki
2009-11-13 16:20 ` [RFC MM] " Minchan Kim
2009-11-13 16:38   ` KAMEZAWA Hiroyuki

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=20091113164029.e7e8bcea.kamezawa.hiroyu@jp.fujitsu.com \
    --to=kamezawa.hiroyu@jp.fujitsu.com \
    --cc=cl@linux-foundation.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