percpu.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #ifndef __ALPHA_PERCPU_H
  2. #define __ALPHA_PERCPU_H
  3. #include <linux/compiler.h>
  4. #include <linux/threads.h>
  5. /*
  6. * Determine the real variable name from the name visible in the
  7. * kernel sources.
  8. */
  9. #define per_cpu_var(var) per_cpu__##var
  10. #ifdef CONFIG_SMP
  11. /*
  12. * per_cpu_offset() is the offset that has to be added to a
  13. * percpu variable to get to the instance for a certain processor.
  14. */
  15. extern unsigned long __per_cpu_offset[NR_CPUS];
  16. #define per_cpu_offset(x) (__per_cpu_offset[x])
  17. #define __my_cpu_offset per_cpu_offset(raw_smp_processor_id())
  18. #ifdef CONFIG_DEBUG_PREEMPT
  19. #define my_cpu_offset per_cpu_offset(smp_processor_id())
  20. #else
  21. #define my_cpu_offset __my_cpu_offset
  22. #endif
  23. #ifndef MODULE
  24. #define SHIFT_PERCPU_PTR(var, offset) RELOC_HIDE(&per_cpu_var(var), (offset))
  25. #define PER_CPU_ATTRIBUTES
  26. #else
  27. /*
  28. * To calculate addresses of locally defined variables, GCC uses 32-bit
  29. * displacement from the GP. Which doesn't work for per cpu variables in
  30. * modules, as an offset to the kernel per cpu area is way above 4G.
  31. *
  32. * This forces allocation of a GOT entry for per cpu variable using
  33. * ldq instruction with a 'literal' relocation.
  34. */
  35. #define SHIFT_PERCPU_PTR(var, offset) ({ \
  36. extern int simple_identifier_##var(void); \
  37. unsigned long __ptr, tmp_gp; \
  38. asm ( "br %1, 1f \n\
  39. 1: ldgp %1, 0(%1) \n\
  40. ldq %0, per_cpu__" #var"(%1)\t!literal" \
  41. : "=&r"(__ptr), "=&r"(tmp_gp)); \
  42. (typeof(&per_cpu_var(var)))(__ptr + (offset)); })
  43. #define PER_CPU_ATTRIBUTES __used
  44. #endif /* MODULE */
  45. /*
  46. * A percpu variable may point to a discarded regions. The following are
  47. * established ways to produce a usable pointer from the percpu variable
  48. * offset.
  49. */
  50. #define per_cpu(var, cpu) \
  51. (*SHIFT_PERCPU_PTR(var, per_cpu_offset(cpu)))
  52. #define __get_cpu_var(var) \
  53. (*SHIFT_PERCPU_PTR(var, my_cpu_offset))
  54. #define __raw_get_cpu_var(var) \
  55. (*SHIFT_PERCPU_PTR(var, __my_cpu_offset))
  56. #else /* ! SMP */
  57. #define per_cpu(var, cpu) (*((void)(cpu), &per_cpu_var(var)))
  58. #define __get_cpu_var(var) per_cpu_var(var)
  59. #define __raw_get_cpu_var(var) per_cpu_var(var)
  60. #define PER_CPU_ATTRIBUTES
  61. #endif /* SMP */
  62. #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu_var(name)
  63. #endif /* __ALPHA_PERCPU_H */