summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>2015-08-26 15:31:38 +0300
committerDmitry Kovalenko <d.kovalenko@samsung.com>2015-08-27 23:40:57 -0700
commit21956928dc58f77d67558a3305fc8a4e69422d40 (patch)
tree99c9251bc5b29de4eee83833fd5ae515c7133a87
parente980252321e347720aee938fa35331d899eb5c53 (diff)
downloadswap-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.c14
-rw-r--r--us_manager/sspt/sspt_filter.c3
-rw-r--r--us_manager/sspt/sspt_proc.c12
-rw-r--r--us_manager/sspt/sspt_proc.h1
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 */