[FIX] multithread using file_list field in img_proc struct 44/39944/1
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Tue, 26 May 2015 16:51:31 +0000 (19:51 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Tue, 26 May 2015 17:01:55 +0000 (20:01 +0300)
Change-Id: I0b8a814cfca377890ee431eb7215dc7295385b3d
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
us_manager/img/img_proc.c
us_manager/img/img_proc.h
us_manager/pf/pf_group.c

index 35b62d3..2029c2e 100644 (file)
  */
 
 
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <us_manager/sspt/sspt_proc.h>
+#include <us_manager/sspt/sspt_file.h>
+#include "img_ip.h"
 #include "img_proc.h"
 #include "img_file.h"
-#include <linux/slab.h>
+
+
+struct img_proc {
+       struct list_head file_list;
+       rwlock_t rwlock;
+};
+
 
 static void img_del_file_by_list(struct img_file *file);
 
@@ -39,7 +51,10 @@ struct img_proc *create_img_proc(void)
        struct img_proc *proc;
 
        proc = kmalloc(sizeof(*proc), GFP_KERNEL);
-       INIT_LIST_HEAD(&proc->file_list);
+       if (proc) {
+               INIT_LIST_HEAD(&proc->file_list);
+               rwlock_init(&proc->rwlock);
+       }
 
        return proc;
 }
@@ -50,28 +65,31 @@ struct img_proc *create_img_proc(void)
  * @param file remove object
  * @return Void
  */
