diff options
Diffstat (limited to 'arch/ia64/mm/tlb.c')
| -rw-r--r-- | arch/ia64/mm/tlb.c | 24 | 
1 files changed, 18 insertions, 6 deletions
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index f426dc78d959..ee09d261f2e6 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c  | |||
| @@ -100,24 +100,36 @@ wrap_mmu_context (struct mm_struct *mm) | |||
| 100 | * this primitive it can be moved up to a spinaphore.h header. | 100 | * this primitive it can be moved up to a spinaphore.h header. | 
| 101 | */ | 101 | */ | 
| 102 | struct spinaphore { | 102 | struct spinaphore { | 
| 103 | atomic_t cur; | 103 | unsigned long ticket; | 
| 104 | unsigned long serve; | ||
| 104 | }; | 105 | }; | 
| 105 | 106 | ||
| 106 | static inline void spinaphore_init(struct spinaphore *ss, int val) | 107 | static inline void spinaphore_init(struct spinaphore *ss, int val) | 
| 107 | { | 108 | { | 
| 108 | atomic_set(&ss->cur, val); | 109 | ss->ticket = 0; | 
| 110 | ss->serve = val; | ||
| 109 | } | 111 | } | 
| 110 | 112 | ||
| 111 | static inline void down_spin(struct spinaphore *ss) | 113 | static inline void down_spin(struct spinaphore *ss) | 
| 112 | { | 114 | { | 
| 113 | while (unlikely(!atomic_add_unless(&ss->cur, -1, 0))) | 115 | unsigned long t = ia64_fetchadd(1, &ss->ticket, acq), serve; | 
| 114 | while (atomic_read(&ss->cur) == 0) | 116 | |
| 115 | cpu_relax(); | 117 | if (time_before(t, ss->serve)) | 
| 118 | return; | ||
| 119 | |||
| 120 | ia64_invala(); | ||
| 121 | |||
| 122 | for (;;) { | ||
| 123 | asm volatile ("ld4.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory"); | ||
| 124 | if (time_before(t, serve)) | ||
| 125 | return; | ||
| 126 | cpu_relax(); | ||
| 127 | } | ||
| 116 | } | 128 | } | 
| 117 | 129 | ||
| 118 | static inline void up_spin(struct spinaphore *ss) | 130 | static inline void up_spin(struct spinaphore *ss) | 
| 119 | { | 131 | { | 
| 120 | atomic_add(1, &ss->cur); | 132 | ia64_fetchadd(1, &ss->serve, rel); | 
| 121 | } | 133 | } | 
| 122 | 134 | ||
| 123 | static struct spinaphore ptcg_sem; | 135 | static struct spinaphore ptcg_sem; | 
