diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2009-12-01 10:16:22 +0300 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2009-12-01 10:16:22 +0300 |
commit | 838632438145ac6863377eb12d8b8eef9c55d288 (patch) | |
tree | fbb0757df837f3c75a99c518a3596c38daef162d /mm/mmu_context.c | |
parent | 9996508b3353063f2d6c48c1a28a84543d72d70b (diff) | |
parent | 29e553631b2a0d4eebd23db630572e1027a9967a (diff) | |
download | linux-838632438145ac6863377eb12d8b8eef9c55d288.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'mm/mmu_context.c')
-rw-r--r-- | mm/mmu_context.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/mm/mmu_context.c b/mm/mmu_context.c new file mode 100644 index 000000000000..ded9081f4021 --- /dev/null +++ b/mm/mmu_context.c @@ -0,0 +1,58 @@ +/* Copyright (C) 2009 Red Hat, Inc. + * + * See ../COPYING for licensing terms. + */ + +#include <linux/mm.h> +#include <linux/mmu_context.h> +#include <linux/sched.h> + +#include <asm/mmu_context.h> + +/* + * use_mm + * Makes the calling kernel thread take on the specified + * mm context. + * Called by the retry thread execute retries within the + * iocb issuer's mm context, so that copy_from/to_user + * operations work seamlessly for aio. + * (Note: this routine is intended to be called only + * from a kernel thread context) + */ +void use_mm(struct mm_struct *mm) +{ + struct mm_struct *active_mm; + struct task_struct *tsk = current; + + task_lock(tsk); + active_mm = tsk->active_mm; + if (active_mm != mm) { + atomic_inc(&mm->mm_count); + tsk->active_mm = mm; + } + tsk->mm = mm; + switch_mm(active_mm, mm, tsk); + task_unlock(tsk); + + if (active_mm != mm) + mmdrop(active_mm); +} + +/* + * unuse_mm + * Reverses the effect of use_mm, i.e. releases the + * specified mm context which was earlier taken on + * by the calling kernel thread + * (Note: this routine is intended to be called only + * from a kernel thread context) + */ +void unuse_mm(struct mm_struct *mm) +{ + struct task_struct *tsk = current; + + task_lock(tsk); + tsk->mm = NULL; + /* active_mm is still 'mm' */ + enter_lazy_tlb(mm, tsk); + task_unlock(tsk); +} |