aboutsummaryrefslogtreecommitdiffstats
path: root/net/can/proc.c
diff options
context:
space:
mode:
authorOliver Hartkopp <socketcan@hartkopp.net>2017-04-25 02:19:41 -0400
committerMarc Kleine-Budde <mkl@pengutronix.de>2017-04-25 03:04:29 -0400
commitcb5635a3677679666e4e81ecbb209d32f13dedcd (patch)
tree2d5357aa8fbb22b3e8b0baba8c838b0234c402d1 /net/can/proc.c
parentf2e72f43e7686720ddc5112fab2f5f71f47dc5e6 (diff)
can: complete initial namespace support
The statistics and its proc output was not implemented as per-net in the initial network namespace support by Mario Kicherer (8e8cda6d737d). This patch adds the missing per-net statistics for the CAN subsystem. Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'net/can/proc.c')
-rw-r--r--net/can/proc.c141
1 files changed, 76 insertions, 65 deletions
diff --git a/net/can/proc.c b/net/can/proc.c
index 9a8d54d57b22..83045f00c63c 100644
--- a/net/can/proc.c
+++ b/net/can/proc.c
@@ -75,21 +75,23 @@ static const char rx_list_name[][8] = {
75 * af_can statistics stuff 75 * af_can statistics stuff
76 */ 76 */
77 77
78static void can_init_stats(void) 78static void can_init_stats(struct net *net)
79{ 79{
80 struct s_stats *can_stats = net->can.can_stats;
81 struct s_pstats *can_pstats = net->can.can_pstats;
80 /* 82 /*
81 * This memset function is called from a timer context (when 83 * This memset function is called from a timer context (when
82 * can_stattimer is active which is the default) OR in a process 84 * can_stattimer is active which is the default) OR in a process
83 * context (reading the proc_fs when can_stattimer is disabled). 85 * context (reading the proc_fs when can_stattimer is disabled).
84 */ 86 */
85 memset(&can_stats, 0, sizeof(can_stats)); 87 memset(can_stats, 0, sizeof(struct s_stats));
86 can_stats.jiffies_init = jiffies; 88 can_stats->jiffies_init = jiffies;
87 89
88 can_pstats.stats_reset++; 90 can_pstats->stats_reset++;
89 91
90 if (user_reset) { 92 if (user_reset) {
91 user_reset = 0; 93 user_reset = 0;
92 can_pstats.user_reset++; 94 can_pstats->user_reset++;
93 } 95 }
94} 96}
95 97
@@ -115,64 +117,66 @@ static unsigned long calc_rate(unsigned long oldjif, unsigned long newjif,
115 117
116void can_stat_update(unsigned long data) 118void can_stat_update(unsigned long data)
117{ 119{
120 struct net *net = (struct net *)data;
121 struct s_stats *can_stats = net->can.can_stats;
118 unsigned long j = jiffies; /* snapshot */ 122 unsigned long j = jiffies; /* snapshot */
119 123
120 /* restart counting in timer context on user request */ 124 /* restart counting in timer context on user request */
121 if (user_reset) 125 if (user_reset)
122 can_init_stats(); 126 can_init_stats(net);
123 127
124 /* restart counting on jiffies overflow */ 128 /* restart counting on jiffies overflow */
125 if (j < can_stats.jiffies_init) 129 if (j < can_stats->jiffies_init)
126 can_init_stats(); 130 can_init_stats(net);
127 131
128 /* prevent overflow in calc_rate() */ 132 /* prevent overflow in calc_rate() */
129 if (can_stats.rx_frames > (ULONG_MAX / HZ)) 133 if (can_stats->rx_frames > (ULONG_MAX / HZ))
130 can_init_stats(); 134 can_init_stats(net);
131 135
132 /* prevent overflow in calc_rate() */ 136 /* prevent overflow in calc_rate() */
133 if (can_stats.tx_frames > (ULONG_MAX / HZ)) 137 if (can_stats->tx_frames > (ULONG_MAX / HZ))
134 can_init_stats(); 138 can_init_stats(net);
135 139
136 /* matches overflow - very improbable */ 140 /* matches overflow - very improbable */
137 if (can_stats.matches > (ULONG_MAX / 100)) 141 if (can_stats->matches > (ULONG_MAX / 100))
138 can_init_stats(); 142 can_init_stats(net);
139 143
140 /* calc total values */ 144 /* calc total values */
141 if (can_stats.rx_frames) 145 if (can_stats->rx_frames)
142 can_stats.total_rx_match_ratio = (can_stats.matches * 100) / 146 can_stats->total_rx_match_ratio = (can_stats->matches * 100) /
143 can_stats.rx_frames; 147 can_stats->rx_frames;
144 148
145 can_stats.total_tx_rate = calc_rate(can_stats.jiffies_init, j, 149 can_stats->total_tx_rate = calc_rate(can_stats->jiffies_init, j,
146 can_stats.tx_frames); 150 can_stats->tx_frames);
147 can_stats.total_rx_rate = calc_rate(can_stats.jiffies_init, j, 151 can_stats->total_rx_rate = calc_rate(can_stats->jiffies_init, j,
148 can_stats.rx_frames); 152 can_stats->rx_frames);
149 153
150 /* calc current values */ 154 /* calc current values */
151 if (can_stats.rx_frames_delta) 155 if (can_stats->rx_frames_delta)
152 can_stats.current_rx_match_ratio = 156 can_stats->current_rx_match_ratio =
153 (can_stats.matches_delta * 100) / 157 (can_stats->matches_delta * 100) /
154 can_stats.rx_frames_delta; 158 can_stats->rx_frames_delta;
155 159
156 can_stats.current_tx_rate = calc_rate(0, HZ, can_stats.tx_frames_delta); 160 can_stats->current_tx_rate = calc_rate(0, HZ, can_stats->tx_frames_delta);
157 can_stats.current_rx_rate = calc_rate(0, HZ, can_stats.rx_frames_delta); 161 can_stats->current_rx_rate = calc_rate(0, HZ, can_stats->rx_frames_delta);
158 162
159 /* check / update maximum values */ 163 /* check / update maximum values */
160 if (can_stats.max_tx_rate < can_stats.current_tx_rate) 164 if (can_stats->max_tx_rate < can_stats->current_tx_rate)
161 can_stats.max_tx_rate = can_stats.current_tx_rate; 165 can_stats->max_tx_rate = can_stats->current_tx_rate;
162 166
163 if (can_stats.max_rx_rate < can_stats.current_rx_rate) 167 if (can_stats->max_rx_rate < can_stats->current_rx_rate)
164 can_stats.max_rx_rate = can_stats.current_rx_rate; 168 can_stats->max_rx_rate = can_stats->current_rx_rate;
165 169
166 if (can_stats.max_rx_match_ratio < can_stats.current_rx_match_ratio) 170 if (can_stats->max_rx_match_ratio < can_stats->current_rx_match_ratio)
167 can_stats.max_rx_match_ratio = can_stats.current_rx_match_ratio; 171 can_stats->max_rx_match_ratio = can_stats->current_rx_match_ratio;
168 172
169 /* clear values for 'current rate' calculation */ 173 /* clear values for 'current rate' calculation */
170 can_stats.tx_frames_delta = 0; 174 can_stats->tx_frames_delta = 0;
171 can_stats.rx_frames_delta = 0; 175 can_stats->rx_frames_delta = 0;
172 can_stats.matches_delta = 0; 176 can_stats->matches_delta = 0;
173 177
174 /* restart timer (one second) */ 178 /* restart timer (one second) */
175 mod_timer(&can_stattimer, round_jiffies(jiffies + HZ)); 179 mod_timer(&net->can.can_stattimer, round_jiffies(jiffies + HZ));
176} 180}
177 181
178/* 182/*
@@ -206,57 +210,61 @@ static void can_print_recv_banner(struct seq_file *m)
206 210
207static int can_stats_proc_show(struct seq_file *m, void *v) 211static int can_stats_proc_show(struct seq_file *m, void *v)
208{ 212{
213 struct net *net = m->private;
214 struct s_stats *can_stats = net->can.can_stats;
215 struct s_pstats *can_pstats = net->can.can_pstats;
216
209 seq_putc(m, '\n'); 217 seq_putc(m, '\n');
210 seq_printf(m, " %8ld transmitted frames (TXF)\n", can_stats.tx_frames); 218 seq_printf(m, " %8ld transmitted frames (TXF)\n", can_stats->tx_frames);
211 seq_printf(m, " %8ld received frames (RXF)\n", can_stats.rx_frames); 219 seq_printf(m, " %8ld received frames (RXF)\n", can_stats->rx_frames);
212 seq_printf(m, " %8ld matched frames (RXMF)\n", can_stats.matches); 220 seq_printf(m, " %8ld matched frames (RXMF)\n", can_stats->matches);
213 221
214 seq_putc(m, '\n'); 222 seq_putc(m, '\n');
215 223
216 if (can_stattimer.function == can_stat_update) { 224 if (net->can.can_stattimer.function == can_stat_update) {
217 seq_printf(m, " %8ld %% total match ratio (RXMR)\n", 225 seq_printf(m, " %8ld %% total match ratio (RXMR)\n",
218 can_stats.total_rx_match_ratio); 226 can_stats->total_rx_match_ratio);
219 227
220 seq_printf(m, " %8ld frames/s total tx rate (TXR)\n", 228 seq_printf(m, " %8ld frames/s total tx rate (TXR)\n",
221 can_stats.total_tx_rate); 229 can_stats->total_tx_rate);
222 seq_printf(m, " %8ld frames/s total rx rate (RXR)\n", 230 seq_printf(m, " %8ld frames/s total rx rate (RXR)\n",
223 can_stats.total_rx_rate); 231 can_stats->total_rx_rate);
224 232
225 seq_putc(m, '\n'); 233 seq_putc(m, '\n');
226 234
227 seq_printf(m, " %8ld %% current match ratio (CRXMR)\n", 235 seq_printf(m, " %8ld %% current match ratio (CRXMR)\n",
228 can_stats.current_rx_match_ratio); 236 can_stats->current_rx_match_ratio);
229 237
230 seq_printf(m, " %8ld frames/s current tx rate (CTXR)\n", 238 seq_printf(m, " %8ld frames/s current tx rate (CTXR)\n",
231 can_stats.current_tx_rate); 239 can_stats->current_tx_rate);
232 seq_printf(m, " %8ld frames/s current rx rate (CRXR)\n", 240 seq_printf(m, " %8ld frames/s current rx rate (CRXR)\n",
233 can_stats.current_rx_rate); 241 can_stats->current_rx_rate);
234 242
235 seq_putc(m, '\n'); 243 seq_putc(m, '\n');
236 244
237 seq_printf(m, " %8ld %% max match ratio (MRXMR)\n", 245 seq_printf(m, " %8ld %% max match ratio (MRXMR)\n",
238 can_stats.max_rx_match_ratio); 246 can_stats->max_rx_match_ratio);
239 247
240 seq_printf(m, " %8ld frames/s max tx rate (MTXR)\n", 248 seq_printf(m, " %8ld frames/s max tx rate (MTXR)\n",
241 can_stats.max_tx_rate); 249 can_stats->max_tx_rate);
242 seq_printf(m, " %8ld frames/s max rx rate (MRXR)\n", 250 seq_printf(m, " %8ld frames/s max rx rate (MRXR)\n",
243 can_stats.max_rx_rate); 251 can_stats->max_rx_rate);
244 252
245 seq_putc(m, '\n'); 253 seq_putc(m, '\n');
246 } 254 }
247 255
248 seq_printf(m, " %8ld current receive list entries (CRCV)\n", 256 seq_printf(m, " %8ld current receive list entries (CRCV)\n",
249 can_pstats.rcv_entries); 257 can_pstats->rcv_entries);
250 seq_printf(m, " %8ld maximum receive list entries (MRCV)\n", 258 seq_printf(m, " %8ld maximum receive list entries (MRCV)\n",
251 can_pstats.rcv_entries_max); 259 can_pstats->rcv_entries_max);
252 260
253 if (can_pstats.stats_reset) 261 if (can_pstats->stats_reset)
254 seq_printf(m, "\n %8ld statistic resets (STR)\n", 262 seq_printf(m, "\n %8ld statistic resets (STR)\n",
255 can_pstats.stats_reset); 263 can_pstats->stats_reset);
256 264
257 if (can_pstats.user_reset) 265 if (can_pstats->user_reset)
258 seq_printf(m, " %8ld user statistic resets (USTR)\n", 266 seq_printf(m, " %8ld user statistic resets (USTR)\n",
259 can_pstats.user_reset); 267 can_pstats->user_reset);
260 268
261 seq_putc(m, '\n'); 269 seq_putc(m, '\n');
262 return 0; 270 return 0;
@@ -264,7 +272,7 @@ static int can_stats_proc_show(struct seq_file *m, void *v)
264 272
265static int can_stats_proc_open(struct inode *inode, struct file *file) 273static int can_stats_proc_open(struct inode *inode, struct file *file)
266{ 274{
267 return single_open(file, can_stats_proc_show, NULL); 275 return single_open_net(inode, file, can_stats_proc_show);
268} 276}
269 277
270static const struct file_operations can_stats_proc_fops = { 278static const struct file_operations can_stats_proc_fops = {
@@ -277,25 +285,28 @@ static const struct file_operations can_stats_proc_fops = {
277 285
278static int can_reset_stats_proc_show(struct seq_file *m, void *v) 286static int can_reset_stats_proc_show(struct seq_file *m, void *v)
279{ 287{
288 struct net *net = m->private;
289 struct s_pstats *can_pstats = net->can.can_pstats;
290 struct s_stats *can_stats = net->can.can_stats;
291
280 user_reset = 1; 292 user_reset = 1;
281 293
282 if (can_stattimer.function == can_stat_update) { 294 if (net->can.can_stattimer.function == can_stat_update) {
283 seq_printf(m, "Scheduled statistic reset #%ld.\n", 295 seq_printf(m, "Scheduled statistic reset #%ld.\n",
284 can_pstats.stats_reset + 1); 296 can_pstats->stats_reset + 1);
285
286 } else { 297 } else {
287 if (can_stats.jiffies_init != jiffies) 298 if (can_stats->jiffies_init != jiffies)
288 can_init_stats(); 299 can_init_stats(net);
289 300
290 seq_printf(m, "Performed statistic reset #%ld.\n", 301 seq_printf(m, "Performed statistic reset #%ld.\n",
291 can_pstats.stats_reset); 302 can_pstats->stats_reset);
292 } 303 }
293 return 0; 304 return 0;
294} 305}
295 306
296static int can_reset_stats_proc_open(struct inode *inode, struct file *file) 307static int can_reset_stats_proc_open(struct inode *inode, struct file *file)
297{ 308{
298 return single_open(file, can_reset_stats_proc_show, NULL); 309 return single_open_net(inode, file, can_reset_stats_proc_show);
299} 310}
300 311
301static const struct file_operations can_reset_stats_proc_fops = { 312static const struct file_operations can_reset_stats_proc_fops = {
@@ -314,7 +325,7 @@ static int can_version_proc_show(struct seq_file *m, void *v)
314 325
315static int can_version_proc_open(struct inode *inode, struct file *file) 326static int can_version_proc_open(struct inode *inode, struct file *file)
316{ 327{
317 return single_open(file, can_version_proc_show, NULL); 328 return single_open_net(inode, file, can_version_proc_show);
318} 329}
319 330
320static const struct file_operations can_version_proc_fops = { 331static const struct file_operations can_version_proc_fops = {