summaryrefslogtreecommitdiff
path: root/arch/ia64/mm/tlb.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-11-19 06:19:03 (GMT)
committerDavid S. Miller <davem@davemloft.net>2009-11-19 06:19:03 (GMT)
commit3505d1a9fd65e2d3e00827857b6795d9d8983658 (patch)
tree941cfafdb57c427bb6b7ebf6354ee93b2a3693b5 /arch/ia64/mm/tlb.c
parentdfef948ed2ba69cf041840b5e860d6b4e16fa0b1 (diff)
parent66b00a7c93ec782d118d2c03bd599cfd041e80a1 (diff)
downloadlinux-fsl-qoriq-3505d1a9fd65e2d3e00827857b6795d9d8983658.tar.xz
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/sfc/sfe4001.c drivers/net/wireless/libertas/cmd.c drivers/staging/Kconfig drivers/staging/Makefile drivers/staging/rtl8187se/Kconfig drivers/staging/rtl8192e/Kconfig
Diffstat (limited to 'arch/ia64/mm/tlb.c')
-rw-r--r--arch/ia64/mm/tlb.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
index f426dc7..ee09d26 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;