diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2009-11-23 14:49:36 -0700 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2009-11-23 14:49:36 -0700 |
commit | 2cfcadde83b308240690ff1c18f117d8bc7a08b0 (patch) | |
tree | aa0795966d070d1f7a5221232d9ba47744bddb5f /arch/ia64/mm/tlb.c | |
parent | e91edcf5a2940bb7f1f316c871dfe9e2aaf9d6d9 (diff) | |
parent | 648f4e3e50c4793d9dbf9a09afa193631f76fa26 (diff) | |
download | talos-op-linux-2cfcadde83b308240690ff1c18f117d8bc7a08b0.tar.gz talos-op-linux-2cfcadde83b308240690ff1c18f117d8bc7a08b0.zip |
Merge commit 'v2.6.32-rc8'
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) * this primitive it can be moved up to a spinaphore.h header. */ struct spinaphore { - atomic_t cur; + unsigned long ticket; + unsigned long serve; }; static inline void spinaphore_init(struct spinaphore *ss, int val) { - atomic_set(&ss->cur, val); + ss->ticket = 0; + ss->serve = val; } static inline void down_spin(struct spinaphore *ss) { - while (unlikely(!atomic_add_unless(&ss->cur, -1, 0))) - while (atomic_read(&ss->cur) == 0) - cpu_relax(); + unsigned long t = ia64_fetchadd(1, &ss->ticket, acq), serve; + + if (time_before(t, ss->serve)) + return; + + ia64_invala(); + + for (;;) { + asm volatile ("ld4.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory"); + if (time_before(t, serve)) + return; + cpu_relax(); + } } static inline void up_spin(struct spinaphore *ss) { - atomic_add(1, &ss->cur); + ia64_fetchadd(1, &ss->serve, rel); } static struct spinaphore ptcg_sem; |