diff options
Diffstat (limited to 'arch/powerpc/mm/mmu_context_nohash.c')
-rw-r--r-- | arch/powerpc/mm/mmu_context_nohash.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c index 030d0005b4d2..8343986809c0 100644 --- a/arch/powerpc/mm/mmu_context_nohash.c +++ b/arch/powerpc/mm/mmu_context_nohash.c | |||
@@ -46,7 +46,7 @@ static unsigned int next_context, nr_free_contexts; | |||
46 | static unsigned long *context_map; | 46 | static unsigned long *context_map; |
47 | static unsigned long *stale_map[NR_CPUS]; | 47 | static unsigned long *stale_map[NR_CPUS]; |
48 | static struct mm_struct **context_mm; | 48 | static struct mm_struct **context_mm; |
49 | static spinlock_t context_lock = SPIN_LOCK_UNLOCKED; | 49 | static DEFINE_SPINLOCK(context_lock); |
50 | 50 | ||
51 | #define CTX_MAP_SIZE \ | 51 | #define CTX_MAP_SIZE \ |
52 | (sizeof(unsigned long) * (last_context / BITS_PER_LONG + 1)) | 52 | (sizeof(unsigned long) * (last_context / BITS_PER_LONG + 1)) |
@@ -73,7 +73,6 @@ static unsigned int steal_context_smp(unsigned int id) | |||
73 | struct mm_struct *mm; | 73 | struct mm_struct *mm; |
74 | unsigned int cpu, max; | 74 | unsigned int cpu, max; |
75 | 75 | ||
76 | again: | ||
77 | max = last_context - first_context; | 76 | max = last_context - first_context; |
78 | 77 | ||
79 | /* Attempt to free next_context first and then loop until we manage */ | 78 | /* 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) | |||
108 | spin_unlock(&context_lock); | 107 | spin_unlock(&context_lock); |
109 | cpu_relax(); | 108 | cpu_relax(); |
110 | spin_lock(&context_lock); | 109 | spin_lock(&context_lock); |
111 | goto again; | 110 | |
111 | /* This will cause the caller to try again */ | ||
112 | return MMU_NO_CONTEXT; | ||
112 | } | 113 | } |
113 | #endif /* CONFIG_SMP */ | 114 | #endif /* CONFIG_SMP */ |
114 | 115 | ||
@@ -194,6 +195,8 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next) | |||
194 | WARN_ON(prev->context.active < 1); | 195 | WARN_ON(prev->context.active < 1); |
195 | prev->context.active--; | 196 | prev->context.active--; |
196 | } | 197 | } |
198 | |||
199 | again: | ||
197 | #endif /* CONFIG_SMP */ | 200 | #endif /* CONFIG_SMP */ |
198 | 201 | ||
199 | /* If we already have a valid assigned context, skip all that */ | 202 | /* 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) | |||
212 | #ifdef CONFIG_SMP | 215 | #ifdef CONFIG_SMP |
213 | if (num_online_cpus() > 1) { | 216 | if (num_online_cpus() > 1) { |
214 | id = steal_context_smp(id); | 217 | id = steal_context_smp(id); |
215 | goto stolen; | 218 | if (id == MMU_NO_CONTEXT) |
219 | goto again; | ||
216 | } | 220 | } |
217 | #endif /* CONFIG_SMP */ | 221 | #endif /* CONFIG_SMP */ |
218 | id = steal_context_up(id); | 222 | id = steal_context_up(id); |
@@ -272,6 +276,7 @@ int init_new_context(struct task_struct *t, struct mm_struct *mm) | |||
272 | */ | 276 | */ |
273 | void destroy_context(struct mm_struct *mm) | 277 | void destroy_context(struct mm_struct *mm) |
274 | { | 278 | { |
279 | unsigned long flags; | ||
275 | unsigned int id; | 280 | unsigned int id; |
276 | 281 | ||
277 | if (mm->context.id == MMU_NO_CONTEXT) | 282 | if (mm->context.id == MMU_NO_CONTEXT) |
@@ -279,18 +284,18 @@ void destroy_context(struct mm_struct *mm) | |||
279 | 284 | ||
280 | WARN_ON(mm->context.active != 0); | 285 | WARN_ON(mm->context.active != 0); |
281 | 286 | ||
282 | spin_lock(&context_lock); | 287 | spin_lock_irqsave(&context_lock, flags); |
283 | id = mm->context.id; | 288 | id = mm->context.id; |
284 | if (id != MMU_NO_CONTEXT) { | 289 | if (id != MMU_NO_CONTEXT) { |
285 | __clear_bit(id, context_map); | 290 | __clear_bit(id, context_map); |
286 | mm->context.id = MMU_NO_CONTEXT; | 291 | mm->context.id = MMU_NO_CONTEXT; |
287 | #ifdef DEBUG_MAP_CONSISTENCY | 292 | #ifdef DEBUG_MAP_CONSISTENCY |
288 | mm->context.active = 0; | 293 | mm->context.active = 0; |
289 | context_mm[id] = NULL; | ||
290 | #endif | 294 | #endif |
295 | context_mm[id] = NULL; | ||
291 | nr_free_contexts++; | 296 | nr_free_contexts++; |
292 | } | 297 | } |
293 | spin_unlock(&context_lock); | 298 | spin_unlock_irqrestore(&context_lock, flags); |
294 | } | 299 | } |
295 | 300 | ||
296 | #ifdef CONFIG_SMP | 301 | #ifdef CONFIG_SMP |