summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYurchenko Darya <d.urchenko@partner.samsung.com>2015-11-25 12:47:34 +0300
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>2016-01-12 16:08:00 +0300
commit8abbfab8a57ca9a468ae50d9693ef474185d2b35 (patch)
tree855e726c8f913506e7c8040c8dc7ae6f5c8642db
parent7c6f2374bef2d9778c90d00837052859aabb0133 (diff)
downloadswap-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.c116
-rw-r--r--energy/energy.c219
-rw-r--r--energy/energy.h8
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 */
};