|
@@ -116,9 +116,26 @@ static inline void spin_time_accum_blocked(u64 start)
|
|
|
}
|
|
|
#endif /* CONFIG_XEN_DEBUG_FS */
|
|
|
|
|
|
+/*
|
|
|
+ * Size struct xen_spinlock so it's the same as arch_spinlock_t.
|
|
|
+ */
|
|
|
+#if NR_CPUS < 256
|
|
|
+typedef u8 xen_spinners_t;
|
|
|
+# define inc_spinners(xl) \
|
|
|
+ asm(LOCK_PREFIX " incb %0" : "+m" ((xl)->spinners) : : "memory");
|
|
|
+# define dec_spinners(xl) \
|
|
|
+ asm(LOCK_PREFIX " decb %0" : "+m" ((xl)->spinners) : : "memory");
|
|
|
+#else
|
|
|
+typedef u16 xen_spinners_t;
|
|
|
+# define inc_spinners(xl) \
|
|
|
+ asm(LOCK_PREFIX " incw %0" : "+m" ((xl)->spinners) : : "memory");
|
|
|
+# define dec_spinners(xl) \
|
|
|
+ asm(LOCK_PREFIX " decw %0" : "+m" ((xl)->spinners) : : "memory");
|
|
|
+#endif
|
|
|
+
|
|
|
struct xen_spinlock {
|
|
|
unsigned char lock; /* 0 -> free; 1 -> locked */
|
|
|
- unsigned short spinners; /* count of waiting cpus */
|
|
|
+ xen_spinners_t spinners; /* count of waiting cpus */
|
|
|
};
|
|
|
|
|
|
static int xen_spin_is_locked(struct arch_spinlock *lock)
|
|
@@ -164,8 +181,7 @@ static inline struct xen_spinlock *spinning_lock(struct xen_spinlock *xl)
|
|
|
|
|
|
wmb(); /* set lock of interest before count */
|
|
|
|
|
|
- asm(LOCK_PREFIX " incw %0"
|
|
|
- : "+m" (xl->spinners) : : "memory");
|
|
|
+ inc_spinners(xl);
|
|
|
|
|
|
return prev;
|
|
|
}
|
|
@@ -176,8 +192,7 @@ static inline struct xen_spinlock *spinning_lock(struct xen_spinlock *xl)
|
|
|
*/
|
|
|
static inline void unspinning_lock(struct xen_spinlock *xl, struct xen_spinlock *prev)
|
|
|
{
|
|
|
- asm(LOCK_PREFIX " decw %0"
|
|
|
- : "+m" (xl->spinners) : : "memory");
|
|
|
+ dec_spinners(xl);
|
|
|
wmb(); /* decrement count before restoring lock */
|
|
|
__this_cpu_write(lock_spinners, prev);
|
|
|
}
|
|
@@ -373,6 +388,8 @@ void xen_uninit_lock_cpu(int cpu)
|
|
|
|
|
|
void __init xen_init_spinlocks(void)
|
|
|
{
|
|
|
+ BUILD_BUG_ON(sizeof(struct xen_spinlock) > sizeof(arch_spinlock_t));
|
|
|
+
|
|
|
pv_lock_ops.spin_is_locked = xen_spin_is_locked;
|
|
|
pv_lock_ops.spin_is_contended = xen_spin_is_contended;
|
|
|
pv_lock_ops.spin_lock = xen_spin_lock;
|