summaryrefslogtreecommitdiffstats
path: root/runtime/uprobes
diff options
context:
space:
mode:
authorSrikar Dronamraju <srikar@linux.vnet.ibm.com>2009-10-19 13:44:21 +0530
committerSrikar Dronamraju <srikar@linux.vnet.ibm.com>2009-10-19 13:44:21 +0530
commit720bbfc68d9e7dfd8c37587c6a61da75d6aab4fa (patch)
treea3114dc7319d78202b40f3458bac4516aedbe4cf /runtime/uprobes
parent3c2341daf979fc38fc534ae91e00594a525962e0 (diff)
downloadsystemtap-steved-720bbfc68d9e7dfd8c37587c6a61da75d6aab4fa.tar.gz
systemtap-steved-720bbfc68d9e7dfd8c37587c6a61da75d6aab4fa.tar.xz
systemtap-steved-720bbfc68d9e7dfd8c37587c6a61da75d6aab4fa.zip
Avoid lockdep warnings.
uprobe_fork_uproc() runs with parent_uproc->rwsem locked. However uprobe_mk_process() that gets called within uprobe_fork_uproc() also locks child_uproc->rwsem after initializing it. Lockdep report confuses this to acquiring a lock that already has been acquired and suggests using sub-classes. The alternatives we have are: 1. use classes level to distinguish different uproc structures. 2. unlock parent_uproc->rwsem before we call uprobe_fork_uproc(). 3. dont try locking child_uproc->rwsem; since we are protected by uproc_mutex as well as parent_uproc->rwsem; We use the last approach. Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com> ---
Diffstat (limited to 'runtime/uprobes')
-rw-r--r--runtime/uprobes/uprobes.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/runtime/uprobes/uprobes.c b/runtime/uprobes/uprobes.c
index 27e923b8..60c84509 100644
--- a/runtime/uprobes/uprobes.c
+++ b/runtime/uprobes/uprobes.c
@@ -652,8 +652,18 @@ dont_add:
return NULL;
}
-/* Runs with uproc_mutex held; returns with uproc->rwsem write-locked. */
-static struct uprobe_process *uprobe_mk_process(struct task_struct *p)
+/*
+ * Create a per process uproc struct.
+ * at_fork: indicates uprobe_mk_process is called from
+ * a fork context of a probe process. refer uprobe_fork_uproc
+ * for more details.
+ *
+ * Runs with uproc_mutex held;
+ * Returns with uproc->rwsem write-locked when not called
+ * from fork context.
+ */
+static struct uprobe_process *uprobe_mk_process(struct task_struct *p,
+ bool at_fork)
{
struct uprobe_process *uproc;
struct uprobe_task *utask;
@@ -668,7 +678,9 @@ static struct uprobe_process *uprobe_mk_process(struct task_struct *p)
/* Initialize fields */
atomic_set(&uproc->refcount, 1);
init_rwsem(&uproc->rwsem);
- down_write(&uproc->rwsem);
+ if (!at_fork)
+ /* not called from fork context. */
+ down_write(&uproc->rwsem);
init_waitqueue_head(&uproc->waitq);
for (i = 0; i < UPROBE_TABLE_SIZE; i++)
INIT_HLIST_HEAD(&uproc->uprobe_table[i]);
@@ -923,7 +935,7 @@ int register_uprobe(struct uprobe *u)
unlock_uproc_table();
goto fail_tsk;
}
- uproc = uprobe_mk_process(p);
+ uproc = uprobe_mk_process(p, 0);
if (IS_ERR(uproc)) {
ret = (int) PTR_ERR(uproc);
unlock_uproc_table();
@@ -2206,13 +2218,12 @@ static int uprobe_fork_uproc(struct uprobe_process *parent_uproc,
if (!try_module_get(THIS_MODULE))
return -ENOSYS;
- child_uproc = uprobe_mk_process(child_tsk);
+ child_uproc = uprobe_mk_process(child_tsk, 1);
if (IS_ERR(child_uproc)) {
ret = (int) PTR_ERR(child_uproc);
module_put(THIS_MODULE);
return ret;
}
- /* child_uproc is write-locked and ref-counted at this point. */
mutex_lock(&child_uproc->ssol_area.setup_mutex);
uprobe_init_ssol(child_uproc, child_tsk,
@@ -2228,7 +2239,6 @@ static int uprobe_fork_uproc(struct uprobe_process *parent_uproc,
&uproc_table[hash_long(child_uproc->tgid,
UPROBE_HASH_BITS)]);
- up_write(&child_uproc->rwsem);
uprobe_decref_process(child_uproc);
return ret;
}