From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
Ingo Molnar <mingo@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
Srikar Dronamraju <srikar@linux.vnet.ibm.com>,
Oleg Nesterov <oleg@redhat.com>,
Frederic Weisbecker <fweisbec@gmail.com>,
Ingo Molnar <mingo@redhat.com>,
Tom Zanussi <tom.zanussi@intel.com>
Subject: [PATCH 06/18] ftrace: Cleanup regex_lock and ftrace_lock around hash updating
Date: Fri, 10 May 2013 20:12:12 -0400 [thread overview]
Message-ID: <20130511001304.214878967@goodmis.org> (raw)
In-Reply-To: 20130511001206.477862307@goodmis.org
[-- Attachment #1: Type: text/plain, Size: 6329 bytes --]
From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cleanup regex_lock and ftrace_lock locking points around
ftrace_ops hash update code.
The new rule is that regex_lock protects ops->*_hash
read-update-write code for each ftrace_ops. Usually,
hash update is done by following sequence.
1. allocate a new local hash and copy the original hash.
2. update the local hash.
3. move(actually, copy) back the local hash to ftrace_ops.
4. update ftrace entries if needed.
5. release the local hash.
This makes regex_lock protect #1-#4, and ftrace_lock
to protect #3, #4 and adding and removing ftrace_ops from the
ftrace_ops_list. The ftrace_lock protects #3 as well because
the move functions update the entries too.
Link: http://lkml.kernel.org/r/20130509054421.30398.83411.stgit@mhiramat-M0-7522
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Tom Zanussi <tom.zanussi@intel.com>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/ftrace.c | 59 +++++++++++++++++++++++++++----------------------
1 file changed, 32 insertions(+), 27 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 827f2fe..cacf085 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -2656,28 +2656,26 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
return -ENOMEM;
}
+ iter->ops = ops;
+ iter->flags = flag;
+
+ mutex_lock(&ops->regex_lock);
+
if (flag & FTRACE_ITER_NOTRACE)
hash = ops->notrace_hash;
else
hash = ops->filter_hash;
- iter->ops = ops;
- iter->flags = flag;
-
if (file->f_mode & FMODE_WRITE) {
- mutex_lock(&ftrace_lock);
iter->hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, hash);
- mutex_unlock(&ftrace_lock);
-
if (!iter->hash) {
trace_parser_put(&iter->parser);
kfree(iter);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out_unlock;
}
}
- mutex_lock(&ops->regex_lock);
-
if ((file->f_mode & FMODE_WRITE) &&
(file->f_flags & O_TRUNC))
ftrace_filter_reset(iter->hash);
@@ -2697,6 +2695,8 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
}
} else
file->private_data = iter;
+
+ out_unlock:
mutex_unlock(&ops->regex_lock);
return ret;
@@ -3012,7 +3012,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
if (WARN_ON(not))
return -EINVAL;
- mutex_lock(&ftrace_lock);
+ mutex_lock(&trace_probe_ops.regex_lock);
hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash);
if (!hash) {
@@ -3070,14 +3070,16 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
} while_for_each_ftrace_rec();
+ mutex_lock(&ftrace_lock);
ret = ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash);
if (ret < 0)
count = ret;
__enable_ftrace_function_probe();
+ mutex_unlock(&ftrace_lock);
out_unlock:
- mutex_unlock(&ftrace_lock);
+ mutex_unlock(&trace_probe_ops.regex_lock);
free_ftrace_hash(hash);
return count;
@@ -3117,7 +3119,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
return;
}
- mutex_lock(&ftrace_lock);
+ mutex_lock(&trace_probe_ops.regex_lock);
hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash);
if (!hash)
@@ -3155,6 +3157,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
list_add(&entry->free_list, &free_list);
}
}
+ mutex_lock(&ftrace_lock);
__disable_ftrace_function_probe();
/*
* Remove after the disable is called. Otherwise, if the last
@@ -3166,9 +3169,10 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
list_del(&entry->free_list);
ftrace_free_entry(entry);
}
+ mutex_unlock(&ftrace_lock);
out_unlock:
- mutex_unlock(&ftrace_lock);
+ mutex_unlock(&trace_probe_ops.regex_lock);
free_ftrace_hash(hash);
}
@@ -3284,11 +3288,10 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
} else
iter = file->private_data;
- mutex_lock(&iter->ops->regex_lock);
-
- ret = -ENODEV;
if (unlikely(ftrace_disabled))
- goto out_unlock;
+ return -ENODEV;
+
+ /* iter->hash is a local copy, so we don't need regex_lock */
parser = &iter->parser;
read = trace_get_user(parser, ubuf, cnt, ppos);
@@ -3299,13 +3302,11 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
parser->idx, enable);
trace_parser_clear(parser);
if (ret < 0)
- goto out_unlock;
+ goto out;
}
ret = read;
-out_unlock:
- mutex_unlock(&iter->ops->regex_lock);
-
+ out:
return ret;
}
@@ -3357,16 +3358,19 @@ ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len,
if (unlikely(ftrace_disabled))
return -ENODEV;
+ mutex_lock(&ops->regex_lock);
+
if (enable)
orig_hash = &ops->filter_hash;
else
orig_hash = &ops->notrace_hash;
hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash);
- if (!hash)
- return -ENOMEM;
+ if (!hash) {
+ ret = -ENOMEM;
+ goto out_regex_unlock;
+ }
- mutex_lock(&ops->regex_lock);
if (reset)
ftrace_filter_reset(hash);
if (buf && !ftrace_match_records(hash, buf, len)) {
@@ -3584,8 +3588,6 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
} else
iter = file->private_data;
- mutex_lock(&iter->ops->regex_lock);
-
parser = &iter->parser;
if (trace_parser_loaded(parser)) {
parser->buffer[parser->idx] = 0;
@@ -3594,6 +3596,8 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
trace_parser_put(parser);
+ mutex_lock(&iter->ops->regex_lock);
+
if (file->f_mode & FMODE_WRITE) {
filter_hash = !!(iter->flags & FTRACE_ITER_FILTER);
@@ -3611,10 +3615,11 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
mutex_unlock(&ftrace_lock);
}
+
+ mutex_unlock(&iter->ops->regex_lock);
free_ftrace_hash(iter->hash);
kfree(iter);
- mutex_unlock(&iter->ops->regex_lock);
return 0;
}
--
1.7.10.4
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
next prev parent reply other threads:[~2013-05-11 0:13 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-11 0:12 [PATCH 00/18] tracing/kprobes: Update kprobes with new ftrace changes Steven Rostedt
2013-05-11 0:12 ` [PATCH 01/18] ring-buffer: Select IRQ_WORK Steven Rostedt
2013-05-11 0:12 ` [PATCH 02/18] tracing: Dont succeed if event_enable_func did not register anything Steven Rostedt
2013-05-11 0:12 ` [PATCH 03/18] tracing: Return error if register_ftrace_function_probe() fails for event_enable_func() Steven Rostedt
2013-05-11 0:12 ` [PATCH 04/18] ftrace: Have ftrace_regex_write() return either read or error Steven Rostedt
2013-05-11 0:12 ` [PATCH 05/18] ftrace, kprobes: Fix a deadlock on ftrace_regex_lock Steven Rostedt
2013-05-11 0:12 ` Steven Rostedt [this message]
2013-05-11 0:12 ` [PATCH 07/18] tracing/kprobes: Fix to increment return event probe hit-count Steven Rostedt
2013-05-11 0:12 ` [PATCH 08/18] tracing: Indicate enabled soft-mode in enable file Steven Rostedt
2013-05-11 0:12 ` [PATCH 09/18] tracing: Modify soft-mode only if theres no other referrer Steven Rostedt
2013-05-11 0:12 ` [PATCH 10/18] tracing: Add helper function trace_create_new_event() to remove duplicate code Steven Rostedt
2013-05-11 0:12 ` [PATCH 11/18] ftrace: Fix locking in register_ftrace_function_probe() Steven Rostedt
2013-05-11 0:12 ` [PATCH 12/18] ftrace: Fix the output of enabled_functions debug file Steven Rostedt
2013-05-11 0:12 ` [PATCH 13/18] ftrace: Fix function probe when more than one probe is added Steven Rostedt
2013-05-11 0:12 ` [PATCH 14/18] tracing/kprobes: Use bool for retprobe checker Steven Rostedt
2013-05-11 0:12 ` [PATCH 15/18] tracing/kprobes: Increment probe hit-count even if it is used by perf Steven Rostedt
2013-05-11 0:12 ` [PATCH 16/18] tracing/kprobes: Pass trace_probe directly from dispatcher Steven Rostedt
2013-05-11 0:12 ` [PATCH 17/18] tracing/kprobes: Support ftrace_event_file base multibuffer Steven Rostedt
2013-05-11 0:12 ` [PATCH 18/18] tracing/kprobes: Support soft-mode disabling Steven Rostedt
2013-05-12 1:16 ` [PATCH 00/18] tracing/kprobes: Update kprobes with new ftrace changes Linus Torvalds
2013-05-12 2:11 ` Steven Rostedt
2013-05-12 2:22 ` Steven Rostedt
2013-05-12 12:50 ` Steven Rostedt
2013-05-12 18:56 ` Linus Torvalds
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130511001304.214878967@goodmis.org \
--to=rostedt@goodmis.org \
--cc=akpm@linux-foundation.org \
--cc=fweisbec@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mingo@kernel.org \
--cc=mingo@redhat.com \
--cc=oleg@redhat.com \
--cc=srikar@linux.vnet.ibm.com \
--cc=tom.zanussi@intel.com \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.