| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #ifndef __ARCH_S390_PERCPU__
 | 
					
						
							|  |  |  | #define __ARCH_S390_PERCPU__
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-23 10:24:32 +02:00
										 |  |  | #include <linux/preempt.h>
 | 
					
						
							|  |  |  | #include <asm/cmpxchg.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * s390 uses its own implementation for per cpu data, the offset of | 
					
						
							|  |  |  |  * the cpu local data area is cached in the cpu's lowcore memory. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-06-24 15:13:53 +09:00
										 |  |  | #define __my_cpu_offset S390_lowcore.percpu_offset
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-21 07:44:08 +02:00
										 |  |  | #ifdef CONFIG_64BIT
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-24 15:13:53 +09:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * For 64 bit module code, the module may be more than 4G above the | 
					
						
							|  |  |  |  * per cpu area, use weak definitions to force the compiler to | 
					
						
							|  |  |  |  * generate external references. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-10-21 07:44:08 +02:00
										 |  |  | #if defined(CONFIG_SMP) && defined(MODULE)
 | 
					
						
							| 
									
										
										
										
											2009-06-24 15:13:53 +09:00
										 |  |  | #define ARCH_NEEDS_WEAK_PER_CPU
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-21 07:57:41 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * We use a compare-and-swap loop since that uses less cpu cycles than | 
					
						
							|  |  |  |  * disabling and enabling interrupts like the generic variant would do. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define arch_this_cpu_to_op_simple(pcp, val, op)			\
 | 
					
						
							| 
									
										
										
										
											2012-09-17 06:46:55 +02:00
										 |  |  | ({									\ | 
					
						
							| 
									
										
										
										
											2011-05-23 10:24:32 +02:00
										 |  |  | 	typedef typeof(pcp) pcp_op_T__;					\ | 
					
						
							|  |  |  | 	pcp_op_T__ old__, new__, prev__;				\ | 
					
						
							|  |  |  | 	pcp_op_T__ *ptr__;						\ | 
					
						
							|  |  |  | 	preempt_disable();						\ | 
					
						
							|  |  |  | 	ptr__ = __this_cpu_ptr(&(pcp));					\ | 
					
						
							|  |  |  | 	prev__ = *ptr__;						\ | 
					
						
							|  |  |  | 	do {								\ | 
					
						
							|  |  |  | 		old__ = prev__;						\ | 
					
						
							|  |  |  | 		new__ = old__ op (val);					\ | 
					
						
							| 
									
										
										
										
											2013-10-21 07:44:08 +02:00
										 |  |  | 		prev__ = cmpxchg(ptr__, old__, new__);			\ | 
					
						
							| 
									
										
										
										
											2011-05-23 10:24:32 +02:00
										 |  |  | 	} while (prev__ != old__);					\ | 
					
						
							|  |  |  | 	preempt_enable();						\ | 
					
						
							| 
									
										
										
										
											2012-09-17 06:46:55 +02:00
										 |  |  | 	new__;								\ | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2011-05-23 10:24:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-21 07:57:41 +02:00
										 |  |  | #define this_cpu_add_1(pcp, val)	arch_this_cpu_to_op_simple(pcp, val, +)
 | 
					
						
							|  |  |  | #define this_cpu_add_2(pcp, val)	arch_this_cpu_to_op_simple(pcp, val, +)
 | 
					
						
							|  |  |  | #define this_cpu_add_return_1(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +)
 | 
					
						
							|  |  |  | #define this_cpu_add_return_2(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +)
 | 
					
						
							|  |  |  | #define this_cpu_and_1(pcp, val)	arch_this_cpu_to_op_simple(pcp, val, &)
 | 
					
						
							|  |  |  | #define this_cpu_and_2(pcp, val)	arch_this_cpu_to_op_simple(pcp, val, &)
 | 
					
						
							|  |  |  | #define this_cpu_or_1(pcp, val)		arch_this_cpu_to_op_simple(pcp, val, |)
 | 
					
						
							|  |  |  | #define this_cpu_or_2(pcp, val)		arch_this_cpu_to_op_simple(pcp, val, |)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef CONFIG_HAVE_MARCH_Z196_FEATURES
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define this_cpu_add_4(pcp, val)	arch_this_cpu_to_op_simple(pcp, val, +)
 | 
					
						
							|  |  |  | #define this_cpu_add_8(pcp, val)	arch_this_cpu_to_op_simple(pcp, val, +)
 | 
					
						
							|  |  |  | #define this_cpu_add_return_4(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +)
 | 
					
						
							|  |  |  | #define this_cpu_add_return_8(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +)
 | 
					
						
							|  |  |  | #define this_cpu_and_4(pcp, val)	arch_this_cpu_to_op_simple(pcp, val, &)
 | 
					
						
							|  |  |  | #define this_cpu_and_8(pcp, val)	arch_this_cpu_to_op_simple(pcp, val, &)
 | 
					
						
							|  |  |  | #define this_cpu_or_4(pcp, val)		arch_this_cpu_to_op_simple(pcp, val, |)
 | 
					
						
							|  |  |  | #define this_cpu_or_8(pcp, val)		arch_this_cpu_to_op_simple(pcp, val, |)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else /* CONFIG_HAVE_MARCH_Z196_FEATURES */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define arch_this_cpu_add(pcp, val, op1, op2, szcast)			\
 | 
					
						
							|  |  |  | {									\ | 
					
						
							|  |  |  | 	typedef typeof(pcp) pcp_op_T__; 				\ | 
					
						
							|  |  |  | 	pcp_op_T__ val__ = (val);					\ | 
					
						
							|  |  |  | 	pcp_op_T__ old__, *ptr__;					\ | 
					
						
							|  |  |  | 	preempt_disable();						\ | 
					
						
							|  |  |  | 	ptr__ = __this_cpu_ptr(&(pcp)); 				\ | 
					
						
							|  |  |  | 	if (__builtin_constant_p(val__) &&				\ | 
					
						
							|  |  |  | 	    ((szcast)val__ > -129) && ((szcast)val__ < 128)) {		\ | 
					
						
							|  |  |  | 		asm volatile(						\ | 
					
						
							|  |  |  | 			op2 "   %[ptr__],%[val__]\n"			\ | 
					
						
							|  |  |  | 			: [ptr__] "+Q" (*ptr__) 			\ | 
					
						
							|  |  |  | 			: [val__] "i" ((szcast)val__)			\ | 
					
						
							|  |  |  | 			: "cc");					\ | 
					
						
							|  |  |  | 	} else {							\ | 
					
						
							|  |  |  | 		asm volatile(						\ | 
					
						
							|  |  |  | 			op1 "   %[old__],%[val__],%[ptr__]\n"		\ | 
					
						
							|  |  |  | 			: [old__] "=d" (old__), [ptr__] "+Q" (*ptr__)	\ | 
					
						
							|  |  |  | 			: [val__] "d" (val__)				\ | 
					
						
							|  |  |  | 			: "cc");					\ | 
					
						
							|  |  |  | 	}								\ | 
					
						
							|  |  |  | 	preempt_enable();						\ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define this_cpu_add_4(pcp, val) arch_this_cpu_add(pcp, val, "laa", "asi", int)
 | 
					
						
							|  |  |  | #define this_cpu_add_8(pcp, val) arch_this_cpu_add(pcp, val, "laag", "agsi", long)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define arch_this_cpu_add_return(pcp, val, op)				\
 | 
					
						
							|  |  |  | ({									\ | 
					
						
							|  |  |  | 	typedef typeof(pcp) pcp_op_T__; 				\ | 
					
						
							|  |  |  | 	pcp_op_T__ val__ = (val);					\ | 
					
						
							|  |  |  | 	pcp_op_T__ old__, *ptr__;					\ | 
					
						
							|  |  |  | 	preempt_disable();						\ | 
					
						
							|  |  |  | 	ptr__ = __this_cpu_ptr(&(pcp)); 				\ | 
					
						
							|  |  |  | 	asm volatile(							\ | 
					
						
							|  |  |  | 		op "    %[old__],%[val__],%[ptr__]\n"			\ | 
					
						
							|  |  |  | 		: [old__] "=d" (old__), [ptr__] "+Q" (*ptr__)		\ | 
					
						
							|  |  |  | 		: [val__] "d" (val__)					\ | 
					
						
							|  |  |  | 		: "cc");						\ | 
					
						
							|  |  |  | 	preempt_enable();						\ | 
					
						
							|  |  |  | 	old__ + val__;							\ | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define this_cpu_add_return_4(pcp, val) arch_this_cpu_add_return(pcp, val, "laa")
 | 
					
						
							|  |  |  | #define this_cpu_add_return_8(pcp, val) arch_this_cpu_add_return(pcp, val, "laag")
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define arch_this_cpu_to_op(pcp, val, op)				\
 | 
					
						
							|  |  |  | {									\ | 
					
						
							|  |  |  | 	typedef typeof(pcp) pcp_op_T__; 				\ | 
					
						
							|  |  |  | 	pcp_op_T__ val__ = (val);					\ | 
					
						
							|  |  |  | 	pcp_op_T__ old__, *ptr__;					\ | 
					
						
							|  |  |  | 	preempt_disable();						\ | 
					
						
							|  |  |  | 	ptr__ = __this_cpu_ptr(&(pcp)); 				\ | 
					
						
							|  |  |  | 	asm volatile(							\ | 
					
						
							|  |  |  | 		op "    %[old__],%[val__],%[ptr__]\n"			\ | 
					
						
							|  |  |  | 		: [old__] "=d" (old__), [ptr__] "+Q" (*ptr__)		\ | 
					
						
							|  |  |  | 		: [val__] "d" (val__)					\ | 
					
						
							|  |  |  | 		: "cc");						\ | 
					
						
							|  |  |  | 	preempt_enable();						\ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define this_cpu_and_4(pcp, val)	arch_this_cpu_to_op(pcp, val, "lan")
 | 
					
						
							|  |  |  | #define this_cpu_and_8(pcp, val)	arch_this_cpu_to_op(pcp, val, "lang")
 | 
					
						
							|  |  |  | #define this_cpu_or_4(pcp, val)		arch_this_cpu_to_op(pcp, val, "lao")
 | 
					
						
							|  |  |  | #define this_cpu_or_8(pcp, val)		arch_this_cpu_to_op(pcp, val, "laog")
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */
 | 
					
						
							| 
									
										
										
										
											2011-05-23 10:24:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-17 07:37:13 +02:00
										 |  |  | #define arch_this_cpu_cmpxchg(pcp, oval, nval)				\
 | 
					
						
							| 
									
										
										
										
											2011-05-23 10:24:32 +02:00
										 |  |  | ({									\ | 
					
						
							|  |  |  | 	typedef typeof(pcp) pcp_op_T__;					\ | 
					
						
							|  |  |  | 	pcp_op_T__ ret__;						\ | 
					
						
							|  |  |  | 	pcp_op_T__ *ptr__;						\ | 
					
						
							|  |  |  | 	preempt_disable();						\ | 
					
						
							|  |  |  | 	ptr__ = __this_cpu_ptr(&(pcp));					\ | 
					
						
							| 
									
										
										
										
											2013-10-21 07:44:08 +02:00
										 |  |  | 	ret__ = cmpxchg(ptr__, oval, nval);				\ | 
					
						
							| 
									
										
										
										
											2011-05-23 10:24:32 +02:00
										 |  |  | 	preempt_enable();						\ | 
					
						
							|  |  |  | 	ret__;								\ | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-22 11:58:51 -06:00
										 |  |  | #define this_cpu_cmpxchg_1(pcp, oval, nval) arch_this_cpu_cmpxchg(pcp, oval, nval)
 | 
					
						
							|  |  |  | #define this_cpu_cmpxchg_2(pcp, oval, nval) arch_this_cpu_cmpxchg(pcp, oval, nval)
 | 
					
						
							|  |  |  | #define this_cpu_cmpxchg_4(pcp, oval, nval) arch_this_cpu_cmpxchg(pcp, oval, nval)
 | 
					
						
							|  |  |  | #define this_cpu_cmpxchg_8(pcp, oval, nval) arch_this_cpu_cmpxchg(pcp, oval, nval)
 | 
					
						
							| 
									
										
										
										
											2011-05-23 10:24:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-17 06:38:22 +02:00
										 |  |  | #define arch_this_cpu_xchg(pcp, nval)					\
 | 
					
						
							|  |  |  | ({									\ | 
					
						
							|  |  |  | 	typeof(pcp) *ptr__;						\ | 
					
						
							|  |  |  | 	typeof(pcp) ret__;						\ | 
					
						
							|  |  |  | 	preempt_disable();						\ | 
					
						
							|  |  |  | 	ptr__ = __this_cpu_ptr(&(pcp));					\ | 
					
						
							|  |  |  | 	ret__ = xchg(ptr__, nval);					\ | 
					
						
							|  |  |  | 	preempt_enable();						\ | 
					
						
							|  |  |  | 	ret__;								\ | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define this_cpu_xchg_1(pcp, nval) arch_this_cpu_xchg(pcp, nval)
 | 
					
						
							|  |  |  | #define this_cpu_xchg_2(pcp, nval) arch_this_cpu_xchg(pcp, nval)
 | 
					
						
							|  |  |  | #define this_cpu_xchg_4(pcp, nval) arch_this_cpu_xchg(pcp, nval)
 | 
					
						
							|  |  |  | #define this_cpu_xchg_8(pcp, nval) arch_this_cpu_xchg(pcp, nval)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-17 07:37:13 +02:00
										 |  |  | #define arch_this_cpu_cmpxchg_double(pcp1, pcp2, o1, o2, n1, n2)	\
 | 
					
						
							|  |  |  | ({									\ | 
					
						
							|  |  |  | 	typeof(pcp1) o1__ = (o1), n1__ = (n1);				\ | 
					
						
							|  |  |  | 	typeof(pcp2) o2__ = (o2), n2__ = (n2);				\ | 
					
						
							|  |  |  | 	typeof(pcp1) *p1__;						\ | 
					
						
							|  |  |  | 	typeof(pcp2) *p2__;						\ | 
					
						
							|  |  |  | 	int ret__;							\ | 
					
						
							|  |  |  | 	preempt_disable();						\ | 
					
						
							|  |  |  | 	p1__ = __this_cpu_ptr(&(pcp1));					\ | 
					
						
							|  |  |  | 	p2__ = __this_cpu_ptr(&(pcp2));					\ | 
					
						
							|  |  |  | 	ret__ = __cmpxchg_double(p1__, p2__, o1__, o2__, n1__, n2__);	\ | 
					
						
							|  |  |  | 	preempt_enable();						\ | 
					
						
							|  |  |  | 	ret__;								\ | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define this_cpu_cmpxchg_double_4 arch_this_cpu_cmpxchg_double
 | 
					
						
							|  |  |  | #define this_cpu_cmpxchg_double_8 arch_this_cpu_cmpxchg_double
 | 
					
						
							| 
									
										
										
										
											2013-10-21 07:44:08 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif /* CONFIG_64BIT */
 | 
					
						
							| 
									
										
										
										
											2012-09-17 07:37:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-30 23:27:58 +01:00
										 |  |  | #include <asm-generic/percpu.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif /* __ARCH_S390_PERCPU__ */
 |