perf_callchain.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /*
  2. * Performance event callchain support - SuperH architecture code
  3. *
  4. * Copyright (C) 2009 Paul Mundt
  5. *
  6. * This file is subject to the terms and conditions of the GNU General Public
  7. * License. See the file "COPYING" in the main directory of this archive
  8. * for more details.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/sched.h>
  12. #include <linux/perf_event.h>
  13. #include <linux/percpu.h>
  14. #include <asm/unwinder.h>
  15. #include <asm/ptrace.h>
  16. static void callchain_warning(void *data, char *msg)
  17. {
  18. }
  19. static void
  20. callchain_warning_symbol(void *data, char *msg, unsigned long symbol)
  21. {
  22. }
  23. static int callchain_stack(void *data, char *name)
  24. {
  25. return 0;
  26. }
  27. static void callchain_address(void *data, unsigned long addr, int reliable)
  28. {
  29. struct perf_callchain_entry *entry = data;
  30. if (reliable)
  31. perf_callchain_store(entry, addr);
  32. }
  33. static const struct stacktrace_ops callchain_ops = {
  34. .warning = callchain_warning,
  35. .warning_symbol = callchain_warning_symbol,
  36. .stack = callchain_stack,
  37. .address = callchain_address,
  38. };
  39. static void
  40. perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry)
  41. {
  42. perf_callchain_store(entry, PERF_CONTEXT_KERNEL);
  43. perf_callchain_store(entry, regs->pc);
  44. unwind_stack(NULL, regs, NULL, &callchain_ops, entry);
  45. }
  46. static void
  47. perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry)
  48. {
  49. int is_user;
  50. if (!regs)
  51. return;
  52. is_user = user_mode(regs);
  53. /*
  54. * Only the kernel side is implemented for now.
  55. */
  56. if (!is_user)
  57. perf_callchain_kernel(regs, entry);
  58. }
  59. /*
  60. * No need for separate IRQ and NMI entries.
  61. */
  62. static DEFINE_PER_CPU(struct perf_callchain_entry, callchain);
  63. struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
  64. {
  65. struct perf_callchain_entry *entry = &__get_cpu_var(callchain);
  66. entry->nr = 0;
  67. perf_do_callchain(regs, entry);
  68. return entry;
  69. }