aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMike Chan2010-05-28 16:32:19 -0500
committerArve Hjønnevåg2013-02-19 17:49:20 -0600
commit6e99aaaa100f8030ec752513a42936c5d85ad9b6 (patch)
tree39b64f71aa750f63d057867eeb1f699927ee33c7 /net
parentc7420c7a2c3d40069d25fa935ca5abc24341e6f8 (diff)
downloadkernel-common-6e99aaaa100f8030ec752513a42936c5d85ad9b6.tar.gz
kernel-common-6e99aaaa100f8030ec752513a42936c5d85ad9b6.tar.xz
kernel-common-6e99aaaa100f8030ec752513a42936c5d85ad9b6.zip
net: activity_stats: Add statistics for network transmission activity
When enabled, tracks the frequency of network transmissions (inbound and outbound) and buckets them accordingly. Buckets are determined by time between network activity. Each bucket represents the number of network transmisions that were N sec or longer apart. Where N is defined as 1 << bucket index. This network pattern tracking is particularly useful for wireless networks (ie: 3G) where batching network activity closely together is more power efficient than far apart. New file: /proc/net/stat/activity output: Min Bucket(sec) Count 1 7 2 0 4 1 8 0 16 0 32 2 64 1 128 0 Change-Id: I4c4cd8627b872a55f326b1715c51bc3bdd6e8d92 Signed-off-by: Mike Chan <mike@android.com>
Diffstat (limited to 'net')
-rw-r--r--net/Kconfig8
-rw-r--r--net/Makefile1
-rw-r--r--net/activity_stats.c115
3 files changed, 124 insertions, 0 deletions
diff --git a/net/Kconfig b/net/Kconfig
index 86511c712a7..bdfbff938d8 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -87,6 +87,14 @@ config ANDROID_PARANOID_NETWORK
87 help 87 help
88 none 88 none
89 89
90config NET_ACTIVITY_STATS
91 bool "Network activity statistics tracking"
92 default y
93 help
94 Network activity statistics are useful for tracking wireless
95 modem activity on 2G, 3G, 4G wireless networks. Counts number of
96 transmissions and groups them in specified time buckets.
97
90config NETWORK_SECMARK 98config NETWORK_SECMARK
91 bool "Security Marking" 99 bool "Security Marking"
92 help 100 help
diff --git a/net/Makefile b/net/Makefile
index 4f4ee083064..2f8855ef534 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -70,3 +70,4 @@ obj-$(CONFIG_CEPH_LIB) += ceph/
70obj-$(CONFIG_BATMAN_ADV) += batman-adv/ 70obj-$(CONFIG_BATMAN_ADV) += batman-adv/
71obj-$(CONFIG_NFC) += nfc/ 71obj-$(CONFIG_NFC) += nfc/
72obj-$(CONFIG_OPENVSWITCH) += openvswitch/ 72obj-$(CONFIG_OPENVSWITCH) += openvswitch/
73obj-$(CONFIG_NET_ACTIVITY_STATS) += activity_stats.o
diff --git a/net/activity_stats.c b/net/activity_stats.c
new file mode 100644
index 00000000000..8a3e9347006
--- /dev/null
+++ b/net/activity_stats.c
@@ -0,0 +1,115 @@
1/* net/activity_stats.c
2 *
3 * Copyright (C) 2010 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * Author: Mike Chan (mike@android.com)
15 */
16
17#include <linux/proc_fs.h>
18#include <linux/suspend.h>
19#include <net/net_namespace.h>
20
21/*
22 * Track transmission rates in buckets (power of 2).
23 * 1,2,4,8...512 seconds.
24 *
25 * Buckets represent the count of network transmissions at least
26 * N seconds apart, where N is 1 << bucket index.
27 */
28#define BUCKET_MAX 10
29
30/* Track network activity frequency */
31static unsigned long activity_stats[BUCKET_MAX];
32static ktime_t last_transmit;
33static ktime_t suspend_time;
34static DEFINE_SPINLOCK(activity_lock);
35
36void activity_stats_update(void)
37{
38 int i;
39 unsigned long flags;
40 ktime_t now;
41 s64 delta;
42
43 spin_lock_irqsave(&activity_lock, flags);
44 now = ktime_get();
45 delta = ktime_to_ns(ktime_sub(now, last_transmit));
46
47 for (i = BUCKET_MAX - 1; i >= 0; i--) {
48 /*
49 * Check if the time delta between network activity is within the
50 * minimum bucket range.
51 */
52 if (delta < (1000000000ULL << i))
53 continue;
54
55 activity_stats[i]++;
56 last_transmit = now;
57 break;
58 }
59 spin_unlock_irqrestore(&activity_lock, flags);
60}
61
62static int activity_stats_read_proc(char *page, char **start, off_t off,
63 int count, int *eof, void *data)
64{
65 int i;
66 int len;
67 char *p = page;
68
69 /* Only print if offset is 0, or we have enough buffer space */
70 if (off || count < (30 * BUCKET_MAX + 22))
71 return -ENOMEM;
72
73 len = snprintf(p, count, "Min Bucket(sec) Count\n");
74 count -= len;
75 p += len;
76
77 for (i = 0; i < BUCKET_MAX; i++) {
78 len = snprintf(p, count, "%15d %lu\n", 1 << i, activity_stats[i]);
79 count -= len;
80 p += len;
81 }
82 *eof = 1;
83
84 return p - page;
85}
86
87static int activity_stats_notifier(struct notifier_block *nb,
88 unsigned long event, void *dummy)
89{
90 switch (event) {
91 case PM_SUSPEND_PREPARE:
92 suspend_time = ktime_get_real();
93 break;
94
95 case PM_POST_SUSPEND:
96 suspend_time = ktime_sub(ktime_get_real(), suspend_time);
97 last_transmit = ktime_sub(last_transmit, suspend_time);
98 }
99
100 return 0;
101}
102
103static struct notifier_block activity_stats_notifier_block = {
104 .notifier_call = activity_stats_notifier,
105};
106
107static int __init activity_stats_init(void)
108{
109 create_proc_read_entry("activity", S_IRUGO,
110 init_net.proc_net_stat, activity_stats_read_proc, NULL);
111 return register_pm_notifier(&activity_stats_notifier_block);
112}
113
114subsys_initcall(activity_stats_init);
115