[FIX] sspt_filter handling
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Wed, 26 Aug 2015 12:31:38 +0000 (15:31 +0300)
committerDmitry Kovalenko <d.kovalenko@samsung.com>
Fri, 28 Aug 2015 06:40:57 +0000 (23:40 -0700)
- 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>
us_manager/pf/pf_group.c
us_manager/sspt/sspt_filter.c
us_manager/sspt/sspt_proc.c
us_manager/sspt/sspt_proc.h

index fb92fdb..548fbe0 100644 (file)
@@ -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);
index 0d02e73..2925d7f 100644 (file)
@@ -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;
index d9473a8..fae2e3f 100644 (file)
@@ -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;
index 46b9e44..03a1db1 100644 (file)
@@ -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 */