[IMPROVE] synchronize usage of sspt_proc.files.head 22/65722/3
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Mon, 11 Apr 2016 14:06:02 +0000 (17:06 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Mon, 18 Apr 2016 07:18:14 +0000 (10:18 +0300)
Change-Id: Id308856c9d300394e3946094a43b6d3c8102eb0d
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
us_manager/helper.c
us_manager/sspt/sspt_debug.h
us_manager/sspt/sspt_proc.c
us_manager/sspt/sspt_proc.h

index 1bdfecf..e3dde3c 100644 (file)
@@ -464,14 +464,12 @@ static void __remove_unmap_probes(struct sspt_proc *proc,
        }
 }
 
-static void remove_unmap_probes(struct task_struct *task,
-                               struct unmap_data *umd)
+static unsigned long cb_munmap(void *data)
 {
        struct sspt_proc *proc;
+       struct unmap_data *umd = (struct unmap_data *)data;
 
-       sspt_proc_write_lock();
-
-       proc = sspt_proc_get_by_task(task);
+       proc = sspt_proc_get_by_task(current);
        if (proc) {
                struct msg_unmap_data msg_data = {
                        .start = umd->start,
@@ -486,39 +484,41 @@ static void remove_unmap_probes(struct task_struct *task,
                sspt_proc_put(proc);
        }
 
-       sspt_proc_write_unlock();
+       atomic_dec(&unmap_cnt);
+       return 0;
 }
 
 static int entry_handler_unmap(struct kretprobe_instance *ri,
                               struct pt_regs *regs)
 {
        struct unmap_data *data = (struct unmap_data *)ri->data;
-       struct task_struct *task = current->group_leader;
-
-       atomic_inc(&unmap_cnt);
 
        data->start = swap_get_karg(regs, 1);
        data->len = (size_t)PAGE_ALIGN(swap_get_karg(regs, 2));
 
-       if (!is_kthread(task) && atomic_read(&stop_flag))
-               remove_unmap_probes(task, data);
-
+       atomic_inc(&unmap_cnt);
        return 0;
 }
 
 static int ret_handler_unmap(struct kretprobe_instance *ri,
                             struct pt_regs *regs)
 {
-       struct task_struct *task;
-
-       task = current->group_leader;
-       if (is_kthread(task) || regs_return_value(regs))
-               goto out;
+       int ret;
 
-       remove_unmap_probes(task, (struct unmap_data *)ri->data);
+       if (regs_return_value(regs)) {
+               atomic_dec(&unmap_cnt);
+               return 0;
+       }
 
-out:
-       atomic_dec(&unmap_cnt);
+       ret = set_jump_cb((unsigned long)ri->ret_addr, regs, cb_munmap,
+                         (struct unmap_data *)ri->data,
+                         sizeof(struct unmap_data));
+       if (ret == 0) {
+               ri->ret_addr = (unsigned long *)get_jump_addr();
+       } else {
+               WARN_ON(1);
+               atomic_dec(&unmap_cnt);
+       }
 
        return 0;
 }
index 5a22b31..a6830ff 100644 (file)
@@ -101,14 +101,16 @@ static inline void print_file_probes(const struct sspt_file *file)
        }
 }
 
-static inline void print_proc_probes(const struct sspt_proc *proc)
+static inline void print_proc_probes(struct sspt_proc *proc)
 {
        struct sspt_file *file;
 
        printk(KERN_INFO "### print_proc_probes\n");
-       list_for_each_entry(file, &proc->file_head, list) {
+       down_read(&proc->files.sem);
+       list_for_each_entry(file, &proc->files.head, list) {
                print_file_probes(file);
        }
+       up_read(&proc->files.sem);
        printk(KERN_INFO "### print_proc_probes\n");
 }
 
index 28239ac..f5e2512 100644 (file)
@@ -178,11 +178,12 @@ static struct sspt_proc *sspt_proc_create(struct task_struct *leader)
                }
 
                INIT_LIST_HEAD(&proc->list);
+               INIT_LIST_HEAD(&proc->files.head);
+               init_rwsem(&proc->files.sem);
                proc->tgid = leader->tgid;
                proc->leader = leader;
                /* FIXME: change the task leader */
                proc->sm = create_sm_us(leader);
-               INIT_LIST_HEAD(&proc->file_head);
                mutex_init(&proc->filters.mtx);
                INIT_LIST_HEAD(&proc->filters.head);
                atomic_set(&proc->usage, 1);
