34
34
#include "vport.h"
35
35
#include "vport-internal_dev.h"
36
36
37
- static void ovs_vport_record_error (struct vport * ,
38
- enum vport_err_type err_type );
39
-
40
37
static LIST_HEAD (vport_ops_list );
41
38
42
39
/* Protected by RCU read lock for reading, ovs_mutex for writing. */
@@ -157,12 +154,6 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops,
157
154
return ERR_PTR (- EINVAL );
158
155
}
159
156
160
- vport -> percpu_stats = netdev_alloc_pcpu_stats (struct pcpu_sw_netstats );
161
- if (!vport -> percpu_stats ) {
162
- kfree (vport );
163
- return ERR_PTR (- ENOMEM );
164
- }
165
-
166
157
return vport ;
167
158
}
168
159
EXPORT_SYMBOL_GPL (ovs_vport_alloc );
@@ -183,7 +174,6 @@ void ovs_vport_free(struct vport *vport)
183
174
* it is safe to use raw dereference.
184
175
*/
185
176
kfree (rcu_dereference_raw (vport -> upcall_portids ));
186
- free_percpu (vport -> percpu_stats );
187
177
kfree (vport );
188
178
}
189
179
EXPORT_SYMBOL_GPL (ovs_vport_free );
@@ -290,30 +280,24 @@ void ovs_vport_del(struct vport *vport)
290
280
*/
291
281
void ovs_vport_get_stats (struct vport * vport , struct ovs_vport_stats * stats )
292
282
{
283
+ struct net_device * dev = vport -> dev ;
293
284
int i ;
294
285
295
286
memset (stats , 0 , sizeof (* stats ));
287
+ stats -> rx_errors = dev -> stats .rx_errors ;
288
+ stats -> tx_errors = dev -> stats .tx_errors ;
289
+ stats -> tx_dropped = dev -> stats .tx_dropped ;
290
+ stats -> rx_dropped = dev -> stats .rx_dropped ;
296
291
297
- /* We potentially have 2 sources of stats that need to be combined:
298
- * those we have collected (split into err_stats and percpu_stats) from
299
- * set_stats() and device error stats from netdev->get_stats() (for
300
- * errors that happen downstream and therefore aren't reported through
301
- * our vport_record_error() function).
302
- * Stats from first source are reported by ovs (OVS_VPORT_ATTR_STATS).
303
- * netdev-stats can be directly read over netlink-ioctl.
304
- */
305
-
306
- stats -> rx_errors = atomic_long_read (& vport -> err_stats .rx_errors );
307
- stats -> tx_errors = atomic_long_read (& vport -> err_stats .tx_errors );
308
- stats -> tx_dropped = atomic_long_read (& vport -> err_stats .tx_dropped );
309
- stats -> rx_dropped = atomic_long_read (& vport -> err_stats .rx_dropped );
292
+ stats -> rx_dropped += atomic_long_read (& dev -> rx_dropped );
293
+ stats -> tx_dropped += atomic_long_read (& dev -> tx_dropped );
310
294
311
295
for_each_possible_cpu (i ) {
312
296
const struct pcpu_sw_netstats * percpu_stats ;
313
297
struct pcpu_sw_netstats local_stats ;
314
298
unsigned int start ;
315
299
316
- percpu_stats = per_cpu_ptr (vport -> percpu_stats , i );
300
+ percpu_stats = per_cpu_ptr (dev -> tstats , i );
317
301
318
302
do {
319
303
start = u64_stats_fetch_begin_irq (& percpu_stats -> syncp );
@@ -468,94 +452,25 @@ u32 ovs_vport_find_upcall_portid(const struct vport *vport, struct sk_buff *skb)
468
452
* Must be called with rcu_read_lock. The packet cannot be shared and
469
453
* skb->data should point to the Ethernet header.
470
454
*/
471
- void ovs_vport_receive (struct vport * vport , struct sk_buff * skb ,
472
- const struct ip_tunnel_info * tun_info )
455
+ int ovs_vport_receive (struct vport * vport , struct sk_buff * skb ,
456
+ const struct ip_tunnel_info * tun_info )
473
457
{
474
- struct pcpu_sw_netstats * stats ;
475
458
struct sw_flow_key key ;
476
459
int error ;
477
460
478
- stats = this_cpu_ptr (vport -> percpu_stats );
479
- u64_stats_update_begin (& stats -> syncp );
480
- stats -> rx_packets ++ ;
481
- stats -> rx_bytes += skb -> len +
482
- (skb_vlan_tag_present (skb ) ? VLAN_HLEN : 0 );
483
- u64_stats_update_end (& stats -> syncp );
484
-
485
461
OVS_CB (skb )-> input_vport = vport ;
486
462
OVS_CB (skb )-> mru = 0 ;
487
463
/* Extract flow from 'skb' into 'key'. */
488
464
error = ovs_flow_key_extract (tun_info , skb , & key );
489
465
if (unlikely (error )) {
490
466
kfree_skb (skb );
491
- return ;
467
+ return error ;
492
468
}
493
469
ovs_dp_process_packet (skb , & key );
470
+ return 0 ;
494
471
}
495
472
EXPORT_SYMBOL_GPL (ovs_vport_receive );
496
473
497
- /**
498
- * ovs_vport_send - send a packet on a device
499
- *
500
- * @vport: vport on which to send the packet
501
- * @skb: skb to send
502
- *
503
- * Sends the given packet and returns the length of data sent. Either ovs
504
- * lock or rcu_read_lock must be held.
505
- */
506
- int ovs_vport_send (struct vport * vport , struct sk_buff * skb )
507
- {
508
- int sent = vport -> ops -> send (vport , skb );
509
-
510
- if (likely (sent > 0 )) {
511
- struct pcpu_sw_netstats * stats ;
512
-
513
- stats = this_cpu_ptr (vport -> percpu_stats );
514
-
515
- u64_stats_update_begin (& stats -> syncp );
516
- stats -> tx_packets ++ ;
517
- stats -> tx_bytes += sent ;
518
- u64_stats_update_end (& stats -> syncp );
519
- } else if (sent < 0 ) {
520
- ovs_vport_record_error (vport , VPORT_E_TX_ERROR );
521
- } else {
522
- ovs_vport_record_error (vport , VPORT_E_TX_DROPPED );
523
- }
524
- return sent ;
525
- }
526
-
527
- /**
528
- * ovs_vport_record_error - indicate device error to generic stats layer
529
- *
530
- * @vport: vport that encountered the error
531
- * @err_type: one of enum vport_err_type types to indicate the error type
532
- *
533
- * If using the vport generic stats layer indicate that an error of the given
534
- * type has occurred.
535
- */
536
- static void ovs_vport_record_error (struct vport * vport ,
537
- enum vport_err_type err_type )
538
- {
539
- switch (err_type ) {
540
- case VPORT_E_RX_DROPPED :
541
- atomic_long_inc (& vport -> err_stats .rx_dropped );
542
- break ;
543
-
544
- case VPORT_E_RX_ERROR :
545
- atomic_long_inc (& vport -> err_stats .rx_errors );
546
- break ;
547
-
548
- case VPORT_E_TX_DROPPED :
549
- atomic_long_inc (& vport -> err_stats .tx_dropped );
550
- break ;
551
-
552
- case VPORT_E_TX_ERROR :
553
- atomic_long_inc (& vport -> err_stats .tx_errors );
554
- break ;
555
- }
556
-
557
- }
558
-
559
474
static void free_vport_rcu (struct rcu_head * rcu )
560
475
{
561
476
struct vport * vport = container_of (rcu , struct vport , rcu );
0 commit comments