1e5a81b62SSteven Rostedt /* 2e5a81b62SSteven Rostedt * Copyright (C) 2008 Steven Rostedt <[email protected]> 3e5a81b62SSteven Rostedt * 4e5a81b62SSteven Rostedt */ 5e5a81b62SSteven Rostedt #include <linux/stacktrace.h> 6e5a81b62SSteven Rostedt #include <linux/kallsyms.h> 7e5a81b62SSteven Rostedt #include <linux/seq_file.h> 8e5a81b62SSteven Rostedt #include <linux/spinlock.h> 9e5a81b62SSteven Rostedt #include <linux/uaccess.h> 10e5a81b62SSteven Rostedt #include <linux/debugfs.h> 11e5a81b62SSteven Rostedt #include <linux/ftrace.h> 12e5a81b62SSteven Rostedt #include <linux/module.h> 13f38f1d2aSSteven Rostedt #include <linux/sysctl.h> 14e5a81b62SSteven Rostedt #include <linux/init.h> 15e5a81b62SSteven Rostedt #include <linux/fs.h> 16e5a81b62SSteven Rostedt #include "trace.h" 17e5a81b62SSteven Rostedt 18e5a81b62SSteven Rostedt #define STACK_TRACE_ENTRIES 500 19e5a81b62SSteven Rostedt 201b6cced6SSteven Rostedt static unsigned long stack_dump_trace[STACK_TRACE_ENTRIES+1] = 211b6cced6SSteven Rostedt { [0 ... (STACK_TRACE_ENTRIES)] = ULONG_MAX }; 221b6cced6SSteven Rostedt static unsigned stack_dump_index[STACK_TRACE_ENTRIES]; 231b6cced6SSteven Rostedt 24e5a81b62SSteven Rostedt static struct stack_trace max_stack_trace = { 25e5a81b62SSteven Rostedt .max_entries = STACK_TRACE_ENTRIES, 26e5a81b62SSteven Rostedt .entries = stack_dump_trace, 27e5a81b62SSteven Rostedt }; 28e5a81b62SSteven Rostedt 29e5a81b62SSteven Rostedt static unsigned long max_stack_size; 30445c8951SThomas Gleixner static arch_spinlock_t max_stack_lock = 31edc35bd7SThomas Gleixner (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; 32e5a81b62SSteven Rostedt 33e5a81b62SSteven Rostedt static int stack_trace_disabled __read_mostly; 34e5a81b62SSteven Rostedt static DEFINE_PER_CPU(int, trace_active); 35f38f1d2aSSteven Rostedt static DEFINE_MUTEX(stack_sysctl_mutex); 36f38f1d2aSSteven Rostedt 37f38f1d2aSSteven Rostedt int stack_tracer_enabled; 38f38f1d2aSSteven Rostedt static int last_stack_tracer_enabled; 39e5a81b62SSteven Rostedt 40e5a81b62SSteven Rostedt static inline void check_stack(void) 41e5a81b62SSteven Rostedt { 421b6cced6SSteven Rostedt unsigned long this_size, flags; 431b6cced6SSteven Rostedt unsigned long *p, *top, *start; 441b6cced6SSteven Rostedt int i; 45e5a81b62SSteven Rostedt 46e5a81b62SSteven Rostedt this_size = ((unsigned long)&this_size) & (THREAD_SIZE-1); 47e5a81b62SSteven Rostedt this_size = THREAD_SIZE - this_size; 48e5a81b62SSteven Rostedt 49e5a81b62SSteven Rostedt if (this_size <= max_stack_size) 50e5a81b62SSteven Rostedt return; 51e5a81b62SSteven Rostedt 5281520a1bSSteven Rostedt /* we do not handle interrupt stacks yet */ 5381520a1bSSteven Rostedt if (!object_is_on_stack(&this_size)) 5481520a1bSSteven Rostedt return; 5581520a1bSSteven Rostedt 56a5e25883SSteven Rostedt local_irq_save(flags); 57*0199c4e6SThomas Gleixner arch_spin_lock(&max_stack_lock); 58e5a81b62SSteven Rostedt 59e5a81b62SSteven Rostedt /* a race could have already updated it */ 60e5a81b62SSteven Rostedt if (this_size <= max_stack_size) 61e5a81b62SSteven Rostedt goto out; 62e5a81b62SSteven Rostedt 63e5a81b62SSteven Rostedt max_stack_size = this_size; 64e5a81b62SSteven Rostedt 65e5a81b62SSteven Rostedt max_stack_trace.nr_entries = 0; 661b6cced6SSteven Rostedt max_stack_trace.skip = 3; 67e5a81b62SSteven Rostedt 68e5a81b62SSteven Rostedt save_stack_trace(&max_stack_trace); 69e5a81b62SSteven Rostedt 701b6cced6SSteven Rostedt /* 711b6cced6SSteven Rostedt * Now find where in the stack these are. 721b6cced6SSteven Rostedt */ 731b6cced6SSteven Rostedt i = 0; 741b6cced6SSteven Rostedt start = &this_size; 751b6cced6SSteven Rostedt top = (unsigned long *) 761b6cced6SSteven Rostedt (((unsigned long)start & ~(THREAD_SIZE-1)) + THREAD_SIZE); 771b6cced6SSteven Rostedt 781b6cced6SSteven Rostedt /* 791b6cced6SSteven Rostedt * Loop through all the entries. One of the entries may 801b6cced6SSteven Rostedt * for some reason be missed on the stack, so we may 811b6cced6SSteven Rostedt * have to account for them. If they are all there, this 821b6cced6SSteven Rostedt * loop will only happen once. This code only takes place 831b6cced6SSteven Rostedt * on a new max, so it is far from a fast path. 841b6cced6SSteven Rostedt */ 851b6cced6SSteven Rostedt while (i < max_stack_trace.nr_entries) { 860a37119dSSteven Rostedt int found = 0; 871b6cced6SSteven Rostedt 881b6cced6SSteven Rostedt stack_dump_index[i] = this_size; 891b6cced6SSteven Rostedt p = start; 901b6cced6SSteven Rostedt 911b6cced6SSteven Rostedt for (; p < top && i < max_stack_trace.nr_entries; p++) { 921b6cced6SSteven Rostedt if (*p == stack_dump_trace[i]) { 931b6cced6SSteven Rostedt this_size = stack_dump_index[i++] = 941b6cced6SSteven Rostedt (top - p) * sizeof(unsigned long); 950a37119dSSteven Rostedt found = 1; 961b6cced6SSteven Rostedt /* Start the search from here */ 971b6cced6SSteven Rostedt start = p + 1; 981b6cced6SSteven Rostedt } 991b6cced6SSteven Rostedt } 1001b6cced6SSteven Rostedt 1010a37119dSSteven Rostedt if (!found) 1021b6cced6SSteven Rostedt i++; 1031b6cced6SSteven Rostedt } 1041b6cced6SSteven Rostedt 105e5a81b62SSteven Rostedt out: 106*0199c4e6SThomas Gleixner arch_spin_unlock(&max_stack_lock); 107a5e25883SSteven Rostedt local_irq_restore(flags); 108e5a81b62SSteven Rostedt } 109e5a81b62SSteven Rostedt 110e5a81b62SSteven Rostedt static void 111e5a81b62SSteven Rostedt stack_trace_call(unsigned long ip, unsigned long parent_ip) 112e5a81b62SSteven Rostedt { 113e5a81b62SSteven Rostedt int cpu, resched; 114e5a81b62SSteven Rostedt 115e5a81b62SSteven Rostedt if (unlikely(!ftrace_enabled || stack_trace_disabled)) 116e5a81b62SSteven Rostedt return; 117e5a81b62SSteven Rostedt 118182e9f5fSSteven Rostedt resched = ftrace_preempt_disable(); 119e5a81b62SSteven Rostedt 120e5a81b62SSteven Rostedt cpu = raw_smp_processor_id(); 121e5a81b62SSteven Rostedt /* no atomic needed, we only modify this variable by this cpu */ 122e5a81b62SSteven Rostedt if (per_cpu(trace_active, cpu)++ != 0) 123e5a81b62SSteven Rostedt goto out; 124e5a81b62SSteven Rostedt 125e5a81b62SSteven Rostedt check_stack(); 126e5a81b62SSteven Rostedt 127e5a81b62SSteven Rostedt out: 128e5a81b62SSteven Rostedt per_cpu(trace_active, cpu)--; 129e5a81b62SSteven Rostedt /* prevent recursion in schedule */ 130182e9f5fSSteven Rostedt ftrace_preempt_enable(resched); 131e5a81b62SSteven Rostedt } 132e5a81b62SSteven Rostedt 133e5a81b62SSteven Rostedt static struct ftrace_ops trace_ops __read_mostly = 134e5a81b62SSteven Rostedt { 135e5a81b62SSteven Rostedt .func = stack_trace_call, 136e5a81b62SSteven Rostedt }; 137e5a81b62SSteven Rostedt 138e5a81b62SSteven Rostedt static ssize_t 139e5a81b62SSteven Rostedt stack_max_size_read(struct file *filp, char __user *ubuf, 140e5a81b62SSteven Rostedt size_t count, loff_t *ppos) 141e5a81b62SSteven Rostedt { 142e5a81b62SSteven Rostedt unsigned long *ptr = filp->private_data; 143e5a81b62SSteven Rostedt char buf[64]; 144e5a81b62SSteven Rostedt int r; 145e5a81b62SSteven Rostedt 146e5a81b62SSteven Rostedt r = snprintf(buf, sizeof(buf), "%ld\n", *ptr); 147e5a81b62SSteven Rostedt if (r > sizeof(buf)) 148e5a81b62SSteven Rostedt r = sizeof(buf); 149e5a81b62SSteven Rostedt return simple_read_from_buffer(ubuf, count, ppos, buf, r); 150e5a81b62SSteven Rostedt } 151e5a81b62SSteven Rostedt 152e5a81b62SSteven Rostedt static ssize_t 153e5a81b62SSteven Rostedt stack_max_size_write(struct file *filp, const char __user *ubuf, 154e5a81b62SSteven Rostedt size_t count, loff_t *ppos) 155e5a81b62SSteven Rostedt { 156e5a81b62SSteven Rostedt long *ptr = filp->private_data; 157e5a81b62SSteven Rostedt unsigned long val, flags; 158e5a81b62SSteven Rostedt char buf[64]; 159e5a81b62SSteven Rostedt int ret; 160e5a81b62SSteven Rostedt 161e5a81b62SSteven Rostedt if (count >= sizeof(buf)) 162e5a81b62SSteven Rostedt return -EINVAL; 163e5a81b62SSteven Rostedt 164e5a81b62SSteven Rostedt if (copy_from_user(&buf, ubuf, count)) 165e5a81b62SSteven Rostedt return -EFAULT; 166e5a81b62SSteven Rostedt 167e5a81b62SSteven Rostedt buf[count] = 0; 168e5a81b62SSteven Rostedt 169e5a81b62SSteven Rostedt ret = strict_strtoul(buf, 10, &val); 170e5a81b62SSteven Rostedt if (ret < 0) 171e5a81b62SSteven Rostedt return ret; 172e5a81b62SSteven Rostedt 173a5e25883SSteven Rostedt local_irq_save(flags); 174*0199c4e6SThomas Gleixner arch_spin_lock(&max_stack_lock); 175e5a81b62SSteven Rostedt *ptr = val; 176*0199c4e6SThomas Gleixner arch_spin_unlock(&max_stack_lock); 177a5e25883SSteven Rostedt local_irq_restore(flags); 178e5a81b62SSteven Rostedt 179e5a81b62SSteven Rostedt return count; 180e5a81b62SSteven Rostedt } 181e5a81b62SSteven Rostedt 182f38f1d2aSSteven Rostedt static const struct file_operations stack_max_size_fops = { 183e5a81b62SSteven Rostedt .open = tracing_open_generic, 184e5a81b62SSteven Rostedt .read = stack_max_size_read, 185e5a81b62SSteven Rostedt .write = stack_max_size_write, 186e5a81b62SSteven Rostedt }; 187e5a81b62SSteven Rostedt 188e5a81b62SSteven Rostedt static void * 1892fc5f0cfSLi Zefan __next(struct seq_file *m, loff_t *pos) 190e5a81b62SSteven Rostedt { 1912fc5f0cfSLi Zefan long n = *pos - 1; 192e5a81b62SSteven Rostedt 1932fc5f0cfSLi Zefan if (n >= max_stack_trace.nr_entries || stack_dump_trace[n] == ULONG_MAX) 194e5a81b62SSteven Rostedt return NULL; 195e5a81b62SSteven Rostedt 1962fc5f0cfSLi Zefan m->private = (void *)n; 1971b6cced6SSteven Rostedt return &m->private; 198e5a81b62SSteven Rostedt } 199e5a81b62SSteven Rostedt 2002fc5f0cfSLi Zefan static void * 2012fc5f0cfSLi Zefan t_next(struct seq_file *m, void *v, loff_t *pos) 2022fc5f0cfSLi Zefan { 2032fc5f0cfSLi Zefan (*pos)++; 2042fc5f0cfSLi Zefan return __next(m, pos); 2052fc5f0cfSLi Zefan } 2062fc5f0cfSLi Zefan 207e5a81b62SSteven Rostedt static void *t_start(struct seq_file *m, loff_t *pos) 208e5a81b62SSteven Rostedt { 209e5a81b62SSteven Rostedt local_irq_disable(); 210*0199c4e6SThomas Gleixner arch_spin_lock(&max_stack_lock); 211e5a81b62SSteven Rostedt 212522a110bSLiming Wang if (*pos == 0) 213522a110bSLiming Wang return SEQ_START_TOKEN; 214522a110bSLiming Wang 2152fc5f0cfSLi Zefan return __next(m, pos); 216e5a81b62SSteven Rostedt } 217e5a81b62SSteven Rostedt 218e5a81b62SSteven Rostedt static void t_stop(struct seq_file *m, void *p) 219e5a81b62SSteven Rostedt { 220*0199c4e6SThomas Gleixner arch_spin_unlock(&max_stack_lock); 221e5a81b62SSteven Rostedt local_irq_enable(); 222e5a81b62SSteven Rostedt } 223e5a81b62SSteven Rostedt 2241b6cced6SSteven Rostedt static int trace_lookup_stack(struct seq_file *m, long i) 225e5a81b62SSteven Rostedt { 2261b6cced6SSteven Rostedt unsigned long addr = stack_dump_trace[i]; 227e5a81b62SSteven Rostedt 22879173bf5SXiao Guangrong return seq_printf(m, "%pF\n", (void *)addr); 229e5a81b62SSteven Rostedt } 230e5a81b62SSteven Rostedt 231e447e1dfSSteven Rostedt static void print_disabled(struct seq_file *m) 232e447e1dfSSteven Rostedt { 233e447e1dfSSteven Rostedt seq_puts(m, "#\n" 234e447e1dfSSteven Rostedt "# Stack tracer disabled\n" 235e447e1dfSSteven Rostedt "#\n" 236e447e1dfSSteven Rostedt "# To enable the stack tracer, either add 'stacktrace' to the\n" 237e447e1dfSSteven Rostedt "# kernel command line\n" 238e447e1dfSSteven Rostedt "# or 'echo 1 > /proc/sys/kernel/stack_tracer_enabled'\n" 239e447e1dfSSteven Rostedt "#\n"); 240e447e1dfSSteven Rostedt } 241e447e1dfSSteven Rostedt 242e5a81b62SSteven Rostedt static int t_show(struct seq_file *m, void *v) 243e5a81b62SSteven Rostedt { 244522a110bSLiming Wang long i; 2451b6cced6SSteven Rostedt int size; 246e5a81b62SSteven Rostedt 247522a110bSLiming Wang if (v == SEQ_START_TOKEN) { 2481b6cced6SSteven Rostedt seq_printf(m, " Depth Size Location" 2491b6cced6SSteven Rostedt " (%d entries)\n" 2501b6cced6SSteven Rostedt " ----- ---- --------\n", 251083a63b4Swalimis max_stack_trace.nr_entries - 1); 252e447e1dfSSteven Rostedt 253e447e1dfSSteven Rostedt if (!stack_tracer_enabled && !max_stack_size) 254e447e1dfSSteven Rostedt print_disabled(m); 255e447e1dfSSteven Rostedt 2561b6cced6SSteven Rostedt return 0; 2571b6cced6SSteven Rostedt } 2581b6cced6SSteven Rostedt 259522a110bSLiming Wang i = *(long *)v; 260522a110bSLiming Wang 2611b6cced6SSteven Rostedt if (i >= max_stack_trace.nr_entries || 2621b6cced6SSteven Rostedt stack_dump_trace[i] == ULONG_MAX) 263e5a81b62SSteven Rostedt return 0; 264e5a81b62SSteven Rostedt 2651b6cced6SSteven Rostedt if (i+1 == max_stack_trace.nr_entries || 2661b6cced6SSteven Rostedt stack_dump_trace[i+1] == ULONG_MAX) 2671b6cced6SSteven Rostedt size = stack_dump_index[i]; 2681b6cced6SSteven Rostedt else 2691b6cced6SSteven Rostedt size = stack_dump_index[i] - stack_dump_index[i+1]; 2701b6cced6SSteven Rostedt 2711b6cced6SSteven Rostedt seq_printf(m, "%3ld) %8d %5d ", i, stack_dump_index[i], size); 2721b6cced6SSteven Rostedt 2731b6cced6SSteven Rostedt trace_lookup_stack(m, i); 274e5a81b62SSteven Rostedt 275e5a81b62SSteven Rostedt return 0; 276e5a81b62SSteven Rostedt } 277e5a81b62SSteven Rostedt 278f38f1d2aSSteven Rostedt static const struct seq_operations stack_trace_seq_ops = { 279e5a81b62SSteven Rostedt .start = t_start, 280e5a81b62SSteven Rostedt .next = t_next, 281e5a81b62SSteven Rostedt .stop = t_stop, 282e5a81b62SSteven Rostedt .show = t_show, 283e5a81b62SSteven Rostedt }; 284e5a81b62SSteven Rostedt 285e5a81b62SSteven Rostedt static int stack_trace_open(struct inode *inode, struct file *file) 286e5a81b62SSteven Rostedt { 287d8cc1ab7SLi Zefan return seq_open(file, &stack_trace_seq_ops); 288e5a81b62SSteven Rostedt } 289e5a81b62SSteven Rostedt 290f38f1d2aSSteven Rostedt static const struct file_operations stack_trace_fops = { 291e5a81b62SSteven Rostedt .open = stack_trace_open, 292e5a81b62SSteven Rostedt .read = seq_read, 293e5a81b62SSteven Rostedt .llseek = seq_lseek, 294d8cc1ab7SLi Zefan .release = seq_release, 295e5a81b62SSteven Rostedt }; 296e5a81b62SSteven Rostedt 297f38f1d2aSSteven Rostedt int 298f38f1d2aSSteven Rostedt stack_trace_sysctl(struct ctl_table *table, int write, 2998d65af78SAlexey Dobriyan void __user *buffer, size_t *lenp, 300f38f1d2aSSteven Rostedt loff_t *ppos) 301f38f1d2aSSteven Rostedt { 302f38f1d2aSSteven Rostedt int ret; 303f38f1d2aSSteven Rostedt 304f38f1d2aSSteven Rostedt mutex_lock(&stack_sysctl_mutex); 305f38f1d2aSSteven Rostedt 3068d65af78SAlexey Dobriyan ret = proc_dointvec(table, write, buffer, lenp, ppos); 307f38f1d2aSSteven Rostedt 308f38f1d2aSSteven Rostedt if (ret || !write || 309a32c7765SLi Zefan (last_stack_tracer_enabled == !!stack_tracer_enabled)) 310f38f1d2aSSteven Rostedt goto out; 311f38f1d2aSSteven Rostedt 312a32c7765SLi Zefan last_stack_tracer_enabled = !!stack_tracer_enabled; 313f38f1d2aSSteven Rostedt 314f38f1d2aSSteven Rostedt if (stack_tracer_enabled) 315f38f1d2aSSteven Rostedt register_ftrace_function(&trace_ops); 316f38f1d2aSSteven Rostedt else 317f38f1d2aSSteven Rostedt unregister_ftrace_function(&trace_ops); 318f38f1d2aSSteven Rostedt 319f38f1d2aSSteven Rostedt out: 320f38f1d2aSSteven Rostedt mutex_unlock(&stack_sysctl_mutex); 321f38f1d2aSSteven Rostedt return ret; 322f38f1d2aSSteven Rostedt } 323f38f1d2aSSteven Rostedt 324f38f1d2aSSteven Rostedt static __init int enable_stacktrace(char *str) 325f38f1d2aSSteven Rostedt { 326e05a43b7SSteven Rostedt stack_tracer_enabled = 1; 327e05a43b7SSteven Rostedt last_stack_tracer_enabled = 1; 328f38f1d2aSSteven Rostedt return 1; 329f38f1d2aSSteven Rostedt } 330f38f1d2aSSteven Rostedt __setup("stacktrace", enable_stacktrace); 331f38f1d2aSSteven Rostedt 332e5a81b62SSteven Rostedt static __init int stack_trace_init(void) 333e5a81b62SSteven Rostedt { 334e5a81b62SSteven Rostedt struct dentry *d_tracer; 335e5a81b62SSteven Rostedt 336e5a81b62SSteven Rostedt d_tracer = tracing_init_dentry(); 337e5a81b62SSteven Rostedt 3385452af66SFrederic Weisbecker trace_create_file("stack_max_size", 0644, d_tracer, 339e5a81b62SSteven Rostedt &max_stack_size, &stack_max_size_fops); 340e5a81b62SSteven Rostedt 3415452af66SFrederic Weisbecker trace_create_file("stack_trace", 0444, d_tracer, 342e5a81b62SSteven Rostedt NULL, &stack_trace_fops); 343e5a81b62SSteven Rostedt 344e05a43b7SSteven Rostedt if (stack_tracer_enabled) 345e5a81b62SSteven Rostedt register_ftrace_function(&trace_ops); 346e5a81b62SSteven Rostedt 347e5a81b62SSteven Rostedt return 0; 348e5a81b62SSteven Rostedt } 349e5a81b62SSteven Rostedt 350e5a81b62SSteven Rostedt device_initcall(stack_trace_init); 351