us_manager: add skipping page faults while handling one 11/169711/5
authorAlexander Aksenov <a.aksenov@samsung.com>
Wed, 7 Feb 2018 14:57:02 +0000 (17:57 +0300)
committerAlexander Aksenov <a.aksenov@samsung.com>
Mon, 19 Feb 2018 13:32:19 +0000 (16:32 +0300)
Change-Id: I67a2188401471232bc800ecc905fba3e925773a3
Signed-off-by: Alexander Aksenov <a.aksenov@samsung.com>
modules/us_manager/pf/pf_group.c
modules/us_manager/pf/pf_group.h
modules/us_manager/us_manager.c

index 03100ae..faed4ac 100644 (file)
@@ -45,6 +45,7 @@
 #include <us_manager/helper.h>
 #include <us_manager/us_common_file.h>
 #include <task_ctx/task_ctx.h>
+#include <kprobe/swap_ktd.h>
 
 
 struct pf_group {
@@ -91,6 +92,34 @@ static void pfg_list_wunlock(void)
 }
 
 
+static void pf_ktd_init(struct task_struct *task, void *data)
+{
+       bool *in_pf = (bool *)data;
+
+       *in_pf = false;
+}
+
+static void pf_ktd_exit(struct task_struct *task, void *data)
+{
+}
+
+static struct ktask_data pf_ktd = {
+       .init = pf_ktd_init,
+       .exit = pf_ktd_exit,
+       .size = sizeof(bool),
+};
+
+static inline void set_in_pf(bool is_in_pf, struct task_struct *task)
+{
+       *(bool *)swap_ktd(&pf_ktd, task) = is_in_pf;
+}
+
+static inline bool check_in_pf(struct task_struct *task)
+{
+       return *(bool *)swap_ktd(&pf_ktd, task);
+}
+
+
 /* struct pl_struct */
 static struct pl_struct *create_pl_struct(struct sspt_proc *proc)
 {
@@ -567,6 +596,8 @@ void check_task_and_install(struct task_struct *task)
        struct sspt_proc *proc;
        enum pf_inst_flag flag;
 
+       set_in_pf(true, task);
+
        flag = pfg_check_task(task);
        switch (flag) {
        case PIF_FIRST:
@@ -589,6 +620,8 @@ void check_task_and_install(struct task_struct *task)
        case PIF_SECOND:
                break;
        }
+
+       set_in_pf(false, task);
 }
 
 /**
@@ -603,6 +636,12 @@ void call_page_fault(struct task_struct *task, unsigned long page_addr)
        struct sspt_proc *proc;
        enum pf_inst_flag flag;
 
+       /* Skip page fault if we're already handling one */
+       if (check_in_pf(task))
+               return;
+
+       set_in_pf(true, task);
+
        flag = pfg_check_task(task);
        switch (flag) {
        case PIF_FIRST:
@@ -632,6 +671,8 @@ void call_page_fault(struct task_struct *task, unsigned long page_addr)
        case PIF_NONE:
                break;
        }
+
+       set_in_pf(false, task);
 }
 
 /**
@@ -865,6 +906,16 @@ void put_all_procs(void)
        sspt_proc_read_unlock();
 }
 
+int pfg_init(void)
+{
+       return swap_ktd_reg(&pf_ktd);
+}
+
+void pfg_exit(void)
+{
+       swap_ktd_unreg(&pf_ktd);
+}
+
 /**
  * @brief For debug
  *
index a9f74f7..f5267aa 100644 (file)
@@ -74,6 +74,9 @@ void uninstall_proc(struct sspt_proc *proc);
 
 void uninstall_page(unsigned long addr);
 
+int pfg_init(void);
+void pfg_exit(void);
+
 /* debug */
 void pfg_print(struct pf_group *pfg);
 /* debug */
index e6101b9..9576082 100644 (file)
@@ -261,6 +261,10 @@ static int init_us_manager(void)
        if (ret)
                goto uninit_pin;
 
+       ret = pfg_init();
+       if (ret)
+               goto uninit_filter;
+
        return 0;
 
 uninit_pin:
@@ -269,6 +273,8 @@ uninit_proc:
        sspt_proc_uninit();
 uninit_helper:
        helper_uninit();
+uninit_filter:
+       exit_us_filter();
 
        return ret;
 }
@@ -280,6 +286,7 @@ static void exit_us_manager(void)
 
        remove_all_cbs();
 
+       pfg_exit();
        exit_us_filter();
        pin_exit();
        sspt_proc_uninit();