diff options
author | Vyacheslav Cherkashin <v.cherkashin@samsung.com> | 2015-08-26 15:31:38 +0300 |
---|---|---|
committer | Dmitry Kovalenko <d.kovalenko@samsung.com> | 2015-08-27 23:40:57 -0700 |
commit | 21956928dc58f77d67558a3305fc8a4e69422d40 (patch) | |
tree | 99c9251bc5b29de4eee83833fd5ae515c7133a87 | |
parent | e980252321e347720aee938fa35331d899eb5c53 (diff) | |
download | swap-modules-21956928dc58f77d67558a3305fc8a4e69422d40.tar.gz swap-modules-21956928dc58f77d67558a3305fc8a4e69422d40.tar.bz2 swap-modules-21956928dc58f77d67558a3305fc8a4e69422d40.zip |
[FIX] sspt_filter handling
- Add rwlock to avoid race conditions (i.e. img copied to sspt
multiple times)
- Use GFP_ATOMIC for sspt_filter allocation (done in atomic context)
Change-Id: I0809a8eb16555e2882d900cab8c544a32bdc16b1
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
-rw-r--r-- | us_manager/pf/pf_group.c | 14 | ||||
-rw-r--r-- | us_manager/sspt/sspt_filter.c | 3 | ||||
-rw-r--r-- | us_manager/sspt/sspt_proc.c | 12 | ||||
-rw-r--r-- | us_manager/sspt/sspt_proc.h | 1 |
4 files changed, 22 insertions, 8 deletions
diff --git a/us_manager/pf/pf_group.c b/us_manager/pf/pf_group.c index fb92fdb5..548fbe06 100644 --- a/us_manager/pf/pf_group.c +++ b/us_manager/pf/pf_group.c @@ -490,11 +490,15 @@ static enum pf_inst_flag pfg_check_task(struct task_struct *task) flag = PIF_FIRST; } - if (proc && sspt_proc_is_filter_new(proc, pfg)) { - img_proc_copy_to_sspt(pfg->i_proc, proc); - sspt_proc_add_filter(proc, pfg); - pfg_add_proc(pfg, proc); - flag = flag == PIF_FIRST ? flag : PIF_ADD_PFG; + if (proc) { + write_lock(&proc->filter_lock); + if (sspt_proc_is_filter_new(proc, pfg)) { + img_proc_copy_to_sspt(pfg->i_proc, proc); + sspt_proc_add_filter(proc, pfg); + pfg_add_proc(pfg, proc); + flag = flag == PIF_FIRST ? flag : PIF_ADD_PFG; + } + write_unlock(&proc->filter_lock); } } read_unlock(&pfg_list_lock); diff --git a/us_manager/sspt/sspt_filter.c b/us_manager/sspt/sspt_filter.c index 0d02e73c..2925d7f6 100644 --- a/us_manager/sspt/sspt_filter.c +++ b/us_manager/sspt/sspt_filter.c @@ -10,12 +10,11 @@ struct sspt_filter *sspt_filter_create(struct sspt_proc *proc, { struct sspt_filter *fl; - fl = kmalloc(sizeof(*fl), GFP_KERNEL); + fl = kmalloc(sizeof(*fl), GFP_ATOMIC); if (fl == NULL) return NULL; INIT_LIST_HEAD(&fl->list); - list_add(&fl->list, &proc->filter_list); fl->proc = proc; fl->pfg = pfg; diff --git a/us_manager/sspt/sspt_proc.c b/us_manager/sspt/sspt_proc.c index d9473a8b..fae2e3f1 100644 --- a/us_manager/sspt/sspt_proc.c +++ b/us_manager/sspt/sspt_proc.c @@ -107,6 +107,7 @@ struct sspt_proc *sspt_proc_create(struct task_struct *task) proc->task = task->group_leader; proc->sm = create_sm_us(task); INIT_LIST_HEAD(&proc->file_list); + rwlock_init(&proc->filter_lock); INIT_LIST_HEAD(&proc->filter_list); atomic_set(&proc->usage, 1); @@ -459,7 +460,11 @@ void sspt_proc_insert_files(struct sspt_proc *proc, struct list_head *head) */ void sspt_proc_add_filter(struct sspt_proc *proc, struct pf_group *pfg) { - sspt_filter_create(proc, pfg); + struct sspt_filter *f; + + f = sspt_filter_create(proc, pfg); + if (f) + list_add(&f->list, &proc->filter_list); } /** @@ -473,12 +478,14 @@ void sspt_proc_del_filter(struct sspt_proc *proc, struct pf_group *pfg) { struct sspt_filter *fl, *tmp; + write_lock(&proc->filter_lock); list_for_each_entry_safe(fl, tmp, &proc->filter_list, list) { if (fl->pfg == pfg) { list_del(&fl->list); sspt_filter_free(fl); } } + write_unlock(&proc->filter_lock); } /** @@ -491,10 +498,12 @@ void sspt_proc_del_all_filters(struct sspt_proc *proc) { struct sspt_filter *fl, *tmp; + write_lock(&proc->filter_lock); list_for_each_entry_safe(fl, tmp, &proc->filter_list, list) { list_del(&fl->list); sspt_filter_free(fl); } + write_unlock(&proc->filter_lock); } /** @@ -546,6 +555,7 @@ bool sspt_proc_is_send_event(struct sspt_proc *proc) { bool is_send = false; + /* FIXME: add read lock (deadlock in sampler) */ sspt_proc_on_each_filter(proc, is_send_event, (void *)&is_send); return is_send; diff --git a/us_manager/sspt/sspt_proc.h b/us_manager/sspt/sspt_proc.h index 46b9e44e..03a1db1d 100644 --- a/us_manager/sspt/sspt_proc.h +++ b/us_manager/sspt/sspt_proc.h @@ -53,6 +53,7 @@ struct sspt_proc { unsigned long r_state_addr; /**< address of r_state */ struct slot_manager *sm; /**< Ptr to the manager slot */ struct list_head file_list; /**< For sspt_file */ + rwlock_t filter_lock; struct list_head filter_list; /**< Filter list */ unsigned first_install:1; /**< Install flag */ struct sspt_feature *feature; /**< Ptr to the feature */ |