aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r--kernel/trace/ftrace.c410
1 files changed, 251 insertions, 159 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 46592feab5a6..e51a1bcb7bed 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -60,6 +60,13 @@ static int last_ftrace_enabled;
60/* Quick disabling of function tracer. */ 60/* Quick disabling of function tracer. */
61int function_trace_stop; 61int function_trace_stop;
62 62
63/* List for set_ftrace_pid's pids. */
64LIST_HEAD(ftrace_pids);
65struct ftrace_pid {
66 struct list_head list;
67 struct pid *pid;
68};
69
63/* 70/*
64 * ftrace_disabled is set when an anomaly is discovered. 71 * ftrace_disabled is set when an anomaly is discovered.
65 * ftrace_disabled is much stronger than ftrace_enabled. 72 * ftrace_disabled is much stronger than ftrace_enabled.
@@ -78,6 +85,10 @@ ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub;
78ftrace_func_t __ftrace_trace_function __read_mostly = ftrace_stub; 85ftrace_func_t __ftrace_trace_function __read_mostly = ftrace_stub;
79ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub; 86ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub;
80 87
88#ifdef CONFIG_FUNCTION_GRAPH_TRACER
89static int ftrace_set_func(unsigned long *array, int *idx, char *buffer);
90#endif
91
81static void ftrace_list_func(unsigned long ip, unsigned long parent_ip) 92static void ftrace_list_func(unsigned long ip, unsigned long parent_ip)
82{ 93{
83 struct ftrace_ops *op = ftrace_list; 94 struct ftrace_ops *op = ftrace_list;
@@ -155,7 +166,7 @@ static int __register_ftrace_function(struct ftrace_ops *ops)
155 else 166 else
156 func = ftrace_list_func; 167 func = ftrace_list_func;
157 168
158 if (ftrace_pid_trace) { 169 if (!list_empty(&ftrace_pids)) {
159 set_ftrace_pid_function(func); 170 set_ftrace_pid_function(func);
160 func = ftrace_pid_func; 171 func = ftrace_pid_func;
161 } 172 }
@@ -203,7 +214,7 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
203 if (ftrace_list->next == &ftrace_list_end) { 214 if (ftrace_list->next == &ftrace_list_end) {
204 ftrace_func_t func = ftrace_list->func; 215 ftrace_func_t func = ftrace_list->func;
205 216
206 if (ftrace_pid_trace) { 217 if (!list_empty(&ftrace_pids)) {
207 set_ftrace_pid_function(func); 218 set_ftrace_pid_function(func);
208 func = ftrace_pid_func; 219 func = ftrace_pid_func;
209 } 220 }
@@ -225,9 +236,13 @@ static void ftrace_update_pid_func(void)
225 if (ftrace_trace_function == ftrace_stub) 236 if (ftrace_trace_function == ftrace_stub)
226 return; 237 return;
227 238
239#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
228 func = ftrace_trace_function; 240 func = ftrace_trace_function;
241#else
242 func = __ftrace_trace_function;
243#endif
229 244
230 if (ftrace_pid_trace) { 245 if (!list_empty(&ftrace_pids)) {
231 set_ftrace_pid_function(func); 246 set_ftrace_pid_function(func);
232 func = ftrace_pid_func; 247 func = ftrace_pid_func;
233 } else { 248 } else {
@@ -736,7 +751,7 @@ ftrace_profile_write(struct file *filp, const char __user *ubuf,
736 out: 751 out:
737 mutex_unlock(&ftrace_profile_lock); 752 mutex_unlock(&ftrace_profile_lock);
738 753
739 filp->f_pos += cnt; 754 *ppos += cnt;
740 755
741 return cnt; 756 return cnt;
742} 757}
@@ -817,8 +832,6 @@ static __init void ftrace_profile_debugfs(struct dentry *d_tracer)
817} 832}
818#endif /* CONFIG_FUNCTION_PROFILER */ 833#endif /* CONFIG_FUNCTION_PROFILER */
819 834
820/* set when tracing only a pid */
821struct pid *ftrace_pid_trace;
822static struct pid * const ftrace_swapper_pid = &init_struct_pid; 835static struct pid * const ftrace_swapper_pid = &init_struct_pid;
823 836
824#ifdef CONFIG_DYNAMIC_FTRACE 837#ifdef CONFIG_DYNAMIC_FTRACE
@@ -1074,14 +1087,9 @@ static void ftrace_replace_code(int enable)
1074 failed = __ftrace_replace_code(rec, enable); 1087 failed = __ftrace_replace_code(rec, enable);
1075 if (failed) { 1088 if (failed) {
1076 rec->flags |= FTRACE_FL_FAILED; 1089 rec->flags |= FTRACE_FL_FAILED;
1077 if ((system_state == SYSTEM_BOOTING) || 1090 ftrace_bug(failed, rec->ip);
1078 !core_kernel_text(rec->ip)) { 1091 /* Stop processing */
1079 ftrace_free_rec(rec); 1092 return;
1080 } else {
1081 ftrace_bug(failed, rec->ip);
1082 /* Stop processing */
1083 return;
1084 }
1085 } 1093 }
1086 } while_for_each_ftrace_rec(); 1094 } while_for_each_ftrace_rec();
1087} 1095}
@@ -1262,12 +1270,34 @@ static int ftrace_update_code(struct module *mod)
1262 ftrace_new_addrs = p->newlist; 1270 ftrace_new_addrs = p->newlist;
1263 p->flags = 0L; 1271 p->flags = 0L;
1264 1272
1265 /* convert record (i.e, patch mcount-call with NOP) */ 1273 /*
1266 if (ftrace_code_disable(mod, p)) { 1274 * Do the initial record convertion from mcount jump
1267 p->flags |= FTRACE_FL_CONVERTED; 1275 * to the NOP instructions.
1268 ftrace_update_cnt++; 1276 */
1269 } else 1277 if (!ftrace_code_disable(mod, p)) {
1270 ftrace_free_rec(p); 1278 ftrace_free_rec(p);
1279 continue;
1280 }
1281
1282 p->flags |= FTRACE_FL_CONVERTED;
1283 ftrace_update_cnt++;
1284
1285 /*
1286 * If the tracing is enabled, go ahead and enable the record.
1287 *
1288 * The reason not to enable the record immediatelly is the
1289 * inherent check of ftrace_make_nop/ftrace_make_call for
1290 * correct previous instructions. Making first the NOP
1291 * conversion puts the module to the correct state, thus
1292 * passing the ftrace_make_call check.
1293 */
1294 if (ftrace_start_up) {
1295 int failed = __ftrace_replace_code(p, 1);
1296 if (failed) {
1297 ftrace_bug(failed, p->ip);
1298 ftrace_free_rec(p);
1299 }
1300 }
1271 } 1301 }
1272 1302
1273 stop = ftrace_now(raw_smp_processor_id()); 1303 stop = ftrace_now(raw_smp_processor_id());
@@ -1657,60 +1687,6 @@ ftrace_regex_lseek(struct file *file, loff_t offset, int origin)
1657 return ret; 1687 return ret;
1658} 1688}
1659 1689
1660enum {
1661 MATCH_FULL,
1662 MATCH_FRONT_ONLY,
1663 MATCH_MIDDLE_ONLY,
1664 MATCH_END_ONLY,
1665};
1666
1667/*
1668 * (static function - no need for kernel doc)
1669 *
1670 * Pass in a buffer containing a glob and this function will
1671 * set search to point to the search part of the buffer and
1672 * return the type of search it is (see enum above).
1673 * This does modify buff.
1674 *
1675 * Returns enum type.
1676 * search returns the pointer to use for comparison.
1677 * not returns 1 if buff started with a '!'
1678 * 0 otherwise.
1679 */
1680static int
1681ftrace_setup_glob(char *buff, int len, char **search, int *not)
1682{
1683 int type = MATCH_FULL;
1684 int i;
1685
1686 if (buff[0] == '!') {
1687 *not = 1;
1688 buff++;
1689 len--;
1690 } else
1691 *not = 0;
1692
1693 *search = buff;
1694
1695 for (i = 0; i < len; i++) {
1696 if (buff[i] == '*') {
1697 if (!i) {
1698 *search = buff + 1;
1699 type = MATCH_END_ONLY;
1700 } else {
1701 if (type == MATCH_END_ONLY)
1702 type = MATCH_MIDDLE_ONLY;
1703 else
1704 type = MATCH_FRONT_ONLY;
1705 buff[i] = 0;
1706 break;
1707 }
1708 }
1709 }
1710
1711 return type;
1712}
1713
1714static int ftrace_match(char *str, char *regex, int len, int type) 1690static int ftrace_match(char *str, char *regex, int len, int type)
1715{ 1691{
1716 int matched = 0; 1692 int matched = 0;
@@ -1759,7 +1735,7 @@ static void ftrace_match_records(char *buff, int len, int enable)
1759 int not; 1735 int not;
1760 1736
1761 flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; 1737 flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
1762 type = ftrace_setup_glob(buff, len, &search, &not); 1738 type = filter_parse_regex(buff, len, &search, &not);
1763 1739
1764 search_len = strlen(search); 1740 search_len = strlen(search);
1765 1741
@@ -1827,7 +1803,7 @@ static void ftrace_match_module_records(char *buff, char *mod, int enable)
1827 } 1803 }
1828 1804
1829 if (strlen(buff)) { 1805 if (strlen(buff)) {
1830 type = ftrace_setup_glob(buff, strlen(buff), &search, &not); 1806 type = filter_parse_regex(buff, strlen(buff), &search, &not);
1831 search_len = strlen(search); 1807 search_len = strlen(search);
1832 } 1808 }
1833 1809
@@ -1992,7 +1968,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
1992 int count = 0; 1968 int count = 0;
1993 char *search; 1969 char *search;
1994 1970
1995 type = ftrace_setup_glob(glob, strlen(glob), &search, &not); 1971 type = filter_parse_regex(glob, strlen(glob), &search, &not);
1996 len = strlen(search); 1972 len = strlen(search);
1997 1973
1998 /* we do not support '!' for function probes */ 1974 /* we do not support '!' for function probes */
@@ -2069,7 +2045,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
2069 else if (glob) { 2045 else if (glob) {
2070 int not; 2046 int not;
2071 2047
2072 type = ftrace_setup_glob(glob, strlen(glob), &search, &not); 2048 type = filter_parse_regex(glob, strlen(glob), &search, &not);
2073 len = strlen(search); 2049 len = strlen(search);
2074 2050
2075 /* we do not support '!' for function probes */ 2051 /* we do not support '!' for function probes */
@@ -2223,15 +2199,15 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
2223 ret = ftrace_process_regex(parser->buffer, 2199 ret = ftrace_process_regex(parser->buffer,
2224 parser->idx, enable); 2200 parser->idx, enable);
2225 if (ret) 2201 if (ret)
2226 goto out; 2202 goto out_unlock;
2227 2203
2228 trace_parser_clear(parser); 2204 trace_parser_clear(parser);
2229 } 2205 }
2230 2206
2231 ret = read; 2207 ret = read;
2232 2208out_unlock:
2233 mutex_unlock(&ftrace_regex_lock); 2209 mutex_unlock(&ftrace_regex_lock);
2234out: 2210
2235 return ret; 2211 return ret;
2236} 2212}
2237 2213
@@ -2313,6 +2289,32 @@ static int __init set_ftrace_filter(char *str)
2313} 2289}
2314__setup("ftrace_filter=", set_ftrace_filter); 2290__setup("ftrace_filter=", set_ftrace_filter);
2315 2291
2292#ifdef CONFIG_FUNCTION_GRAPH_TRACER
2293static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata;
2294static int __init set_graph_function(char *str)
2295{
2296 strlcpy(ftrace_graph_buf, str, FTRACE_FILTER_SIZE);
2297 return 1;
2298}
2299__setup("ftrace_graph_filter=", set_graph_function);
2300
2301static void __init set_ftrace_early_graph(char *buf)
2302{
2303 int ret;
2304 char *func;
2305
2306 while (buf) {
2307 func = strsep(&buf, ",");
2308 /* we allow only one expression at a time */
2309 ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count,
2310 func);
2311 if (ret)
2312 printk(KERN_DEBUG "ftrace: function %s not "
2313 "traceable\n", func);
2314 }
2315}
2316#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
2317
2316static void __init set_ftrace_early_filter(char *buf, int enable) 2318static void __init set_ftrace_early_filter(char *buf, int enable)
2317{ 2319{
2318 char *func; 2320 char *func;
@@ -2329,6 +2331,10 @@ static void __init set_ftrace_early_filters(void)
2329 set_ftrace_early_filter(ftrace_filter_buf, 1); 2331 set_ftrace_early_filter(ftrace_filter_buf, 1);
2330 if (ftrace_notrace_buf[0]) 2332 if (ftrace_notrace_buf[0])
2331 set_ftrace_early_filter(ftrace_notrace_buf, 0); 2333 set_ftrace_early_filter(ftrace_notrace_buf, 0);
2334#ifdef CONFIG_FUNCTION_GRAPH_TRACER
2335 if (ftrace_graph_buf[0])
2336 set_ftrace_early_graph(ftrace_graph_buf);
2337#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
2332} 2338}
2333 2339
2334static int 2340static int
@@ -2514,7 +2520,7 @@ ftrace_set_func(unsigned long *array, int *idx, char *buffer)
2514 return -ENODEV; 2520 return -ENODEV;
2515 2521
2516 /* decode regex */ 2522 /* decode regex */
2517 type = ftrace_setup_glob(buffer, strlen(buffer), &search, &not); 2523 type = filter_parse_regex(buffer, strlen(buffer), &search, &not);
2518 if (not) 2524 if (not)
2519 return -EINVAL; 2525 return -EINVAL;
2520 2526
@@ -2625,7 +2631,7 @@ static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer)
2625 return 0; 2631 return 0;
2626} 2632}
2627 2633
2628static int ftrace_convert_nops(struct module *mod, 2634static int ftrace_process_locs(struct module *mod,
2629 unsigned long *start, 2635 unsigned long *start,
2630 unsigned long *end) 2636 unsigned long *end)
2631{ 2637{
@@ -2658,19 +2664,17 @@ static int ftrace_convert_nops(struct module *mod,
2658} 2664}
2659 2665
2660#ifdef CONFIG_MODULES 2666#ifdef CONFIG_MODULES
2661void ftrace_release(void *start, void *end) 2667void ftrace_release_mod(struct module *mod)
2662{ 2668{
2663 struct dyn_ftrace *rec; 2669 struct dyn_ftrace *rec;
2664 struct ftrace_page *pg; 2670 struct ftrace_page *pg;
2665 unsigned long s = (unsigned long)start;
2666 unsigned long e = (unsigned long)end;
2667 2671
2668 if (ftrace_disabled || !start || start == end) 2672 if (ftrace_disabled)
2669 return; 2673 return;
2670 2674
2671 mutex_lock(&ftrace_lock); 2675 mutex_lock(&ftrace_lock);
2672 do_for_each_ftrace_rec(pg, rec) { 2676 do_for_each_ftrace_rec(pg, rec) {
2673 if ((rec->ip >= s) && (rec->ip < e)) { 2677 if (within_module_core(rec->ip, mod)) {
2674 /* 2678 /*
2675 * rec->ip is changed in ftrace_free_rec() 2679 * rec->ip is changed in ftrace_free_rec()
2676 * It should not between s and e if record was freed. 2680 * It should not between s and e if record was freed.
@@ -2687,7 +2691,7 @@ static void ftrace_init_module(struct module *mod,
2687{ 2691{
2688 if (ftrace_disabled || start == end) 2692 if (ftrace_disabled || start == end)
2689 return; 2693 return;
2690 ftrace_convert_nops(mod, start, end); 2694 ftrace_process_locs(mod, start, end);
2691} 2695}
2692 2696
2693static int ftrace_module_notify(struct notifier_block *self, 2697static int ftrace_module_notify(struct notifier_block *self,
@@ -2702,9 +2706,7 @@ static int ftrace_module_notify(struct notifier_block *self,
2702 mod->num_ftrace_callsites); 2706 mod->num_ftrace_callsites);
2703 break; 2707 break;
2704 case MODULE_STATE_GOING: 2708 case MODULE_STATE_GOING:
2705 ftrace_release(mod->ftrace_callsites, 2709 ftrace_release_mod(mod);
2706 mod->ftrace_callsites +
2707 mod->num_ftrace_callsites);
2708 break; 2710 break;
2709 } 2711 }
2710 2712
@@ -2750,7 +2752,7 @@ void __init ftrace_init(void)
2750 2752
2751 last_ftrace_enabled = ftrace_enabled = 1; 2753 last_ftrace_enabled = ftrace_enabled = 1;
2752 2754
2753 ret = ftrace_convert_nops(NULL, 2755 ret = ftrace_process_locs(NULL,
2754 __start_mcount_loc, 2756 __start_mcount_loc,
2755 __stop_mcount_loc); 2757 __stop_mcount_loc);
2756 2758
@@ -2783,23 +2785,6 @@ static inline void ftrace_startup_enable(int command) { }
2783# define ftrace_shutdown_sysctl() do { } while (0) 2785# define ftrace_shutdown_sysctl() do { } while (0)
2784#endif /* CONFIG_DYNAMIC_FTRACE */ 2786#endif /* CONFIG_DYNAMIC_FTRACE */
2785 2787
2786static ssize_t
2787ftrace_pid_read(struct file *file, char __user *ubuf,
2788 size_t cnt, loff_t *ppos)
2789{
2790 char buf[64];
2791 int r;
2792
2793 if (ftrace_pid_trace == ftrace_swapper_pid)
2794 r = sprintf(buf, "swapper tasks\n");
2795 else if (ftrace_pid_trace)
2796 r = sprintf(buf, "%u\n", pid_vnr(ftrace_pid_trace));
2797 else
2798 r = sprintf(buf, "no pid\n");
2799
2800 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
2801}
2802
2803static void clear_ftrace_swapper(void) 2788static void clear_ftrace_swapper(void)
2804{ 2789{
2805 struct task_struct *p; 2790 struct task_struct *p;
@@ -2850,14 +2835,12 @@ static void set_ftrace_pid(struct pid *pid)
2850 rcu_read_unlock(); 2835 rcu_read_unlock();
2851} 2836}
2852 2837
2853static void clear_ftrace_pid_task(struct pid **pid) 2838static void clear_ftrace_pid_task(struct pid *pid)
2854{ 2839{
2855 if (*pid == ftrace_swapper_pid) 2840 if (pid == ftrace_swapper_pid)
2856 clear_ftrace_swapper(); 2841 clear_ftrace_swapper();
2857 else 2842 else
2858 clear_ftrace_pid(*pid); 2843 clear_ftrace_pid(pid);
2859
2860 *pid = NULL;
2861} 2844}
2862 2845
2863static void set_ftrace_pid_task(struct pid *pid) 2846static void set_ftrace_pid_task(struct pid *pid)
@@ -2868,74 +2851,184 @@ static void set_ftrace_pid_task(struct pid *pid)
2868 set_ftrace_pid(pid); 2851 set_ftrace_pid(pid);
2869} 2852}
2870 2853
2871static ssize_t 2854static int ftrace_pid_add(int p)
2872ftrace_pid_write(struct file *filp, const char __user *ubuf,
2873 size_t cnt, loff_t *ppos)
2874{ 2855{
2875 struct pid *pid; 2856 struct pid *pid;
2876 char buf[64]; 2857 struct ftrace_pid *fpid;
2877 long val; 2858 int ret = -EINVAL;
2878 int ret;
2879 2859
2880 if (cnt >= sizeof(buf)) 2860 mutex_lock(&ftrace_lock);
2881 return -EINVAL;
2882 2861
2883 if (copy_from_user(&buf, ubuf, cnt)) 2862 if (!p)
2884 return -EFAULT; 2863 pid = ftrace_swapper_pid;
2864 else
2865 pid = find_get_pid(p);
2885 2866
2886 buf[cnt] = 0; 2867 if (!pid)
2868 goto out;
2887 2869
2888 ret = strict_strtol(buf, 10, &val); 2870 ret = 0;
2889 if (ret < 0)
2890 return ret;
2891 2871
2892 mutex_lock(&ftrace_lock); 2872 list_for_each_entry(fpid, &ftrace_pids, list)
2893 if (val < 0) { 2873 if (fpid->pid == pid)
2894 /* disable pid tracing */ 2874 goto out_put;
2895 if (!ftrace_pid_trace)
2896 goto out;
2897 2875
2898 clear_ftrace_pid_task(&ftrace_pid_trace); 2876 ret = -ENOMEM;
2899 2877
2900 } else { 2878 fpid = kmalloc(sizeof(*fpid), GFP_KERNEL);
2901 /* swapper task is special */ 2879 if (!fpid)
2902 if (!val) { 2880 goto out_put;
2903 pid = ftrace_swapper_pid;
2904 if (pid == ftrace_pid_trace)
2905 goto out;
2906 } else {
2907 pid = find_get_pid(val);
2908 2881
2909 if (pid == ftrace_pid_trace) { 2882 list_add(&fpid->list, &ftrace_pids);
2910 put_pid(pid); 2883 fpid->pid = pid;
2911 goto out;
2912 }
2913 }
2914 2884
2915 if (ftrace_pid_trace) 2885 set_ftrace_pid_task(pid);
2916 clear_ftrace_pid_task(&ftrace_pid_trace);
2917 2886
2918 if (!pid) 2887 ftrace_update_pid_func();
2919 goto out; 2888 ftrace_startup_enable(0);
2889
2890 mutex_unlock(&ftrace_lock);
2891 return 0;
2892
2893out_put:
2894 if (pid != ftrace_swapper_pid)
2895 put_pid(pid);
2920 2896
2921 ftrace_pid_trace = pid; 2897out:
2898 mutex_unlock(&ftrace_lock);
2899 return ret;
2900}
2901
2902static void ftrace_pid_reset(void)
2903{
2904 struct ftrace_pid *fpid, *safe;
2922 2905
2923 set_ftrace_pid_task(ftrace_pid_trace); 2906 mutex_lock(&ftrace_lock);
2907 list_for_each_entry_safe(fpid, safe, &ftrace_pids, list) {
2908 struct pid *pid = fpid->pid;
2909
2910 clear_ftrace_pid_task(pid);
2911
2912 list_del(&fpid->list);
2913 kfree(fpid);
2924 } 2914 }
2925 2915
2926 /* update the function call */
2927 ftrace_update_pid_func(); 2916 ftrace_update_pid_func();
2928 ftrace_startup_enable(0); 2917 ftrace_startup_enable(0);
2929 2918
2930 out:
2931 mutex_unlock(&ftrace_lock); 2919 mutex_unlock(&ftrace_lock);
2920}
2932 2921
2933 return cnt; 2922static void *fpid_start(struct seq_file *m, loff_t *pos)
2923{
2924 mutex_lock(&ftrace_lock);
2925
2926 if (list_empty(&ftrace_pids) && (!*pos))
2927 return (void *) 1;
2928
2929 return seq_list_start(&ftrace_pids, *pos);
2930}
2931
2932static void *fpid_next(struct seq_file *m, void *v, loff_t *pos)
2933{
2934 if (v == (void *)1)
2935 return NULL;
2936
2937 return seq_list_next(v, &ftrace_pids, pos);
2938}
2939
2940static void fpid_stop(struct seq_file *m, void *p)
2941{
2942 mutex_unlock(&ftrace_lock);
2943}
2944
2945static int fpid_show(struct seq_file *m, void *v)
2946{
2947 const struct ftrace_pid *fpid = list_entry(v, struct ftrace_pid, list);
2948
2949 if (v == (void *)1) {
2950 seq_printf(m, "no pid\n");
2951 return 0;
2952 }
2953
2954 if (fpid->pid == ftrace_swapper_pid)
2955 seq_printf(m, "swapper tasks\n");
2956 else
2957 seq_printf(m, "%u\n", pid_vnr(fpid->pid));
2958
2959 return 0;
2960}
2961
2962static const struct seq_operations ftrace_pid_sops = {
2963 .start = fpid_start,
2964 .next = fpid_next,
2965 .stop = fpid_stop,
2966 .show = fpid_show,
2967};
2968
2969static int
2970ftrace_pid_open(struct inode *inode, struct file *file)
2971{
2972 int ret = 0;
2973
2974 if ((file->f_mode & FMODE_WRITE) &&
2975 (file->f_flags & O_TRUNC))
2976 ftrace_pid_reset();
2977
2978 if (file->f_mode & FMODE_READ)
2979 ret = seq_open(file, &ftrace_pid_sops);
2980
2981 return ret;
2982}
2983
2984static ssize_t
2985ftrace_pid_write(struct file *filp, const char __user *ubuf,
2986 size_t cnt, loff_t *ppos)
2987{
2988 char buf[64], *tmp;
2989 long val;
2990 int ret;
2991
2992 if (cnt >= sizeof(buf))
2993 return -EINVAL;
2994
2995 if (copy_from_user(&buf, ubuf, cnt))
2996 return -EFAULT;
2997
2998 buf[cnt] = 0;
2999
3000 /*
3001 * Allow "echo > set_ftrace_pid" or "echo -n '' > set_ftrace_pid"
3002 * to clean the filter quietly.
3003 */
3004 tmp = strstrip(buf);
3005 if (strlen(tmp) == 0)
3006 return 1;
3007
3008 ret = strict_strtol(tmp, 10, &val);
3009 if (ret < 0)
3010 return ret;
3011
3012 ret = ftrace_pid_add(val);
3013
3014 return ret ? ret : cnt;
3015}
3016
3017static int
3018ftrace_pid_release(struct inode *inode, struct file *file)
3019{
3020 if (file->f_mode & FMODE_READ)
3021 seq_release(inode, file);
3022
3023 return 0;
2934} 3024}
2935 3025
2936static const struct file_operations ftrace_pid_fops = { 3026static const struct file_operations ftrace_pid_fops = {
2937 .read = ftrace_pid_read, 3027 .open = ftrace_pid_open,
2938 .write = ftrace_pid_write, 3028 .write = ftrace_pid_write,
3029 .read = seq_read,
3030 .llseek = seq_lseek,
3031 .release = ftrace_pid_release,
2939}; 3032};
2940 3033
2941static __init int ftrace_init_debugfs(void) 3034static __init int ftrace_init_debugfs(void)
@@ -3298,4 +3391,3 @@ void ftrace_graph_stop(void)
3298 ftrace_stop(); 3391 ftrace_stop();
3299} 3392}
3300#endif 3393#endif
3301