kmemtrace.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /*
  2. * Copyright (C) 2008 Pekka Enberg, Eduard - Gabriel Munteanu
  3. *
  4. * This file is released under GPL version 2.
  5. */
  6. #include <linux/string.h>
  7. #include <linux/debugfs.h>
  8. #include <linux/relay.h>
  9. #include <linux/module.h>
  10. #include <linux/marker.h>
  11. #include <linux/gfp.h>
  12. #include <linux/kmemtrace.h>
  13. #define KMEMTRACE_SUBBUF_SIZE 524288
  14. #define KMEMTRACE_DEF_N_SUBBUFS 20
  15. static struct rchan *kmemtrace_chan;
  16. static u32 kmemtrace_buf_overruns;
  17. static unsigned int kmemtrace_n_subbufs;
  18. #ifdef CONFIG_KMEMTRACE_DEFAULT_ENABLED
  19. static unsigned int kmemtrace_enabled = 1;
  20. #else
  21. static unsigned int kmemtrace_enabled = 0;
  22. #endif
  23. /*
  24. * The sequence number is used for reordering kmemtrace packets
  25. * in userspace, since they are logged as per-CPU data.
  26. *
  27. * atomic_t should always be a 32-bit signed integer. Wraparound is not
  28. * likely to occur, but userspace can deal with it by expecting a certain
  29. * sequence number in the next packet that will be read.
  30. */
  31. static atomic_t kmemtrace_seq_num;
  32. #define KMEMTRACE_ABI_VERSION 1
  33. static u32 kmemtrace_abi_version __read_mostly = KMEMTRACE_ABI_VERSION;
  34. enum kmemtrace_event_id {
  35. KMEMTRACE_EVENT_ALLOC = 0,
  36. KMEMTRACE_EVENT_FREE,
  37. };
  38. struct kmemtrace_event {
  39. u8 event_id;
  40. u8 type_id;
  41. u16 event_size;
  42. s32 seq_num;
  43. u64 call_site;
  44. u64 ptr;
  45. } __attribute__ ((__packed__));
  46. struct kmemtrace_stats_alloc {
  47. u64 bytes_req;
  48. u64 bytes_alloc;
  49. u32 gfp_flags;
  50. s32 numa_node;
  51. } __attribute__ ((__packed__));
  52. static void kmemtrace_probe_alloc(void *probe_data, void *call_data,
  53. const char *format, va_list *args)
  54. {
  55. unsigned long flags;
  56. struct kmemtrace_event *ev;
  57. struct kmemtrace_stats_alloc *stats;
  58. void *buf;
  59. local_irq_save(flags);
  60. buf = relay_reserve(kmemtrace_chan,
  61. sizeof(struct kmemtrace_event) +
  62. sizeof(struct kmemtrace_stats_alloc));
  63. if (!buf)
  64. goto failed;
  65. /*
  66. * Don't convert this to use structure initializers,
  67. * C99 does not guarantee the rvalues evaluation order.
  68. */
  69. ev = buf;
  70. ev->event_id = KMEMTRACE_EVENT_ALLOC;
  71. ev->type_id = va_arg(*args, int);
  72. ev->event_size = sizeof(struct kmemtrace_event) +
  73. sizeof(struct kmemtrace_stats_alloc);
  74. ev->seq_num = atomic_add_return(1, &kmemtrace_seq_num);
  75. ev->call_site = va_arg(*args, unsigned long);
  76. ev->ptr = va_arg(*args, unsigned long);
  77. stats = buf + sizeof(struct kmemtrace_event);
  78. stats->bytes_req = va_arg(*args, unsigned long);
  79. stats->bytes_alloc = va_arg(*args, unsigned long);
  80. stats->gfp_flags = va_arg(*args, unsigned long);
  81. stats->numa_node = va_arg(*args, int);
  82. failed:
  83. local_irq_restore(flags);
  84. }
  85. static void kmemtrace_probe_free(void *probe_data, void *call_data,
  86. const char *format, va_list *args)
  87. {
  88. unsigned long flags;
  89. struct kmemtrace_event *ev;
  90. local_irq_save(flags);
  91. ev = relay_reserve(kmemtrace_chan, sizeof(struct kmemtrace_event));
  92. if (!ev)
  93. goto failed;
  94. /*
  95. * Don't convert this to use structure initializers,
  96. * C99 does not guarantee the rvalues evaluation order.
  97. */
  98. ev->event_id = KMEMTRACE_EVENT_FREE;
  99. ev->type_id = va_arg(*args, int);
  100. ev->event_size = sizeof(struct kmemtrace_event);
  101. ev->seq_num = atomic_add_return(1, &kmemtrace_seq_num);
  102. ev->call_site = va_arg(*args, unsigned long);
  103. ev->ptr = va_arg(*args, unsigned long);
  104. failed:
  105. local_irq_restore(flags);
  106. }
  107. static struct dentry *
  108. kmemtrace_create_buf_file(const char *filename, struct dentry *parent,
  109. int mode, struct rchan_buf *buf, int *is_global)
  110. {
  111. return debugfs_create_file(filename, mode, parent, buf,
  112. &relay_file_operations);
  113. }
  114. static int kmemtrace_remove_buf_file(struct dentry *dentry)
  115. {
  116. debugfs_remove(dentry);
  117. return 0;
  118. }
  119. static int kmemtrace_subbuf_start(struct rchan_buf *buf,
  120. void *subbuf,
  121. void *prev_subbuf,
  122. size_t prev_padding)
  123. {
  124. if (relay_buf_full(buf)) {
  125. /*
  126. * We know it's not SMP-safe, but neither
  127. * debugfs_create_u32() is.
  128. */
  129. kmemtrace_buf_overruns++;
  130. return 0;
  131. }
  132. return 1;
  133. }
  134. static struct rchan_callbacks relay_callbacks = {
  135. .create_buf_file = kmemtrace_create_buf_file,
  136. .remove_buf_file = kmemtrace_remove_buf_file,
  137. .subbuf_start = kmemtrace_subbuf_start,
  138. };
  139. static struct dentry *kmemtrace_dir;
  140. static struct dentry *kmemtrace_overruns_dentry;
  141. static struct dentry *kmemtrace_abi_version_dentry;
  142. static struct dentry *kmemtrace_enabled_dentry;
  143. static int kmemtrace_start_probes(void)
  144. {
  145. int err;
  146. err = marker_probe_register("kmemtrace_alloc", "type_id %d "
  147. "call_site %lu ptr %lu "
  148. "bytes_req %lu bytes_alloc %lu "
  149. "gfp_flags %lu node %d",
  150. kmemtrace_probe_alloc, NULL);
  151. if (err)
  152. return err;
  153. err = marker_probe_register("kmemtrace_free", "type_id %d "
  154. "call_site %lu ptr %lu",
  155. kmemtrace_probe_free, NULL);
  156. return err;
  157. }
  158. static void kmemtrace_stop_probes(void)
  159. {
  160. marker_probe_unregister("kmemtrace_alloc",
  161. kmemtrace_probe_alloc, NULL);
  162. marker_probe_unregister("kmemtrace_free",
  163. kmemtrace_probe_free, NULL);
  164. }
  165. static int kmemtrace_enabled_get(void *data, u64 *val)
  166. {
  167. *val = *((int *) data);
  168. return 0;
  169. }
  170. static int kmemtrace_enabled_set(void *data, u64 val)
  171. {
  172. u64 old_val = kmemtrace_enabled;
  173. *((int *) data) = !!val;
  174. if (old_val == val)
  175. return 0;
  176. if (val)
  177. kmemtrace_start_probes();
  178. else
  179. kmemtrace_stop_probes();
  180. return 0;
  181. }
  182. DEFINE_SIMPLE_ATTRIBUTE(kmemtrace_enabled_fops,
  183. kmemtrace_enabled_get,
  184. kmemtrace_enabled_set, "%llu\n");
  185. static void kmemtrace_cleanup(void)
  186. {
  187. if (kmemtrace_enabled_dentry)
  188. debugfs_remove(kmemtrace_enabled_dentry);
  189. kmemtrace_stop_probes();
  190. if (kmemtrace_abi_version_dentry)
  191. debugfs_remove(kmemtrace_abi_version_dentry);
  192. if (kmemtrace_overruns_dentry)
  193. debugfs_remove(kmemtrace_overruns_dentry);
  194. relay_close(kmemtrace_chan);
  195. kmemtrace_chan = NULL;
  196. if (kmemtrace_dir)
  197. debugfs_remove(kmemtrace_dir);
  198. }
  199. static int __init kmemtrace_setup_late(void)
  200. {
  201. if (!kmemtrace_chan)
  202. goto failed;
  203. kmemtrace_dir = debugfs_create_dir("kmemtrace", NULL);
  204. if (!kmemtrace_dir)
  205. goto cleanup;
  206. kmemtrace_abi_version_dentry =
  207. debugfs_create_u32("abi_version", S_IRUSR,
  208. kmemtrace_dir, &kmemtrace_abi_version);
  209. kmemtrace_overruns_dentry =
  210. debugfs_create_u32("total_overruns", S_IRUSR,
  211. kmemtrace_dir, &kmemtrace_buf_overruns);
  212. if (!kmemtrace_overruns_dentry || !kmemtrace_abi_version_dentry)
  213. goto cleanup;
  214. kmemtrace_enabled_dentry =
  215. debugfs_create_file("enabled", S_IRUSR | S_IWUSR,
  216. kmemtrace_dir, &kmemtrace_enabled,
  217. &kmemtrace_enabled_fops);
  218. if (!kmemtrace_enabled_dentry)
  219. goto cleanup;
  220. if (relay_late_setup_files(kmemtrace_chan, "cpu", kmemtrace_dir))
  221. goto cleanup;
  222. printk(KERN_INFO "kmemtrace: fully up.\n");
  223. return 0;
  224. cleanup:
  225. kmemtrace_cleanup();
  226. failed:
  227. return 1;
  228. }
  229. late_initcall(kmemtrace_setup_late);
  230. static int __init kmemtrace_set_boot_enabled(char *str)
  231. {
  232. if (!str)
  233. return -EINVAL;
  234. if (!strcmp(str, "yes"))
  235. kmemtrace_enabled = 1;
  236. else if (!strcmp(str, "no"))
  237. kmemtrace_enabled = 0;
  238. else
  239. return -EINVAL;
  240. return 0;
  241. }
  242. early_param("kmemtrace.enable", kmemtrace_set_boot_enabled);
  243. static int __init kmemtrace_set_subbufs(char *str)
  244. {
  245. get_option(&str, &kmemtrace_n_subbufs);
  246. return 0;
  247. }
  248. early_param("kmemtrace.subbufs", kmemtrace_set_subbufs);
  249. void kmemtrace_init(void)
  250. {
  251. if (!kmemtrace_n_subbufs)
  252. kmemtrace_n_subbufs = KMEMTRACE_DEF_N_SUBBUFS;
  253. kmemtrace_chan = relay_open(NULL, NULL, KMEMTRACE_SUBBUF_SIZE,
  254. kmemtrace_n_subbufs, &relay_callbacks,
  255. NULL);
  256. if (!kmemtrace_chan) {
  257. printk(KERN_ERR "kmemtrace: could not open relay channel.\n");
  258. return;
  259. }
  260. if (!kmemtrace_enabled) {
  261. printk(KERN_INFO "kmemtrace: disabled. Pass "
  262. "kemtrace.enable=yes as kernel parameter for "
  263. "boot-time tracing.");
  264. return;
  265. }
  266. if (kmemtrace_start_probes()) {
  267. printk(KERN_ERR "kmemtrace: could not register marker probes!\n");
  268. kmemtrace_cleanup();
  269. return;
  270. }
  271. printk(KERN_INFO "kmemtrace: enabled.\n");
  272. }