diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-04-25 15:02:35 +0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-04-25 15:02:35 +0400 |
commit | 2fc565e4eaf8fc633bfc741b90e1f28dba732ee1 (patch) | |
tree | 98c994692f84aee07cf1c7b4cda245ae5235a94d /arch/sparc/mm/tlb.c | |
parent | 7fc7d047216aa4923d401c637be2ebc6e3d5bd9b (diff) | |
parent | 5cc50fc858a5ab37dc2744d72d7ffed96f23afd8 (diff) | |
download | linux-2fc565e4eaf8fc633bfc741b90e1f28dba732ee1.tar.xz |
Merge tag 'asoc-v3.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: More updates for v3.10
A few more fixes, nothing too major though the DMA changes fix modular
builds.
Diffstat (limited to 'arch/sparc/mm/tlb.c')
-rw-r--r-- | arch/sparc/mm/tlb.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c index ba6ae7ffdc2c..272aa4f7657e 100644 --- a/arch/sparc/mm/tlb.c +++ b/arch/sparc/mm/tlb.c @@ -24,11 +24,17 @@ static DEFINE_PER_CPU(struct tlb_batch, tlb_batch); void flush_tlb_pending(void) { struct tlb_batch *tb = &get_cpu_var(tlb_batch); + struct mm_struct *mm = tb->mm; - if (tb->tlb_nr) { - flush_tsb_user(tb); + if (!tb->tlb_nr) + goto out; - if (CTX_VALID(tb->mm->context)) { + flush_tsb_user(tb); + + if (CTX_VALID(mm->context)) { + if (tb->tlb_nr == 1) { + global_flush_tlb_page(mm, tb->vaddrs[0]); + } else { #ifdef CONFIG_SMP smp_flush_tlb_pending(tb->mm, tb->tlb_nr, &tb->vaddrs[0]); @@ -37,12 +43,30 @@ void flush_tlb_pending(void) tb->tlb_nr, &tb->vaddrs[0]); #endif } - tb->tlb_nr = 0; } + tb->tlb_nr = 0; + +out: put_cpu_var(tlb_batch); } +void arch_enter_lazy_mmu_mode(void) +{ + struct tlb_batch *tb = &__get_cpu_var(tlb_batch); + + tb->active = 1; +} + +void arch_leave_lazy_mmu_mode(void) +{ + struct tlb_batch *tb = &__get_cpu_var(tlb_batch); + + if (tb->tlb_nr) + flush_tlb_pending(); + tb->active = 0; +} + static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, bool exec) { @@ -60,6 +84,12 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, nr = 0; } + if (!tb->active) { + global_flush_tlb_page(mm, vaddr); + flush_tsb_user_page(mm, vaddr); + return; + } + if (nr == 0) tb->mm = mm; |