]>
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> | |
15 | #include <linux/slab.h> | |
16 | #include <linux/errno.h> | |
17 | #include <linux/kernel_stat.h> | |
18 | #include <linux/netdevice.h> | |
19 | ||
20 | #include "appldata.h" | |
21 | ||
22 | ||
23 | #define MY_PRINT_NAME "appldata_net_sum" /* for debug messages, etc. */ | |
24 | ||
25 | ||
26 | /* | |
27 | * Network data | |
28 | * | |
29 | * This is accessed as binary data by z/VM. If changes to it can't be avoided, | |
30 | * the structure version (product ID, see appldata_base.c) needs to be changed | |
31 | * as well and all documentation and z/VM applications using it must be updated. | |
32 | * | |
33 | * The record layout is documented in the Linux for zSeries Device Drivers | |
34 | * book: | |
35 | * http://oss.software.ibm.com/developerworks/opensource/linux390/index.shtml | |
36 | */ | |
2b67fc46 | 37 | static struct appldata_net_sum_data { |
1da177e4 LT |
38 | u64 timestamp; |
39 | u32 sync_count_1; /* after VM collected the record data, */ | |
40 | u32 sync_count_2; /* sync_count_1 and sync_count_2 should be the | |
41 | same. If not, the record has been updated on | |
42 | the Linux side while VM was collecting the | |
43 | (possibly corrupt) data */ | |
44 | ||
45 | u32 nr_interfaces; /* nr. of network interfaces being monitored */ | |
46 | ||
47 | u32 padding; /* next value is 64-bit aligned, so these */ | |
48 | /* 4 byte would be padded out by compiler */ | |
49 | ||
50 | u64 rx_packets; /* total packets received */ | |
51 | u64 tx_packets; /* total packets transmitted */ | |
52 | u64 rx_bytes; /* total bytes received */ | |
53 | u64 tx_bytes; /* total bytes transmitted */ | |
54 | u64 rx_errors; /* bad packets received */ | |
55 | u64 tx_errors; /* packet transmit problems */ | |
56 | u64 rx_dropped; /* no space in linux buffers */ | |
57 | u64 tx_dropped; /* no space available in linux */ | |
58 | u64 collisions; /* collisions while transmitting */ | |
f26d583e | 59 | } __attribute__((packed)) appldata_net_sum_data; |
1da177e4 LT |
60 | |
61 | ||
62 | static inline void appldata_print_debug(struct appldata_net_sum_data *net_data) | |
63 | { | |
64 | P_DEBUG("--- NET - RECORD ---\n"); | |
65 | ||
66 | P_DEBUG("nr_interfaces = %u\n", net_data->nr_interfaces); | |
67 | P_DEBUG("rx_packets = %8lu\n", net_data->rx_packets); | |
68 | P_DEBUG("tx_packets = %8lu\n", net_data->tx_packets); | |
69 | P_DEBUG("rx_bytes = %8lu\n", net_data->rx_bytes); | |
70 | P_DEBUG("tx_bytes = %8lu\n", net_data->tx_bytes); | |
71 | P_DEBUG("rx_errors = %8lu\n", net_data->rx_errors); | |
72 | P_DEBUG("tx_errors = %8lu\n", net_data->tx_errors); | |
73 | P_DEBUG("rx_dropped = %8lu\n", net_data->rx_dropped); | |
74 | P_DEBUG("tx_dropped = %8lu\n", net_data->tx_dropped); | |
75 | P_DEBUG("collisions = %8lu\n", net_data->collisions); | |
76 | ||
77 | P_DEBUG("sync_count_1 = %u\n", net_data->sync_count_1); | |
78 | P_DEBUG("sync_count_2 = %u\n", net_data->sync_count_2); | |
79 | P_DEBUG("timestamp = %lX\n", net_data->timestamp); | |
80 | } | |
81 | ||
82 | /* | |
83 | * appldata_get_net_sum_data() | |
84 | * | |
85 | * gather accumulated network statistics | |
86 | */ | |
87 | static void appldata_get_net_sum_data(void *data) | |
88 | { | |
89 | int i; | |
90 | struct appldata_net_sum_data *net_data; | |
91 | struct net_device *dev; | |
92 | struct net_device_stats *stats; | |
93 | unsigned long rx_packets, tx_packets, rx_bytes, tx_bytes, rx_errors, | |
94 | tx_errors, rx_dropped, tx_dropped, collisions; | |
95 | ||
96 | net_data = data; | |
97 | net_data->sync_count_1++; | |
98 | ||
99 | i = 0; | |
100 | rx_packets = 0; | |
101 | tx_packets = 0; | |
102 | rx_bytes = 0; | |
103 | tx_bytes = 0; | |
104 | rx_errors = 0; | |
105 | tx_errors = 0; | |
106 | rx_dropped = 0; | |
107 | tx_dropped = 0; | |
108 | collisions = 0; | |
109 | read_lock(&dev_base_lock); | |
110 | for (dev = dev_base; dev != NULL; dev = dev->next) { | |
111 | if (dev->get_stats == NULL) { | |
112 | continue; | |
113 | } | |
114 | stats = dev->get_stats(dev); | |
115 | rx_packets += stats->rx_packets; | |
116 | tx_packets += stats->tx_packets; | |
117 | rx_bytes += stats->rx_bytes; | |
118 | tx_bytes += stats->tx_bytes; | |
119 | rx_errors += stats->rx_errors; | |
120 | tx_errors += stats->tx_errors; | |
121 | rx_dropped += stats->rx_dropped; | |
122 | tx_dropped += stats->tx_dropped; | |
123 | collisions += stats->collisions; | |
124 | i++; | |
125 | } | |
126 | read_unlock(&dev_base_lock); | |
127 | net_data->nr_interfaces = i; | |
128 | net_data->rx_packets = rx_packets; | |
129 | net_data->tx_packets = tx_packets; | |
130 | net_data->rx_bytes = rx_bytes; | |
131 | net_data->tx_bytes = tx_bytes; | |
132 | net_data->rx_errors = rx_errors; | |
133 | net_data->tx_errors = tx_errors; | |
134 | net_data->rx_dropped = rx_dropped; | |
135 | net_data->tx_dropped = tx_dropped; | |
136 | net_data->collisions = collisions; | |
137 | ||
138 | net_data->timestamp = get_clock(); | |
139 | net_data->sync_count_2++; | |
140 | #ifdef APPLDATA_DEBUG | |
141 | appldata_print_debug(net_data); | |
142 | #endif | |
143 | } | |
144 | ||
145 | ||
146 | static struct appldata_ops ops = { | |
147 | .ctl_nr = CTL_APPLDATA_NET_SUM, | |
148 | .name = "net_sum", | |
149 | .record_nr = APPLDATA_RECORD_NET_SUM_ID, | |
150 | .size = sizeof(struct appldata_net_sum_data), | |
151 | .callback = &appldata_get_net_sum_data, | |
152 | .data = &appldata_net_sum_data, | |
153 | .owner = THIS_MODULE, | |
5b5dd21a | 154 | .mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */ |
1da177e4 LT |
155 | }; |
156 | ||
157 | ||
158 | /* | |
159 | * appldata_net_init() | |
160 | * | |
161 | * init data, register ops | |
162 | */ | |
163 | static int __init appldata_net_init(void) | |
164 | { | |
165 | int rc; | |
166 | ||
167 | P_DEBUG("sizeof(net) = %lu\n", sizeof(struct appldata_net_sum_data)); | |
168 | ||
169 | rc = appldata_register_ops(&ops); | |
170 | if (rc != 0) { | |
171 | P_ERROR("Error registering ops, rc = %i\n", rc); | |
172 | } else { | |
173 | P_DEBUG("%s-ops registered!\n", ops.name); | |
174 | } | |
175 | return rc; | |
176 | } | |
177 | ||
178 | /* | |
179 | * appldata_net_exit() | |
180 | * | |
181 | * unregister ops | |
182 | */ | |
183 | static void __exit appldata_net_exit(void) | |
184 | { | |
185 | appldata_unregister_ops(&ops); | |
186 | P_DEBUG("%s-ops unregistered!\n", ops.name); | |
187 | } | |
188 | ||
189 | ||
190 | module_init(appldata_net_init); | |
191 | module_exit(appldata_net_exit); | |
192 | ||
193 | MODULE_LICENSE("GPL"); | |
194 | MODULE_AUTHOR("Gerald Schaefer"); | |
195 | MODULE_DESCRIPTION("Linux-VM Monitor Stream, accumulated network statistics"); |