Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * arch/s390/appldata/appldata_net_sum.c | |
3 | * | |
4 | * Data gathering module for Linux-VM Monitor Stream, Stage 1. | |
5 | * Collects accumulated network statistics (Packets received/transmitted, | |
6 | * dropped, errors, ...). | |
7 | * | |
5b5dd21a | 8 | * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. |
1da177e4 | 9 | * |
5b5dd21a | 10 | * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> |
1da177e4 LT |
11 | */ |
12 | ||
1da177e4 LT |
13 | #include <linux/module.h> |
14 | #include <linux/init.h> | |
1da177e4 LT |
15 | #include <linux/errno.h> |
16 | #include <linux/kernel_stat.h> | |
17 | #include <linux/netdevice.h> | |
881d966b | 18 | #include <net/net_namespace.h> |
1da177e4 LT |
19 | |
20 | #include "appldata.h" | |
21 | ||
22 | ||
1da177e4 LT |
23 | /* |
24 | * Network data | |
25 | * | |
26 | * This is accessed as binary data by z/VM. If changes to it can't be avoided, | |
27 | * the structure version (product ID, see appldata_base.c) needs to be changed | |
28 | * as well and all documentation and z/VM applications using it must be updated. | |
29 | * | |
30 | * The record layout is documented in the Linux for zSeries Device Drivers | |
31 | * book: | |
32 | * http://oss.software.ibm.com/developerworks/opensource/linux390/index.shtml | |
33 | */ | |
2b67fc46 | 34 | static struct appldata_net_sum_data { |
1da177e4 LT |
35 | u64 timestamp; |
36 | u32 sync_count_1; /* after VM collected the record data, */ | |
37 | u32 sync_count_2; /* sync_count_1 and sync_count_2 should be the | |
38 | same. If not, the record has been updated on | |
39 | the Linux side while VM was collecting the | |
40 | (possibly corrupt) data */ | |
41 | ||
42 | u32 nr_interfaces; /* nr. of network interfaces being monitored */ | |
43 | ||
44 | u32 padding; /* next value is 64-bit aligned, so these */ | |
45 | /* 4 byte would be padded out by compiler */ | |
46 | ||
47 | u64 rx_packets; /* total packets received */ | |
48 | u64 tx_packets; /* total packets transmitted */ | |
49 | u64 rx_bytes; /* total bytes received */ | |
50 | u64 tx_bytes; /* total bytes transmitted */ | |
51 | u64 rx_errors; /* bad packets received */ | |
52 | u64 tx_errors; /* packet transmit problems */ | |
53 | u64 rx_dropped; /* no space in linux buffers */ | |
54 | u64 tx_dropped; /* no space available in linux */ | |
55 | u64 collisions; /* collisions while transmitting */ | |
f26d583e | 56 | } __attribute__((packed)) appldata_net_sum_data; |
1da177e4 LT |
57 | |
58 | ||
1da177e4 LT |
59 | /* |
60 | * appldata_get_net_sum_data() | |
61 | * | |
62 | * gather accumulated network statistics | |
63 | */ | |
64 | static void appldata_get_net_sum_data(void *data) | |
65 | { | |
66 | int i; | |
67 | struct appldata_net_sum_data *net_data; | |
68 | struct net_device *dev; | |
1da177e4 LT |
69 | unsigned long rx_packets, tx_packets, rx_bytes, tx_bytes, rx_errors, |
70 | tx_errors, rx_dropped, tx_dropped, collisions; | |
71 | ||
72 | net_data = data; | |
73 | net_data->sync_count_1++; | |
74 | ||
75 | i = 0; | |
76 | rx_packets = 0; | |
77 | tx_packets = 0; | |
78 | rx_bytes = 0; | |
79 | tx_bytes = 0; | |
80 | rx_errors = 0; | |
81 | tx_errors = 0; | |
82 | rx_dropped = 0; | |
83 | tx_dropped = 0; | |
84 | collisions = 0; | |
e576b9ef | 85 | |
86 | rcu_read_lock(); | |
87 | for_each_netdev_rcu(&init_net, dev) { | |
28172739 ED |
88 | struct rtnl_link_stats64 temp; |
89 | const struct net_device_stats *stats = dev_get_stats(dev, &temp); | |
eeda3fd6 | 90 | |
1da177e4 LT |
91 | rx_packets += stats->rx_packets; |
92 | tx_packets += stats->tx_packets; | |
93 | rx_bytes += stats->rx_bytes; | |
94 | tx_bytes += stats->tx_bytes; | |
95 | rx_errors += stats->rx_errors; | |
96 | tx_errors += stats->tx_errors; | |
97 | rx_dropped += stats->rx_dropped; | |
98 | tx_dropped += stats->tx_dropped; | |
99 | collisions += stats->collisions; | |
100 | i++; | |
101 | } | |
e576b9ef | 102 | rcu_read_unlock(); |
103 | ||
1da177e4 LT |
104 | net_data->nr_interfaces = i; |
105 | net_data->rx_packets = rx_packets; | |
106 | net_data->tx_packets = tx_packets; | |
107 | net_data->rx_bytes = rx_bytes; | |
108 | net_data->tx_bytes = tx_bytes; | |
109 | net_data->rx_errors = rx_errors; | |
110 | net_data->tx_errors = tx_errors; | |
111 | net_data->rx_dropped = rx_dropped; | |
112 | net_data->tx_dropped = tx_dropped; | |
113 | net_data->collisions = collisions; | |
114 | ||
115 | net_data->timestamp = get_clock(); | |
116 | net_data->sync_count_2++; | |
1da177e4 LT |
117 | } |
118 | ||
119 | ||
120 | static struct appldata_ops ops = { | |
1da177e4 LT |
121 | .name = "net_sum", |
122 | .record_nr = APPLDATA_RECORD_NET_SUM_ID, | |
123 | .size = sizeof(struct appldata_net_sum_data), | |
124 | .callback = &appldata_get_net_sum_data, | |
125 | .data = &appldata_net_sum_data, | |
126 | .owner = THIS_MODULE, | |
5b5dd21a | 127 | .mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */ |
1da177e4 LT |
128 | }; |
129 | ||
130 | ||
131 | /* | |
132 | * appldata_net_init() | |
133 | * | |
134 | * init data, register ops | |
135 | */ | |
136 | static int __init appldata_net_init(void) | |
137 | { | |
d3ae942d | 138 | return appldata_register_ops(&ops); |
1da177e4 LT |
139 | } |
140 | ||
141 | /* | |
142 | * appldata_net_exit() | |
143 | * | |
144 | * unregister ops | |
145 | */ | |
146 | static void __exit appldata_net_exit(void) | |
147 | { | |
148 | appldata_unregister_ops(&ops); | |
1da177e4 LT |
149 | } |
150 | ||
151 | ||
152 | module_init(appldata_net_init); | |
153 | module_exit(appldata_net_exit); | |
154 | ||
155 | MODULE_LICENSE("GPL"); | |
156 | MODULE_AUTHOR("Gerald Schaefer"); | |
157 | MODULE_DESCRIPTION("Linux-VM Monitor Stream, accumulated network statistics"); |