aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-02-17 05:31:01 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-17 05:31:01 -0500
commitf492d3f8385a98f828e8220d14492337dc29e07b (patch)
tree31f22c83f7e45388955aacb45c425d7cb6a4d78c /kernel
parentc4e2b432d5b57e2faaeea048079b31c243079647 (diff)
parente110e3d1eaa0f9628918be67ddd32e8ad65a2871 (diff)
Merge branch 'tip/tracing/ftrace' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace into tracing/ftrace
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/ftrace.c929
-rw-r--r--kernel/trace/ring_buffer.c9
-rw-r--r--kernel/trace/trace_functions.c163
3 files changed, 904 insertions, 197 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 1796e018fbff..6533c1d20155 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -27,6 +27,7 @@
27#include <linux/sysctl.h> 27#include <linux/sysctl.h>
28#include <linux/ctype.h> 28#include <linux/ctype.h>
29#include <linux/list.h> 29#include <linux/list.h>
30#include <linux/hash.h>
30 31
31#include <asm/ftrace.h> 32#include <asm/ftrace.h>
32 33
@@ -44,14 +45,14 @@
44 ftrace_kill(); \ 45 ftrace_kill(); \
45 } while (0) 46 } while (0)
46 47
48/* hash bits for specific function selection */
49#define FTRACE_HASH_BITS 7
50#define FTRACE_FUNC_HASHSIZE (1 << FTRACE_HASH_BITS)
51
47/* ftrace_enabled is a method to turn ftrace on or off */ 52/* ftrace_enabled is a method to turn ftrace on or off */
48int ftrace_enabled __read_mostly; 53int ftrace_enabled __read_mostly;
49static int last_ftrace_enabled; 54static int last_ftrace_enabled;
50 55
51/* set when tracing only a pid */
52struct pid *ftrace_pid_trace;
53static struct pid * const ftrace_swapper_pid = &init_struct_pid;
54
55/* Quick disabling of function tracer. */ 56/* Quick disabling of function tracer. */
56int function_trace_stop; 57int function_trace_stop;
57 58
@@ -61,9 +62,7 @@ int function_trace_stop;
61 */ 62 */
62static int ftrace_disabled __read_mostly; 63static int ftrace_disabled __read_mostly;
63 64
64static DEFINE_SPINLOCK(ftrace_lock); 65static DEFINE_MUTEX(ftrace_lock);
65static DEFINE_MUTEX(ftrace_sysctl_lock);
66static DEFINE_MUTEX(ftrace_start_lock);
67 66
68static struct ftrace_ops ftrace_list_end __read_mostly = 67static struct ftrace_ops ftrace_list_end __read_mostly =
69{ 68{
@@ -134,9 +133,6 @@ static void ftrace_test_stop_func(unsigned long ip, unsigned long parent_ip)
134 133
135static int __register_ftrace_function(struct ftrace_ops *ops) 134static int __register_ftrace_function(struct ftrace_ops *ops)
136{ 135{
137 /* should not be called from interrupt context */
138 spin_lock(&ftrace_lock);
139
140 ops->next = ftrace_list; 136 ops->next = ftrace_list;
141 /* 137 /*
142 * We are entering ops into the ftrace_list but another 138 * We are entering ops into the ftrace_list but another
@@ -172,18 +168,12 @@ static int __register_ftrace_function(struct ftrace_ops *ops)
172#endif 168#endif
173 } 169 }
174 170
175 spin_unlock(&ftrace_lock);
176
177 return 0; 171 return 0;
178} 172}
179 173
180static int __unregister_ftrace_function(struct ftrace_ops *ops) 174static int __unregister_ftrace_function(struct ftrace_ops *ops)
181{ 175{
182 struct ftrace_ops **p; 176 struct ftrace_ops **p;
183 int ret = 0;
184
185 /* should not be called from interrupt context */
186 spin_lock(&ftrace_lock);
187 177
188 /* 178 /*
189 * If we are removing the last function, then simply point 179 * If we are removing the last function, then simply point
@@ -192,17 +182,15 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
192 if (ftrace_list == ops && ops->next == &ftrace_list_end) { 182 if (ftrace_list == ops && ops->next == &ftrace_list_end) {
193 ftrace_trace_function = ftrace_stub; 183 ftrace_trace_function = ftrace_stub;
194 ftrace_list = &ftrace_list_end; 184 ftrace_list = &ftrace_list_end;
195 goto out; 185 return 0;
196 } 186 }
197 187
198 for (p = &ftrace_list; *p != &ftrace_list_end; p = &(*p)->next) 188 for (p = &ftrace_list; *p != &ftrace_list_end; p = &(*p)->next)
199 if (*p == ops) 189 if (*p == ops)
200 break; 190 break;
201 191
202 if (*p != ops) { 192 if (*p != ops)
203 ret = -1; 193 return -1;
204 goto out;
205 }
206 194
207 *p = (*p)->next; 195 *p = (*p)->next;
208 196
@@ -223,18 +211,14 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
223 } 211 }
224 } 212 }
225 213
226 out: 214 return 0;
227 spin_unlock(&ftrace_lock);
228
229 return ret;
230} 215}
231 216
232static void ftrace_update_pid_func(void) 217static void ftrace_update_pid_func(void)
233{ 218{
234 ftrace_func_t func; 219 ftrace_func_t func;
235 220
236 /* should not be called from interrupt context */ 221 mutex_lock(&ftrace_lock);
237 spin_lock(&ftrace_lock);
238 222
239 if (ftrace_trace_function == ftrace_stub) 223 if (ftrace_trace_function == ftrace_stub)
240 goto out; 224 goto out;
@@ -256,7 +240,7 @@ static void ftrace_update_pid_func(void)
256#endif 240#endif
257 241
258 out: 242 out:
259 spin_unlock(&ftrace_lock); 243 mutex_unlock(&ftrace_lock);
260} 244}
261 245
262#ifdef CONFIG_DYNAMIC_FTRACE 246#ifdef CONFIG_DYNAMIC_FTRACE
@@ -264,6 +248,21 @@ static void ftrace_update_pid_func(void)
264# error Dynamic ftrace depends on MCOUNT_RECORD 248# error Dynamic ftrace depends on MCOUNT_RECORD
265#endif 249#endif
266 250
251/* set when tracing only a pid */
252struct pid *ftrace_pid_trace;
253static struct pid * const ftrace_swapper_pid = &init_struct_pid;
254static struct hlist_head ftrace_func_hash[FTRACE_FUNC_HASHSIZE] __read_mostly;
255
256struct ftrace_func_hook {
257 struct hlist_node node;
258 struct ftrace_hook_ops *ops;
259 unsigned long flags;
260 unsigned long ip;
261 void *data;
262 struct rcu_head rcu;
263};
264
265
267enum { 266enum {
268 FTRACE_ENABLE_CALLS = (1 << 0), 267 FTRACE_ENABLE_CALLS = (1 << 0),
269 FTRACE_DISABLE_CALLS = (1 << 1), 268 FTRACE_DISABLE_CALLS = (1 << 1),
@@ -297,6 +296,19 @@ static struct ftrace_page *ftrace_pages;
297 296
298static struct dyn_ftrace *ftrace_free_records; 297static struct dyn_ftrace *ftrace_free_records;
299 298
299/*
300 * This is a double for. Do not use 'break' to break out of the loop,
301 * you must use a goto.
302 */
303#define do_for_each_ftrace_rec(pg, rec) \
304 for (pg = ftrace_pages_start; pg; pg = pg->next) { \
305 int _____i; \
306 for (_____i = 0; _____i < pg->index; _____i++) { \
307 rec = &pg->records[_____i];
308
309#define while_for_each_ftrace_rec() \
310 } \
311 }
300 312
301#ifdef CONFIG_KPROBES 313#ifdef CONFIG_KPROBES
302 314
@@ -341,23 +353,16 @@ void ftrace_release(void *start, unsigned long size)
341 struct ftrace_page *pg; 353 struct ftrace_page *pg;
342 unsigned long s = (unsigned long)start; 354 unsigned long s = (unsigned long)start;
343 unsigned long e = s + size; 355 unsigned long e = s + size;
344 int i;
345 356
346 if (ftrace_disabled || !start) 357 if (ftrace_disabled || !start)
347 return; 358 return;
348 359
349 /* should not be called from interrupt context */ 360 mutex_lock(&ftrace_lock);
350 spin_lock(&ftrace_lock); 361 do_for_each_ftrace_rec(pg, rec) {
351 362 if ((rec->ip >= s) && (rec->ip < e))
352 for (pg = ftrace_pages_start; pg; pg = pg->next) { 363 ftrace_free_rec(rec);
353 for (i = 0; i < pg->index; i++) { 364 } while_for_each_ftrace_rec();
354 rec = &pg->records[i]; 365 mutex_unlock(&ftrace_lock);
355
356 if ((rec->ip >= s) && (rec->ip < e))
357 ftrace_free_rec(rec);
358 }
359 }
360 spin_unlock(&ftrace_lock);
361} 366}
362 367
363static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip) 368static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip)
@@ -523,41 +528,37 @@ __ftrace_replace_code(struct dyn_ftrace *rec, int enable)
523 528
524static void ftrace_replace_code(int enable) 529static void ftrace_replace_code(int enable)
525{ 530{
526 int i, failed; 531 int failed;
527 struct dyn_ftrace *rec; 532 struct dyn_ftrace *rec;
528 struct ftrace_page *pg; 533 struct ftrace_page *pg;
529 534
530 for (pg = ftrace_pages_start; pg; pg = pg->next) { 535 do_for_each_ftrace_rec(pg, rec) {
531 for (i = 0; i < pg->index; i++) { 536 /*
532 rec = &pg->records[i]; 537 * Skip over free records and records that have
533 538 * failed.
534 /* 539 */
535 * Skip over free records and records that have 540 if (rec->flags & FTRACE_FL_FREE ||
536 * failed. 541 rec->flags & FTRACE_FL_FAILED)
537 */ 542 continue;
538 if (rec->flags & FTRACE_FL_FREE ||
539 rec->flags & FTRACE_FL_FAILED)
540 continue;
541 543
542 /* ignore updates to this record's mcount site */ 544 /* ignore updates to this record's mcount site */
543 if (get_kprobe((void *)rec->ip)) { 545 if (get_kprobe((void *)rec->ip)) {
544 freeze_record(rec); 546 freeze_record(rec);
545 continue; 547 continue;
546 } else { 548 } else {
547 unfreeze_record(rec); 549 unfreeze_record(rec);
548 } 550 }
549 551
550 failed = __ftrace_replace_code(rec, enable); 552 failed = __ftrace_replace_code(rec, enable);
551 if (failed && (rec->flags & FTRACE_FL_CONVERTED)) { 553 if (failed && (rec->flags & FTRACE_FL_CONVERTED)) {
552 rec->flags |= FTRACE_FL_FAILED; 554 rec->flags |= FTRACE_FL_FAILED;
553 if ((system_state == SYSTEM_BOOTING) || 555 if ((system_state == SYSTEM_BOOTING) ||
554 !core_kernel_text(rec->ip)) { 556 !core_kernel_text(rec->ip)) {
555 ftrace_free_rec(rec); 557 ftrace_free_rec(rec);
556 } else 558 } else
557 ftrace_bug(failed, rec->ip); 559 ftrace_bug(failed, rec->ip);
558 }
559 } 560 }
560 } 561 } while_for_each_ftrace_rec();
561} 562}
562 563
563static int 564static int
@@ -623,13 +624,10 @@ static void ftrace_startup(int command)
623 if (unlikely(ftrace_disabled)) 624 if (unlikely(ftrace_disabled))
624 return; 625 return;
625 626
626 mutex_lock(&ftrace_start_lock);
627 ftrace_start_up++; 627 ftrace_start_up++;
628 command |= FTRACE_ENABLE_CALLS; 628 command |= FTRACE_ENABLE_CALLS;
629 629
630 ftrace_startup_enable(command); 630 ftrace_startup_enable(command);
631
632 mutex_unlock(&ftrace_start_lock);
633} 631}
634 632
635static void ftrace_shutdown(int command) 633static void ftrace_shutdown(int command)
@@ -637,7 +635,6 @@ static void ftrace_shutdown(int command)
637 if (unlikely(ftrace_disabled)) 635 if (unlikely(ftrace_disabled))
638 return; 636 return;
639 637
640 mutex_lock(&ftrace_start_lock);
641 ftrace_start_up--; 638 ftrace_start_up--;
642 if (!ftrace_start_up) 639 if (!ftrace_start_up)
643 command |= FTRACE_DISABLE_CALLS; 640 command |= FTRACE_DISABLE_CALLS;
@@ -648,11 +645,9 @@ static void ftrace_shutdown(int command)
648 } 645 }
649 646
650 if (!command || !ftrace_enabled) 647 if (!command || !ftrace_enabled)
651 goto out; 648 return;
652 649
653 ftrace_run_update_code(command); 650 ftrace_run_update_code(command);
654 out:
655 mutex_unlock(&ftrace_start_lock);
656} 651}
657 652
658static void ftrace_startup_sysctl(void) 653static void ftrace_startup_sysctl(void)
@@ -662,7 +657,6 @@ static void ftrace_startup_sysctl(void)
662 if (unlikely(ftrace_disabled)) 657 if (unlikely(ftrace_disabled))
663 return; 658 return;
664 659
665 mutex_lock(&ftrace_start_lock);
666 /* Force update next time */ 660 /* Force update next time */
667 saved_ftrace_func = NULL; 661 saved_ftrace_func = NULL;
668 /* ftrace_start_up is true if we want ftrace running */ 662 /* ftrace_start_up is true if we want ftrace running */
@@ -670,7 +664,6 @@ static void ftrace_startup_sysctl(void)
670 command |= FTRACE_ENABLE_CALLS; 664 command |= FTRACE_ENABLE_CALLS;
671 665
672 ftrace_run_update_code(command); 666 ftrace_run_update_code(command);
673 mutex_unlock(&ftrace_start_lock);
674} 667}
675 668
676static void ftrace_shutdown_sysctl(void) 669static void ftrace_shutdown_sysctl(void)
@@ -680,13 +673,11 @@ static void ftrace_shutdown_sysctl(void)
680 if (unlikely(ftrace_disabled)) 673 if (unlikely(ftrace_disabled))
681 return; 674 return;
682 675
683 mutex_lock(&ftrace_start_lock);
684 /* ftrace_start_up is true if ftrace is running */ 676 /* ftrace_start_up is true if ftrace is running */
685 if (ftrace_start_up) 677 if (ftrace_start_up)
686 command |= FTRACE_DISABLE_CALLS; 678 command |= FTRACE_DISABLE_CALLS;
687 679
688 ftrace_run_update_code(command); 680 ftrace_run_update_code(command);
689 mutex_unlock(&ftrace_start_lock);
690} 681}
691 682
692static cycle_t ftrace_update_time; 683static cycle_t ftrace_update_time;
@@ -773,12 +764,15 @@ enum {
773 FTRACE_ITER_CONT = (1 << 1), 764 FTRACE_ITER_CONT = (1 << 1),
774 FTRACE_ITER_NOTRACE = (1 << 2), 765 FTRACE_ITER_NOTRACE = (1 << 2),
775 FTRACE_ITER_FAILURES = (1 << 3), 766 FTRACE_ITER_FAILURES = (1 << 3),
767 FTRACE_ITER_PRINTALL = (1 << 4),
768 FTRACE_ITER_HASH = (1 << 5),
776}; 769};
777 770
778#define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ 771#define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */
779 772
780struct ftrace_iterator { 773struct ftrace_iterator {
781 struct ftrace_page *pg; 774 struct ftrace_page *pg;
775 int hidx;
782 int idx; 776 int idx;
783 unsigned flags; 777 unsigned flags;
784 unsigned char buffer[FTRACE_BUFF_MAX+1]; 778 unsigned char buffer[FTRACE_BUFF_MAX+1];
@@ -787,15 +781,89 @@ struct ftrace_iterator {
787}; 781};
788 782
789static void * 783static void *
784t_hash_next(struct seq_file *m, void *v, loff_t *pos)
785{
786 struct ftrace_iterator *iter = m->private;
787 struct hlist_node *hnd = v;
788 struct hlist_head *hhd;
789
790 WARN_ON(!(iter->flags & FTRACE_ITER_HASH));
791
792 (*pos)++;
793
794 retry:
795 if (iter->hidx >= FTRACE_FUNC_HASHSIZE)
796 return NULL;
797
798 hhd = &ftrace_func_hash[iter->hidx];
799
800 if (hlist_empty(hhd)) {
801 iter->hidx++;
802 hnd = NULL;
803 goto retry;
804 }
805
806 if (!hnd)
807 hnd = hhd->first;
808 else {
809 hnd = hnd->next;
810 if (!hnd) {
811 iter->hidx++;
812 goto retry;
813 }
814 }
815
816 return hnd;
817}
818
819static void *t_hash_start(struct seq_file *m, loff_t *pos)
820{
821 struct ftrace_iterator *iter = m->private;
822 void *p = NULL;
823
824 iter->flags |= FTRACE_ITER_HASH;
825
826 return t_hash_next(m, p, pos);
827}
828
829static int t_hash_show(struct seq_file *m, void *v)
830{
831 struct ftrace_func_hook *rec;
832 struct hlist_node *hnd = v;
833 char str[KSYM_SYMBOL_LEN];
834
835 rec = hlist_entry(hnd, struct ftrace_func_hook, node);
836
837 if (rec->ops->print)
838 return rec->ops->print(m, rec->ip, rec->ops, rec->data);
839
840 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
841 seq_printf(m, "%s:", str);
842
843 kallsyms_lookup((unsigned long)rec->ops->func, NULL, NULL, NULL, str);
844 seq_printf(m, "%s", str);
845
846 if (rec->data)
847 seq_printf(m, ":%p", rec->data);
848 seq_putc(m, '\n');
849
850 return 0;
851}
852
853static void *
790t_next(struct seq_file *m, void *v, loff_t *pos) 854t_next(struct seq_file *m, void *v, loff_t *pos)
791{ 855{
792 struct ftrace_iterator *iter = m->private; 856 struct ftrace_iterator *iter = m->private;
793 struct dyn_ftrace *rec = NULL; 857 struct dyn_ftrace *rec = NULL;
794 858
859 if (iter->flags & FTRACE_ITER_HASH)
860 return t_hash_next(m, v, pos);
861
795 (*pos)++; 862 (*pos)++;
796 863
797 /* should not be called from interrupt context */ 864 if (iter->flags & FTRACE_ITER_PRINTALL)
798 spin_lock(&ftrace_lock); 865 return NULL;
866
799 retry: 867 retry:
800 if (iter->idx >= iter->pg->index) { 868 if (iter->idx >= iter->pg->index) {
801 if (iter->pg->next) { 869 if (iter->pg->next) {
@@ -824,7 +892,6 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
824 goto retry; 892 goto retry;
825 } 893 }
826 } 894 }
827 spin_unlock(&ftrace_lock);
828 895
829 return rec; 896 return rec;
830} 897}
@@ -834,6 +901,23 @@ static void *t_start(struct seq_file *m, loff_t *pos)
834 struct ftrace_iterator *iter = m->private; 901 struct ftrace_iterator *iter = m->private;
835 void *p = NULL; 902 void *p = NULL;
836 903
904 mutex_lock(&ftrace_lock);
905 /*
906 * For set_ftrace_filter reading, if we have the filter
907 * off, we can short cut and just print out that all
908 * functions are enabled.
909 */
910 if (iter->flags & FTRACE_ITER_FILTER && !ftrace_filtered) {
911 if (*pos > 0)
912 return t_hash_start(m, pos);
913 iter->flags |= FTRACE_ITER_PRINTALL;
914 (*pos)++;
915 return iter;
916 }
917
918 if (iter->flags & FTRACE_ITER_HASH)
919 return t_hash_start(m, pos);
920
837 if (*pos > 0) { 921 if (*pos > 0) {
838 if (iter->idx < 0) 922 if (iter->idx < 0)
839 return p; 923 return p;
@@ -843,18 +927,31 @@ static void *t_start(struct seq_file *m, loff_t *pos)
843 927
844 p = t_next(m, p, pos); 928 p = t_next(m, p, pos);
845 929
930 if (!p)
931 return t_hash_start(m, pos);
932
846 return p; 933 return p;
847} 934}
848 935
849static void t_stop(struct seq_file *m, void *p) 936static void t_stop(struct seq_file *m, void *p)
850{ 937{
938 mutex_unlock(&ftrace_lock);
851} 939}
852 940
853static int t_show(struct seq_file *m, void *v) 941static int t_show(struct seq_file *m, void *v)
854{ 942{
943 struct ftrace_iterator *iter = m->private;
855 struct dyn_ftrace *rec = v; 944 struct dyn_ftrace *rec = v;
856 char str[KSYM_SYMBOL_LEN]; 945 char str[KSYM_SYMBOL_LEN];
857 946
947 if (iter->flags & FTRACE_ITER_HASH)
948 return t_hash_show(m, v);
949
950 if (iter->flags & FTRACE_ITER_PRINTALL) {
951 seq_printf(m, "#### all functions enabled ####\n");
952 return 0;
953 }
954
858 if (!rec) 955 if (!rec)
859 return 0; 956 return 0;
860 957
@@ -933,23 +1030,16 @@ static void ftrace_filter_reset(int enable)
933 struct ftrace_page *pg; 1030 struct ftrace_page *pg;
934 struct dyn_ftrace *rec; 1031 struct dyn_ftrace *rec;
935 unsigned long type = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; 1032 unsigned long type = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
936 unsigned i;
937 1033
938 /* should not be called from interrupt context */ 1034 mutex_lock(&ftrace_lock);
939 spin_lock(&ftrace_lock);
940 if (enable) 1035 if (enable)
941 ftrace_filtered = 0; 1036 ftrace_filtered = 0;
942 pg = ftrace_pages_start; 1037 do_for_each_ftrace_rec(pg, rec) {
943 while (pg) { 1038 if (rec->flags & FTRACE_FL_FAILED)
944 for (i = 0; i < pg->index; i++) { 1039 continue;
945 rec = &pg->records[i]; 1040 rec->flags &= ~type;
946 if (rec->flags & FTRACE_FL_FAILED) 1041 } while_for_each_ftrace_rec();
947 continue; 1042 mutex_unlock(&ftrace_lock);
948 rec->flags &= ~type;
949 }
950 pg = pg->next;
951 }
952 spin_unlock(&ftrace_lock);
953} 1043}
954 1044
955static int 1045static int
@@ -1030,86 +1120,533 @@ enum {
1030 MATCH_END_ONLY, 1120 MATCH_END_ONLY,
1031}; 1121};
1032 1122
1033static void 1123/*
1034ftrace_match(unsigned char *buff, int len, int enable) 1124 * (static function - no need for kernel doc)
1125 *
1126 * Pass in a buffer containing a glob and this function will
1127 * set search to point to the search part of the buffer and
1128 * return the type of search it is (see enum above).
1129 * This does modify buff.
1130 *
1131 * Returns enum type.
1132 * search returns the pointer to use for comparison.
1133 * not returns 1 if buff started with a '!'
1134 * 0 otherwise.
1135 */
1136static int
1137ftrace_setup_glob(char *buff, int len, char **search, int *not)
1035{ 1138{
1036 char str[KSYM_SYMBOL_LEN];
1037 char *search = NULL;
1038 struct ftrace_page *pg;
1039 struct dyn_ftrace *rec;
1040 int type = MATCH_FULL; 1139 int type = MATCH_FULL;
1041 unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; 1140 int i;
1042 unsigned i, match = 0, search_len = 0;
1043 int not = 0;
1044 1141
1045 if (buff[0] == '!') { 1142 if (buff[0] == '!') {
1046 not = 1; 1143 *not = 1;
1047 buff++; 1144 buff++;
1048 len--; 1145 len--;
1049 } 1146 } else
1147 *not = 0;
1148
1149 *search = buff;
1050 1150
1051 for (i = 0; i < len; i++) { 1151 for (i = 0; i < len; i++) {
1052 if (buff[i] == '*') { 1152 if (buff[i] == '*') {
1053 if (!i) { 1153 if (!i) {
1054 search = buff + i + 1; 1154 *search = buff + 1;
1055 type = MATCH_END_ONLY; 1155 type = MATCH_END_ONLY;
1056 search_len = len - (i + 1);
1057 } else { 1156 } else {
1058 if (type == MATCH_END_ONLY) { 1157 if (type == MATCH_END_ONLY)
1059 type = MATCH_MIDDLE_ONLY; 1158 type = MATCH_MIDDLE_ONLY;
1060 } else { 1159 else
1061 match = i;
1062 type = MATCH_FRONT_ONLY; 1160 type = MATCH_FRONT_ONLY;
1063 }
1064 buff[i] = 0; 1161 buff[i] = 0;
1065 break; 1162 break;
1066 } 1163 }
1067 } 1164 }
1068 } 1165 }
1069 1166
1070 /* should not be called from interrupt context */ 1167 return type;
1071 spin_lock(&ftrace_lock); 1168}
1072 if (enable) 1169
1073 ftrace_filtered = 1; 1170static int ftrace_match(char *str, char *regex, int len, int type)
1074 pg = ftrace_pages_start; 1171{
1075 while (pg) { 1172 int matched = 0;
1076 for (i = 0; i < pg->index; i++) { 1173 char *ptr;
1077 int matched = 0; 1174
1078 char *ptr; 1175 switch (type) {
1079 1176 case MATCH_FULL:
1080 rec = &pg->records[i]; 1177 if (strcmp(str, regex) == 0)
1081 if (rec->flags & FTRACE_FL_FAILED) 1178 matched = 1;
1179 break;
1180 case MATCH_FRONT_ONLY:
1181 if (strncmp(str, regex, len) == 0)
1182 matched = 1;
1183 break;
1184 case MATCH_MIDDLE_ONLY:
1185 if (strstr(str, regex))
1186 matched = 1;
1187 break;
1188 case MATCH_END_ONLY:
1189 ptr = strstr(str, regex);
1190 if (ptr && (ptr[len] == 0))
1191 matched = 1;
1192 break;
1193 }
1194
1195 return matched;
1196}
1197
1198static int
1199ftrace_match_record(struct dyn_ftrace *rec, char *regex, int len, int type)
1200{
1201 char str[KSYM_SYMBOL_LEN];
1202
1203 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
1204 return ftrace_match(str, regex, len, type);
1205}
1206
1207static void ftrace_match_records(char *buff, int len, int enable)
1208{
1209 char *search;
1210 struct ftrace_page *pg;
1211 struct dyn_ftrace *rec;
1212 int type;
1213 unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
1214 unsigned search_len;
1215 int not;
1216
1217 type = ftrace_setup_glob(buff, len, &search, &not);
1218
1219 search_len = strlen(search);
1220
1221 mutex_lock(&ftrace_lock);
1222 do_for_each_ftrace_rec(pg, rec) {
1223
1224 if (rec->flags & FTRACE_FL_FAILED)
1225 continue;
1226
1227 if (ftrace_match_record(rec, search, search_len, type)) {
1228 if (not)
1229 rec->flags &= ~flag;
1230 else
1231 rec->flags |= flag;
1232 }
1233 /*
1234 * Only enable filtering if we have a function that
1235 * is filtered on.
1236 */
1237 if (enable && (rec->flags & FTRACE_FL_FILTER))
1238 ftrace_filtered = 1;
1239 } while_for_each_ftrace_rec();
1240 mutex_unlock(&ftrace_lock);
1241}
1242
1243static int
1244ftrace_match_module_record(struct dyn_ftrace *rec, char *mod,
1245 char *regex, int len, int type)
1246{
1247 char str[KSYM_SYMBOL_LEN];
1248 char *modname;
1249
1250 kallsyms_lookup(rec->ip, NULL, NULL, &modname, str);
1251
1252 if (!modname || strcmp(modname, mod))
1253 return 0;
1254
1255 /* blank search means to match all funcs in the mod */
1256 if (len)
1257 return ftrace_match(str, regex, len, type);
1258 else
1259 return 1;
1260}
1261
1262static void ftrace_match_module_records(char *buff, char *mod, int enable)
1263{
1264 char *search = buff;
1265 struct ftrace_page *pg;
1266 struct dyn_ftrace *rec;
1267 int type = MATCH_FULL;
1268 unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
1269 unsigned search_len = 0;
1270 int not = 0;
1271
1272 /* blank or '*' mean the same */
1273 if (strcmp(buff, "*") == 0)
1274 buff[0] = 0;
1275
1276 /* handle the case of 'dont filter this module' */
1277 if (strcmp(buff, "!") == 0 || strcmp(buff, "!*") == 0) {
1278 buff[0] = 0;
1279 not = 1;
1280 }
1281
1282 if (strlen(buff)) {
1283 type = ftrace_setup_glob(buff, strlen(buff), &search, &not);
1284 search_len = strlen(search);
1285 }
1286
1287 mutex_lock(&ftrace_lock);
1288 do_for_each_ftrace_rec(pg, rec) {
1289
1290 if (rec->flags & FTRACE_FL_FAILED)
1291 continue;
1292
1293 if (ftrace_match_module_record(rec, mod,
1294 search, search_len, type)) {
1295 if (not)
1296 rec->flags &= ~flag;
1297 else
1298 rec->flags |= flag;
1299 }
1300 if (enable && (rec->flags & FTRACE_FL_FILTER))
1301 ftrace_filtered = 1;
1302
1303 } while_for_each_ftrace_rec();
1304 mutex_unlock(&ftrace_lock);
1305}
1306
1307/*
1308 * We register the module command as a template to show others how
1309 * to register the a command as well.
1310 */
1311
1312static int
1313ftrace_mod_callback(char *func, char *cmd, char *param, int enable)
1314{
1315 char *mod;
1316
1317 /*
1318 * cmd == 'mod' because we only registered this func
1319 * for the 'mod' ftrace_func_command.
1320 * But if you register one func with multiple commands,
1321 * you can tell which command was used by the cmd
1322 * parameter.
1323 */
1324
1325 /* we must have a module name */
1326 if (!param)
1327 return -EINVAL;
1328
1329 mod = strsep(&param, ":");
1330 if (!strlen(mod))
1331 return -EINVAL;
1332
1333 ftrace_match_module_records(func, mod, enable);
1334 return 0;
1335}
1336
1337static struct ftrace_func_command ftrace_mod_cmd = {
1338 .name = "mod",
1339 .func = ftrace_mod_callback,
1340};
1341
1342static int __init ftrace_mod_cmd_init(void)
1343{
1344 return register_ftrace_command(&ftrace_mod_cmd);
1345}
1346device_initcall(ftrace_mod_cmd_init);
1347
1348static void
1349function_trace_hook_call(unsigned long ip, unsigned long parent_ip)
1350{
1351 struct ftrace_func_hook *entry;
1352 struct hlist_head *hhd;
1353 struct hlist_node *n;
1354 unsigned long key;
1355 int resched;
1356
1357 key = hash_long(ip, FTRACE_HASH_BITS);
1358
1359 hhd = &ftrace_func_hash[key];
1360
1361 if (hlist_empty(hhd))
1362 return;
1363
1364 /*
1365 * Disable preemption for these calls to prevent a RCU grace
1366 * period. This syncs the hash iteration and freeing of items
1367 * on the hash. rcu_read_lock is too dangerous here.
1368 */
1369 resched = ftrace_preempt_disable();
1370 hlist_for_each_entry_rcu(entry, n, hhd, node) {
1371 if (entry->ip == ip)
1372 entry->ops->func(ip, parent_ip, &entry->data);
1373 }
1374 ftrace_preempt_enable(resched);
1375}
1376
1377static struct ftrace_ops trace_hook_ops __read_mostly =
1378{
1379 .func = function_trace_hook_call,
1380};
1381
1382static int ftrace_hook_registered;
1383
1384static void __enable_ftrace_function_hook(void)
1385{
1386 int i;
1387
1388 if (ftrace_hook_registered)
1389 return;
1390
1391 for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
1392 struct hlist_head *hhd = &ftrace_func_hash[i];
1393 if (hhd->first)
1394 break;
1395 }
1396 /* Nothing registered? */
1397 if (i == FTRACE_FUNC_HASHSIZE)
1398 return;
1399
1400 __register_ftrace_function(&trace_hook_ops);
1401 ftrace_startup(0);
1402 ftrace_hook_registered = 1;
1403}
1404
1405static void __disable_ftrace_function_hook(void)
1406{
1407 int i;
1408
1409 if (!ftrace_hook_registered)
1410 return;
1411
1412 for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
1413 struct hlist_head *hhd = &ftrace_func_hash[i];
1414 if (hhd->first)
1415 return;
1416 }
1417
1418 /* no more funcs left */
1419 __unregister_ftrace_function(&trace_hook_ops);
1420 ftrace_shutdown(0);
1421 ftrace_hook_registered = 0;
1422}
1423
1424
1425static void ftrace_free_entry_rcu(struct rcu_head *rhp)
1426{
1427 struct ftrace_func_hook *entry =
1428 container_of(rhp, struct ftrace_func_hook, rcu);
1429
1430 if (entry->ops->free)
1431 entry->ops->free(&entry->data);
1432 kfree(entry);
1433}
1434
1435
1436int
1437register_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
1438 void *data)
1439{
1440 struct ftrace_func_hook *entry;
1441 struct ftrace_page *pg;
1442 struct dyn_ftrace *rec;
1443 unsigned long key;
1444 int type, len, not;
1445 int count = 0;
1446 char *search;
1447
1448 type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
1449 len = strlen(search);
1450
1451 /* we do not support '!' for function hooks */
1452 if (WARN_ON(not))
1453 return -EINVAL;
1454
1455 mutex_lock(&ftrace_lock);
1456 do_for_each_ftrace_rec(pg, rec) {
1457
1458 if (rec->flags & FTRACE_FL_FAILED)
1459 continue;
1460
1461 if (!ftrace_match_record(rec, search, len, type))
1462 continue;
1463
1464 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
1465 if (!entry) {
1466 /* If we did not hook to any, then return error */
1467 if (!count)
1468 count = -ENOMEM;
1469 goto out_unlock;
1470 }
1471
1472 count++;
1473
1474 entry->data = data;
1475
1476 /*
1477 * The caller might want to do something special
1478 * for each function we find. We call the callback
1479 * to give the caller an opportunity to do so.
1480 */
1481 if (ops->callback) {
1482 if (ops->callback(rec->ip, &entry->data) < 0) {
1483 /* caller does not like this func */
1484 kfree(entry);
1082 continue; 1485 continue;
1083 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
1084 switch (type) {
1085 case MATCH_FULL:
1086 if (strcmp(str, buff) == 0)
1087 matched = 1;
1088 break;
1089 case MATCH_FRONT_ONLY:
1090 if (memcmp(str, buff, match) == 0)
1091 matched = 1;
1092 break;
1093 case MATCH_MIDDLE_ONLY:
1094 if (strstr(str, search))
1095 matched = 1;
1096 break;
1097 case MATCH_END_ONLY:
1098 ptr = strstr(str, search);
1099 if (ptr && (ptr[search_len] == 0))
1100 matched = 1;
1101 break;
1102 } 1486 }
1103 if (matched) { 1487 }
1104 if (not) 1488
1105 rec->flags &= ~flag; 1489 entry->ops = ops;
1106 else 1490 entry->ip = rec->ip;
1107 rec->flags |= flag; 1491
1492 key = hash_long(entry->ip, FTRACE_HASH_BITS);
1493 hlist_add_head_rcu(&entry->node, &ftrace_func_hash[key]);
1494
1495 } while_for_each_ftrace_rec();
1496 __enable_ftrace_function_hook();
1497
1498 out_unlock:
1499 mutex_unlock(&ftrace_lock);
1500
1501 return count;
1502}
1503
1504enum {
1505 HOOK_TEST_FUNC = 1,
1506 HOOK_TEST_DATA = 2
1507};
1508
1509static void
1510__unregister_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
1511 void *data, int flags)
1512{
1513 struct ftrace_func_hook *entry;
1514 struct hlist_node *n, *tmp;
1515 char str[KSYM_SYMBOL_LEN];
1516 int type = MATCH_FULL;
1517 int i, len = 0;
1518 char *search;
1519
1520 if (glob && (strcmp(glob, "*") || !strlen(glob)))
1521 glob = NULL;
1522 else {
1523 int not;
1524
1525 type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
1526 len = strlen(search);
1527
1528 /* we do not support '!' for function hooks */
1529 if (WARN_ON(not))
1530 return;
1531 }
1532
1533 mutex_lock(&ftrace_lock);
1534 for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
1535 struct hlist_head *hhd = &ftrace_func_hash[i];
1536
1537 hlist_for_each_entry_safe(entry, n, tmp, hhd, node) {
1538
1539 /* break up if statements for readability */
1540 if ((flags & HOOK_TEST_FUNC) && entry->ops != ops)
1541 continue;
1542
1543 if ((flags & HOOK_TEST_DATA) && entry->data != data)
1544 continue;
1545
1546 /* do this last, since it is the most expensive */
1547 if (glob) {
1548 kallsyms_lookup(entry->ip, NULL, NULL,
1549 NULL, str);
1550 if (!ftrace_match(str, glob, len, type))
1551 continue;
1108 } 1552 }
1553
1554 hlist_del(&entry->node);
1555 call_rcu(&entry->rcu, ftrace_free_entry_rcu);
1109 } 1556 }
1110 pg = pg->next;
1111 } 1557 }
1112 spin_unlock(&ftrace_lock); 1558 __disable_ftrace_function_hook();
1559 mutex_unlock(&ftrace_lock);
1560}
1561
1562void
1563unregister_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
1564 void *data)
1565{
1566 __unregister_ftrace_function_hook(glob, ops, data,
1567 HOOK_TEST_FUNC | HOOK_TEST_DATA);
1568}
1569
1570void
1571unregister_ftrace_function_hook_func(char *glob, struct ftrace_hook_ops *ops)
1572{
1573 __unregister_ftrace_function_hook(glob, ops, NULL, HOOK_TEST_FUNC);
1574}
1575
1576void unregister_ftrace_function_hook_all(char *glob)
1577{
1578 __unregister_ftrace_function_hook(glob, NULL, NULL, 0);
1579}
1580
1581static LIST_HEAD(ftrace_commands);
1582static DEFINE_MUTEX(ftrace_cmd_mutex);
1583
1584int register_ftrace_command(struct ftrace_func_command *cmd)
1585{
1586 struct ftrace_func_command *p;
1587 int ret = 0;
1588
1589 mutex_lock(&ftrace_cmd_mutex);
1590 list_for_each_entry(p, &ftrace_commands, list) {
1591 if (strcmp(cmd->name, p->name) == 0) {
1592 ret = -EBUSY;
1593 goto out_unlock;
1594 }
1595 }
1596 list_add(&cmd->list, &ftrace_commands);
1597 out_unlock:
1598 mutex_unlock(&ftrace_cmd_mutex);
1599
1600 return ret;
1601}
1602
1603int unregister_ftrace_command(struct ftrace_func_command *cmd)
1604{
1605 struct ftrace_func_command *p, *n;
1606 int ret = -ENODEV;
1607
1608 mutex_lock(&ftrace_cmd_mutex);
1609 list_for_each_entry_safe(p, n, &ftrace_commands, list) {
1610 if (strcmp(cmd->name, p->name) == 0) {
1611 ret = 0;
1612 list_del_init(&p->list);
1613 goto out_unlock;
1614 }
1615 }
1616 out_unlock:
1617 mutex_unlock(&ftrace_cmd_mutex);
1618
1619 return ret;
1620}
1621
1622static int ftrace_process_regex(char *buff, int len, int enable)
1623{
1624 struct ftrace_func_command *p;
1625 char *func, *command, *next = buff;
1626 int ret = -EINVAL;
1627
1628 func = strsep(&next, ":");
1629
1630 if (!next) {
1631 ftrace_match_records(func, len, enable);
1632 return 0;
1633 }
1634
1635 /* command found */
1636
1637 command = strsep(&next, ":");
1638
1639 mutex_lock(&ftrace_cmd_mutex);
1640 list_for_each_entry(p, &ftrace_commands, list) {
1641 if (strcmp(p->name, command) == 0) {
1642 ret = p->func(func, command, next, enable);
1643 goto out_unlock;
1644 }
1645 }
1646 out_unlock:
1647 mutex_unlock(&ftrace_cmd_mutex);
1648
1649 return ret;
1113} 1650}
1114 1651
1115static ssize_t 1652static ssize_t
@@ -1179,7 +1716,10 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
1179 if (isspace(ch)) { 1716 if (isspace(ch)) {
1180 iter->filtered++; 1717 iter->filtered++;
1181 iter->buffer[iter->buffer_idx] = 0; 1718 iter->buffer[iter->buffer_idx] = 0;
1182 ftrace_match(iter->buffer, iter->buffer_idx, enable); 1719 ret = ftrace_process_regex(iter->buffer,
1720 iter->buffer_idx, enable);
1721 if (ret)
1722 goto out;
1183 iter->buffer_idx = 0; 1723 iter->buffer_idx = 0;
1184 } else 1724 } else
1185 iter->flags |= FTRACE_ITER_CONT; 1725 iter->flags |= FTRACE_ITER_CONT;
@@ -1218,7 +1758,7 @@ ftrace_set_regex(unsigned char *buf, int len, int reset, int enable)
1218 if (reset) 1758 if (reset)
1219 ftrace_filter_reset(enable); 1759 ftrace_filter_reset(enable);
1220 if (buf) 1760 if (buf)
1221 ftrace_match(buf, len, enable); 1761 ftrace_match_records(buf, len, enable);
1222 mutex_unlock(&ftrace_regex_lock); 1762 mutex_unlock(&ftrace_regex_lock);
1223} 1763}
1224 1764
@@ -1268,15 +1808,13 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable)
1268 if (iter->buffer_idx) { 1808 if (iter->buffer_idx) {
1269 iter->filtered++; 1809 iter->filtered++;
1270 iter->buffer[iter->buffer_idx] = 0; 1810 iter->buffer[iter->buffer_idx] = 0;
1271 ftrace_match(iter->buffer, iter->buffer_idx, enable); 1811 ftrace_match_records(iter->buffer, iter->buffer_idx, enable);
1272 } 1812 }
1273 1813
1274 mutex_lock(&ftrace_sysctl_lock); 1814 mutex_lock(&ftrace_lock);
1275 mutex_lock(&ftrace_start_lock);
1276 if (ftrace_start_up && ftrace_enabled) 1815 if (ftrace_start_up && ftrace_enabled)
1277 ftrace_run_update_code(FTRACE_ENABLE_CALLS); 1816 ftrace_run_update_code(FTRACE_ENABLE_CALLS);
1278 mutex_unlock(&ftrace_start_lock); 1817 mutex_unlock(&ftrace_lock);
1279 mutex_unlock(&ftrace_sysctl_lock);
1280 1818
1281 kfree(iter); 1819 kfree(iter);
1282 mutex_unlock(&ftrace_regex_lock); 1820 mutex_unlock(&ftrace_regex_lock);
@@ -1429,36 +1967,33 @@ ftrace_set_func(unsigned long *array, int idx, char *buffer)
1429 struct dyn_ftrace *rec; 1967 struct dyn_ftrace *rec;
1430 struct ftrace_page *pg; 1968 struct ftrace_page *pg;
1431 int found = 0; 1969 int found = 0;
1432 int i, j; 1970 int j;
1433 1971
1434 if (ftrace_disabled) 1972 if (ftrace_disabled)
1435 return -ENODEV; 1973 return -ENODEV;
1436 1974
1437 /* should not be called from interrupt context */ 1975 mutex_lock(&ftrace_lock);
1438 spin_lock(&ftrace_lock); 1976 do_for_each_ftrace_rec(pg, rec) {
1439
1440 for (pg = ftrace_pages_start; pg; pg = pg->next) {
1441 for (i = 0; i < pg->index; i++) {
1442 rec = &pg->records[i];
1443 1977
1444 if (rec->flags & (FTRACE_FL_FAILED | FTRACE_FL_FREE)) 1978 if (rec->flags & (FTRACE_FL_FAILED | FTRACE_FL_FREE))
1445 continue; 1979 continue;
1446 1980
1447 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str); 1981 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
1448 if (strcmp(str, buffer) == 0) { 1982 if (strcmp(str, buffer) == 0) {
1449 found = 1; 1983 /* Return 1 if we add it to the array */
1450 for (j = 0; j < idx; j++) 1984 found = 1;
1451 if (array[j] == rec->ip) { 1985 for (j = 0; j < idx; j++)
1452 found = 0; 1986 if (array[j] == rec->ip) {
1453 break; 1987 found = 0;
1454 } 1988 break;
1455 if (found) 1989 }
1456 array[idx] = rec->ip; 1990 if (found)
1457 break; 1991 array[idx] = rec->ip;
1458 } 1992 goto out;
1459 } 1993 }
1460 } 1994 } while_for_each_ftrace_rec();
1461 spin_unlock(&ftrace_lock); 1995 out:
1996 mutex_unlock(&ftrace_lock);
1462 1997
1463 return found ? 0 : -EINVAL; 1998 return found ? 0 : -EINVAL;
1464} 1999}
@@ -1596,7 +2131,7 @@ static int ftrace_convert_nops(struct module *mod,
1596 unsigned long addr; 2131 unsigned long addr;
1597 unsigned long flags; 2132 unsigned long flags;
1598 2133
1599 mutex_lock(&ftrace_start_lock); 2134 mutex_lock(&ftrace_lock);
1600 p = start; 2135 p = start;
1601 while (p < end) { 2136 while (p < end) {
1602 addr = ftrace_call_adjust(*p++); 2137 addr = ftrace_call_adjust(*p++);
@@ -1615,7 +2150,7 @@ static int ftrace_convert_nops(struct module *mod,
1615 local_irq_save(flags); 2150 local_irq_save(flags);
1616 ftrace_update_code(mod); 2151 ftrace_update_code(mod);
1617 local_irq_restore(flags); 2152 local_irq_restore(flags);
1618 mutex_unlock(&ftrace_start_lock); 2153 mutex_unlock(&ftrace_lock);
1619 2154
1620 return 0; 2155 return 0;
1621} 2156}
@@ -1788,7 +2323,7 @@ ftrace_pid_write(struct file *filp, const char __user *ubuf,
1788 if (ret < 0) 2323 if (ret < 0)
1789 return ret; 2324 return ret;
1790 2325
1791 mutex_lock(&ftrace_start_lock); 2326 mutex_lock(&ftrace_lock);
1792 if (val < 0) { 2327 if (val < 0) {
1793 /* disable pid tracing */ 2328 /* disable pid tracing */
1794 if (!ftrace_pid_trace) 2329 if (!ftrace_pid_trace)
@@ -1827,7 +2362,7 @@ ftrace_pid_write(struct file *filp, const char __user *ubuf,
1827 ftrace_startup_enable(0); 2362 ftrace_startup_enable(0);
1828 2363
1829 out: 2364 out:
1830 mutex_unlock(&ftrace_start_lock); 2365 mutex_unlock(&ftrace_lock);
1831 2366
1832 return cnt; 2367 return cnt;
1833} 2368}
@@ -1890,12 +2425,12 @@ int register_ftrace_function(struct ftrace_ops *ops)
1890 if (unlikely(ftrace_disabled)) 2425 if (unlikely(ftrace_disabled))
1891 return -1; 2426 return -1;
1892 2427
1893 mutex_lock(&ftrace_sysctl_lock); 2428 mutex_lock(&ftrace_lock);
1894 2429
1895 ret = __register_ftrace_function(ops); 2430 ret = __register_ftrace_function(ops);
1896 ftrace_startup(0); 2431 ftrace_startup(0);
1897 2432
1898 mutex_unlock(&ftrace_sysctl_lock); 2433 mutex_unlock(&ftrace_lock);
1899 return ret; 2434 return ret;
1900} 2435}
1901 2436
@@ -1909,10 +2444,10 @@ int unregister_ftrace_function(struct ftrace_ops *ops)
1909{ 2444{
1910 int ret; 2445 int ret;
1911 2446
1912 mutex_lock(&ftrace_sysctl_lock); 2447 mutex_lock(&ftrace_lock);
1913 ret = __unregister_ftrace_function(ops); 2448 ret = __unregister_ftrace_function(ops);
1914 ftrace_shutdown(0); 2449 ftrace_shutdown(0);
1915 mutex_unlock(&ftrace_sysctl_lock); 2450 mutex_unlock(&ftrace_lock);
1916 2451
1917 return ret; 2452 return ret;
1918} 2453}
@@ -1927,7 +2462,7 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
1927 if (unlikely(ftrace_disabled)) 2462 if (unlikely(ftrace_disabled))
1928 return -ENODEV; 2463 return -ENODEV;
1929 2464
1930 mutex_lock(&ftrace_sysctl_lock); 2465 mutex_lock(&ftrace_lock);
1931 2466
1932 ret = proc_dointvec(table, write, file, buffer, lenp, ppos); 2467 ret = proc_dointvec(table, write, file, buffer, lenp, ppos);
1933 2468
@@ -1956,7 +2491,7 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
1956 } 2491 }
1957 2492
1958 out: 2493 out:
1959 mutex_unlock(&ftrace_sysctl_lock); 2494 mutex_unlock(&ftrace_lock);
1960 return ret; 2495 return ret;
1961} 2496}
1962 2497
@@ -2068,7 +2603,7 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc,
2068{ 2603{
2069 int ret = 0; 2604 int ret = 0;
2070 2605
2071 mutex_lock(&ftrace_sysctl_lock); 2606 mutex_lock(&ftrace_lock);
2072 2607
2073 ftrace_suspend_notifier.notifier_call = ftrace_suspend_notifier_call; 2608 ftrace_suspend_notifier.notifier_call = ftrace_suspend_notifier_call;
2074 register_pm_notifier(&ftrace_suspend_notifier); 2609 register_pm_notifier(&ftrace_suspend_notifier);
@@ -2086,13 +2621,13 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc,
2086 ftrace_startup(FTRACE_START_FUNC_RET); 2621 ftrace_startup(FTRACE_START_FUNC_RET);
2087 2622
2088out: 2623out:
2089 mutex_unlock(&ftrace_sysctl_lock); 2624 mutex_unlock(&ftrace_lock);
2090 return ret; 2625 return ret;
2091} 2626}
2092 2627
2093void unregister_ftrace_graph(void) 2628void unregister_ftrace_graph(void)
2094{ 2629{
2095 mutex_lock(&ftrace_sysctl_lock); 2630 mutex_lock(&ftrace_lock);
2096 2631
2097 atomic_dec(&ftrace_graph_active); 2632 atomic_dec(&ftrace_graph_active);
2098 ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub; 2633 ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub;
@@ -2100,7 +2635,7 @@ void unregister_ftrace_graph(void)
2100 ftrace_shutdown(FTRACE_STOP_FUNC_RET); 2635 ftrace_shutdown(FTRACE_STOP_FUNC_RET);
2101 unregister_pm_notifier(&ftrace_suspend_notifier); 2636 unregister_pm_notifier(&ftrace_suspend_notifier);
2102 2637
2103 mutex_unlock(&ftrace_sysctl_lock); 2638 mutex_unlock(&ftrace_lock);
2104} 2639}
2105 2640
2106/* Allocate a return stack for newly created task */ 2641/* Allocate a return stack for newly created task */
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 2b4626ce95d6..8f19f1aa42b0 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -98,6 +98,15 @@ void tracing_off_permanent(void)
98 set_bit(RB_BUFFERS_DISABLED_BIT, &ring_buffer_flags); 98 set_bit(RB_BUFFERS_DISABLED_BIT, &ring_buffer_flags);
99} 99}
100 100
101/**
102 * tracing_is_on - show state of ring buffers enabled
103 */
104int tracing_is_on(void)
105{
106 return ring_buffer_flags == RB_BUFFERS_ON;
107}
108EXPORT_SYMBOL_GPL(tracing_is_on);
109
101#include "trace.h" 110#include "trace.h"
102 111
103/* Up this if you want to test the TIME_EXTENTS and normalization */ 112/* Up this if you want to test the TIME_EXTENTS and normalization */
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 36bf9568ccd9..f520aa419dff 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -9,6 +9,7 @@
9 * Copyright (C) 2004-2006 Ingo Molnar 9 * Copyright (C) 2004-2006 Ingo Molnar
10 * Copyright (C) 2004 William Lee Irwin III 10 * Copyright (C) 2004 William Lee Irwin III
11 */ 11 */
12#include <linux/ring_buffer.h>
12#include <linux/debugfs.h> 13#include <linux/debugfs.h>
13#include <linux/uaccess.h> 14#include <linux/uaccess.h>
14#include <linux/ftrace.h> 15#include <linux/ftrace.h>
@@ -231,9 +232,171 @@ static struct tracer function_trace __read_mostly =
231#endif 232#endif
232}; 233};
233 234
235#ifdef CONFIG_DYNAMIC_FTRACE
236static void
237ftrace_traceon(unsigned long ip, unsigned long parent_ip, void **data)
238{
239 long *count = (long *)data;
240
241 if (tracing_is_on())
242 return;
243
244 if (!*count)
245 return;
246
247 if (*count != -1)
248 (*count)--;
249
250 tracing_on();
251}
252
253static void
254ftrace_traceoff(unsigned long ip, unsigned long parent_ip, void **data)
255{
256 long *count = (long *)data;
257
258 if (!tracing_is_on())
259 return;
260
261 if (!*count)
262 return;
263
264 if (*count != -1)
265 (*count)--;
266
267 tracing_off();
268}
269
270static int
271ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
272 struct ftrace_hook_ops *ops, void *data);
273
274static struct ftrace_hook_ops traceon_hook_ops = {
275 .func = ftrace_traceon,
276 .print = ftrace_trace_onoff_print,
277};
278
279static struct ftrace_hook_ops traceoff_hook_ops = {
280 .func = ftrace_traceoff,
281 .print = ftrace_trace_onoff_print,
282};
283
284static int
285ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
286 struct ftrace_hook_ops *ops, void *data)
287{
288 char str[KSYM_SYMBOL_LEN];
289 long count = (long)data;
290
291 kallsyms_lookup(ip, NULL, NULL, NULL, str);
292 seq_printf(m, "%s:", str);
293
294 if (ops == &traceon_hook_ops)
295 seq_printf(m, "traceon");
296 else
297 seq_printf(m, "traceoff");
298
299 if (count != -1)
300 seq_printf(m, ":count=%ld", count);
301 seq_putc(m, '\n');
302
303 return 0;
304}
305
306static int
307ftrace_trace_onoff_unreg(char *glob, char *cmd, char *param)
308{
309 struct ftrace_hook_ops *ops;
310
311 /* we register both traceon and traceoff to this callback */
312 if (strcmp(cmd, "traceon") == 0)
313 ops = &traceon_hook_ops;
314 else
315 ops = &traceoff_hook_ops;
316
317 unregister_ftrace_function_hook_func(glob, ops);
318
319 return 0;
320}
321
322static int
323ftrace_trace_onoff_callback(char *glob, char *cmd, char *param, int enable)
324{
325 struct ftrace_hook_ops *ops;
326 void *count = (void *)-1;
327 char *number;
328 int ret;
329
330 /* hash funcs only work with set_ftrace_filter */
331 if (!enable)
332 return -EINVAL;
333
334 if (glob[0] == '!')
335 return ftrace_trace_onoff_unreg(glob+1, cmd, param);
336
337 /* we register both traceon and traceoff to this callback */
338 if (strcmp(cmd, "traceon") == 0)
339 ops = &traceon_hook_ops;
340 else
341 ops = &traceoff_hook_ops;
342
343 if (!param)
344 goto out_reg;
345
346 number = strsep(&param, ":");
347
348 if (!strlen(number))
349 goto out_reg;
350
351 /*
352 * We use the callback data field (which is a pointer)
353 * as our counter.
354 */
355 ret = strict_strtoul(number, 0, (unsigned long *)&count);
356 if (ret)
357 return ret;
358
359 out_reg:
360 ret = register_ftrace_function_hook(glob, ops, count);
361
362 return ret;
363}
364
365static struct ftrace_func_command ftrace_traceon_cmd = {
366 .name = "traceon",
367 .func = ftrace_trace_onoff_callback,
368};
369
370static struct ftrace_func_command ftrace_traceoff_cmd = {
371 .name = "traceoff",
372 .func = ftrace_trace_onoff_callback,
373};
374
375static int __init init_func_cmd_traceon(void)
376{
377 int ret;
378
379 ret = register_ftrace_command(&ftrace_traceoff_cmd);
380 if (ret)
381 return ret;
382
383 ret = register_ftrace_command(&ftrace_traceon_cmd);
384 if (ret)
385 unregister_ftrace_command(&ftrace_traceoff_cmd);
386 return ret;
387}
388#else
389static inline int init_func_cmd_traceon(void)
390{
391 return 0;
392}
393#endif /* CONFIG_DYNAMIC_FTRACE */
394
234static __init int init_function_trace(void) 395static __init int init_function_trace(void)
235{ 396{
397 init_func_cmd_traceon();
236 return register_tracer(&function_trace); 398 return register_tracer(&function_trace);
237} 399}
238 400
239device_initcall(init_function_trace); 401device_initcall(init_function_trace);
402