1 /* net/activity_stats.c
3 * Copyright (C) 2010 Google, Inc.
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.
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.
14 * Author: Mike Chan (mike@android.com)
17 #include <linux/proc_fs.h>
18 #include <linux/seq_file.h>
19 #include <linux/suspend.h>
20 #include <net/net_namespace.h>
23 * Track transmission rates in buckets (power of 2).
24 * 1,2,4,8...512 seconds.
26 * Buckets represent the count of network transmissions at least
27 * N seconds apart, where N is 1 << bucket index.
31 /* Track network activity frequency */
32 static unsigned long activity_stats
[BUCKET_MAX
];
33 static ktime_t last_transmit
;
34 static ktime_t suspend_time
;
35 static DEFINE_SPINLOCK(activity_lock
);
37 void activity_stats_update(void)
44 spin_lock_irqsave(&activity_lock
, flags
);
46 delta
= ktime_to_ns(ktime_sub(now
, last_transmit
));
48 for (i
= BUCKET_MAX
- 1; i
>= 0; i
--) {
50 * Check if the time delta between network activity is within the
51 * minimum bucket range.
53 if (delta
< (1000000000ULL << i
))
60 spin_unlock_irqrestore(&activity_lock
, flags
);
63 static int activity_stats_show(struct seq_file
*m
, void *v
)
68 seq_printf(m
, "Min Bucket(sec) Count\n");
70 for (i
= 0; i
< BUCKET_MAX
; i
++) {
71 ret
= seq_printf(m
, "%15d %lu\n", 1 << i
, activity_stats
[i
]);
79 static int activity_stats_notifier(struct notifier_block
*nb
,
80 unsigned long event
, void *dummy
)
83 case PM_SUSPEND_PREPARE
:
84 suspend_time
= ktime_get_real();
88 suspend_time
= ktime_sub(ktime_get_real(), suspend_time
);
89 last_transmit
= ktime_sub(last_transmit
, suspend_time
);
95 static int activity_stats_open(struct inode
*inode
, struct file
*file
)
97 return single_open(file
, activity_stats_show
, PDE_DATA(inode
));
100 static const struct file_operations activity_stats_fops
= {
101 .open
= activity_stats_open
,
104 .release
= seq_release
,
107 static struct notifier_block activity_stats_notifier_block
= {
108 .notifier_call
= activity_stats_notifier
,
111 static int __init
activity_stats_init(void)
113 proc_create("activity", S_IRUGO
,
114 init_net
.proc_net_stat
, &activity_stats_fops
);
115 return register_pm_notifier(&activity_stats_notifier_block
);
118 subsys_initcall(activity_stats_init
);