diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-11-06 02:00:48 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-11-06 02:00:48 -0500 |
commit | 02cee68998010c4a2cc2383c86babc2ecc737183 (patch) | |
tree | 13c6483472f672c3b2570b075ed2ad4fd4c5405e /arch/ia64/mm/tlb.c | |
parent | f5ba35023697e54a24487bcd822194390a333893 (diff) | |
parent | b419148e567728f6af0c3b01965c1cc141e3e13a (diff) |
Merge commit 'v2.6.32-rc6' into next
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; |