aboutsummaryrefslogtreecommitdiffstats
path: root/net/can/proc.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-09-05 06:17:50 -0400
committerDavid S. Miller <davem@davemloft.net>2019-09-05 06:17:50 -0400
commit44c40910b66f786d33ffd2682ef38750eebb567c (patch)
tree69b08b2eb39c5d39996d2e29016a31874381be01 /net/can/proc.c
parent8330f73fe9742f201f467639f8356cf58756fb9f (diff)
parent9d71dd0c70099914fcd063135da3c580865e924c (diff)
Merge tag 'linux-can-next-for-5.4-20190904' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next
Marc Kleine-Budde says: ==================== pull-request: can-next 2019-09-04 j1939 this is a pull request for net-next/master consisting of 21 patches. the first 12 patches are by me and target the CAN core infrastructure. They clean up the names of variables , structs and struct members, convert can_rx_register() to use max() instead of open coding it and remove unneeded code from the can_pernet_exit() callback. The next three patches are also by me and they introduce and make use of the CAN midlayer private structure. It is used to hold protocol specific per device data structures. The next patch is by Oleksij Rempel, switches the &net->can.rcvlists_lock from a spin_lock() to a spin_lock_bh(), so that it can be used from NAPI (soft IRQ) context. The next 4 patches are by Kurt Van Dijck, he first updates his email address via mailmap and then extends sockaddr_can to include j1939 members. The final patch is the collective effort of many entities (The j1939 authors: Oliver Hartkopp, Bastian Stender, Elenita Hinds, kbuild test robot, Kurt Van Dijck, Maxime Jayat, Robin van der Gracht, Oleksij Rempel, Marc Kleine-Budde). It adds support of SAE J1939 protocol to the CAN networking stack. SAE J1939 is the vehicle bus recommended practice used for communication and diagnostics among vehicle components. Originating in the car and heavy-duty truck industry in the United States, it is now widely used in other parts of the world. P.S.: This pull request doesn't invalidate my last pull request: "pull-request: can-next 2019-09-03". ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/can/proc.c')
-rw-r--r--net/can/proc.c163
1 files changed, 83 insertions, 80 deletions
diff --git a/net/can/proc.c b/net/can/proc.c
index edb822c31902..e6881bfc3ed1 100644
--- a/net/can/proc.c
+++ b/net/can/proc.c
@@ -45,6 +45,7 @@
45#include <linux/list.h> 45#include <linux/list.h>
46#include <linux/rcupdate.h> 46#include <linux/rcupdate.h>
47#include <linux/if_arp.h> 47#include <linux/if_arp.h>
48#include <linux/can/can-ml.h>
48#include <linux/can/core.h> 49#include <linux/can/core.h>
49 50
50#include "af_can.h" 51#include "af_can.h"
@@ -78,21 +79,21 @@ static const char rx_list_name[][8] = {
78 79
79static void can_init_stats(struct net *net) 80static void can_init_stats(struct net *net)
80{ 81{
81 struct s_stats *can_stats = net->can.can_stats; 82 struct can_pkg_stats *pkg_stats = net->can.pkg_stats;
82 struct s_pstats *can_pstats = net->can.can_pstats; 83 struct can_rcv_lists_stats *rcv_lists_stats = net->can.rcv_lists_stats;
83 /* 84 /*
84 * This memset function is called from a timer context (when 85 * This memset function is called from a timer context (when
85 * can_stattimer is active which is the default) OR in a process 86 * can_stattimer is active which is the default) OR in a process
86 * context (reading the proc_fs when can_stattimer is disabled). 87 * context (reading the proc_fs when can_stattimer is disabled).
87 */ 88 */
88 memset(can_stats, 0, sizeof(struct s_stats)); 89 memset(pkg_stats, 0, sizeof(struct can_pkg_stats));
89 can_stats->jiffies_init = jiffies; 90 pkg_stats->jiffies_init = jiffies;
90 91
91 can_pstats->stats_reset++; 92 rcv_lists_stats->stats_reset++;
92 93
93 if (user_reset) { 94 if (user_reset) {
94 user_reset = 0; 95 user_reset = 0;
95 can_pstats->user_reset++; 96 rcv_lists_stats->user_reset++;
96 } 97 }
97} 98}
98 99
@@ -118,8 +119,8 @@ static unsigned long calc_rate(unsigned long oldjif, unsigned long newjif,
118 119
119void can_stat_update(struct timer_list *t) 120void can_stat_update(struct timer_list *t)
120{ 121{
121 struct net *net = from_timer(net, t, can.can_stattimer); 122 struct net *net = from_timer(net, t, can.stattimer);
122 struct s_stats *can_stats = net->can.can_stats; 123 struct can_pkg_stats *pkg_stats = net->can.pkg_stats;
123 unsigned long j = jiffies; /* snapshot */ 124 unsigned long j = jiffies; /* snapshot */
124 125
125 /* restart counting in timer context on user request */ 126 /* restart counting in timer context on user request */
@@ -127,57 +128,57 @@ void can_stat_update(struct timer_list *t)
127 can_init_stats(net); 128 can_init_stats(net);
128 129
129 /* restart counting on jiffies overflow */ 130 /* restart counting on jiffies overflow */
130 if (j < can_stats->jiffies_init) 131 if (j < pkg_stats->jiffies_init)
131 can_init_stats(net); 132 can_init_stats(net);
132 133
133 /* prevent overflow in calc_rate() */ 134 /* prevent overflow in calc_rate() */
134 if (can_stats->rx_frames > (ULONG_MAX / HZ)) 135 if (pkg_stats->rx_frames > (ULONG_MAX / HZ))
135 can_init_stats(net); 136 can_init_stats(net);
136 137
137 /* prevent overflow in calc_rate() */ 138 /* prevent overflow in calc_rate() */
138 if (can_stats->tx_frames > (ULONG_MAX / HZ)) 139 if (pkg_stats->tx_frames > (ULONG_MAX / HZ))
139 can_init_stats(net); 140 can_init_stats(net);
140 141
141 /* matches overflow - very improbable */ 142 /* matches overflow - very improbable */
142 if (can_stats->matches > (ULONG_MAX / 100)) 143 if (pkg_stats->matches > (ULONG_MAX / 100))
143 can_init_stats(net); 144 can_init_stats(net);
144 145
145 /* calc total values */ 146 /* calc total values */
146 if (can_stats->rx_frames) 147 if (pkg_stats->rx_frames)
147 can_stats->total_rx_match_ratio = (can_stats->matches * 100) / 148 pkg_stats->total_rx_match_ratio = (pkg_stats->matches * 100) /
148 can_stats->rx_frames; 149 pkg_stats->rx_frames;
149 150
150 can_stats->total_tx_rate = calc_rate(can_stats->jiffies_init, j, 151 pkg_stats->total_tx_rate = calc_rate(pkg_stats->jiffies_init, j,
151 can_stats->tx_frames); 152 pkg_stats->tx_frames);
152 can_stats->total_rx_rate = calc_rate(can_stats->jiffies_init, j, 153 pkg_stats->total_rx_rate = calc_rate(pkg_stats->jiffies_init, j,
153 can_stats->rx_frames); 154 pkg_stats->rx_frames);
154 155
155 /* calc current values */ 156 /* calc current values */
156 if (can_stats->rx_frames_delta) 157 if (pkg_stats->rx_frames_delta)
157 can_stats->current_rx_match_ratio = 158 pkg_stats->current_rx_match_ratio =
158 (can_stats->matches_delta * 100) / 159 (pkg_stats->matches_delta * 100) /
159 can_stats->rx_frames_delta; 160 pkg_stats->rx_frames_delta;
160 161
161 can_stats->current_tx_rate = calc_rate(0, HZ, can_stats->tx_frames_delta); 162 pkg_stats->current_tx_rate = calc_rate(0, HZ, pkg_stats->tx_frames_delta);
162 can_stats->current_rx_rate = calc_rate(0, HZ, can_stats->rx_frames_delta); 163 pkg_stats->current_rx_rate = calc_rate(0, HZ, pkg_stats->rx_frames_delta);
163 164
164 /* check / update maximum values */ 165 /* check / update maximum values */
165 if (can_stats->max_tx_rate < can_stats->current_tx_rate) 166 if (pkg_stats->max_tx_rate < pkg_stats->current_tx_rate)
166 can_stats->max_tx_rate = can_stats->current_tx_rate; 167 pkg_stats->max_tx_rate = pkg_stats->current_tx_rate;
167 168
168 if (can_stats->max_rx_rate < can_stats->current_rx_rate) 169 if (pkg_stats->max_rx_rate < pkg_stats->current_rx_rate)
169 can_stats->max_rx_rate = can_stats->current_rx_rate; 170 pkg_stats->max_rx_rate = pkg_stats->current_rx_rate;
170 171
171 if (can_stats->max_rx_match_ratio < can_stats->current_rx_match_ratio) 172 if (pkg_stats->max_rx_match_ratio < pkg_stats->current_rx_match_ratio)
172 can_stats->max_rx_match_ratio = can_stats->current_rx_match_ratio; 173 pkg_stats->max_rx_match_ratio = pkg_stats->current_rx_match_ratio;
173 174
174 /* clear values for 'current rate' calculation */ 175 /* clear values for 'current rate' calculation */
175 can_stats->tx_frames_delta = 0; 176 pkg_stats->tx_frames_delta = 0;
176 can_stats->rx_frames_delta = 0; 177 pkg_stats->rx_frames_delta = 0;
177 can_stats->matches_delta = 0; 178 pkg_stats->matches_delta = 0;
178 179
179 /* restart timer (one second) */ 180 /* restart timer (one second) */
180 mod_timer(&net->can.can_stattimer, round_jiffies(jiffies + HZ)); 181 mod_timer(&net->can.stattimer, round_jiffies(jiffies + HZ));
181} 182}
182 183
183/* 184/*
@@ -212,60 +213,60 @@ static void can_print_recv_banner(struct seq_file *m)
212static int can_stats_proc_show(struct seq_file *m, void *v) 213static int can_stats_proc_show(struct seq_file *m, void *v)
213{ 214{
214 struct net *net = m->private; 215 struct net *net = m->private;
215 struct s_stats *can_stats = net->can.can_stats; 216 struct can_pkg_stats *pkg_stats = net->can.pkg_stats;
216 struct s_pstats *can_pstats = net->can.can_pstats; 217 struct can_rcv_lists_stats *rcv_lists_stats = net->can.rcv_lists_stats;
217 218
218 seq_putc(m, '\n'); 219 seq_putc(m, '\n');
219 seq_printf(m, " %8ld transmitted frames (TXF)\n", can_stats->tx_frames); 220 seq_printf(m, " %8ld transmitted frames (TXF)\n", pkg_stats->tx_frames);
220 seq_printf(m, " %8ld received frames (RXF)\n", can_stats->rx_frames); 221 seq_printf(m, " %8ld received frames (RXF)\n", pkg_stats->rx_frames);
221 seq_printf(m, " %8ld matched frames (RXMF)\n", can_stats->matches); 222 seq_printf(m, " %8ld matched frames (RXMF)\n", pkg_stats->matches);
222 223
223 seq_putc(m, '\n'); 224 seq_putc(m, '\n');
224 225
225 if (net->can.can_stattimer.function == can_stat_update) { 226 if (net->can.stattimer.function == can_stat_update) {
226 seq_printf(m, " %8ld %% total match ratio (RXMR)\n", 227 seq_printf(m, " %8ld %% total match ratio (RXMR)\n",
227 can_stats->total_rx_match_ratio); 228 pkg_stats->total_rx_match_ratio);
228 229
229 seq_printf(m, " %8ld frames/s total tx rate (TXR)\n", 230 seq_printf(m, " %8ld frames/s total tx rate (TXR)\n",
230 can_stats->total_tx_rate); 231 pkg_stats->total_tx_rate);
231 seq_printf(m, " %8ld frames/s total rx rate (RXR)\n", 232 seq_printf(m, " %8ld frames/s total rx rate (RXR)\n",
232 can_stats->total_rx_rate); 233 pkg_stats->total_rx_rate);
233 234
234 seq_putc(m, '\n'); 235 seq_putc(m, '\n');
235 236
236 seq_printf(m, " %8ld %% current match ratio (CRXMR)\n", 237 seq_printf(m, " %8ld %% current match ratio (CRXMR)\n",
237 can_stats->current_rx_match_ratio); 238 pkg_stats->current_rx_match_ratio);
238 239
239 seq_printf(m, " %8ld frames/s current tx rate (CTXR)\n", 240 seq_printf(m, " %8ld frames/s current tx rate (CTXR)\n",
240 can_stats->current_tx_rate); 241 pkg_stats->current_tx_rate);
241 seq_printf(m, " %8ld frames/s current rx rate (CRXR)\n", 242 seq_printf(m, " %8ld frames/s current rx rate (CRXR)\n",
242 can_stats->current_rx_rate); 243 pkg_stats->current_rx_rate);
243 244
244 seq_putc(m, '\n'); 245 seq_putc(m, '\n');
245 246
246 seq_printf(m, " %8ld %% max match ratio (MRXMR)\n", 247 seq_printf(m, " %8ld %% max match ratio (MRXMR)\n",
247 can_stats->max_rx_match_ratio); 248 pkg_stats->max_rx_match_ratio);
248 249
249 seq_printf(m, " %8ld frames/s max tx rate (MTXR)\n", 250 seq_printf(m, " %8ld frames/s max tx rate (MTXR)\n",
250 can_stats->max_tx_rate); 251 pkg_stats->max_tx_rate);
251 seq_printf(m, " %8ld frames/s max rx rate (MRXR)\n", 252 seq_printf(m, " %8ld frames/s max rx rate (MRXR)\n",
252 can_stats->max_rx_rate); 253 pkg_stats->max_rx_rate);
253 254
254 seq_putc(m, '\n'); 255 seq_putc(m, '\n');
255 } 256 }
256 257
257 seq_printf(m, " %8ld current receive list entries (CRCV)\n", 258 seq_printf(m, " %8ld current receive list entries (CRCV)\n",
258 can_pstats->rcv_entries); 259 rcv_lists_stats->rcv_entries);
259 seq_printf(m, " %8ld maximum receive list entries (MRCV)\n", 260 seq_printf(m, " %8ld maximum receive list entries (MRCV)\n",
260 can_pstats->rcv_entries_max); 261 rcv_lists_stats->rcv_entries_max);
261 262
262 if (can_pstats->stats_reset) 263 if (rcv_lists_stats->stats_reset)
263 seq_printf(m, "\n %8ld statistic resets (STR)\n", 264 seq_printf(m, "\n %8ld statistic resets (STR)\n",
264 can_pstats->stats_reset); 265 rcv_lists_stats->stats_reset);
265 266
266 if (can_pstats->user_reset) 267 if (rcv_lists_stats->user_reset)
267 seq_printf(m, " %8ld user statistic resets (USTR)\n", 268 seq_printf(m, " %8ld user statistic resets (USTR)\n",
268 can_pstats->user_reset); 269 rcv_lists_stats->user_reset);
269 270
270 seq_putc(m, '\n'); 271 seq_putc(m, '\n');
271 return 0; 272 return 0;
@@ -274,20 +275,20 @@ static int can_stats_proc_show(struct seq_file *m, void *v)
274static int can_reset_stats_proc_show(struct seq_file *m, void *v) 275static int can_reset_stats_proc_show(struct seq_file *m, void *v)
275{ 276{
276 struct net *net = m->private; 277 struct net *net = m->private;
277 struct s_pstats *can_pstats = net->can.can_pstats; 278 struct can_rcv_lists_stats *rcv_lists_stats = net->can.rcv_lists_stats;
278 struct s_stats *can_stats = net->can.can_stats; 279 struct can_pkg_stats *pkg_stats = net->can.pkg_stats;
279 280
280 user_reset = 1; 281 user_reset = 1;
281 282
282 if (net->can.can_stattimer.function == can_stat_update) { 283 if (net->can.stattimer.function == can_stat_update) {
283 seq_printf(m, "Scheduled statistic reset #%ld.\n", 284 seq_printf(m, "Scheduled statistic reset #%ld.\n",
284 can_pstats->stats_reset + 1); 285 rcv_lists_stats->stats_reset + 1);
285 } else { 286 } else {
286 if (can_stats->jiffies_init != jiffies) 287 if (pkg_stats->jiffies_init != jiffies)
287 can_init_stats(net); 288 can_init_stats(net);
288 289
289 seq_printf(m, "Performed statistic reset #%ld.\n", 290 seq_printf(m, "Performed statistic reset #%ld.\n",
290 can_pstats->stats_reset); 291 rcv_lists_stats->stats_reset);
291 } 292 }
292 return 0; 293 return 0;
293} 294}
@@ -300,11 +301,11 @@ static int can_version_proc_show(struct seq_file *m, void *v)
300 301
301static inline void can_rcvlist_proc_show_one(struct seq_file *m, int idx, 302static inline void can_rcvlist_proc_show_one(struct seq_file *m, int idx,
302 struct net_device *dev, 303 struct net_device *dev,
303 struct can_dev_rcv_lists *d) 304 struct can_dev_rcv_lists *dev_rcv_lists)
304{ 305{
305 if (!hlist_empty(&d->rx[idx])) { 306 if (!hlist_empty(&dev_rcv_lists->rx[idx])) {
306 can_print_recv_banner(m); 307 can_print_recv_banner(m);
307 can_print_rcvlist(m, &d->rx[idx], dev); 308 can_print_rcvlist(m, &dev_rcv_lists->rx[idx], dev);
308 } else 309 } else
309 seq_printf(m, " (%s: no entry)\n", DNAME(dev)); 310 seq_printf(m, " (%s: no entry)\n", DNAME(dev));
310 311
@@ -315,7 +316,7 @@ static int can_rcvlist_proc_show(struct seq_file *m, void *v)
315 /* double cast to prevent GCC warning */ 316 /* double cast to prevent GCC warning */
316 int idx = (int)(long)PDE_DATA(m->file->f_inode); 317 int idx = (int)(long)PDE_DATA(m->file->f_inode);
317 struct net_device *dev; 318 struct net_device *dev;
318 struct can_dev_rcv_lists *d; 319 struct can_dev_rcv_lists *dev_rcv_lists;
319 struct net *net = m->private; 320 struct net *net = m->private;
320 321
321 seq_printf(m, "\nreceive list '%s':\n", rx_list_name[idx]); 322 seq_printf(m, "\nreceive list '%s':\n", rx_list_name[idx]);
@@ -323,8 +324,8 @@ static int can_rcvlist_proc_show(struct seq_file *m, void *v)
323 rcu_read_lock(); 324 rcu_read_lock();
324 325
325 /* receive list for 'all' CAN devices (dev == NULL) */ 326 /* receive list for 'all' CAN devices (dev == NULL) */
326 d = net->can.can_rx_alldev_list; 327 dev_rcv_lists = net->can.rx_alldev_list;
327 can_rcvlist_proc_show_one(m, idx, NULL, d); 328 can_rcvlist_proc_show_one(m, idx, NULL, dev_rcv_lists);
328 329
329 /* receive list for registered CAN devices */ 330 /* receive list for registered CAN devices */
330 for_each_netdev_rcu(net, dev) { 331 for_each_netdev_rcu(net, dev) {
@@ -366,7 +367,7 @@ static inline void can_rcvlist_proc_show_array(struct seq_file *m,
366static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v) 367static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v)
367{ 368{
368 struct net_device *dev; 369 struct net_device *dev;
369 struct can_dev_rcv_lists *d; 370 struct can_dev_rcv_lists *dev_rcv_lists;
370 struct net *net = m->private; 371 struct net *net = m->private;
371 372
372 /* RX_SFF */ 373 /* RX_SFF */
@@ -375,15 +376,16 @@ static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v)
375 rcu_read_lock(); 376 rcu_read_lock();
376 377
377 /* sff receive list for 'all' CAN devices (dev == NULL) */ 378 /* sff receive list for 'all' CAN devices (dev == NULL) */
378 d = net->can.can_rx_alldev_list; 379 dev_rcv_lists = net->can.rx_alldev_list;
379 can_rcvlist_proc_show_array(m, NULL, d->rx_sff, ARRAY_SIZE(d->rx_sff)); 380 can_rcvlist_proc_show_array(m, NULL, dev_rcv_lists->rx_sff,
381 ARRAY_SIZE(dev_rcv_lists->rx_sff));
380 382
381 /* sff receive list for registered CAN devices */ 383 /* sff receive list for registered CAN devices */
382 for_each_netdev_rcu(net, dev) { 384 for_each_netdev_rcu(net, dev) {
383 if (dev->type == ARPHRD_CAN && dev->ml_priv) { 385 if (dev->type == ARPHRD_CAN && dev->ml_priv) {
384 d = dev->ml_priv; 386 dev_rcv_lists = dev->ml_priv;
385 can_rcvlist_proc_show_array(m, dev, d->rx_sff, 387 can_rcvlist_proc_show_array(m, dev, dev_rcv_lists->rx_sff,
386 ARRAY_SIZE(d->rx_sff)); 388 ARRAY_SIZE(dev_rcv_lists->rx_sff));
387 } 389 }
388 } 390 }
389 391
@@ -396,7 +398,7 @@ static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v)
396static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v) 398static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v)
397{ 399{
398 struct net_device *dev; 400 struct net_device *dev;
399 struct can_dev_rcv_lists *d; 401 struct can_dev_rcv_lists *dev_rcv_lists;
400 struct net *net = m->private; 402 struct net *net = m->private;
401 403
402 /* RX_EFF */ 404 /* RX_EFF */
@@ -405,15 +407,16 @@ static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v)
405 rcu_read_lock(); 407 rcu_read_lock();
406 408
407 /* eff receive list for 'all' CAN devices (dev == NULL) */ 409 /* eff receive list for 'all' CAN devices (dev == NULL) */
408 d = net->can.can_rx_alldev_list; 410 dev_rcv_lists = net->can.rx_alldev_list;
409 can_rcvlist_proc_show_array(m, NULL, d->rx_eff, ARRAY_SIZE(d->rx_eff)); 411 can_rcvlist_proc_show_array(m, NULL, dev_rcv_lists->rx_eff,
412 ARRAY_SIZE(dev_rcv_lists->rx_eff));
410 413
411 /* eff receive list for registered CAN devices */ 414 /* eff receive list for registered CAN devices */
412 for_each_netdev_rcu(net, dev) { 415 for_each_netdev_rcu(net, dev) {
413 if (dev->type == ARPHRD_CAN && dev->ml_priv) { 416 if (dev->type == ARPHRD_CAN && dev->ml_priv) {
414 d = dev->ml_priv; 417 dev_rcv_lists = dev->ml_priv;
415 can_rcvlist_proc_show_array(m, dev, d->rx_eff, 418 can_rcvlist_proc_show_array(m, dev, dev_rcv_lists->rx_eff,
416 ARRAY_SIZE(d->rx_eff)); 419 ARRAY_SIZE(dev_rcv_lists->rx_eff));
417 } 420 }
418 } 421 }
419 422