percpu.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. #ifndef _ASM_X86_PERCPU_H
  2. #define _ASM_X86_PERCPU_H
  3. #ifdef CONFIG_X86_64
  4. #define __percpu_seg gs
  5. #define __percpu_mov_op movq
  6. #else
  7. #define __percpu_seg fs
  8. #define __percpu_mov_op movl
  9. #endif
  10. #ifdef __ASSEMBLY__
  11. /*
  12. * PER_CPU finds an address of a per-cpu variable.
  13. *
  14. * Args:
  15. * var - variable name
  16. * reg - 32bit register
  17. *
  18. * The resulting address is stored in the "reg" argument.
  19. *
  20. * Example:
  21. * PER_CPU(cpu_gdt_descr, %ebx)
  22. */
  23. #ifdef CONFIG_SMP
  24. #define PER_CPU(var, reg) \
  25. __percpu_mov_op %__percpu_seg:this_cpu_off, reg; \
  26. lea var(reg), reg
  27. #define PER_CPU_VAR(var) %__percpu_seg:var
  28. #else /* ! SMP */
  29. #define PER_CPU(var, reg) __percpu_mov_op $var, reg
  30. #define PER_CPU_VAR(var) var
  31. #endif /* SMP */
  32. #ifdef CONFIG_X86_64_SMP
  33. #define INIT_PER_CPU_VAR(var) init_per_cpu__##var
  34. #else
  35. #define INIT_PER_CPU_VAR(var) var
  36. #endif
  37. #else /* ...!ASSEMBLY */
  38. #include <linux/kernel.h>
  39. #include <linux/stringify.h>
  40. #ifdef CONFIG_SMP
  41. #define __percpu_prefix "%%"__stringify(__percpu_seg)":"
  42. #define __my_cpu_offset percpu_read(this_cpu_off)
  43. /*
  44. * Compared to the generic __my_cpu_offset version, the following
  45. * saves one instruction and avoids clobbering a temp register.
  46. */
  47. #define __this_cpu_ptr(ptr) \
  48. ({ \
  49. unsigned long tcp_ptr__; \
  50. __verify_pcpu_ptr(ptr); \
  51. asm volatile("add " __percpu_arg(1) ", %0" \
  52. : "=r" (tcp_ptr__) \
  53. : "m" (this_cpu_off), "0" (ptr)); \
  54. (typeof(*(ptr)) __kernel __force *)tcp_ptr__; \
  55. })
  56. #else
  57. #define __percpu_prefix ""
  58. #endif
  59. #define __percpu_arg(x) __percpu_prefix "%P" #x
  60. /*
  61. * Initialized pointers to per-cpu variables needed for the boot
  62. * processor need to use these macros to get the proper address
  63. * offset from __per_cpu_load on SMP.
  64. *
  65. * There also must be an entry in vmlinux_64.lds.S
  66. */
  67. #define DECLARE_INIT_PER_CPU(var) \
  68. extern typeof(var) init_per_cpu_var(var)
  69. #ifdef CONFIG_X86_64_SMP
  70. #define init_per_cpu_var(var) init_per_cpu__##var
  71. #else
  72. #define init_per_cpu_var(var) var
  73. #endif
  74. /* For arch-specific code, we can use direct single-insn ops (they
  75. * don't give an lvalue though). */
  76. extern void __bad_percpu_size(void);
  77. #define percpu_to_op(op, var, val) \
  78. do { \
  79. typedef typeof(var) pto_T__; \
  80. if (0) { \
  81. pto_T__ pto_tmp__; \
  82. pto_tmp__ = (val); \
  83. (void)pto_tmp__; \
  84. } \
  85. switch (sizeof(var)) { \
  86. case 1: \
  87. asm(op "b %1,"__percpu_arg(0) \
  88. : "+m" (var) \
  89. : "qi" ((pto_T__)(val))); \
  90. break; \
  91. case 2: \
  92. asm(op "w %1,"__percpu_arg(0) \
  93. : "+m" (var) \
  94. : "ri" ((pto_T__)(val))); \
  95. break; \
  96. case 4: \
  97. asm(op "l %1,"__percpu_arg(0) \
  98. : "+m" (var) \
  99. : "ri" ((pto_T__)(val))); \
  100. break; \
  101. case 8: \
  102. asm(op "q %1,"__percpu_arg(0) \
  103. : "+m" (var) \
  104. : "re" ((pto_T__)(val))); \
  105. break; \
  106. default: __bad_percpu_size(); \
  107. } \
  108. } while (0)
  109. /*
  110. * Generate a percpu add to memory instruction and optimize code
  111. * if one is added or subtracted.
  112. */
  113. #define percpu_add_op(var, val) \
  114. do { \
  115. typedef typeof(var) pao_T__; \
  116. const int pao_ID__ = (__builtin_constant_p(val) && \
  117. ((val) == 1 || (val) == -1)) ? (val) : 0; \
  118. if (0) { \
  119. pao_T__ pao_tmp__; \
  120. pao_tmp__ = (val); \
  121. (void)pao_tmp__; \
  122. } \
  123. switch (sizeof(var)) { \
  124. case 1: \
  125. if (pao_ID__ == 1) \
  126. asm("incb "__percpu_arg(0) : "+m" (var)); \
  127. else if (pao_ID__ == -1) \
  128. asm("decb "__percpu_arg(0) : "+m" (var)); \
  129. else \
  130. asm("addb %1, "__percpu_arg(0) \
  131. : "+m" (var) \
  132. : "qi" ((pao_T__)(val))); \
  133. break; \
  134. case 2: \
  135. if (pao_ID__ == 1) \
  136. asm("incw "__percpu_arg(0) : "+m" (var)); \
  137. else if (pao_ID__ == -1) \
  138. asm("decw "__percpu_arg(0) : "+m" (var)); \
  139. else \
  140. asm("addw %1, "__percpu_arg(0) \
  141. : "+m" (var) \
  142. : "ri" ((pao_T__)(val))); \
  143. break; \
  144. case 4: \
  145. if (pao_ID__ == 1) \
  146. asm("incl "__percpu_arg(0) : "+m" (var)); \
  147. else if (pao_ID__ == -1) \
  148. asm("decl "__percpu_arg(0) : "+m" (var)); \
  149. else \
  150. asm("addl %1, "__percpu_arg(0) \
  151. : "+m" (var) \
  152. : "ri" ((pao_T__)(val))); \
  153. break; \
  154. case 8: \
  155. if (pao_ID__ == 1) \
  156. asm("incq "__percpu_arg(0) : "+m" (var)); \
  157. else if (pao_ID__ == -1) \
  158. asm("decq "__percpu_arg(0) : "+m" (var)); \
  159. else \
  160. asm("addq %1, "__percpu_arg(0) \
  161. : "+m" (var) \
  162. : "re" ((pao_T__)(val))); \
  163. break; \
  164. default: __bad_percpu_size(); \
  165. } \
  166. } while (0)
  167. #define percpu_from_op(op, var, constraint) \
  168. ({ \
  169. typeof(var) pfo_ret__; \
  170. switch (sizeof(var)) { \
  171. case 1: \
  172. asm(op "b "__percpu_arg(1)",%0" \
  173. : "=q" (pfo_ret__) \
  174. : constraint); \
  175. break; \
  176. case 2: \
  177. asm(op "w "__percpu_arg(1)",%0" \
  178. : "=r" (pfo_ret__) \
  179. : constraint); \
  180. break; \
  181. case 4: \
  182. asm(op "l "__percpu_arg(1)",%0" \
  183. : "=r" (pfo_ret__) \
  184. : constraint); \
  185. break; \
  186. case 8: \
  187. asm(op "q "__percpu_arg(1)",%0" \
  188. : "=r" (pfo_ret__) \
  189. : constraint); \
  190. break; \
  191. default: __bad_percpu_size(); \
  192. } \
  193. pfo_ret__; \
  194. })
  195. #define percpu_unary_op(op, var) \
  196. ({ \
  197. switch (sizeof(var)) { \
  198. case 1: \
  199. asm(op "b "__percpu_arg(0) \
  200. : "+m" (var)); \
  201. break; \
  202. case 2: \
  203. asm(op "w "__percpu_arg(0) \
  204. : "+m" (var)); \
  205. break; \
  206. case 4: \
  207. asm(op "l "__percpu_arg(0) \
  208. : "+m" (var)); \
  209. break; \
  210. case 8: \
  211. asm(op "q "__percpu_arg(0) \
  212. : "+m" (var)); \
  213. break; \
  214. default: __bad_percpu_size(); \
  215. } \
  216. })
  217. /*
  218. * Add return operation
  219. */
  220. #define percpu_add_return_op(var, val) \
  221. ({ \
  222. typeof(var) paro_ret__ = val; \
  223. switch (sizeof(var)) { \
  224. case 1: \
  225. asm("xaddb %0, "__percpu_arg(1) \
  226. : "+q" (paro_ret__), "+m" (var) \
  227. : : "memory"); \
  228. break; \
  229. case 2: \
  230. asm("xaddw %0, "__percpu_arg(1) \
  231. : "+r" (paro_ret__), "+m" (var) \
  232. : : "memory"); \
  233. break; \
  234. case 4: \
  235. asm("xaddl %0, "__percpu_arg(1) \
  236. : "+r" (paro_ret__), "+m" (var) \
  237. : : "memory"); \
  238. break; \
  239. case 8: \
  240. asm("xaddq %0, "__percpu_arg(1) \
  241. : "+re" (paro_ret__), "+m" (var) \
  242. : : "memory"); \
  243. break; \
  244. default: __bad_percpu_size(); \
  245. } \
  246. paro_ret__ += val; \
  247. paro_ret__; \
  248. })
  249. /*
  250. * xchg is implemented using cmpxchg without a lock prefix. xchg is
  251. * expensive due to the implied lock prefix. The processor cannot prefetch
  252. * cachelines if xchg is used.
  253. */
  254. #define percpu_xchg_op(var, nval) \
  255. ({ \
  256. typeof(var) pxo_ret__; \
  257. typeof(var) pxo_new__ = (nval); \
  258. switch (sizeof(var)) { \
  259. case 1: \
  260. asm("\n\tmov "__percpu_arg(1)",%%al" \
  261. "\n1:\tcmpxchgb %2, "__percpu_arg(1) \
  262. "\n\tjnz 1b" \
  263. : "=&a" (pxo_ret__), "+m" (var) \
  264. : "q" (pxo_new__) \
  265. : "memory"); \
  266. break; \
  267. case 2: \
  268. asm("\n\tmov "__percpu_arg(1)",%%ax" \
  269. "\n1:\tcmpxchgw %2, "__percpu_arg(1) \
  270. "\n\tjnz 1b" \
  271. : "=&a" (pxo_ret__), "+m" (var) \
  272. : "r" (pxo_new__) \
  273. : "memory"); \
  274. break; \
  275. case 4: \
  276. asm("\n\tmov "__percpu_arg(1)",%%eax" \
  277. "\n1:\tcmpxchgl %2, "__percpu_arg(1) \
  278. "\n\tjnz 1b" \
  279. : "=&a" (pxo_ret__), "+m" (var) \
  280. : "r" (pxo_new__) \
  281. : "memory"); \
  282. break; \
  283. case 8: \
  284. asm("\n\tmov "__percpu_arg(1)",%%rax" \
  285. "\n1:\tcmpxchgq %2, "__percpu_arg(1) \
  286. "\n\tjnz 1b" \
  287. : "=&a" (pxo_ret__), "+m" (var) \
  288. : "r" (pxo_new__) \
  289. : "memory"); \
  290. break; \
  291. default: __bad_percpu_size(); \
  292. } \
  293. pxo_ret__; \
  294. })
  295. /*
  296. * cmpxchg has no such implied lock semantics as a result it is much
  297. * more efficient for cpu local operations.
  298. */
  299. #define percpu_cmpxchg_op(var, oval, nval) \
  300. ({ \
  301. typeof(var) pco_ret__; \
  302. typeof(var) pco_old__ = (oval); \
  303. typeof(var) pco_new__ = (nval); \
  304. switch (sizeof(var)) { \
  305. case 1: \
  306. asm("cmpxchgb %2, "__percpu_arg(1) \
  307. : "=a" (pco_ret__), "+m" (var) \
  308. : "q" (pco_new__), "0" (pco_old__) \
  309. : "memory"); \
  310. break; \
  311. case 2: \
  312. asm("cmpxchgw %2, "__percpu_arg(1) \
  313. : "=a" (pco_ret__), "+m" (var) \
  314. : "r" (pco_new__), "0" (pco_old__) \
  315. : "memory"); \
  316. break; \
  317. case 4: \
  318. asm("cmpxchgl %2, "__percpu_arg(1) \
  319. : "=a" (pco_ret__), "+m" (var) \
  320. : "r" (pco_new__), "0" (pco_old__) \
  321. : "memory"); \
  322. break; \
  323. case 8: \
  324. asm("cmpxchgq %2, "__percpu_arg(1) \
  325. : "=a" (pco_ret__), "+m" (var) \
  326. : "r" (pco_new__), "0" (pco_old__) \
  327. : "memory"); \
  328. break; \
  329. default: __bad_percpu_size(); \
  330. } \
  331. pco_ret__; \
  332. })
  333. /*
  334. * percpu_read() makes gcc load the percpu variable every time it is
  335. * accessed while percpu_read_stable() allows the value to be cached.
  336. * percpu_read_stable() is more efficient and can be used if its value
  337. * is guaranteed to be valid across cpus. The current users include
  338. * get_current() and get_thread_info() both of which are actually
  339. * per-thread variables implemented as per-cpu variables and thus
  340. * stable for the duration of the respective task.
  341. */
  342. #define percpu_read(var) percpu_from_op("mov", var, "m" (var))
  343. #define percpu_read_stable(var) percpu_from_op("mov", var, "p" (&(var)))
  344. #define percpu_write(var, val) percpu_to_op("mov", var, val)
  345. #define percpu_add(var, val) percpu_add_op(var, val)
  346. #define percpu_sub(var, val) percpu_add_op(var, -(val))
  347. #define percpu_and(var, val) percpu_to_op("and", var, val)
  348. #define percpu_or(var, val) percpu_to_op("or", var, val)
  349. #define percpu_xor(var, val) percpu_to_op("xor", var, val)
  350. #define percpu_inc(var) percpu_unary_op("inc", var)
  351. #define __this_cpu_read_1(pcp) percpu_from_op("mov", (pcp), "m"(pcp))
  352. #define __this_cpu_read_2(pcp) percpu_from_op("mov", (pcp), "m"(pcp))
  353. #define __this_cpu_read_4(pcp) percpu_from_op("mov", (pcp), "m"(pcp))
  354. #define __this_cpu_write_1(pcp, val) percpu_to_op("mov", (pcp), val)
  355. #define __this_cpu_write_2(pcp, val) percpu_to_op("mov", (pcp), val)
  356. #define __this_cpu_write_4(pcp, val) percpu_to_op("mov", (pcp), val)
  357. #define __this_cpu_add_1(pcp, val) percpu_add_op((pcp), val)
  358. #define __this_cpu_add_2(pcp, val) percpu_add_op((pcp), val)
  359. #define __this_cpu_add_4(pcp, val) percpu_add_op((pcp), val)
  360. #define __this_cpu_and_1(pcp, val) percpu_to_op("and", (pcp), val)
  361. #define __this_cpu_and_2(pcp, val) percpu_to_op("and", (pcp), val)
  362. #define __this_cpu_and_4(pcp, val) percpu_to_op("and", (pcp), val)
  363. #define __this_cpu_or_1(pcp, val) percpu_to_op("or", (pcp), val)
  364. #define __this_cpu_or_2(pcp, val) percpu_to_op("or", (pcp), val)
  365. #define __this_cpu_or_4(pcp, val) percpu_to_op("or", (pcp), val)
  366. #define __this_cpu_xor_1(pcp, val) percpu_to_op("xor", (pcp), val)
  367. #define __this_cpu_xor_2(pcp, val) percpu_to_op("xor", (pcp), val)
  368. #define __this_cpu_xor_4(pcp, val) percpu_to_op("xor", (pcp), val)
  369. #define __this_cpu_xchg_1(pcp, val) percpu_xchg_op(pcp, val)
  370. #define __this_cpu_xchg_2(pcp, val) percpu_xchg_op(pcp, val)
  371. #define __this_cpu_xchg_4(pcp, val) percpu_xchg_op(pcp, val)
  372. #define this_cpu_read_1(pcp) percpu_from_op("mov", (pcp), "m"(pcp))
  373. #define this_cpu_read_2(pcp) percpu_from_op("mov", (pcp), "m"(pcp))
  374. #define this_cpu_read_4(pcp) percpu_from_op("mov", (pcp), "m"(pcp))
  375. #define this_cpu_write_1(pcp, val) percpu_to_op("mov", (pcp), val)
  376. #define this_cpu_write_2(pcp, val) percpu_to_op("mov", (pcp), val)
  377. #define this_cpu_write_4(pcp, val) percpu_to_op("mov", (pcp), val)
  378. #define this_cpu_add_1(pcp, val) percpu_add_op((pcp), val)
  379. #define this_cpu_add_2(pcp, val) percpu_add_op((pcp), val)
  380. #define this_cpu_add_4(pcp, val) percpu_add_op((pcp), val)
  381. #define this_cpu_and_1(pcp, val) percpu_to_op("and", (pcp), val)
  382. #define this_cpu_and_2(pcp, val) percpu_to_op("and", (pcp), val)
  383. #define this_cpu_and_4(pcp, val) percpu_to_op("and", (pcp), val)
  384. #define this_cpu_or_1(pcp, val) percpu_to_op("or", (pcp), val)
  385. #define this_cpu_or_2(pcp, val) percpu_to_op("or", (pcp), val)
  386. #define this_cpu_or_4(pcp, val) percpu_to_op("or", (pcp), val)
  387. #define this_cpu_xor_1(pcp, val) percpu_to_op("xor", (pcp), val)
  388. #define this_cpu_xor_2(pcp, val) percpu_to_op("xor", (pcp), val)
  389. #define this_cpu_xor_4(pcp, val) percpu_to_op("xor", (pcp), val)
  390. #define this_cpu_xchg_1(pcp, nval) percpu_xchg_op(pcp, nval)
  391. #define this_cpu_xchg_2(pcp, nval) percpu_xchg_op(pcp, nval)
  392. #define this_cpu_xchg_4(pcp, nval) percpu_xchg_op(pcp, nval)
  393. #ifndef CONFIG_M386
  394. #define __this_cpu_add_return_1(pcp, val) percpu_add_return_op(pcp, val)
  395. #define __this_cpu_add_return_2(pcp, val) percpu_add_return_op(pcp, val)
  396. #define __this_cpu_add_return_4(pcp, val) percpu_add_return_op(pcp, val)
  397. #define __this_cpu_cmpxchg_1(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
  398. #define __this_cpu_cmpxchg_2(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
  399. #define __this_cpu_cmpxchg_4(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
  400. #define this_cpu_add_return_1(pcp, val) percpu_add_return_op(pcp, val)
  401. #define this_cpu_add_return_2(pcp, val) percpu_add_return_op(pcp, val)
  402. #define this_cpu_add_return_4(pcp, val) percpu_add_return_op(pcp, val)
  403. #define this_cpu_cmpxchg_1(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
  404. #define this_cpu_cmpxchg_2(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
  405. #define this_cpu_cmpxchg_4(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
  406. #endif /* !CONFIG_M386 */
  407. #ifdef CONFIG_X86_CMPXCHG64
  408. #define percpu_cmpxchg8b_double(pcp1, pcp2, o1, o2, n1, n2) \
  409. ({ \
  410. bool __ret; \
  411. typeof(pcp1) __o1 = (o1), __n1 = (n1); \
  412. typeof(pcp2) __o2 = (o2), __n2 = (n2); \
  413. asm volatile("cmpxchg8b "__percpu_arg(1)"\n\tsetz %0\n\t" \
  414. : "=a" (__ret), "+m" (pcp1), "+m" (pcp2), "+d" (__o2) \
  415. : "b" (__n1), "c" (__n2), "a" (__o1)); \
  416. __ret; \
  417. })
  418. #define __this_cpu_cmpxchg_double_4 percpu_cmpxchg8b_double
  419. #define this_cpu_cmpxchg_double_4 percpu_cmpxchg8b_double
  420. #endif /* CONFIG_X86_CMPXCHG64 */
  421. /*
  422. * Per cpu atomic 64 bit operations are only available under 64 bit.
  423. * 32 bit must fall back to generic operations.
  424. */
  425. #ifdef CONFIG_X86_64
  426. #define __this_cpu_read_8(pcp) percpu_from_op("mov", (pcp), "m"(pcp))
  427. #define __this_cpu_write_8(pcp, val) percpu_to_op("mov", (pcp), val)
  428. #define __this_cpu_add_8(pcp, val) percpu_add_op((pcp), val)
  429. #define __this_cpu_and_8(pcp, val) percpu_to_op("and", (pcp), val)
  430. #define __this_cpu_or_8(pcp, val) percpu_to_op("or", (pcp), val)
  431. #define __this_cpu_xor_8(pcp, val) percpu_to_op("xor", (pcp), val)
  432. #define __this_cpu_add_return_8(pcp, val) percpu_add_return_op(pcp, val)
  433. #define __this_cpu_xchg_8(pcp, nval) percpu_xchg_op(pcp, nval)
  434. #define __this_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
  435. #define this_cpu_read_8(pcp) percpu_from_op("mov", (pcp), "m"(pcp))
  436. #define this_cpu_write_8(pcp, val) percpu_to_op("mov", (pcp), val)
  437. #define this_cpu_add_8(pcp, val) percpu_add_op((pcp), val)
  438. #define this_cpu_and_8(pcp, val) percpu_to_op("and", (pcp), val)
  439. #define this_cpu_or_8(pcp, val) percpu_to_op("or", (pcp), val)
  440. #define this_cpu_xor_8(pcp, val) percpu_to_op("xor", (pcp), val)
  441. #define this_cpu_add_return_8(pcp, val) percpu_add_return_op(pcp, val)
  442. #define this_cpu_xchg_8(pcp, nval) percpu_xchg_op(pcp, nval)
  443. #define this_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
  444. /*
  445. * Pretty complex macro to generate cmpxchg16 instruction. The instruction
  446. * is not supported on early AMD64 processors so we must be able to emulate
  447. * it in software. The address used in the cmpxchg16 instruction must be
  448. * aligned to a 16 byte boundary.
  449. */
  450. #define percpu_cmpxchg16b_double(pcp1, pcp2, o1, o2, n1, n2) \
  451. ({ \
  452. bool __ret; \
  453. typeof(pcp1) __o1 = (o1), __n1 = (n1); \
  454. typeof(pcp2) __o2 = (o2), __n2 = (n2); \
  455. alternative_io("leaq %P1,%%rsi\n\tcall this_cpu_cmpxchg16b_emu\n\t", \
  456. "cmpxchg16b " __percpu_arg(1) "\n\tsetz %0\n\t", \
  457. X86_FEATURE_CX16, \
  458. ASM_OUTPUT2("=a" (__ret), "+m" (pcp1), \
  459. "+m" (pcp2), "+d" (__o2)), \
  460. "b" (__n1), "c" (__n2), "a" (__o1) : "rsi"); \
  461. __ret; \
  462. })
  463. #define __this_cpu_cmpxchg_double_8 percpu_cmpxchg16b_double
  464. #define this_cpu_cmpxchg_double_8 percpu_cmpxchg16b_double
  465. #endif
  466. /* This is not atomic against other CPUs -- CPU preemption needs to be off */
  467. #define x86_test_and_clear_bit_percpu(bit, var) \
  468. ({ \
  469. int old__; \
  470. asm volatile("btr %2,"__percpu_arg(1)"\n\tsbbl %0,%0" \
  471. : "=r" (old__), "+m" (var) \
  472. : "dIr" (bit)); \
  473. old__; \
  474. })
  475. static __always_inline int x86_this_cpu_constant_test_bit(unsigned int nr,
  476. const unsigned long __percpu *addr)
  477. {
  478. unsigned long __percpu *a = (unsigned long *)addr + nr / BITS_PER_LONG;
  479. return ((1UL << (nr % BITS_PER_LONG)) & percpu_read(*a)) != 0;
  480. }
  481. static inline int x86_this_cpu_variable_test_bit(int nr,
  482. const unsigned long __percpu *addr)
  483. {
  484. int oldbit;
  485. asm volatile("bt "__percpu_arg(2)",%1\n\t"
  486. "sbb %0,%0"
  487. : "=r" (oldbit)
  488. : "m" (*(unsigned long *)addr), "Ir" (nr));
  489. return oldbit;
  490. }
  491. #define x86_this_cpu_test_bit(nr, addr) \
  492. (__builtin_constant_p((nr)) \
  493. ? x86_this_cpu_constant_test_bit((nr), (addr)) \
  494. : x86_this_cpu_variable_test_bit((nr), (addr)))
  495. #include <asm-generic/percpu.h>
  496. /* We can use this directly for local CPU (faster). */
  497. DECLARE_PER_CPU(unsigned long, this_cpu_off);
  498. #endif /* !__ASSEMBLY__ */
  499. #ifdef CONFIG_SMP
  500. /*
  501. * Define the "EARLY_PER_CPU" macros. These are used for some per_cpu
  502. * variables that are initialized and accessed before there are per_cpu
  503. * areas allocated.
  504. */
  505. #define DEFINE_EARLY_PER_CPU(_type, _name, _initvalue) \
  506. DEFINE_PER_CPU(_type, _name) = _initvalue; \
  507. __typeof__(_type) _name##_early_map[NR_CPUS] __initdata = \
  508. { [0 ... NR_CPUS-1] = _initvalue }; \
  509. __typeof__(_type) *_name##_early_ptr __refdata = _name##_early_map
  510. #define EXPORT_EARLY_PER_CPU_SYMBOL(_name) \
  511. EXPORT_PER_CPU_SYMBOL(_name)
  512. #define DECLARE_EARLY_PER_CPU(_type, _name) \
  513. DECLARE_PER_CPU(_type, _name); \
  514. extern __typeof__(_type) *_name##_early_ptr; \
  515. extern __typeof__(_type) _name##_early_map[]
  516. #define early_per_cpu_ptr(_name) (_name##_early_ptr)
  517. #define early_per_cpu_map(_name, _idx) (_name##_early_map[_idx])
  518. #define early_per_cpu(_name, _cpu) \
  519. *(early_per_cpu_ptr(_name) ? \
  520. &early_per_cpu_ptr(_name)[_cpu] : \
  521. &per_cpu(_name, _cpu))
  522. #else /* !CONFIG_SMP */
  523. #define DEFINE_EARLY_PER_CPU(_type, _name, _initvalue) \
  524. DEFINE_PER_CPU(_type, _name) = _initvalue
  525. #define EXPORT_EARLY_PER_CPU_SYMBOL(_name) \
  526. EXPORT_PER_CPU_SYMBOL(_name)
  527. #define DECLARE_EARLY_PER_CPU(_type, _name) \
  528. DECLARE_PER_CPU(_type, _name)
  529. #define early_per_cpu(_name, _cpu) per_cpu(_name, _cpu)
  530. #define early_per_cpu_ptr(_name) NULL
  531. /* no early_per_cpu_map() */
  532. #endif /* !CONFIG_SMP */
  533. #endif /* _ASM_X86_PERCPU_H */