-void free_img_proc(struct img_proc *ip)
+void free_img_proc(struct img_proc *proc)
 {
        struct img_file *file, *tmp;
 
-       list_for_each_entry_safe(file, tmp, &ip->file_list, list) {
+       list_for_each_entry_safe(file, tmp, &proc->file_list, list) {
                img_del_file_by_list(file);
                free_img_file(file);
        }
 
-       kfree(ip);
+       kfree(proc);
 }
 
+/* called with write_[lock/unlock](&proc->rwlock) */
 static void img_add_file_by_list(struct img_proc *proc, struct img_file *file)
 {
        list_add(&file->list, &proc->file_list);
 }
 
+/* called with write_[lock/unlock](&proc->rwlock) */
 static void img_del_file_by_list(struct img_file *file)
 {
        list_del(&file->list);
 }
 
+/* called with read_[lock/unlock](&proc->rwlock) */
 static struct img_file *find_img_file(struct img_proc *proc,
                                      struct dentry *dentry)
 {
@@ -100,11 +118,18 @@ int img_proc_add_ip(struct img_proc *proc, struct dentry *dentry,
        int ret;
        struct img_file *file;
 
+       write_lock(&proc->rwlock);
        file = find_img_file(proc, dentry);
-       if (file)
-               return img_file_add_ip(file, addr, probe_i);
+       if (file) {
+               ret = img_file_add_ip(file, addr, probe_i);
+               goto unlock;
+       }
 
        file = create_img_file(dentry);
+       if (file == NULL) {
+               ret = -ENOMEM;
+               goto unlock;
+       }
 
        ret = img_file_add_ip(file, addr, probe_i);
        if (ret) {
@@ -114,6 +139,8 @@ int img_proc_add_ip(struct img_proc *proc, struct dentry *dentry,
                img_add_file_by_list(proc, file);
        }
 
+unlock:
+       write_unlock(&proc->rwlock);
        return ret;
 }
 
@@ -132,9 +159,12 @@ int img_proc_del_ip(struct img_proc *proc,
        int ret;
        struct img_file *file;
 
+       write_lock(&proc->rwlock);
        file = find_img_file(proc, dentry);
-       if (file == NULL)
-               return -EINVAL;
+       if (file == NULL) {
+               ret = -EINVAL;
+               goto unlock;
+       }
 
        ret = img_file_del_ip(file, addr);
        if (ret == 0 && img_file_empty(file)) {
@@ -142,9 +172,27 @@ int img_proc_del_ip(struct img_proc *proc,
                free_img_file(file);
        }
 
+unlock:
+       write_unlock(&proc->rwlock);
        return ret;
 }
 
+void img_proc_copy_to_sspt(struct img_proc *i_proc, struct sspt_proc *proc)
+{
+       struct sspt_file *file;
+       struct img_file *i_file;
+       struct img_ip *i_ip;
+
+       read_lock(&i_proc->rwlock);
+       list_for_each_entry(i_file, &i_proc->file_list, list) {
+               file = sspt_proc_find_file_or_new(proc, i_file->dentry);
+
+               list_for_each_entry(i_ip, &i_file->ip_list, list)
+                       sspt_file_add_ip(file, i_ip->addr, i_ip->info);
+       }
+       read_unlock(&i_proc->rwlock);
+}
+
 /**
  * @brief For debug
  *
@@ -158,8 +206,11 @@ void img_proc_print(struct img_proc *proc)
        struct img_file *file;
 
        printk(KERN_INFO "### img_proc_print:\n");
+
+       read_lock(&proc->rwlock);
        list_for_each_entry(file, &proc->file_list, list) {
                img_file_print(file);
        }
+       read_unlock(&proc->rwlock);
 }
 /* debug */
index 02aae81..8bdc67d 100644 (file)
 #include <linux/types.h>
 
 struct dentry;
+struct sspt_proc;
 struct probe_info;
 
-/**
- * @struct img_proc
- * @breaf Image of process
- */
-struct img_proc {
-       struct list_head file_list;     /**< For img_file */
-};
 
 struct img_proc *create_img_proc(void);
 void free_img_proc(struct img_proc *proc);
@@ -47,6 +41,8 @@ int img_proc_del_ip(struct img_proc *proc,
                    struct dentry *dentry,
                    unsigned long addr);
 
+void img_proc_copy_to_sspt(struct img_proc *i_proc, struct sspt_proc *proc);
+
 /* debug */
 void img_proc_print(struct img_proc *proc);
 /* debug */
index 349e8c3..06d85a0 100644 (file)
@@ -80,20 +80,6 @@ static void del_pl_struct(struct pl_struct *pls)
        list_del(&pls->list);
 }
 
-void copy_proc_form_img_to_sspt(struct img_proc *i_proc, struct sspt_proc *proc)
-{
-       struct sspt_file *file;
-       struct img_file *i_file;
-       struct img_ip *i_ip;
-
-       list_for_each_entry(i_file, &i_proc->file_list, list) {
-               file = sspt_proc_find_file_or_new(proc, i_file->dentry);
-
-               list_for_each_entry(i_ip, &i_file->ip_list, list)
-                       sspt_file_add_ip(file, i_ip->addr, i_ip->info);
-       }
-}
-
 static struct pl_struct *find_pl_struct(struct pf_group *pfg,
                                        struct task_struct *task)
 {
@@ -126,7 +112,7 @@ static struct sspt_proc *new_proc_by_pfg(struct pf_group *pfg,
        struct sspt_proc *proc;
 
        proc = sspt_proc_get_by_task_or_new(task, pfg->filter.priv);
-       copy_proc_form_img_to_sspt(pfg->i_proc, proc);
+       img_proc_copy_to_sspt(pfg->i_proc, proc);
        sspt_proc_add_filter(proc, pfg);
 
        pls = create_pl_struct(proc);
@@ -471,7 +457,7 @@ void check_task_and_install(struct task_struct *task)
                proc = get_proc_by_pfg(pfg, task);
                if (proc) {
                        if (sspt_proc_is_filter_new(proc, pfg)) {
-                               copy_proc_form_img_to_sspt(pfg->i_proc, proc);
+                               img_proc_copy_to_sspt(pfg->i_proc, proc);
                                sspt_proc_add_filter(proc, pfg);
                        } else {
                                printk(KERN_ERR "SWAP US_MANAGER: Error! Trying"
@@ -516,7 +502,7 @@ void call_page_fault(struct task_struct *task, unsigned long page_addr)
                proc = get_proc_by_pfg(pfg, task);
                if (proc) {
                        if (sspt_proc_is_filter_new(proc, pfg)) {
-                               copy_proc_form_img_to_sspt(pfg->i_proc, proc);
+                               img_proc_copy_to_sspt(pfg->i_proc, proc);
                                sspt_proc_add_filter(proc, pfg);
                        }
                        break;