X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=arch%2Fpowerpc%2Fmm%2Fmmu_context_nohash.c;h=c42858780cbd239565289bb572b5cbf2198744e2;hb=3035c8634f0538a0c6946e3191bb6c9284b63798;hp=a70e311bd457d83991895b2a519411f9ead6499d;hpb=e4c393fd551654179c46b65e4a70ea20d831c783;p=deliverable%2Flinux.git diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c index a70e311bd457..c42858780cbd 100644 --- a/arch/powerpc/mm/mmu_context_nohash.c +++ b/arch/powerpc/mm/mmu_context_nohash.c @@ -73,7 +73,6 @@ static unsigned int steal_context_smp(unsigned int id) struct mm_struct *mm; unsigned int cpu, max; - again: max = last_context - first_context; /* Attempt to free next_context first and then loop until we manage */ @@ -108,7 +107,9 @@ static unsigned int steal_context_smp(unsigned int id) spin_unlock(&context_lock); cpu_relax(); spin_lock(&context_lock); - goto again; + + /* This will cause the caller to try again */ + return MMU_NO_CONTEXT; } #endif /* CONFIG_SMP */ @@ -127,12 +128,12 @@ static unsigned int steal_context_up(unsigned int id) pr_debug("[%d] steal context %d from mm @%p\n", cpu, id, mm); - /* Mark this mm has having no context anymore */ - mm->context.id = MMU_NO_CONTEXT; - /* Flush the TLB for that context */ local_flush_tlb_mm(mm); + /* Mark this mm has having no context anymore */ + mm->context.id = MMU_NO_CONTEXT; + /* XXX This clear should ultimately be part of local_flush_tlb_mm */ __clear_bit(id, stale_map[cpu]); @@ -194,6 +195,8 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next) WARN_ON(prev->context.active < 1); prev->context.active--; } + + again: #endif /* CONFIG_SMP */ /* If we already have a valid assigned context, skip all that */ @@ -212,7 +215,8 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next) #ifdef CONFIG_SMP if (num_online_cpus() > 1) { id = steal_context_smp(id); - goto stolen; + if (id == MMU_NO_CONTEXT) + goto again; } #endif /* CONFIG_SMP */ id = steal_context_up(id); @@ -286,8 +290,8 @@ void destroy_context(struct mm_struct *mm) mm->context.id = MMU_NO_CONTEXT; #ifdef DEBUG_MAP_CONSISTENCY mm->context.active = 0; - context_mm[id] = NULL; #endif + context_mm[id] = NULL; nr_free_contexts++; } spin_unlock(&context_lock);