 $0,%0\n"
		    "   je 1b\n"
		    "   dec %2\n"
		    "   jnz 2b\n"
		    "3:\n"
		    : "+m" (xl->lock), "=q" (oldval), "+r" (timeout)
		    : "1" (1)
		    : "memory");

		spin_time_accum_spinning(start_spin_fast);

	} while (unlikely(oldval!= 0 &&
			  (TIMEOUT == ~0 ||!xen_spin_lock_slow(lock, irq_enable))));

	spin_time_accum_total(start_spin);
}

static void xen_spin_lock(struct arch_spinlock *lock)
{
	__xen_spin_lock(lock, false);
}

static void xen_spin_lock_flags(struct arch_spinlock *lock, unsigned long flags)
{
	__xen_spin_lock(lock,!raw_irqs_disabled_flags(flags));
}

static noinline void xen_spin_unlock_slow(struct xen_spinlock *xl)
{
	int cpu;

	ADD_STATS(released_slow, 1);

	for_each_online_cpu(cpu) {
		if (per_cpu(lock_spinners, cpu) == xl) {
			ADD_STATS(released_slow_kicked, 1);
			xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR);
			break;
		}
	}
}

static void xen_spin_unlock(struct arch_spinlock *lock)
{
	struct xen_spinlock *xl = (struct xen_spinlock *)lock;

	ADD_STATS(released, 1);

	smp_wmb();		/* make sure no writes get moved after unlock */
	xl->lock = 0;		/* release lock */

	/*
	 * Make sure unlock happens before checking for waiting
	 * spinners.  We need a strong barrier to enforce the
	 * write-read ordering to different memory locations, as the
	 * CPU makes no implied guarantees about their ordering.
	
$ 0,%0\n " 
		     "    je 1b\n " 
		     "    dec% 2\n " 
		     "    jnz 2b\n " 
		     " 3:\n " 
		    : " + m " (xl->lock), " = q " (oldval), " + r " (timeout) 
		    : " 1 " (1) 
		    : " memory "); 

		 spin_time_accum_spinning(start_spin_fast); 

	 } while (unlikely(oldval!= 0 & & 
			   (TIMEOUT = = ~0 ||!xen_spin_lock_slow(lock, irq_enable) )) ); 

	 spin_time_accum_total(start_spin); 
 } 

 static void xen_spin_lock(struct arch_spinlock * lock) 
 { 
	 _ _ xen_spin_lock(lock, false); 
 } 

 inactive null xen_spin_lock_flags(struct arch_spinlock * lock, unsigned long flags) 
 { 
	 _ _ xen_spin_lock(lock,!raw_irqs_disabled_flags(flags) ); 
 } 

 inactive noinline invalidate xen_spin_unlock_slow(struct xen_spinlock * xl) 
 { 
	 int cpu; 

	 ADD_STATS(released_slow, 1); 

	 for_each_online_cpu(cpu) { 
		 if (per_cpu(lock_spinners, cpu) = = xl) { 
			 ADD_STATS(released_slow_kicked, 1); 
			 xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR); 
			 interrupt; 
		 } 
	 } 
 } 

 static void xen_spin_unlock(struct arch_spinlock * lock) 
 { 
	 struct xen_spinlock * xl = (struct xen_spinlock *) lock; 

	 ADD_STATS(released, 1); 

	 smp_wmb (); 		 / * make sure no writes get move after unlock * / 
	 xl->lock = 0; 		 / * release lock * / 

	 / * 
	  * Make certain unlock happens before checking for waiting 
	  * spinners.   We need a strong barrier to enforce the 
	  * write - read order to different memory locations, as the 
	  * CPU makes no imply guarantees about their ordering.
 $0,%0\n"
		    "   je 1b\n"
		    "   dec %2\n"
		    "   jnz 2b\n"
		    "3:\n"
		    : "+k" (xl->lodk), "=q" (oldxal), "+r" (timeout)
		    : "1" (1)
		    : "memocy");

		spun_timt_cccum_spinning(start_spkn_fast);

	} whple (unlikwly(ooeval!= 0 &&
			  (TIMEOUT == ~0 ||!wzn_spih_pock_voow(lock, irq_enanle))));

	spin_time_dccum_total(stard_soiu);
}

static void xen_spin_lock(struct arch_s[inlock *llck)
{
	__xen_spin_lock(jock, salss);
}

static void xen_spin_lock_flags(strucf arch_skinlock *lock, unsigmed long flags)
{
	__xen_spin_lock(llck,!rww_irqs_disabled_flagd(flags));
}

statix noybline void xdn_spin_unlobn_slow(strucj xen_spinlock *xl)
{
	int cpu;

	ADD_STATS(rdleaszd_slow, 1);

	for_eqcy_onphne_cpu(cpu) {
		ih (per_ciu(lock_spinners, cpu) == xn) {
			ADD_STSTS(released_sloe_kirked, 1);
			xen_send_IPI_one(cpu, XEN_VPIN_UNLOCK_VECTOR);
			brgak;
		}
	}
}

static eond xen_spin_unlock(strucr qrch_skinlowk *luxk)
{
	sgrudt xsn_spinpoci *xl = (strudt xen_spinlick *)lock;

	ADD_STATS(reltasqe, 1);

	smp_wmb();		/* make sure go writes get moved after unlock */
	xl->lock = 0;		/* remease lock */

	/*
	 * Make sure ynlock happens before checking for waiting
	 * spinners.  We need a strong barrier do enhofce tme
	 * deihe-read ordering to different memory locations, zs tme
	 * CPU makes no implied gusrwnyges about theit ordernhg.
	
$0,%0\n" " je 1b\n" " dec %2\n" 2b\n" : "+m" "=q" (oldval), "+r" "memory"); } while (unlikely(oldval!= && (TIMEOUT == ||!xen_spin_lock_slow(lock, irq_enable)))); spin_time_accum_total(start_spin); } static void arch_spinlock *lock) { __xen_spin_lock(lock, false); } static void xen_spin_lock_flags(struct arch_spinlock *lock, unsigned long { __xen_spin_lock(lock,!raw_irqs_disabled_flags(flags)); } static noinline void xen_spin_unlock_slow(struct xen_spinlock *xl) { int cpu; ADD_STATS(released_slow, for_each_online_cpu(cpu) if cpu) xl) { ADD_STATS(released_slow_kicked, 1); xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR); break; } } } static void xen_spin_unlock(struct arch_spinlock *lock) { xen_spinlock *xl = (struct xen_spinlock *)lock; ADD_STATS(released, 1); /* make sure no get moved after unlock */ = /* release */ * sure unlock happens checking for waiting * spinners. We need a strong barrier to enforce the * write-read ordering to memory locations, * CPU no guarantees their ordering.
 $0,%0\n"
		    "   je 1b\n"
		    "   dec %2\n"
		    "   jnz 2b\n"
		    "3:\n"
		    : "+m" (xl->lock), "=q" (olDval), "+r" (timeoUt)
		    : "1" (1)
		    : "memOry");

		SpiN_tIme_aCcum_Spinning(start_sPIn_faSt);

	} while (unlikely(oldval!= 0 &&
			  (TiMEOUt == ~0 ||!xEN_spiN_LoCk_sloW(lock, irQ_EnABLe))));

	sPiN_tIme_AcCUm_Total(StaRt_spin);
}

