diff options
author | Yurchenko Darya <d.urchenko@partner.samsung.com> | 2015-11-25 12:47:34 +0300 |
---|---|---|
committer | Vyacheslav Cherkashin <v.cherkashin@samsung.com> | 2016-01-12 16:08:00 +0300 |
commit | 8abbfab8a57ca9a468ae50d9693ef474185d2b35 (patch) | |
tree | 855e726c8f913506e7c8040c8dc7ae6f5c8642db | |
parent | 7c6f2374bef2d9778c90d00837052859aabb0133 (diff) | |
download | swap-modules-8abbfab8a57ca9a468ae50d9693ef474185d2b35.tar.gz swap-modules-8abbfab8a57ca9a468ae50d9693ef474185d2b35.tar.bz2 swap-modules-8abbfab8a57ca9a468ae50d9693ef474185d2b35.zip |
[IMPROVE] added bluetooth consumption
Change-Id: I759f90891d4635fe366ae68a1fbae1e3c5a622c3
Signed-off-by: Yurchenko Darya <d.urchenko@partner.samsung.com>
-rw-r--r-- | energy/debugfs_energy.c | 116 | ||||
-rw-r--r-- | energy/energy.c | 219 | ||||
-rw-r--r-- | energy/energy.h | 8 |
3 files changed, 342 insertions, 1 deletions
diff --git a/energy/debugfs_energy.c b/energy/debugfs_energy.c index c5c5cd47..258f2b96 100644 --- a/energy/debugfs_energy.c +++ b/energy/debugfs_energy.c @@ -161,6 +161,98 @@ static u64 wf_send_apps(void) return div_u64(byte * wf_send_coef.num, wf_send_coef.denom); } +/* l2cap_recv_acldata */ +static DEFINE_RATIONAL(l2cap_recv_acldata_coef); + +static u64 l2cap_recv_acldata_system(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_L2CAP_RECV_SYSTEM, &byte, sizeof(byte)); + + return div_u64(byte * l2cap_recv_acldata_coef.num, + l2cap_recv_acldata_coef.denom); +} + +static u64 l2cap_recv_acldata_apps(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_L2CAP_RECV_APPS, &byte, sizeof(byte)); + + return div_u64(byte * l2cap_recv_acldata_coef.num, + l2cap_recv_acldata_coef.denom); +} + +/* sco_recv_scodata */ +static DEFINE_RATIONAL(sco_recv_scodata_coef); + +static u64 sco_recv_scodata_system(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_SCO_RECV_SYSTEM, &byte, sizeof(byte)); + + return div_u64(byte * sco_recv_scodata_coef.num, + sco_recv_scodata_coef.denom); +} + +static u64 sco_recv_scodata_apps(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_SCO_RECV_APPS, &byte, sizeof(byte)); + + return div_u64(byte * sco_recv_scodata_coef.num, + sco_recv_scodata_coef.denom); +} + +/* hci_send_acl */ +static DEFINE_RATIONAL(hci_send_acl_coef); + +static u64 hci_send_acl_system(void) +{ + u64 byte = 0; + + get_parameter_energy(PT_SEND_ACL_SYSTEM, &byte, sizeof(byte)); + + return div_u64(byte * hci_send_acl_coef.num, hci_send_acl_coef.denom); +} + +static u64 hci_send_acl_apps(void) +{ + u64 byte = 0; + + get_parameter_energy(PT_SEND_ACL_APPS, &byte, sizeof(byte)); + + return div_u64(byte * hci_send_acl_coef.num, hci_send_acl_coef.denom); +} + +/* hci_send_sco */ +static DEFINE_RATIONAL(hci_send_sco_coef); + +static u64 hci_send_sco_system(void) +{ + u64 byte = 0; + + get_parameter_energy(PT_SEND_SCO_SYSTEM, &byte, sizeof(byte)); + + return div_u64(byte * hci_send_sco_coef.num, hci_send_sco_coef.denom); +} + +static u64 hci_send_sco_apps(void) +{ + u64 byte = 0; + + get_parameter_energy(PT_SEND_SCO_APPS, &byte, sizeof(byte)); + + return div_u64(byte * hci_send_sco_coef.num, hci_send_sco_coef.denom); +} + + + + + /* ============================================================================ * === PARAMETERS === * ============================================================================ @@ -262,6 +354,30 @@ struct param_data parameters[] = { .coef = &wf_send_coef, .system = wf_send_system, .apps = wf_send_apps + }, + { + .name = "sco_recv_scodata", + .coef = &sco_recv_scodata_coef, + .system = sco_recv_scodata_system, + .apps = sco_recv_scodata_apps + }, + { + .name = "l2cap_recv_acldata", + .coef = &l2cap_recv_acldata_coef, + .system = l2cap_recv_acldata_system, + .apps = l2cap_recv_acldata_apps + }, + { + .name = "hci_send_acl", + .coef = &hci_send_acl_coef, + .system = hci_send_acl_system, + .apps = hci_send_acl_apps + }, + { + .name = "hci_send_sco", + .coef = &hci_send_sco_coef, + .system = hci_send_sco_system, + .apps = hci_send_sco_apps } }; diff --git a/energy/energy.c b/energy/energy.c index b4d069be..5fa22865 100644 --- a/energy/energy.c +++ b/energy/energy.c @@ -139,6 +139,18 @@ struct energy_data { /* for sock_send */ atomic64_t bytes_send; + + /* for l2cap_recv */ + atomic64_t bytes_l2cap_recv_acldata; + + /* for sco_recv_scodata */ + atomic64_t bytes_sco_recv_scodata; + + /* for hci_send_acl */ + atomic64_t bytes_hci_send_acl; + + /* for hci_send_sco */ + atomic64_t bytes_hci_send_sco; }; static sspt_feature_id_t feature_id = SSPT_FEATURE_ID_BAD; @@ -153,6 +165,10 @@ static void init_ed(struct energy_data *ed) atomic64_set(&ed->bytes_written, 0); atomic64_set(&ed->bytes_recv, 0); atomic64_set(&ed->bytes_send, 0); + atomic64_set(&ed->bytes_l2cap_recv_acldata, 0); + atomic64_set(&ed->bytes_sco_recv_scodata, 0); + atomic64_set(&ed->bytes_hci_send_acl, 0); + atomic64_set(&ed->bytes_hci_send_sco, 0); } static void uninit_ed(struct energy_data *ed) @@ -162,6 +178,10 @@ static void uninit_ed(struct energy_data *ed) atomic64_set(&ed->bytes_written, 0); atomic64_set(&ed->bytes_recv, 0); atomic64_set(&ed->bytes_send, 0); + atomic64_set(&ed->bytes_l2cap_recv_acldata, 0); + atomic64_set(&ed->bytes_sco_recv_scodata, 0); + atomic64_set(&ed->bytes_hci_send_acl, 0); + atomic64_set(&ed->bytes_hci_send_sco, 0); } static void *create_ed(void) @@ -588,12 +608,170 @@ static void energy_wifi_unset(void) +/* ============================================================================ + * = bluetooth = + * ============================================================================ + */ +#define RET_HANDLER_BT_NAME(name) ret_handler_bt_##name +#define DEFINE_RET_HANDLER_BT(name) \ + int RET_HANDLER_BT_NAME(name)(struct kretprobe_instance *ri, \ + struct pt_regs *regs) \ + { \ + unsigned int len = *(unsigned int *)ri->data; \ + if (len) { \ + struct energy_data *ed = get_energy_data(current); \ + if (ed) \ + atomic64_add(len, &ed->bytes_##name); \ + atomic64_add(len, &ed_system.bytes_##name); \ + } \ + return 0; \ +} + +static DEFINE_RET_HANDLER_BT(l2cap_recv_acldata) +static DEFINE_RET_HANDLER_BT(sco_recv_scodata) +static DEFINE_RET_HANDLER_BT(hci_send_acl) +static DEFINE_RET_HANDLER_BT(hci_send_sco) + +static int entry_handler_generic_bt(struct kretprobe_instance *ri, + struct pt_regs *regs) +{ + struct sk_buff *skb = (struct sk_buff *)swap_get_sarg(regs, 1); + unsigned int *len = (unsigned int *)ri->data; + + *len = skb ? skb->len : 0; + + return 0; +} + +static struct kretprobe l2cap_recv_acldata_krp = { + .entry_handler = entry_handler_generic_bt, + .handler = RET_HANDLER_BT_NAME(l2cap_recv_acldata), + .data_size = sizeof(unsigned int) +}; + +static struct kretprobe sco_recv_scodata_krp = { + .entry_handler = entry_handler_generic_bt, + .handler = RET_HANDLER_BT_NAME(sco_recv_scodata), + .data_size = sizeof(unsigned int) +}; + +static struct kretprobe hci_send_acl_krp = { + .entry_handler = entry_handler_generic_bt, + .handler = RET_HANDLER_BT_NAME(hci_send_acl), + .data_size = sizeof(unsigned int) +}; + +static struct kretprobe hci_send_sco_krp = { + .entry_handler = entry_handler_generic_bt, + .handler = RET_HANDLER_BT_NAME(hci_send_sco), + .data_size = sizeof(unsigned int) +}; + + +static int energy_bt_once(void) +{ + const char *sym; + + sym = "l2cap_recv_acldata"; + l2cap_recv_acldata_krp.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym); + if (l2cap_recv_acldata_krp.kp.addr == NULL) + goto not_found; + + sym = "sco_recv_scodata"; + sco_recv_scodata_krp.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym); + if (sco_recv_scodata_krp.kp.addr == NULL) + goto not_found; + + sym = "hci_send_acl"; + hci_send_acl_krp.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym); + if (hci_send_acl_krp.kp.addr == NULL) + goto not_found; + + sym = "hci_send_sco"; + hci_send_sco_krp.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym); + if (hci_send_sco_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_bt_flag = 0; + +static int energy_bt_set(void) +{ + int ret; + + ret = swap_register_kretprobe(&l2cap_recv_acldata_krp); + if (ret) { + pr_err("register fail 'l2cap_recv_acldata_krp' ret=%d\n", ret); + return ret; + } + + ret = swap_register_kretprobe(&sco_recv_scodata_krp); + if (ret) { + printk("register fail 'sco_recv_scodata_krp' ret=%d\n" ,ret); + goto unreg_l2cap_recv_acldata; + } + + ret = swap_register_kretprobe(&hci_send_acl_krp); + if (ret) { + printk("register fail 'hci_send_acl_krp' ret=%d\n", ret); + goto unreg_sco_recv_scodata; + } + + ret = swap_register_kretprobe(&hci_send_sco_krp); + if (ret) { + printk("register fail 'hci_send_sco_krp' ret=%d\n", ret); + goto unreg_hci_send_acl; + } + + energy_bt_flag = 1; + + return 0; + +unreg_hci_send_acl: + swap_unregister_kretprobe(&hci_send_acl_krp); + +unreg_sco_recv_scodata: + swap_unregister_kretprobe(&sco_recv_scodata_krp); + +unreg_l2cap_recv_acldata: + swap_unregister_kretprobe(&l2cap_recv_acldata_krp); + + return ret; +} + +static void energy_bt_unset(void) +{ + if (energy_bt_flag == 0) + return; + + swap_unregister_kretprobe(&hci_send_sco_krp); + swap_unregister_kretprobe(&hci_send_acl_krp); + swap_unregister_kretprobe(&sco_recv_scodata_krp); + swap_unregister_kretprobe(&l2cap_recv_acldata_krp); + + energy_bt_flag = 0; +} + + + + + enum parameter_type { PT_CPU, PT_READ, PT_WRITE, PT_WF_RECV, - PT_WF_SEND + PT_WF_SEND, + PT_L2CAP_RECV, + PT_SCO_RECV, + PT_SEND_ACL, + PT_SEND_SCO }; struct cmd_pt { @@ -630,6 +808,18 @@ static void callback_for_proc(struct sspt_proc *proc, void *data) case PT_WF_SEND: *val += atomic64_read(&ed->bytes_send); break; + case PT_L2CAP_RECV: + *val += atomic64_read(&ed->bytes_l2cap_recv_acldata); + break; + case PT_SCO_RECV: + *val += atomic64_read(&ed->bytes_sco_recv_scodata); + break; + case PT_SEND_ACL: + *val += atomic64_read(&ed->bytes_hci_send_acl); + break; + case PT_SEND_SCO: + *val += atomic64_read(&ed->bytes_hci_send_sco); + break; default: break; } @@ -690,6 +880,18 @@ int get_parameter_energy(enum parameter_energy pe, void *buf, size_t sz) case PE_WF_SEND_SYSTEM: *val = atomic64_read(&ed_system.bytes_send); break; + case PE_L2CAP_RECV_SYSTEM: + *val = atomic64_read(&ed_system.bytes_l2cap_recv_acldata); + break; + case PE_SCO_RECV_SYSTEM: + *val = atomic64_read(&ed_system.bytes_sco_recv_scodata); + break; + case PT_SEND_ACL_SYSTEM: + *val = atomic64_read(&ed_system.bytes_hci_send_acl); + break; + case PT_SEND_SCO_SYSTEM: + *val = atomic64_read(&ed_system.bytes_hci_send_sco); + break; case PE_READ_APPS: current_parameter_apps(PT_READ, buf, sz); break; @@ -702,6 +904,18 @@ int get_parameter_energy(enum parameter_energy pe, void *buf, size_t sz) case PE_WF_SEND_APPS: current_parameter_apps(PT_WF_SEND, buf, sz); break; + case PE_L2CAP_RECV_APPS: + current_parameter_apps(PT_L2CAP_RECV, buf, sz); + break; + case PE_SCO_RECV_APPS: + current_parameter_apps(PT_SCO_RECV, buf, sz); + break; + case PT_SEND_ACL_APPS: + current_parameter_apps(PT_SEND_ACL, buf, sz); + break; + case PT_SEND_SCO_APPS: + current_parameter_apps(PT_SEND_SCO, buf, sz); + break; default: ret = -EINVAL; break; @@ -735,6 +949,7 @@ int do_set_energy(void) goto unregister_sys_write; } + energy_bt_set(); energy_wifi_set(); /* TODO: check return value */ @@ -755,6 +970,7 @@ void do_unset_energy(void) { lcd_unset_energy(); energy_wifi_unset(); + energy_bt_unset(); swap_unregister_kretprobe(&switch_to_krp); swap_unregister_kretprobe(&sys_write_krp); @@ -837,6 +1053,7 @@ int energy_once(void) if (sys_write_krp.kp.addr == NULL) goto not_found; + energy_bt_once(); energy_wifi_once(); return 0; diff --git a/energy/energy.h b/energy/energy.h index e2f7812f..7466570d 100644 --- a/energy/energy.h +++ b/energy/energy.h @@ -44,6 +44,14 @@ enum parameter_energy { 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 */ + PE_L2CAP_RECV_SYSTEM, /**< number of bytes(ACL packets) are recv by system through bluetooth */ + PE_L2CAP_RECV_APPS, /**< number of bytes(ACL packets) are recv by apps through bluetooth */ + PE_SCO_RECV_SYSTEM, /**< number of bytes(SCO packets) are recv by system through bluetooth */ + PE_SCO_RECV_APPS, /**< number of bytes(SCO packets) are recv by apps through bluetooth */ + PT_SEND_ACL_SYSTEM, /**< number of bytes(ACL packets) are send by system through bluetooth */ + PT_SEND_ACL_APPS, /**< number of bytes(ACL packets) are send by apps through bluetooth */ + PT_SEND_SCO_SYSTEM, /**< number of bytes(SCO packets) are send by system through bluetooth */ + PT_SEND_SCO_APPS, /**< number of bytes(SCO packets) are send by apps through bluetooth */ }; |