callchain.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * Performance events callchain code, extracted from core.c:
  3. *
  4. * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
  5. * Copyright (C) 2008-2011 Red Hat, Inc., Ingo Molnar
  6. * Copyright (C) 2008-2011 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
  7. * Copyright © 2009 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
  8. *
  9. * For licensing details see kernel-base/COPYING
  10. */
  11. #include <linux/perf_event.h>
  12. #include <linux/slab.h>
  13. #include "internal.h"
  14. struct callchain_cpus_entries {
  15. struct rcu_head rcu_head;
  16. struct perf_callchain_entry *cpu_entries[0];
  17. };
  18. static DEFINE_PER_CPU(int, callchain_recursion[PERF_NR_CONTEXTS]);
  19. static atomic_t nr_callchain_events;
  20. static DEFINE_MUTEX(callchain_mutex);
  21. static struct callchain_cpus_entries *callchain_cpus_entries;
  22. __weak void perf_callchain_kernel(struct perf_callchain_entry *entry,
  23. struct pt_regs *regs)
  24. {
  25. }
  26. __weak void perf_callchain_user(struct perf_callchain_entry *entry,
  27. struct pt_regs *regs)
  28. {
  29. }
  30. static void release_callchain_buffers_rcu(struct rcu_head *head)
  31. {
  32. struct callchain_cpus_entries *entries;
  33. int cpu;
  34. entries = container_of(head, struct callchain_cpus_entries, rcu_head);
  35. for_each_possible_cpu(cpu)
  36. kfree(entries->cpu_entries[cpu]);
  37. kfree(entries);
  38. }
  39. static void release_callchain_buffers(void)
  40. {
  41. struct callchain_cpus_entries *entries;
  42. entries = callchain_cpus_entries;
  43. RCU_INIT_POINTER(callchain_cpus_entries, NULL);
  44. call_rcu(&entries->rcu_head, release_callchain_buffers_rcu);
  45. }
  46. static int alloc_callchain_buffers(void)
  47. {
  48. int cpu;
  49. int size;
  50. struct callchain_cpus_entries *entries;
  51. /*
  52. * We can't use the percpu allocation API for data that can be
  53. * accessed from NMI. Use a temporary manual per cpu allocation
  54. * until that gets sorted out.
  55. */
  56. size = offsetof(struct callchain_cpus_entries, cpu_entries[nr_cpu_ids]);
  57. entries = kzalloc(size, GFP_KERNEL);
  58. if (!entries)
  59. return -ENOMEM;
  60. size = sizeof(struct perf_callchain_entry) * PERF_NR_CONTEXTS;
  61. for_each_possible_cpu(cpu) {
  62. entries->cpu_entries[cpu] = kmalloc_node(size, GFP_KERNEL,
  63. cpu_to_node(cpu));
  64. if (!entries->cpu_entries[cpu])
  65. goto fail;
  66. }
  67. rcu_assign_pointer(callchain_cpus_entries, entries);
  68. return 0;
  69. fail:
  70. for_each_possible_cpu(cpu)
  71. kfree(entries->cpu_entries[cpu]);
  72. kfree(entries);
  73. return -ENOMEM;
  74. }
  75. int get_callchain_buffers(void)
  76. {
  77. int err = 0;
  78. int count;
  79. mutex_lock(&callchain_mutex);
  80. count = atomic_inc_return(&nr_callchain_events);
  81. if (WARN_ON_ONCE(count < 1)) {
  82. err = -EINVAL;
  83. goto exit;
  84. }
  85. if (count > 1) {
  86. /* If the allocation failed, give up */
  87. if (!callchain_cpus_entries)
  88. err = -ENOMEM;
  89. goto exit;
  90. }
  91. err = alloc_callchain_buffers();
  92. exit:
  93. if (err)
  94. atomic_dec(&nr_callchain_events);
  95. mutex_unlock(&callchain_mutex);
  96. return err;
  97. }
  98. void put_callchain_buffers(void)
  99. {
  100. if (atomic_dec_and_mutex_lock(&nr_callchain_events, &callchain_mutex)) {
  101. release_callchain_buffers();
  102. mutex_unlock(&callchain_mutex);
  103. }
  104. }
  105. static struct perf_callchain_entry *get_callchain_entry(int *rctx)
  106. {
  107. int cpu;
  108. struct callchain_cpus_entries *entries;
  109. *rctx = get_recursion_context(this_cpu_ptr(callchain_recursion));
  110. if (*rctx == -1)
  111. return NULL;
  112. entries = rcu_dereference(callchain_cpus_entries);
  113. if (!entries)
  114. return NULL;
  115. cpu = smp_processor_id();
  116. return &entries->cpu_entries[cpu][*rctx];
  117. }
  118. static void
  119. put_callchain_entry(int rctx)
  120. {
  121. put_recursion_context(this_cpu_ptr(callchain_recursion), rctx);
  122. }
  123. struct perf_callchain_entry *
  124. perf_callchain(struct perf_event *event, struct pt_regs *regs)
  125. {
  126. int rctx;
  127. struct perf_callchain_entry *entry;
  128. int kernel = !event->attr.exclude_callchain_kernel;
  129. int user = !event->attr.exclude_callchain_user;
  130. if (!kernel && !user)
  131. return NULL;
  132. entry = get_callchain_entry(&rctx);
  133. if (rctx == -1)
  134. return NULL;
  135. if (!entry)
  136. goto exit_put;
  137. entry->nr = 0;
  138. if (kernel && !user_mode(regs)) {
  139. perf_callchain_store(entry, PERF_CONTEXT_KERNEL);
  140. perf_callchain_kernel(entry, regs);
  141. }
  142. if (user) {
  143. if (!user_mode(regs)) {
  144. if (current->mm)
  145. regs = task_pt_regs(current);
  146. else
  147. regs = NULL;
  148. }
  149. if (regs) {
  150. /*
  151. * Disallow cross-task user callchains.
  152. */
  153. if (event->ctx->task && event->ctx->task != current)
  154. goto exit_put;
  155. perf_callchain_store(entry, PERF_CONTEXT_USER);
  156. perf_callchain_user(entry, regs);
  157. }
  158. }
  159. exit_put:
  160. put_callchain_entry(rctx);
  161. return entry;
  162. }