}
EXPORT_SYMBOL_GPL(swap_task_data_set);
+
+static atomic_t start_flag = ATOMIC_INIT(0);
+
static int copy_process_ret_handler(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
struct task_struct *task;
+ if (atomic_read(&start_flag) == 0)
+ return 0;
+
task = (struct task_struct *)regs_return_value(regs);
if (!IS_ERR(task))
swap_task_data_clean(task);
static int do_exit_handler(struct kprobe *p, struct pt_regs *regs)
{
- struct task_data *td = __td(current);
+ struct task_data *td;
+
+ if (atomic_read(&start_flag) == 0)
+ return 0;
+ td = __td(current);
__td_free(td);
return 0;
static int __task_data_init(void *data)
{
struct task_struct *g, *t;
- unsigned long addr;
- int ret;
- addr = swap_ksyms_substr("copy_process");
- if (addr == 0) {
- printk(TD_PREFIX "Cannot find address for copy_process\n");
- return -EINVAL;
- }
- copy_process_rp.kp.addr = (kprobe_opcode_t *)addr;
- ret = swap_register_kretprobe(©_process_rp);
- if (ret)
- goto reg_failed;
-
- addr = swap_ksyms_substr("do_exit");
- if (addr == 0) {
- printk(TD_PREFIX "Cannot find address for do_exit\n");
- return -EINVAL;
- }
- do_exit_probe.addr = (kprobe_opcode_t *)addr;
- ret = swap_register_kprobe(&do_exit_probe);
- if (ret)
- goto unreg_copy_process;
+ /* set start_flags */
+ atomic_set(&start_flag, 1);
do_each_thread(g, t) {
swap_task_data_clean(t);
} while_each_thread(g, t);
return 0;
-
-unreg_copy_process:
- swap_unregister_kretprobe(©_process_rp);
-
-reg_failed:
- printk(TD_PREFIX "0x%lx: probe registration failed\n", addr);
-
- return ret;
}
static int __task_data_exit(void *data)
struct task_struct *g, *t;
struct task_data *td;
- swap_unregister_kprobe(&do_exit_probe);
-
do_each_thread(g, t) {
td = __td(t);
__td_free(td);
} while_each_thread(g, t);
+ /* reset start_flags */
+ atomic_set(&start_flag, 0);
+
return 0;
}
{
int ret;
+ ret = swap_register_kprobe(&do_exit_probe);
+ if (ret) {
+ pr_err(TD_PREFIX "register on 'do_exit' failed: ret=%d\n", ret);
+ return;
+ }
+
+ ret = swap_register_kretprobe(©_process_rp);
+ if (ret) {
+ swap_unregister_kprobe(&do_exit_probe);
+ pr_err(TD_PREFIX "register on 'copy_process' failed: ret=%d\n", ret);
+ return;
+ }
+
/* stop_machine: cannot get tasklist_lock from module */
ret = stop_machine(__task_data_init, NULL, NULL);
if (ret)
{
int ret;
- swap_unregister_kretprobe(©_process_rp);
-
/* stop_machine: the same here */
ret = stop_machine(__task_data_exit, NULL, NULL);
if (ret) {
* all the installed probes */
swap_unregister_kprobe(&do_exit_probe);
}
+
+ swap_unregister_kretprobe(©_process_rp);
+ swap_unregister_kprobe(&do_exit_probe);
+}
+
+static int task_data_once(void)
+{
+ const char *sym;
+
+ sym = "copy_process";
+ copy_process_rp.kp.addr = (kprobe_opcode_t *)swap_ksyms_substr(sym);
+ if (copy_process_rp.kp.addr == NULL)
+ goto not_found;
+
+ sym = "do_exit";
+ do_exit_probe.addr = (kprobe_opcode_t *)swap_ksyms_substr(sym);
+ if (do_exit_probe.addr == NULL)
+ goto not_found;
+
+ return 0;
+
+not_found:
+ pr_err(TD_PREFIX "ERROR: symbol %s(...) not found\n", sym);
+ return -ESRCH;
}
static int task_data_init(void)
int ret = 0;
__task_data_cbs_start_h = us_manager_reg_cb(START_CB, task_data_start);
-
if (__task_data_cbs_start_h < 0) {
ret = __task_data_cbs_start_h;
printk(KERN_ERR TD_PREFIX "start_cb registration failed\n");
goto out;
}
- __task_data_cbs_stop_h = us_manager_reg_cb(STOP_CB, task_data_stop);
-
+ __task_data_cbs_stop_h = us_manager_reg_cb(STOP_CB_TD, task_data_stop);
if (__task_data_cbs_stop_h < 0) {
ret = __task_data_cbs_stop_h;
us_manager_unreg_cb(__task_data_cbs_start_h);
us_manager_unreg_cb(__task_data_cbs_stop_h);
}
-SWAP_LIGHT_INIT_MODULE(NULL, task_data_init, task_data_exit, NULL, NULL);
-
+SWAP_LIGHT_INIT_MODULE(task_data_once, task_data_init, task_data_exit,
+ NULL, NULL);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SWAP Task Data Module");