[IMPROVE] storing sspt_proc in group_leader's stack 51/65351/2
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Wed, 6 Apr 2016 12:46:57 +0000 (15:46 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Tue, 12 Apr 2016 08:07:37 +0000 (11:07 +0300)
Change-Id: I3ea8e4809efe461c24949ab543ba11e317847504
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
12 files changed:
energy/energy.c
preload/preload_module.c
preload/preload_pd.c
us_manager/helper.c
us_manager/pf/pf_group.c
us_manager/sspt/sspt.h
us_manager/sspt/sspt_file.c
us_manager/sspt/sspt_filter.c
us_manager/sspt/sspt_page.c
us_manager/sspt/sspt_proc.c
us_manager/sspt/sspt_proc.h
us_manager/us_manager.c

index 6eb863c..5a44dae 100644 (file)
@@ -295,7 +295,7 @@ static struct energy_data *get_energy_data(struct task_struct *task)
        void *data = NULL;
        struct sspt_proc *proc;
 
-       proc = sspt_proc_get_by_task(task);
+       proc = sspt_proc_by_task(task);
        if (proc)
                data = sspt_get_feature_data(proc->feature, feature_id);
 
index b8d613d..650e7bb 100644 (file)
@@ -266,7 +266,7 @@ static bool __is_proc_mmap_mappable(struct task_struct *task)
                return false;
 
        r_debug_addr += r_state_offset;
-       proc = sspt_proc_get_by_task(task);
+       proc = sspt_proc_by_task(task);
        if (proc)
                proc->r_state_addr = r_debug_addr;
 
@@ -333,7 +333,7 @@ static int mmap_entry_handler(struct kretprobe_instance *ri,
                return 0;
        }
 
-       proc = sspt_proc_get_by_task(task);
+       proc = sspt_proc_by_task(task);
        if (!proc)
                return 0;
 
@@ -372,7 +372,7 @@ static int mmap_ret_handler(struct kretprobe_instance *ri,
        if (IS_ERR_VALUE(vaddr))
                return 0;
 
-       proc = sspt_proc_get_by_task(task);
+       proc = sspt_proc_by_task(task);
        if (!proc)
                return 0;
 
index 17aa742..62c242d 100644 (file)
@@ -407,7 +407,7 @@ static void *pd_create(struct sspt_proc *proc)
 {
        struct pd_t *pd;
 
-       pd = do_create_pd(proc->task);
+       pd = do_create_pd(proc->leader);
 
        return (void *)pd;
 }
index 92d829b..7bdb801 100644 (file)
@@ -69,7 +69,7 @@ static int entry_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs)
 #endif /* CONFIG_arch */
 
        if (data->addr) {
-               struct sspt_proc * proc = sspt_proc_get_by_task(current);
+               struct sspt_proc *proc = sspt_proc_by_task(current);
 
                if (proc && (proc->r_state_addr == data->addr))
                        /* skip ret_handler_pf() for current task */
@@ -212,7 +212,7 @@ static void rm_uprobes_child(struct kretprobe_instance *ri,
        };
 
        sspt_proc_write_lock();
-       proc = sspt_proc_get_by_task_no_lock(current);
+       proc = sspt_proc_by_task(current);
        if (proc) {
                sspt_proc_on_each_ip(proc, func_uinst_creare, (void *)&cdata.head);
                urinst_info_get_current_hlist(&cdata.rhead, false);
@@ -359,7 +359,7 @@ static unsigned long mr_cb(void *data)
 
        /* TODO: this lock for synchronizing to disarm urp */
        down_write(&mm->mmap_sem);
-       if (task->tgid != task->pid) {
+       if (task != task->group_leader) {
                struct sspt_proc *proc;
                struct hlist_head head = HLIST_HEAD_INIT;
 
@@ -371,7 +371,7 @@ static unsigned long mr_cb(void *data)
                /* if the thread is killed we need to discard pending
                 * uretprobe instances which have not triggered yet */
                sspt_proc_write_lock();
-               proc = sspt_proc_get_by_task_no_lock(task);
+               proc = sspt_proc_by_task(task);
                if (proc) {
                        urinst_info_get_current_hlist(&head, true);
                }
@@ -481,7 +481,7 @@ static void __remove_unmap_probes(struct sspt_proc *proc,
        if (sspt_proc_get_files_by_region(proc, &head, start, len)) {
                struct sspt_file *file, *n;
                unsigned long end = start + len;
-               struct task_struct *task = proc->task;
+               struct task_struct *task = proc->leader;
 
                list_for_each_entry_safe(file, n, &head, list) {
                        if (file->vm_start >= end)
@@ -503,7 +503,7 @@ static void remove_unmap_probes(struct task_struct *task,
 
        sspt_proc_write_lock();
 
-       proc = sspt_proc_get_by_task_no_lock(task);
+       proc = sspt_proc_by_task(task);
        if (proc) {
                struct msg_unmap_data msg_data = {
                        .start = umd->start,
@@ -615,7 +615,7 @@ static int ret_handler_mmap(struct kretprobe_instance *ri,
        if (IS_ERR_VALUE(start_addr))
                return 0;
 
-       proc = sspt_proc_get_by_task(task);
+       proc = sspt_proc_by_task(task);
        if (proc == NULL)
                return 0;
 
@@ -723,6 +723,43 @@ static void unregister_comm(void)
 
 
 
+/*
+ ******************************************************************************
+ *                               release_task()                               *
+ ******************************************************************************
+ */
+static int release_task_h(struct kprobe *p, struct pt_regs *regs)
+{
+       struct task_struct *task = (struct task_struct *)swap_get_karg(regs, 0);
+       struct task_struct *cur = current;
+
+       if (cur->flags & PF_KTHREAD)
+               return 0;
+
+       /* EXEC: change group leader */
+       if (cur != task && task->pid == cur->pid)
+               sspt_change_leader(task, cur);
+
+       return 0;
+}
+
+struct kprobe release_task_kp = {
+       .pre_handler = release_task_h,
+};
+
+static int reg_release_task(void)
+{
+       return swap_register_kprobe(&release_task_kp);
+}
+
+static void unreg_release_task(void)
+{
+       swap_unregister_kprobe(&release_task_kp);
+}
+
+
+
+
 
 /**
  * @brief Registration of helper
@@ -735,13 +772,18 @@ int register_helper(void)
 
        atomic_set(&stop_flag, 0);
 
+       /* tracking group leader changing */
+       ret = reg_release_task();
+       if (ret)
+               return ret;
+
        /*
         * install probe on 'set_task_comm' to detect when field comm struct
         * task_struct changes
         */
        ret = register_comm();
        if (ret)
-               return ret;
+               goto unreg_rel_task;
 
        /* install probe on 'do_munmap' to detect when for remove US probes */
        ret = register_unmap();
@@ -788,6 +830,9 @@ unreg_unmap:
 unreg_comm:
        unregister_comm();
 
+unreg_rel_task:
+       unreg_release_task();
+
        return ret;
 }
 
@@ -814,6 +859,7 @@ void unregister_helper_bottom(void)
        unregister_mr();
        unregister_unmap();
        unregister_comm();
+       unreg_release_task();
 }
 
 /**
@@ -856,6 +902,11 @@ int once_helper(void)
        if (comm_kretprobe.kp.addr == NULL)
                goto not_found;
 
+       sym = "release_task";
+       release_task_kp.addr = (kprobe_opcode_t *)swap_ksyms(sym);
+       if (release_task_kp.addr == NULL)
+               goto not_found;
+
        return 0;
 
 not_found:
index 5bafc1b..3665b09 100644 (file)
@@ -158,6 +158,26 @@ static int pfg_add_proc(struct pf_group *pfg, struct sspt_proc *proc)
        return 0;
 }
 
+static int pfg_del_proc(struct pf_group *pfg, struct sspt_proc *proc)
+{
+       struct pl_struct *pls, *pls_free = NULL;
+
+       spin_lock(&pfg->pl_lock);
+       list_for_each_entry(pls, &pfg->proc_list, list) {
+               if (pls->proc == proc) {
+                       list_del(&pls->list);
+                       pls_free = pls;
+                       break;
+               }
+       }
+       spin_unlock(&pfg->pl_lock);
+
+       if (pls_free)
+               free_pl_struct(pls_free);
+
+       return !!pls_free;
+}
+
 
 /* called with pfg_list_lock held */
 static void pfg_add_to_list(struct pf_group *pfg)
@@ -186,10 +206,10 @@ static void msg_info(struct sspt_filter *f, void *data)
                        dentry = (struct dentry *)f->pfg->filter.priv;
 
                        if (cb->msg_info)
-                               cb->msg_info(f->proc->task, dentry);
+                               cb->msg_info(f->proc->leader, dentry);
 
                        if (cb->msg_status_info)
-                               cb->msg_status_info(f->proc->task);
+                               cb->msg_status_info(f->proc->leader);
                }
        }
 }
@@ -492,7 +512,7 @@ static enum pf_inst_flag pfg_check_task(struct task_struct *task)
                        continue;
 
                if (proc == NULL)
-                       proc = sspt_proc_get_by_task(task);
+                       proc = sspt_proc_by_task(task);
 
                if (proc) {
                        flag = flag == PIF_NONE ? PIF_SECOND : flag;
@@ -521,6 +541,16 @@ static enum pf_inst_flag pfg_check_task(struct task_struct *task)
        return flag;
 }
 
+static void pfg_all_del_proc(struct sspt_proc *proc)
+{
+       struct pf_group *pfg;
+
+       pfg_list_rlock();
+       list_for_each_entry(pfg, &pfg_list, list)
+               pfg_del_proc(pfg, proc);
+       pfg_list_runlock();
+}
+
 /**
  * @brief Check task and install probes on demand
  *
@@ -536,7 +566,7 @@ void check_task_and_install(struct task_struct *task)
        switch (flag) {
        case PIF_FIRST:
        case PIF_ADD_PFG:
-               proc = sspt_proc_get_by_task(task);
+               proc = sspt_proc_by_task(task);
                if (proc)
                        first_install(task, proc);
                break;
@@ -563,13 +593,13 @@ void call_page_fault(struct task_struct *task, unsigned long page_addr)
        switch (flag) {
        case PIF_FIRST:
        case PIF_ADD_PFG:
-               proc = sspt_proc_get_by_task(task);
+               proc = sspt_proc_by_task(task);
                if (proc)
                        first_install(task, proc);
                break;
 
        case PIF_SECOND:
-               proc = sspt_proc_get_by_task(task);
+               proc = sspt_proc_by_task(task);
                if (proc)
                        subsequent_install(task, proc, page_addr);
                break;
@@ -589,12 +619,38 @@ void call_page_fault(struct task_struct *task, unsigned long page_addr)
 /* called with sspt_proc_write_lock() */
 void uninstall_proc(struct sspt_proc *proc)
 {
-       struct task_struct *task = proc->task;
+       struct task_struct *task = proc->leader;
 
        sspt_proc_uninstall(proc, task, US_UNREGS_PROBE);
        sspt_proc_cleanup(proc);
 }
 
+
+static void mmr_from_exit(struct sspt_proc *proc)
+{
+       BUG_ON(proc->leader != current);
+
+       sspt_proc_write_lock();
+       list_del(&proc->list);
+       sspt_proc_write_unlock();
+
+       uninstall_proc(proc);
+
+       pfg_all_del_proc(proc);
+       sspt_reset_proc(proc->leader);
+}
+
+static void mmr_from_exec(struct sspt_proc *proc)
+{
+       BUG_ON(proc->leader != current);
+
+       if (proc->suspect.after_exec) {
+               sspt_proc_uninstall(proc, proc->leader, US_UNREGS_PROBE);
+       } else {
+               mmr_from_exit(proc);
+       }
+}
+
 /**
  * @brief Remove probes from the task on demand
  *
@@ -605,14 +661,13 @@ void call_mm_release(struct task_struct *task)
 {
        struct sspt_proc *proc;
 
-       sspt_proc_write_lock();
-       proc = sspt_proc_get_by_task_no_lock(task);
-       if (proc)
-               list_del(&proc->list);
-       sspt_proc_write_unlock();
-
-       if (proc)
-               uninstall_proc(proc);
+       proc = sspt_proc_by_task(task);
+       if (proc) {
+               if (task->flags & PF_EXITING)
+                       mmr_from_exit(proc);
+               else
+                       mmr_from_exec(proc);
+       }
 }
 
 /**
@@ -650,7 +705,7 @@ static void tasks_get(struct list_head *head)
                if (task->flags & PF_KTHREAD)
                        continue;
 
-               if (sspt_proc_get_by_task(task))
+               if (sspt_proc_by_task(task))
                        continue;
 
                /* TODO: get rid of GFP_ATOMIC */
@@ -745,9 +800,11 @@ void uninstall_all(void)
 
 static void __do_get_proc(struct sspt_proc *proc, void *data)
 {
-       get_task_struct(proc->task);
-       proc->__task = proc->task;
-       proc->__mm = get_task_mm(proc->task);
+       struct task_struct *task = proc->leader;
+
+       get_task_struct(task);
+       proc->__task = task;
+       proc->__mm = get_task_mm(task);
 }
 
 static void __do_put_proc(struct sspt_proc *proc, void *data)
index bc8b6f5..8bec181 100644 (file)
@@ -59,7 +59,7 @@ static inline int sspt_register_usprobe(struct sspt_ip *ip)
        }
 
        up->addr = (kprobe_opcode_t *)ip->orig_addr;
-       up->task = ip->page->file->proc->task;
+       up->task = ip->page->file->proc->leader;
        up->sm = ip->page->file->proc->sm;
 
        ret = probe_info_register(ip->desc->type, ip);
index 2ad0b8a..c700f39 100644 (file)
@@ -284,7 +284,7 @@ void sspt_file_install(struct sspt_file *file)
                            page_addr >= file->vm_end)
                                continue;
 
-                       mm = page->file->proc->task->mm;
+                       mm = page->file->proc->leader->mm;
                        if (page_present(mm, page_addr))
                                sspt_register_page(page, file);
                }
index 2925d7f..f7a0799 100644 (file)
@@ -29,7 +29,7 @@ void sspt_filter_free(struct sspt_filter *fl)
                struct pfg_msg_cb *cb = pfg_msg_cb_get(fl->pfg);
 
                if (cb && cb->msg_term)
-                       cb->msg_term(fl->proc->task);
+                       cb->msg_term(fl->proc->leader);
        }
 
        kfree(fl);
index 54971f9..d5e7640 100644 (file)
@@ -144,7 +144,7 @@ int sspt_register_page(struct sspt_page *page, struct sspt_file *file)
 
        spin_lock(&page->ip_list.lock);
        if (list_empty(&page->ip_list.not_inst)) {
-               struct task_struct *task = page->file->proc->task;
+               struct task_struct *task = page->file->proc->leader;
 
                printk(KERN_INFO "page %lx in %s task[tgid=%u, pid=%u] "
                       "already installed\n",
index 2a45014..0f70788 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/list.h>
+#include <kprobe/swap_ktd.h>
 #include <us_manager/us_slot_manager.h>
 
 static LIST_HEAD(proc_probes_list);
@@ -83,16 +84,79 @@ void sspt_proc_write_unlock(void)
 }
 
 
-/**
- * @brief Create sspt_proc struct
- *
- * @param task Pointer to the task_struct struct
- * @param priv Private data
- * @return Pointer to the created sspt_proc struct
- */
-struct sspt_proc *sspt_proc_create(struct task_struct *task)
+static void ktd_init(struct task_struct *task, void *data)
+{
+       struct sspt_proc **pproc = (struct sspt_proc **)data;
+
+       *pproc = NULL;
+}
+
+static void ktd_exit(struct task_struct *task, void *data)
+{
+       struct sspt_proc **pproc = (struct sspt_proc **)data;
+
+       WARN_ON(*pproc);
+}
+
+struct ktask_data ktd = {
+       .init = ktd_init,
+       .exit = ktd_exit,
+       .size = sizeof(struct sspt_proc *),
+};
+
+static struct sspt_proc **pproc_by_task(struct task_struct *task)
+{
+       return (struct sspt_proc **)swap_ktd(&ktd, task);
+}
+
+int sspt_proc_init(void)
+{
+       return swap_ktd_reg(&ktd);
+}
+
+void sspt_proc_uninit(void)
+{
+       swap_ktd_unreg(&ktd);
+}
+
+void sspt_change_leader(struct task_struct *prev, struct task_struct *next)
+{
+       struct sspt_proc **prev_pproc;
+
+       prev_pproc = pproc_by_task(prev);
+       if (*prev_pproc) {
+               struct sspt_proc **next_pproc;
+
+               next_pproc = pproc_by_task(next);
+               get_task_struct(next);
+
+               /* Change the keeper sspt_proc */
+               BUG_ON(*next_pproc);
+               *next_pproc = *prev_pproc;
+               *prev_pproc = NULL;
+
+               /* Set new the task leader to sspt_proc */
+               (*next_pproc)->leader = next;
+
+               put_task_struct(prev);
+       }
+}
+
+void sspt_reset_proc(struct task_struct *task)
 {
-       struct sspt_proc *proc = kzalloc(sizeof(*proc), GFP_ATOMIC);
+       struct sspt_proc **pproc;
+
+       pproc = pproc_by_task(task->group_leader);
+       *pproc = NULL;
+}
+
+
+
+
+
+static struct sspt_proc *sspt_proc_create(struct task_struct *leader)
+{
+       struct sspt_proc *proc = kzalloc(sizeof(*proc), GFP_KERNEL);
 
        if (proc) {
                proc->feature = sspt_create_feature();
@@ -102,18 +166,19 @@ struct sspt_proc *sspt_proc_create(struct task_struct *task)
                }
 
                INIT_LIST_HEAD(&proc->list);
-               proc->tgid = task->tgid;
-               proc->task = task->group_leader;
-               proc->sm = create_sm_us(task);
+               proc->tgid = leader->tgid;
+               proc->leader = leader;
+               /* FIXME: change the task leader */
+               proc->sm = create_sm_us(leader);
                INIT_LIST_HEAD(&proc->file_head);
                mutex_init(&proc->filters.mtx);
                INIT_LIST_HEAD(&proc->filters.head);
                atomic_set(&proc->usage, 1);
 
-               get_task_struct(proc->task);
+               get_task_struct(proc->leader);
 
-               /* add to list */
-               list_add(&proc->list, &proc_probes_list);
+               proc->suspect.after_exec = 1;
+               proc->suspect.after_fork = 0;
        }
 
        return proc;
@@ -163,41 +228,16 @@ void sspt_proc_put(struct sspt_proc *proc)
                        proc->__task = NULL;
                }
 
-               put_task_struct(proc->task);
+               put_task_struct(proc->leader);
                kfree(proc);
        }
 }
 
-struct sspt_proc *sspt_proc_get_by_task(struct task_struct *task)
+struct sspt_proc *sspt_proc_by_task(struct task_struct *task)
 {
-       struct sspt_proc *proc;
-
-       sspt_proc_read_lock();
-       proc = sspt_proc_get_by_task_no_lock(task);
-       sspt_proc_read_unlock();
-
-       return proc;
+       return *pproc_by_task(task->group_leader);
 }
-EXPORT_SYMBOL_GPL(sspt_proc_get_by_task);
-
-/**
- * @brief Get sspt_proc by task
- *
- * @param task Pointer on the task_struct struct
- * @return Pointer on the sspt_proc struct
- */
-struct sspt_proc *sspt_proc_get_by_task_no_lock(struct task_struct *task)
-{
-       struct sspt_proc *proc, *tmp;
-
-       list_for_each_entry_safe(proc, tmp, &proc_probes_list, list) {
-               if (proc->tgid == task->tgid)
-                       return proc;
-       }
-
-       return NULL;
-}
-EXPORT_SYMBOL_GPL(sspt_proc_get_by_task_no_lock);
+EXPORT_SYMBOL_GPL(sspt_proc_by_task);
 
 /**
  * @brief Call func() on each proc (no lock)
@@ -239,15 +279,29 @@ EXPORT_SYMBOL_GPL(on_each_proc);
  */
 struct sspt_proc *sspt_proc_get_by_task_or_new(struct task_struct *task)
 {
-       struct sspt_proc *proc;
-
-       sspt_proc_write_lock();
-       proc = sspt_proc_get_by_task_no_lock(task);
-       if (proc == NULL)
-               proc = sspt_proc_create(task);
-       sspt_proc_write_unlock();
+       static DEFINE_MUTEX(local_mutex);
+       struct sspt_proc **pproc;
+       struct task_struct *leader = task->group_leader;
+
+       pproc = pproc_by_task(leader);
+       if (*pproc)
+               goto out;
+
+       /* This lock for synchronizing to create sspt_proc */
+       mutex_lock(&local_mutex);
+       pproc = pproc_by_task(leader);
+       if (*pproc == NULL) {
+               *pproc = sspt_proc_create(leader);
+               if (*pproc) {
+                       sspt_proc_write_lock();
+                       list_add(&(*pproc)->list, &proc_probes_list);
+                       sspt_proc_write_unlock();
+               }
+       }
+       mutex_unlock(&local_mutex);
 
-       return proc;
+out:
+       return *pproc;
 }
 
 /**
@@ -322,7 +376,7 @@ struct sspt_file *sspt_proc_find_file(struct sspt_proc *proc,
  */
 void sspt_proc_install_page(struct sspt_proc *proc, unsigned long page_addr)
 {
-       struct mm_struct *mm = proc->task->mm;
+       struct mm_struct *mm = proc->leader->mm;
        struct vm_area_struct *vma;
 
        vma = find_vma_intersection(mm, page_addr, page_addr + 1);
@@ -350,7 +404,7 @@ void sspt_proc_install_page(struct sspt_proc *proc, unsigned long page_addr)
 void sspt_proc_install(struct sspt_proc *proc)
 {
        struct vm_area_struct *vma;
-       struct mm_struct *mm = proc->task->mm;
+       struct mm_struct *mm = proc->leader->mm;
 
        proc->first_install = 1;
 
index 740c9c2..54eb80d 100644 (file)
@@ -52,12 +52,17 @@ struct sspt_proc {
        struct list_head file_head;     /**< For sspt_file */
 
        pid_t tgid;                     /**< Thread group ID */
-       struct task_struct *task;       /**< Ptr to the task */
+       struct task_struct *leader;     /**< Ptr to the task leader */
        struct mm_struct *__mm;
        struct task_struct *__task;
        struct slot_manager *sm;        /**< Ptr to the manager slot */
 
        struct {
+               unsigned after_exec:1;
+               unsigned after_fork:1;
+       } suspect;
+
+       struct {
                struct mutex mtx;       /**< Mutex for filter list */
                struct list_head head;  /**< Filter head */
        } filters;
@@ -79,7 +84,6 @@ struct sspt_proc_cb {
 
 struct list_head *sspt_proc_list(void);
 
-struct sspt_proc *sspt_proc_create(struct task_struct *task);
 void sspt_proc_cleanup(struct sspt_proc *proc);
 struct sspt_proc *sspt_proc_get(struct sspt_proc *proc);
 void sspt_proc_put(struct sspt_proc *proc);
@@ -88,8 +92,7 @@ void on_each_proc_no_lock(void (*func)(struct sspt_proc *, void *),
                          void *data);
 void on_each_proc(void (*func)(struct sspt_proc *, void *), void *data);
 
-struct sspt_proc *sspt_proc_get_by_task(struct task_struct *task);
-struct sspt_proc *sspt_proc_get_by_task_no_lock(struct task_struct *task);
+struct sspt_proc *sspt_proc_by_task(struct task_struct *task);
 struct sspt_proc *sspt_proc_get_by_task_or_new(struct task_struct *task);
 void sspt_proc_free_all(void);
 
@@ -131,4 +134,10 @@ int sspt_proc_cb_set(struct sspt_proc_cb *cb);
 void sspt_proc_priv_create(struct sspt_proc *proc);
 void sspt_proc_priv_destroy(struct sspt_proc *proc);
 
+void sspt_reset_proc(struct task_struct *task);
+void sspt_change_leader(struct task_struct *prev, struct task_struct *next);
+int sspt_proc_init(void);
+void sspt_proc_uninit(void);
+
+
 #endif /* __SSPT_PROC__ */
index 25c6c31..9b66b6e 100644 (file)
@@ -200,7 +200,7 @@ static int us_filter(struct task_struct *task)
        struct sspt_proc *proc;
 
        /* FIXME: add read lock (deadlock in sampler) */
-       proc = sspt_proc_get_by_task_no_lock(task);
+       proc = sspt_proc_by_task(task);
        if (proc)
                return sspt_proc_is_send_event(proc);
 
@@ -245,13 +245,24 @@ static int init_us_manager(void)
 {
        int ret;
 
-       ret = pin_init();
+       ret = sspt_proc_init();
        if (ret)
                return ret;
 
+       ret = pin_init();
+       if (ret)
+               goto uninit_proc;
+
        ret = init_us_filter();
        if (ret)
-               pin_exit();
+               goto uninit_pin;
+
+       return 0;
+
+uninit_pin:
+       pin_exit();
+uninit_proc:
+       sspt_proc_uninit();
 
        return ret;
 }
@@ -265,6 +276,7 @@ static void exit_us_manager(void)
 
        exit_us_filter();
        pin_exit();
+       sspt_proc_uninit();
 }
 
 SWAP_LIGHT_INIT_MODULE(usm_once, init_us_manager, exit_us_manager,