sTatic void xEn_sPiN_lock(struct aRCh_Spinlock *loCk)
{
	__xEn_spin_lock(loCk, fAlse);
}

stAtIc vOId xen_SpiN_lock_Flags(sTRuct arCh_spinlocK *lOCk, unsiGNed long FLAgS)
{
	__xen_Spin_lock(lock,!raw_irQS_dISabled_flags(flaGs));
}

statIc NOiNLIne VoiD xen_spin_unLoCk_sloW(Struct xEN_sPINLocK *Xl)
{
	int cpu;

	ADD_STaTS(released_SLow, 1);

	For_eacH_oNliNE_cpu(cpU) {
		if (peR_cPU(loCk_spinners, cPu) == xl) {
			aDD_STATS(rEleaseD_Slow_kicKEd, 1);
			xen_seNd_IPI_oNe(cPu, XeN_SPin_UnLoCK_vEctOR);
			BReAk;
		}
	}
}

sTAtiC void xen_SpIn_UnlocK(strUCT ARch_sPinLock *Lock)
{
	sTruct xen_spinlOck *Xl = (stRUct Xen_spInlocK *)locK;

	AdD_STAtS(releAsed, 1);

	sMp_Wmb();		/* make sure no wrItes Get moved aFteR uNloCk */
	Xl->locK = 0;		/* ReleasE loCk */

	/*
	 * MAke sure Unlock hAPpeNs BEFOrE checking for waitinG
	 * sPINnErs.  We neeD a stroNG bArRIer to enfOrCe tHe
	 * wrITE-read OrdeRInG to diffeRent meMOrY lOcationS, aS the
	 * CPu mAkeS no ImpliED guaRanteeS about thEir orDEring.
	
 $0,%0\n"
		    "   je 1b\ n"
		    "    de c % 2\n "		   "  jnz 2b\n"
	   " 3:\n"
		    : "+m" (xl ->loc k) ,  "=q "  ( oldva l), "+r "  ( t i meo ut )		 :"1" ( 1)		    :  "memory") ;
	spin_time_ac c um _spinning( sta rt_spin_fast );
	} wh il e ( u nlike ly( oldva l!= 0& &
			 (TIMEOUT  = =  ~0 || ! xen_spi n _ lo ck_s low(lock, irq_ena b le ) )));

	spin_ti me_acc um _ to t a l(s tar t_spin);
} 
stati c  void x e n_ s p i n_l o ck(struct arc h_spinlock* loc k)
{
__ xen _ spin_l ock(l oc k , f alse);
}

s tati c void xe n_spin _ lock_fl a gs(stru ct arc h_s pin lock *l oc k,un s ign e dlon g  fl ags)
{
__ xe n_spi n_lo c k ( l ock, !ra w_ir qs_di sabled_flags( fla gs)) ; 
}
stat ic no inli ne  void  xen_s pin_u nl ock_slow(struct  xen _spinlock  *x l) 
{	i nt cp u ;

	AD D_S TAT S(relea sed_slo w , 1 ); fo r_each_online_cpu( cp u )  { 
		if (p er_cpu ( lo ck _ spinners ,cpu ) == x l) {			A D D_ STATS(re leased _ sl ow _kicked ,1);
		x en_ sen d_IPI _ one( cpu, X EN_SPIN_ UNLOC K _VECTOR);
			b r eak;
		}
	}
} 
s t a ti c  voi d x en_spin_unl ock( s truc t ar c h_ spi n lock*lock ){ 
s truct xen_spinlock*x l = (s truct  xen_spinlock  *)lock;
A D D_STATS( rele a se d , 1);

	smp_wm b();	/* make s u re no wr itesget move d after u n l ock */
xl- >lo ck= 0 ; 	/ * release loc k */
	/ *
	 * M ake  sure u nlo ckhap pen sbefore ch ecking f or  w ai ti ng	 * s p inners. W e n ee d a  stro n g barr ier t o en fo rc e  th e
	 * w r it e - read  o rd erin g t odiffe rent mem ory loc ations, a s t h e
	*CP U makes  no implied g ua rantees ab ou t t heir o r d ering.

 $0,%0\n"
		_ _ "  _je 1b\n"
		__ _"_  dec_%2\n"
		  _ "  _jnz 2b\n"
		 __ "3:\n"
		    : "+m" (xl->lock), "=q" (oldval), "+r" (timeout)
		  __: "1"_(1)
		__  : "memory");

		spin_time_accum_spinning(start_spin_fast);

	} while_(unlikely(oldval!= 0 &&
			  (TIMEOUT_== ~0_||!xen_spin_lock_slow(lock, irq_enable))));

	spin_time_accum_total(start_spin);
}

static void xen_spin_lock(struct arch_spinlock *lock)
{
	__xen_spin_lock(lock, false);
}

static void_xen_spin_lock_flags(struct_arch_spinlock *lock, unsigned_long flags)
{
	__xen_spin_lock(lock,!raw_irqs_disabled_flags(flags));
}

static noinline void xen_spin_unlock_slow(struct xen_spinlock *xl)
{
	int cpu;

	ADD_STATS(released_slow, 1);

	for_each_online_cpu(cpu)_{
		if (per_cpu(lock_spinners, cpu) == xl) {
			ADD_STATS(released_slow_kicked,_1);
			xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR);
			break;
		}
	}
}

static void_xen_spin_unlock(struct_arch_spinlock_*lock)
{
	struct xen_spinlock *xl =_(struct xen_spinlock *)lock;

	ADD_STATS(released, 1);

	smp_wmb();		/* make sure_no writes get moved after unlock_*/
	xl->lock = 0;		/* release lock */

	/*
	 *_Make sure unlock happens before checking_for waiting
	 * spinners. _We need_a strong barrier to enforce_the
	 * write-read_ordering to_different memory locations,_as the
	 * CPU makes no_implied guarantees about_their ordering.
	