[IMPROVE] added wifi consumption 83/55883/1
authorYurchenko Darya <d.urchenko@partner.samsung.com>
Mon, 23 Nov 2015 17:10:02 +0000 (20:10 +0300)
committerDmitry Kovalenko <d.kovalenko@samsung.com>
Wed, 30 Dec 2015 04:43:25 +0000 (07:43 +0300)
Change-Id: I8e465c6ca1c5c9743ec71c9e10eb1dca2d6b5ed2
Signed-off-by: Yurchenko Darya <d.urchenko@partner.samsung.com>
energy/debugfs_energy.c
energy/energy.c
energy/energy.h

index 0278445..eb9c7a0 100644 (file)
@@ -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
        }
 };
 
index 3192f19..d9eca32 100644 (file)
 #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>
@@ -130,6 +135,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;
@@ -142,6 +152,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)
@@ -149,6 +161,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)
@@ -439,10 +453,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 {
@@ -473,6 +630,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;
                }
@@ -527,12 +690,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;
@@ -569,6 +744,8 @@ int do_set_energy(void)
                goto unregister_sys_write;
        }
 
+       energy_wifi_set();
+
        /* TODO: check return value */
        lcd_set_energy();
 
@@ -586,6 +763,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);
@@ -668,6 +846,8 @@ int energy_once(void)
        if (sys_write_krp.kp.addr == NULL)
                goto not_found;
 
+       energy_wifi_once();
+
        return 0;
 
 not_found:
index 9626d1d..e2f7812 100644 (file)
@@ -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 */
 };