Fix race condition while we unregister uprobes 68/101568/2
authorAnatolii Nikulin <nikulin.a@samsung.com>
Thu, 1 Dec 2016 12:12:10 +0000 (15:12 +0300)
committerAnatolii Nikulin <nikulin.a@samsung.com>
Thu, 1 Dec 2016 12:21:15 +0000 (15:21 +0300)
When we stop profiling, da_manager and profiling application may
unregister the same probe simultaneously.

Change-Id: I81d4e02fa97f27215ebf321e6c58896ec761ce2a
Signed-off-by: Anatolii Nikulin <nikulin.a@samsung.com>
uprobe/swap_uprobes.c

index f9c0ff0..2d7d844 100644 (file)
@@ -52,6 +52,7 @@ enum {
 
 static DEFINE_RWLOCK(st_lock);
 static struct hlist_head slot_table[UPROBE_TABLE_SIZE];
+static DEFINE_MUTEX(up_mtx);   /* Protects uprobe_table */
 struct hlist_head uprobe_table[UPROBE_TABLE_SIZE];
 
 static DEFINE_MUTEX(urp_mtx);  /* Protects uretprobe_inst_table */
@@ -550,11 +551,12 @@ void __swap_unregister_uprobe(struct uprobe *p, int disarm)
        if (!p->task)
                return;
 
+       mutex_lock(&up_mtx);
        rcu_read_lock();
        old_p = get_uprobe(p->addr, p->task->tgid);
        rcu_read_unlock();
        if (unlikely(!old_p))
-               return;
+               goto out_unlock;
 
        if (p != old_p) {
                rcu_read_lock();
@@ -566,8 +568,7 @@ void __swap_unregister_uprobe(struct uprobe *p, int disarm)
                        }
                }
                rcu_read_unlock();
-
-               return;
+               goto out_unlock;
        }
 
 valid_p:
@@ -616,6 +617,9 @@ valid_p:
                                old_p->post_handler = NULL;
                }
        }
+
+out_unlock:
+       mutex_unlock(&up_mtx);
 }
 EXPORT_SYMBOL_GPL(__swap_unregister_uprobe);