diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-11-04 11:54:15 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-11-04 11:59:45 +0100 |
commit | a2e71271535fde493c32803b1f34789f97efcb5e (patch) | |
tree | 90d7139bea2f49e947f27af92614fa6eca50b64d /arch/ia64/mm | |
parent | 6d7aa9d721c8c640066142fd9534afcdf68d7f9d (diff) | |
parent | b419148e567728f6af0c3b01965c1cc141e3e13a (diff) |
Merge commit 'v2.6.32-rc6' into perf/core
Conflicts:
tools/perf/Makefile
Merge reason: Resolve the conflict, merge to upstream and merge in
perf fixes so we can add a dependent patch.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/ia64/mm')
-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 f426dc78d95..ee09d261f2e 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; |