diff options
Diffstat (limited to 'arch/ia64/mm/tlb.c')
| -rw-r--r-- | arch/ia64/mm/tlb.c | 33 | 
1 files changed, 18 insertions, 15 deletions
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index 39628fca274c..41105d454423 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c  | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | 29 | ||
| 30 | static struct { | 30 | static struct { | 
| 31 | unsigned long mask; /* mask of supported purge page-sizes */ | 31 | unsigned long mask; /* mask of supported purge page-sizes */ | 
| 32 | unsigned long max_bits; /* log2() of largest supported purge page-size */ | 32 | unsigned long max_bits; /* log2 of largest supported purge page-size */ | 
| 33 | } purge; | 33 | } purge; | 
| 34 | 34 | ||
| 35 | struct ia64_ctx ia64_ctx = { | 35 | struct ia64_ctx ia64_ctx = { | 
| @@ -58,7 +58,7 @@ mmu_context_init (void) | |||
| 58 | void | 58 | void | 
| 59 | wrap_mmu_context (struct mm_struct *mm) | 59 | wrap_mmu_context (struct mm_struct *mm) | 
| 60 | { | 60 | { | 
| 61 | int i; | 61 | int i, cpu; | 
| 62 | unsigned long flush_bit; | 62 | unsigned long flush_bit; | 
| 63 | 63 | ||
| 64 | for (i=0; i <= ia64_ctx.max_ctx / BITS_PER_LONG; i++) { | 64 | for (i=0; i <= ia64_ctx.max_ctx / BITS_PER_LONG; i++) { | 
| @@ -72,20 +72,21 @@ wrap_mmu_context (struct mm_struct *mm) | |||
| 72 | ia64_ctx.limit = find_next_bit(ia64_ctx.bitmap, | 72 | ia64_ctx.limit = find_next_bit(ia64_ctx.bitmap, | 
| 73 | ia64_ctx.max_ctx, ia64_ctx.next); | 73 | ia64_ctx.max_ctx, ia64_ctx.next); | 
| 74 | 74 | ||
| 75 | /* can't call flush_tlb_all() here because of race condition with O(1) scheduler [EF] */ | 75 | /* | 
| 76 | { | 76 | * can't call flush_tlb_all() here because of race condition | 
| 77 | int cpu = get_cpu(); /* prevent preemption/migration */ | 77 | * with O(1) scheduler [EF] | 
| 78 | for_each_online_cpu(i) { | 78 | */ | 
| 79 | if (i != cpu) | 79 | cpu = get_cpu(); /* prevent preemption/migration */ | 
| 80 | per_cpu(ia64_need_tlb_flush, i) = 1; | 80 | for_each_online_cpu(i) | 
| 81 | } | 81 | if (i != cpu) | 
| 82 | put_cpu(); | 82 | per_cpu(ia64_need_tlb_flush, i) = 1; | 
| 83 | } | 83 | put_cpu(); | 
| 84 | local_flush_tlb_all(); | 84 | local_flush_tlb_all(); | 
| 85 | } | 85 | } | 
| 86 | 86 | ||
| 87 | void | 87 | void | 
| 88 | ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long nbits) | 88 | ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, | 
| 89 | unsigned long end, unsigned long nbits) | ||
| 89 | { | 90 | { | 
| 90 | static DEFINE_SPINLOCK(ptcg_lock); | 91 | static DEFINE_SPINLOCK(ptcg_lock); | 
| 91 | 92 | ||
| @@ -133,7 +134,8 @@ local_flush_tlb_all (void) | |||
| 133 | } | 134 | } | 
| 134 | 135 | ||
| 135 | void | 136 | void | 
| 136 | flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end) | 137 | flush_tlb_range (struct vm_area_struct *vma, unsigned long start, | 
| 138 | unsigned long end) | ||
| 137 | { | 139 | { | 
| 138 | struct mm_struct *mm = vma->vm_mm; | 140 | struct mm_struct *mm = vma->vm_mm; | 
| 139 | unsigned long size = end - start; | 141 | unsigned long size = end - start; | 
| @@ -147,7 +149,8 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long | |||
| 147 | #endif | 149 | #endif | 
| 148 | 150 | ||
| 149 | nbits = ia64_fls(size + 0xfff); | 151 | nbits = ia64_fls(size + 0xfff); | 
| 150 | while (unlikely (((1UL << nbits) & purge.mask) == 0) && (nbits < purge.max_bits)) | 152 | while (unlikely (((1UL << nbits) & purge.mask) == 0) && | 
| 153 | (nbits < purge.max_bits)) | ||
| 151 | ++nbits; | 154 | ++nbits; | 
| 152 | if (nbits > purge.max_bits) | 155 | if (nbits > purge.max_bits) | 
| 153 | nbits = purge.max_bits; | 156 | nbits = purge.max_bits; | 
| @@ -189,5 +192,5 @@ ia64_tlb_init (void) | |||
| 189 | local_cpu_data->ptce_stride[0] = ptce_info.stride[0]; | 192 | local_cpu_data->ptce_stride[0] = ptce_info.stride[0]; | 
| 190 | local_cpu_data->ptce_stride[1] = ptce_info.stride[1]; | 193 | local_cpu_data->ptce_stride[1] = ptce_info.stride[1]; | 
| 191 | 194 | ||
| 192 | local_flush_tlb_all(); /* nuke left overs from bootstrapping... */ | 195 | local_flush_tlb_all(); /* nuke left overs from bootstrapping... */ | 
| 193 | } | 196 | } | 
