diff options
author | Yurchenko Darya <d.urchenko@partner.samsung.com> | 2015-11-23 20:10:02 +0300 |
---|---|---|
committer | Vyacheslav Cherkashin <v.cherkashin@samsung.com> | 2016-01-12 16:07:54 +0300 |
commit | 7c6f2374bef2d9778c90d00837052859aabb0133 (patch) | |
tree | eca840953f3e6a9d6e011549e44f31566caf6411 | |
parent | c00d7bef2dac1b454ac50d2f6a036fdef3e8bdf1 (diff) | |
download | swap-modules-7c6f2374bef2d9778c90d00837052859aabb0133.tar.gz swap-modules-7c6f2374bef2d9778c90d00837052859aabb0133.tar.bz2 swap-modules-7c6f2374bef2d9778c90d00837052859aabb0133.zip |
[IMPROVE] added wifi consumption
Change-Id: I8e465c6ca1c5c9743ec71c9e10eb1dca2d6b5ed2
Signed-off-by: Yurchenko Darya <d.urchenko@partner.samsung.com>
-rw-r--r-- | energy/debugfs_energy.c | 51 | ||||
-rw-r--r-- | energy/energy.c | 182 | ||||
-rw-r--r-- | energy/energy.h | 6 |
3 files changed, 237 insertions, 2 deletions
diff --git a/energy/debugfs_energy.c b/energy/debugfs_energy.c index 684f1708..c5c5cd47 100644 --- a/energy/debugfs_energy.c +++ b/energy/debugfs_energy.c @@ -119,8 +119,47 @@ static u64 fw_apps(void) } +/* wifi recv */ +static DEFINE_RATIONAL(wf_recv_coef); +static u64 wf_recv_system(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_WF_RECV_SYSTEM, &byte, sizeof(byte)); + + return div_u64(byte * wf_recv_coef.num, wf_recv_coef.denom); +} + +static u64 wf_recv_apps(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_WF_RECV_APPS, &byte, sizeof(byte)); + + return div_u64(byte * wf_recv_coef.num, wf_recv_coef.denom); +} +/* wifi send */ +static DEFINE_RATIONAL(wf_send_coef); + +static u64 wf_send_system(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_WF_SEND_SYSTEM, &byte, sizeof(byte)); + + return div_u64(byte * wf_send_coef.num, wf_send_coef.denom); +} + +static u64 wf_send_apps(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_WF_SEND_APPS, &byte, sizeof(byte)); + + return div_u64(byte * wf_send_coef.num, wf_send_coef.denom); +} /* ============================================================================ * === PARAMETERS === @@ -211,6 +250,18 @@ struct param_data parameters[] = { .coef = &fw_coef, .system = fw_system, .apps = fw_apps + }, + { + .name = "wf_recv", + .coef = &wf_recv_coef, + .system = wf_recv_system, + .apps = wf_recv_apps + }, + { + .name = "wf_send", + .coef = &wf_send_coef, + .system = wf_send_system, + .apps = wf_send_apps } }; diff --git a/energy/energy.c b/energy/energy.c index 9aea152e..b4d069be 100644 --- a/energy/energy.c +++ b/energy/energy.c @@ -30,6 +30,11 @@ #include <linux/magic.h> #include <linux/slab.h> #include <linux/spinlock.h> +#include <linux/net.h> +#include <linux/socket.h> +#include <linux/skbuff.h> +#include <linux/string.h> +#include <net/sock.h> #include <kprobe/swap_kprobes.h> #include <ksyms/ksyms.h> #include <us_manager/sspt/sspt_proc.h> @@ -129,6 +134,11 @@ struct energy_data { /*for sys_write */ atomic64_t bytes_written; + /*for recvmsg*/ + atomic64_t bytes_recv; + + /* for sock_send */ + atomic64_t bytes_send; }; static sspt_feature_id_t feature_id = SSPT_FEATURE_ID_BAD; @@ -141,6 +151,8 @@ static void init_ed(struct energy_data *ed) cpus_time_init(&ed->ct, 0); atomic64_set(&ed->bytes_read, 0); atomic64_set(&ed->bytes_written, 0); + atomic64_set(&ed->bytes_recv, 0); + atomic64_set(&ed->bytes_send, 0); } static void uninit_ed(struct energy_data *ed) @@ -148,6 +160,8 @@ static void uninit_ed(struct energy_data *ed) cpus_time_init(&ed->ct, 0); atomic64_set(&ed->bytes_read, 0); atomic64_set(&ed->bytes_written, 0); + atomic64_set(&ed->bytes_recv, 0); + atomic64_set(&ed->bytes_send, 0); } static void *create_ed(void) @@ -433,10 +447,153 @@ static struct kretprobe sys_write_krp = { +/* ============================================================================ + * = wifi = + * ============================================================================ + */ +static bool check_wlan0(struct socket *sock) +{ + /* FIXME: hardcode interface */ + const char *name_intrf = "wlan0"; + + if (sock->sk->sk_dst_cache && + sock->sk->sk_dst_cache->dev && + !strcmp(sock->sk->sk_dst_cache->dev->name, name_intrf)) + return true; + + return false; +} + +static int entry_handler_wf_sock(struct kretprobe_instance *ri, + struct pt_regs *regs) +{ + bool *ok = (bool *)ri->data; + struct socket *socket = (struct socket *)swap_get_karg(regs, 0); + + *ok = check_wlan0(socket); + + return 0; +} + +static int ret_handler_wf_sock_recv(struct kretprobe_instance *ri, + struct pt_regs *regs) +{ + int ret = regs_return_value(regs); + + if (ret > 0) { + bool ok = *(bool *)ri->data; + + if (ok) { + struct energy_data *ed; + + ed = get_energy_data(current); + if (ed) + atomic64_add(ret, &ed->bytes_recv); + atomic64_add(ret, &ed_system.bytes_recv); + } + } + + return 0; +} + +static int ret_handler_wf_sock_send(struct kretprobe_instance *ri, + struct pt_regs *regs) +{ + int ret = regs_return_value(regs); + + if (ret > 0) { + bool ok = *(bool *)ri->data; + + if (ok) { + struct energy_data *ed; + + ed = get_energy_data(current); + if (ed) + atomic64_add(ret, &ed->bytes_send); + atomic64_add(ret, &ed_system.bytes_send); + } + } + + return 0; +} + +static struct kretprobe sock_recv_krp = { + .entry_handler = entry_handler_wf_sock, + .handler = ret_handler_wf_sock_recv, + .data_size = sizeof(bool) +}; + +static struct kretprobe sock_send_krp = { + .entry_handler = entry_handler_wf_sock, + .handler = ret_handler_wf_sock_send, + .data_size = sizeof(bool) +}; + +static int energy_wifi_once(void) +{ + const char *sym; + + sym = "sock_recvmsg"; + sock_recv_krp.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym); + if (sock_recv_krp.kp.addr == NULL) + goto not_found; + + sym = "sock_sendmsg"; + sock_send_krp.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym); + if (sock_send_krp.kp.addr == NULL) + goto not_found; + + return 0; + +not_found: + printk(KERN_INFO "ERROR: symbol '%s' not found\n", sym); + return -ESRCH; +} + +static int energy_wifi_flag = 0; + +static int energy_wifi_set(void) +{ + int ret; + + ret = swap_register_kretprobe(&sock_recv_krp); + if (ret) { + pr_err("swap_register_kretprobe(sock_recv_krp) ret=%d\n" ,ret); + return ret; + } + + ret = swap_register_kretprobe(&sock_send_krp); + if (ret) { + pr_err("swap_register_kretprobe(sock_send_krp) ret=%d\n" ,ret); + swap_unregister_kretprobe(&sock_recv_krp); + } + + energy_wifi_flag = 1; + + return ret; +} + +static void energy_wifi_unset(void) +{ + if (energy_wifi_flag == 0) + return; + + swap_unregister_kretprobe(&sock_send_krp); + swap_unregister_kretprobe(&sock_recv_krp); + + energy_wifi_flag = 0; +} + + + + + enum parameter_type { PT_CPU, PT_READ, - PT_WRITE + PT_WRITE, + PT_WF_RECV, + PT_WF_SEND }; struct cmd_pt { @@ -467,6 +624,12 @@ static void callback_for_proc(struct sspt_proc *proc, void *data) case PT_WRITE: *val += atomic64_read(&ed->bytes_written); break; + case PT_WF_RECV: + *val += atomic64_read(&ed->bytes_recv); + break; + case PT_WF_SEND: + *val += atomic64_read(&ed->bytes_send); + break; default: break; } @@ -521,12 +684,24 @@ int get_parameter_energy(enum parameter_energy pe, void *buf, size_t sz) case PE_WRITE_SYSTEM: *val = atomic64_read(&ed_system.bytes_written); break; + case PE_WF_RECV_SYSTEM: + *val = atomic64_read(&ed_system.bytes_recv); + break; + case PE_WF_SEND_SYSTEM: + *val = atomic64_read(&ed_system.bytes_send); + break; case PE_READ_APPS: current_parameter_apps(PT_READ, buf, sz); break; case PE_WRITE_APPS: current_parameter_apps(PT_WRITE, buf, sz); break; + case PE_WF_RECV_APPS: + current_parameter_apps(PT_WF_RECV, buf, sz); + break; + case PE_WF_SEND_APPS: + current_parameter_apps(PT_WF_SEND, buf, sz); + break; default: ret = -EINVAL; break; @@ -560,6 +735,8 @@ int do_set_energy(void) goto unregister_sys_write; } + energy_wifi_set(); + /* TODO: check return value */ lcd_set_energy(); @@ -577,6 +754,7 @@ unregister_sys_write: void do_unset_energy(void) { lcd_unset_energy(); + energy_wifi_unset(); swap_unregister_kretprobe(&switch_to_krp); swap_unregister_kretprobe(&sys_write_krp); @@ -659,6 +837,8 @@ int energy_once(void) if (sys_write_krp.kp.addr == NULL) goto not_found; + energy_wifi_once(); + return 0; not_found: diff --git a/energy/energy.h b/energy/energy.h index 9626d1d4..e2f7812f 100644 --- a/energy/energy.h +++ b/energy/energy.h @@ -39,7 +39,11 @@ enum parameter_energy { PE_READ_SYSTEM, /**< number of bytes are read by system */ PE_WRITE_SYSTEM, /**< number of bytes are write by system */ PE_READ_APPS, /**< number of bytes are read by apps */ - PE_WRITE_APPS /**< number of bytes are write by apps*/ + PE_WRITE_APPS, /**< number of bytes are write by apps */ + PE_WF_RECV_SYSTEM, /**< number of bytes are receive by system through wifi */ + PE_WF_SEND_SYSTEM, /**< number of bytes are send by system through wifi */ + PE_WF_RECV_APPS, /**< number of bytes are receive by apps through wifi */ + PE_WF_SEND_APPS, /**< number of bytes are send by apps through wifi */ }; |