aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2016-11-14 16:31:49 -0500
committerSteven Rostedt <rostedt@goodmis.org>2016-11-14 16:31:49 -0500
commit546fece4eae871f033925ccf0ff2b740725ae915 (patch)
tree04608cf612ed5f5173992abc25c554ed5169e9f7
parent977c1f9c8c022d0173181766b34a0db3705265a4 (diff)
ftrace: Add more checks for FTRACE_FL_DISABLED in processing ip records
When a module is first loaded and its function ip records are added to the ftrace list of functions to modify, they are set to DISABLED, as their text is still in a read only state. When the module is fully loaded, and can be updated, the flag is cleared, and if their's any functions that should be tracing them, it is updated at that moment. But there's several locations that do record accounting and should ignore records that are marked as disabled, or they can cause issues. Alexei already fixed one location, but others need to be addressed. Cc: stable@vger.kernel.org Fixes: b7ffffbb46f2 "ftrace: Add infrastructure for delayed enabling of module functions" Reported-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--kernel/trace/ftrace.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 326498baab83..da87b3cba5b3 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1862,6 +1862,10 @@ static int __ftrace_hash_update_ipmodify(struct ftrace_ops *ops,
1862 1862
1863 /* Update rec->flags */ 1863 /* Update rec->flags */
1864 do_for_each_ftrace_rec(pg, rec) { 1864 do_for_each_ftrace_rec(pg, rec) {
1865
1866 if (rec->flags & FTRACE_FL_DISABLED)
1867 continue;
1868
1865 /* We need to update only differences of filter_hash */ 1869 /* We need to update only differences of filter_hash */
1866 in_old = !!ftrace_lookup_ip(old_hash, rec->ip); 1870 in_old = !!ftrace_lookup_ip(old_hash, rec->ip);
1867 in_new = !!ftrace_lookup_ip(new_hash, rec->ip); 1871 in_new = !!ftrace_lookup_ip(new_hash, rec->ip);
@@ -1884,6 +1888,10 @@ rollback:
1884 1888
1885 /* Roll back what we did above */ 1889 /* Roll back what we did above */
1886 do_for_each_ftrace_rec(pg, rec) { 1890 do_for_each_ftrace_rec(pg, rec) {
1891
1892 if (rec->flags & FTRACE_FL_DISABLED)
1893 continue;
1894
1887 if (rec == end) 1895 if (rec == end)
1888 goto err_out; 1896 goto err_out;
1889 1897
@@ -2397,6 +2405,10 @@ void __weak ftrace_replace_code(int enable)
2397 return; 2405 return;
2398 2406
2399 do_for_each_ftrace_rec(pg, rec) { 2407 do_for_each_ftrace_rec(pg, rec) {
2408
2409 if (rec->flags & FTRACE_FL_DISABLED)
2410 continue;
2411
2400 failed = __ftrace_replace_code(rec, enable); 2412 failed = __ftrace_replace_code(rec, enable);
2401 if (failed) { 2413 if (failed) {
2402 ftrace_bug(failed, rec); 2414 ftrace_bug(failed, rec);
@@ -3598,6 +3610,10 @@ match_records(struct ftrace_hash *hash, char *func, int len, char *mod)
3598 goto out_unlock; 3610 goto out_unlock;
3599 3611
3600 do_for_each_ftrace_rec(pg, rec) { 3612 do_for_each_ftrace_rec(pg, rec) {
3613
3614 if (rec->flags & FTRACE_FL_DISABLED)
3615 continue;
3616
3601 if (ftrace_match_record(rec, &func_g, mod_match, exclude_mod)) { 3617 if (ftrace_match_record(rec, &func_g, mod_match, exclude_mod)) {
3602 ret = enter_record(hash, rec, clear_filter); 3618 ret = enter_record(hash, rec, clear_filter);
3603 if (ret < 0) { 3619 if (ret < 0) {
@@ -3793,6 +3809,9 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3793 3809
3794 do_for_each_ftrace_rec(pg, rec) { 3810 do_for_each_ftrace_rec(pg, rec) {
3795 3811
3812 if (rec->flags & FTRACE_FL_DISABLED)
3813 continue;
3814
3796 if (!ftrace_match_record(rec, &func_g, NULL, 0)) 3815 if (!ftrace_match_record(rec, &func_g, NULL, 0))
3797 continue; 3816 continue;
3798 3817
@@ -4685,6 +4704,9 @@ ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer)
4685 4704
4686 do_for_each_ftrace_rec(pg, rec) { 4705 do_for_each_ftrace_rec(pg, rec) {
4687 4706
4707 if (rec->flags & FTRACE_FL_DISABLED)
4708 continue;
4709
4688 if (ftrace_match_record(rec, &func_g, NULL, 0)) { 4710 if (ftrace_match_record(rec, &func_g, NULL, 0)) {
4689 /* if it is in the array */ 4711 /* if it is in the array */
4690 exists = false; 4712 exists = false;