vgetcpu.c 826 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Fast user context implementation of getcpu()
  4. */
  5. #include <asm/vdso.h>
  6. #include <linux/getcpu.h>
  7. static __always_inline int read_cpu_id(void)
  8. {
  9. int cpu_id;
  10. __asm__ __volatile__(
  11. " rdtime.d $zero, %0\n"
  12. : "=r" (cpu_id)
  13. :
  14. : "memory");
  15. return cpu_id;
  16. }
  17. static __always_inline const struct vdso_pcpu_data *get_pcpu_data(void)
  18. {
  19. return (struct vdso_pcpu_data *)(get_vdso_base() - VDSO_DATA_SIZE);
  20. }
  21. extern
  22. int __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused);
  23. int __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused)
  24. {
  25. int cpu_id;
  26. const struct vdso_pcpu_data *data;
  27. cpu_id = read_cpu_id();
  28. if (cpu)
  29. *cpu = cpu_id;
  30. if (node) {
  31. data = get_pcpu_data();
  32. *node = data[cpu_id].node;
  33. }
  34. return 0;
  35. }