diff options
author | kenistoj <kenistoj> | 2008-01-25 23:55:04 +0000 |
---|---|---|
committer | kenistoj <kenistoj> | 2008-01-25 23:55:04 +0000 |
commit | fb10329303b55f4b7af98237e65d72c030df13b0 (patch) | |
tree | 326cc0efa5719a742f95b7580b605fbc91273de0 | |
parent | 1939ea3217ce8b8fae35e4a70f4cd5c1c431e438 (diff) | |
download | systemtap-steved-fb10329303b55f4b7af98237e65d72c030df13b0.tar.gz systemtap-steved-fb10329303b55f4b7af98237e65d72c030df13b0.tar.xz systemtap-steved-fb10329303b55f4b7af98237e65d72c030df13b0.zip |
* runtime/uprobes/uprobes.c: Within a probed process, serialize
calls to access_process_vm() when populating instructions
slots. Fixes an SMP bug on multithreaded apps with many
active probepoints.
* runtime/uprobes/uprobes.h: Ditto
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | runtime/uprobes/uprobes.c | 12 | ||||
-rw-r--r-- | runtime/uprobes/uprobes.h | 7 |
3 files changed, 26 insertions, 1 deletions
@@ -1,3 +1,11 @@ +2008-01-25 Jim Keniston <jkenisto@us.ibm.com> + + * runtime/uprobes/uprobes.c: Within a probed process, serialize + calls to access_process_vm() when populating instructions + slots. Fixes an SMP bug on multithreaded apps with many + active probepoints. + * runtime/uprobes/uprobes.h: Ditto + 2008-01-25 Frank Ch. Eigler <fche@elastic.org> PR 5672. diff --git a/runtime/uprobes/uprobes.c b/runtime/uprobes/uprobes.c index 501c4298..f0b72c46 100644 --- a/runtime/uprobes/uprobes.c +++ b/runtime/uprobes/uprobes.c @@ -649,6 +649,7 @@ static struct uprobe_process *uprobe_mk_process(struct task_struct *p) uproc->ssol_area.insn_area = NULL; uproc->ssol_area.initialized = 0; mutex_init(&uproc->ssol_area.setup_mutex); + /* Initialize rest of area in uprobe_init_ssol(). */ #ifdef CONFIG_UPROBES_SSOL uproc->sstep_out_of_line = 1; #else @@ -1257,6 +1258,7 @@ static noinline void uprobe_init_ssol(struct uprobe_process *uproc) area->insn_area = ERR_PTR(-ENOMEM); return; } + mutex_init(&area->populate_mutex); spin_lock_init(&area->lock); area->next_slot = 0; slot_addr = (char*) area->insn_area; @@ -1405,8 +1407,10 @@ found_slot: s->last_used = jiffies; s->state = SSOL_ASSIGNED; /* Copy the original instruction to the chosen slot. */ + mutex_lock(&area->populate_mutex); len = access_process_vm(current, (unsigned long)s->insn, ppt->insn, MAX_UINSN_BYTES, 1); + mutex_unlock(&area->populate_mutex); if (unlikely(len < MAX_UINSN_BYTES)) { up_write(&s->rwsem); printk(KERN_ERR "Failed to copy instruction at %#lx" @@ -1450,12 +1454,18 @@ static struct uprobe_ssol_slot static struct uprobe_ssol_slot *uprobe_get_insn_slot(struct uprobe_probept *ppt) { - struct uprobe_ssol_slot *slot = ppt->slot; + struct uprobe_ssol_slot *slot; +retry: + slot = ppt->slot; if (unlikely(!slot)) return uprobe_find_insn_slot(ppt); down_read(&slot->rwsem); + if (unlikely(slot != ppt->slot)) { + up_read(&slot->rwsem); + goto retry; + } if (unlikely(slot->owner != ppt)) { up_read(&slot->rwsem); return uprobe_find_insn_slot(ppt); diff --git a/runtime/uprobes/uprobes.h b/runtime/uprobes/uprobes.h index e8a06599..418518f8 100644 --- a/runtime/uprobes/uprobes.h +++ b/runtime/uprobes/uprobes.h @@ -157,6 +157,13 @@ struct uprobe_ssol_area { /* lock held while finding a free slot */ spinlock_t lock; + /* + * We currently use access_process_vm() to populate instruction + * slots. Calls must be serialized because access_process_vm() + * isn't thread-safe. + */ + struct mutex populate_mutex; + /* Next slot to steal */ int next_slot; |