* = __switch_to =
* ============================================================================
*/
-static void do_entry_handler_switch(struct task_struct *task)
+static void switch_handler_prev(struct task_struct *task, int cpu)
{
- int cpu;
struct cpus_time *ct;
struct energy_data *ed;
unsigned long flags;
- cpu = smp_processor_id();
-
ct = task->tgid ? &ed_system.ct : &ct_idle;
cpus_time_lock(ct, flags);
cpus_time_update_running(ct, cpu, get_ntime(), start_time);
}
}
-static void do_ret_handler_switch(struct task_struct *task)
+static void switch_handler_next(struct task_struct *task, int cpu)
{
- int cpu;
struct cpus_time *ct;
struct energy_data *ed;
unsigned long flags;
- cpu = smp_processor_id();
-
ct = task->tgid ? &ed_system.ct : &ct_idle;
cpus_time_lock(ct, flags);
cpus_time_save_entry(ct, cpu, get_ntime());
}
}
-#ifndef CONFIG_SWAP_HOOK_SWITCH_TO
+#ifdef CONFIG_SWAP_HOOK_SWITCH_TO
+
+static void handler_switch(struct task_struct *prev,
+ struct task_struct *next)
+{
+ int cpu = smp_processor_id();
+
+ switch_handler_prev(prev, cpu);
+ switch_handler_next(next, cpu);
+}
+
+static struct swap_hook_ctx switch_to_hook = {
+ .hook = handler_switch
+};
+
+static int switch_to_enable(void)
+{
+ return swap_hook_ctx_reg(&switch_to_hook);
+}
+
+static void switch_to_disable(void)
+{
+ swap_hook_ctx_unreg(&switch_to_hook);
+}
+
+#else /* CONFIG_SWAP_HOOK_SWITCH_TO */
+
static int ret_handler_switch(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
- do_ret_handler_switch(current);
+ switch_handler_next(current, smp_processor_id());
return 0;
}
static int entry_handler_switch(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
- do_entry_handler_switch(current);
+ switch_handler_prev(current, smp_processor_id());
return 0;
}
.entry_handler = entry_handler_switch,
.handler = ret_handler_switch,
};
+
+static int switch_to_once(void)
+{
+ const char *sym = "__switch_to";
+ switch_to_krp.kp.addr = swap_ksyms(sym);
+ if (switch_to_krp.kp.addr == 0) {
+ pr_err("ERROR: symbol '%s' not found\n", sym);
+ return -ESRCH;
+ }
+
+ return 0;
+}
+
+static int switch_to_enable(void)
+{
+ return swap_register_kretprobe(&switch_to_krp);
+}
+
+static void switch_to_disable(void)
+{
+ swap_unregister_kretprobe(&switch_to_krp);
+}
+
#endif /* !CONFIG_SWAP_HOOK_SWITCH_TO */
};
-# ifdef CONFIG_SWAP_HOOK_SWITCH_TO
-static void handler_switch(struct task_struct *prev,
- struct task_struct *next)
-{
- do_entry_handler_switch(prev);
- do_ret_handler_switch(next);
-}
-
-static struct swap_hook_ctx switch_to_hook = {
- .hook = handler_switch
-};
-# endif /* CONFIG_SWAP_HOOK_SWITCH_TO */
-
int do_set_energy(void)
{
int ret = 0;
init_data_energy();
- swap_hook_ctx_reg(&switch_to_hook);
+ switch_to_enable();
ret = swap_td_raw_reg(&sys_call_tdraw, sizeof(struct sys_read_data));
if (ret)
return ret;
{
/* TODO: uinit lcd */
swap_hook_energy_unset();
- swap_hook_ctx_unreg(&switch_to_hook);
+ switch_to_disable();
hook_syscall_unreg(&sys_write_hook);
hook_syscall_unreg(&sys_read_hook);
goto unregister_sys_read;
}
- ret = swap_register_kretprobe(&switch_to_krp);
+ ret = switch_to_enable();
if (ret) {
- printk(KERN_INFO "swap_register_kretprobe(__switch_to) "
- "result=%d!\n",
- ret);
+ pr_info("Error __switch_to enable, ret=%d\n", ret);
goto unregister_sys_write;
}
energy_xxx_unset(wifi_probes, wifi_probes_cnt, &wifi_flag);
energy_xxx_unset(bt_probes, bt_probes_cnt, &energy_bt_flag);
- swap_unregister_kretprobe(&switch_to_krp);
+ switch_to_disable();
swap_unregister_kretprobe(&sys_write_krp);
swap_unregister_kretprobe(&sys_read_krp);
int energy_once(void)
{
+ int ret;
const char *sym;
- sym = "__switch_to";
- switch_to_krp.kp.addr = swap_ksyms(sym);
- if (switch_to_krp.kp.addr == 0)
- goto not_found;
+ ret = switch_to_once();
+ if (ret) {
+ pr_err("ERROR: 'switch_to' cannot init, ret=%d\n", ret);
+ return ret;
+ }
sym = "sys_read";
sys_read_krp.kp.addr = swap_ksyms(sym);