From fa15f4a3db796a624834932ebec72c1f31287dd6 Mon Sep 17 00:00:00 2001 From: Vyacheslav Cherkashin Date: Tue, 26 May 2015 19:51:31 +0300 Subject: [PATCH] [FIX] multithread using file_list field in img_proc struct Change-Id: I0b8a814cfca377890ee431eb7215dc7295385b3d Signed-off-by: Vyacheslav Cherkashin --- us_manager/img/img_proc.c | 69 ++++++++++++++++++++++++++++++++++++++++------- us_manager/img/img_proc.h | 10 +++---- us_manager/pf/pf_group.c | 20 +++----------- 3 files changed, 66 insertions(+), 33 deletions(-) diff --git a/us_manager/img/img_proc.c b/us_manager/img/img_proc.c index 35b62d3..2029c2e 100644 --- a/us_manager/img/img_proc.c +++ b/us_manager/img/img_proc.c @@ -23,9 +23,21 @@ */ +#include +#include +#include +#include +#include +#include "img_ip.h" #include "img_proc.h" #include "img_file.h" -#include + + +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 */ diff --git a/us_manager/img/img_proc.h b/us_manager/img/img_proc.h index 02aae81..8bdc67d 100644 --- a/us_manager/img/img_proc.h +++ b/us_manager/img/img_proc.h @@ -28,15 +28,9 @@ #include 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 */ diff --git a/us_manager/pf/pf_group.c b/us_manager/pf/pf_group.c index 349e8c3..06d85a0 100644 --- a/us_manager/pf/pf_group.c +++ b/us_manager/pf/pf_group.c @@ -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; -- 2.7.4