Fixes a problem seen on SMP systems when multiple threads of a multithreaded app are pounding the probed instruction when the uprobe is registered. uprobe_verify_ssol() was releasing the second thread through before SSOL setup was complete. --- include/linux/uprobes.h | 3 +++ kernel/uprobes.c | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff -puN include/linux/uprobes.h~uprobes-smp-pounder-fix include/linux/uprobes.h --- linux-2.6.21-rc6/include/linux/uprobes.h~uprobes-smp-pounder-fix 2007-06-09 11:21:05.000000000 -0700 +++ linux-2.6.21-rc6-jimk/include/linux/uprobes.h 2007-06-09 11:23:33.000000000 -0700 @@ -169,6 +169,9 @@ struct uprobe_ssol_area { /* Ensures 2 threads don't try to set up the vma simultaneously. */ struct mutex setup_mutex; + + /* 1 = we've at least tried. IS_ERR(insn_area) if we failed. */ + int initialized; }; /* diff -puN kernel/uprobes.c~uprobes-smp-pounder-fix kernel/uprobes.c --- linux-2.6.21-rc6/kernel/uprobes.c~uprobes-smp-pounder-fix 2007-06-09 11:21:05.000000000 -0700 +++ linux-2.6.21-rc6-jimk/kernel/uprobes.c 2007-06-09 11:23:51.000000000 -0700 @@ -285,9 +285,9 @@ static void rouse_all_threads(struct upr if (utask->quiescing) { utask->quiescing = 0; if (utask->state == UPTASK_QUIESCENT) { - clear_utrace_quiesce(utask); utask->state = UPTASK_RUNNING; uproc->n_quiescent_threads--; + clear_utrace_quiesce(utask); } } } @@ -533,6 +533,7 @@ static struct uprobe_process *uprobe_mk_ uproc->uretprobe_trampoline_addr = NULL; uproc->ssol_area.insn_area = NULL; + uproc->ssol_area.initialized = 0; mutex_init(&uproc->ssol_area.setup_mutex); #ifdef CONFIG_UPROBES_SSOL uproc->sstep_out_of_line = 1; @@ -1020,13 +1021,14 @@ static __user uprobe_opcode_t { struct uprobe_ssol_area *area = &uproc->ssol_area; - if (unlikely(!area->insn_area)) { + if (unlikely(!area->initialized)) { /* First time through for this probed process */ static DEFINE_MUTEX(ssol_setup_mutex); mutex_lock(&ssol_setup_mutex); - if (likely(!area->insn_area)) + if (likely(!area->initialized)) /* Nobody snuck in and set things up ahead of us. */ uprobe_init_ssol(uproc); + area->initialized = 1; mutex_unlock(&ssol_setup_mutex); } return area->insn_area; _