@@ -210,10 +211,12 @@ void sspt_proc_cleanup(struct sspt_proc *proc)
 
        sspt_proc_del_all_filters(proc);
 
-       list_for_each_entry_safe(file, n, &proc->file_head, list) {
+       down_write(&proc->files.sem);
+       list_for_each_entry_safe(file, n, &proc->files.head, list) {
                list_del(&file->list);
                sspt_file_free(file);
        }
+       up_write(&proc->files.sem);
 
        sspt_destroy_feature(proc->feature);
 
@@ -349,8 +352,10 @@ void sspt_proc_check_empty(void)
 
 static void sspt_proc_add_file(struct sspt_proc *proc, struct sspt_file *file)
 {
-       list_add(&file->list, &proc->file_head);
+       down_write(&proc->files.sem);
+       list_add(&file->list, &proc->files.head);
        file->proc = proc;
+       up_write(&proc->files.sem);
 }
 
 /**
@@ -387,12 +392,17 @@ struct sspt_file *sspt_proc_find_file(struct sspt_proc *proc,
 {
        struct sspt_file *file;
 
-       list_for_each_entry(file, &proc->file_head, list) {
+       down_read(&proc->files.sem);
+       list_for_each_entry(file, &proc->files.head, list) {
                if (dentry == file->dentry)
-                       return file;
+                       goto unlock;
        }
+       file = NULL;
 
-       return NULL;
+unlock:
+       up_read(&proc->files.sem);
+
+       return file;
 }
 
 /**
@@ -464,14 +474,16 @@ int sspt_proc_uninstall(struct sspt_proc *proc,
        int err = 0;
        struct sspt_file *file;
 
-       list_for_each_entry_rcu(file, &proc->file_head, list) {
+       down_read(&proc->files.sem);
+       list_for_each_entry(file, &proc->files.head, list) {
                err = sspt_file_uninstall(file, task, flag);
                if (err != 0) {
                        printk(KERN_INFO "ERROR sspt_proc_uninstall: err=%d\n",
                               err);
-                       return err;
+                       break;
                }
        }
+       up_read(&proc->files.sem);
 
        return err;
 }
@@ -501,12 +513,14 @@ int sspt_proc_get_files_by_region(struct sspt_proc *proc,
        struct sspt_file *file, *n;
        unsigned long end = start + len;
 
-       list_for_each_entry_safe(file, n, &proc->file_head, list) {
+       down_write(&proc->files.sem);
+       list_for_each_entry_safe(file, n, &proc->files.head, list) {
                if (intersection(file->vm_start, file->vm_end, start, end)) {
                        ret = 1;
                        list_move(&file->list, head);
                }
        }
+       up_write(&proc->files.sem);
 
        return ret;
 }
@@ -520,7 +534,9 @@ int sspt_proc_get_files_by_region(struct sspt_proc *proc,
  */
 void sspt_proc_insert_files(struct sspt_proc *proc, struct list_head *head)
 {
-       list_splice(head, &proc->file_head);
+       down_write(&proc->files.sem);
+       list_splice(head, &proc->files.head);
+       up_write(&proc->files.sem);
 }
 
 /**
@@ -611,8 +627,10 @@ void sspt_proc_on_each_ip(struct sspt_proc *proc,
 {
        struct sspt_file *file;
 
-       list_for_each_entry(file, &proc->file_head, list)
+       down_read(&proc->files.sem);
+       list_for_each_entry(file, &proc->files.head, list)
                sspt_file_on_each_ip(file, func, data);
+       up_read(&proc->files.sem);
 }
 
 static void is_send_event(struct sspt_filter *f, void *data)
index 835b9cb..ec7a133 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/types.h>
 #include <linux/mutex.h>
+#include <linux/rwsem.h>
 #include "sspt_file.h"
 
 struct slot_manager;
@@ -49,7 +50,10 @@ struct sspt_proc {
        struct list_head list;          /**< For global process list */
 
        /* sspt_file */
-       struct list_head file_head;     /**< For sspt_file */
+       struct {
+               struct rw_semaphore sem;/**< Semaphore for files list */
+               struct list_head head;  /**< For sspt_file */
+       } files;
 
        pid_t tgid;                     /**< Thread group ID */
        struct task_struct *leader;     /**< Ptr to the task leader */