@@ -708,25 +708,66 @@ netdev_nl_stats_by_queue(struct net_device *netdev, struct sk_buff *rsp,
708
708
return 0 ;
709
709
}
710
710
711
+ /**
712
+ * netdev_stat_queue_sum() - add up queue stats from range of queues
713
+ * @netdev: net_device
714
+ * @rx_start: index of the first Rx queue to query
715
+ * @rx_end: index after the last Rx queue (first *not* to query)
716
+ * @rx_sum: output Rx stats, should be already initialized
717
+ * @tx_start: index of the first Tx queue to query
718
+ * @tx_end: index after the last Tx queue (first *not* to query)
719
+ * @tx_sum: output Tx stats, should be already initialized
720
+ *
721
+ * Add stats from [start, end) range of queue IDs to *x_sum structs.
722
+ * The sum structs must be already initialized. Usually this
723
+ * helper is invoked from the .get_base_stats callbacks of drivers
724
+ * to account for stats of disabled queues. In that case the ranges
725
+ * are usually [netdev->real_num_*x_queues, netdev->num_*x_queues).
726
+ */
727
+ void netdev_stat_queue_sum (struct net_device * netdev ,
728
+ int rx_start , int rx_end ,
729
+ struct netdev_queue_stats_rx * rx_sum ,
730
+ int tx_start , int tx_end ,
731
+ struct netdev_queue_stats_tx * tx_sum )
732
+ {
733
+ const struct netdev_stat_ops * ops ;
734
+ struct netdev_queue_stats_rx rx ;
735
+ struct netdev_queue_stats_tx tx ;
736
+ int i ;
737
+
738
+ ops = netdev -> stat_ops ;
739
+
740
+ for (i = rx_start ; i < rx_end ; i ++ ) {
741
+ memset (& rx , 0xff , sizeof (rx ));
742
+ if (ops -> get_queue_stats_rx )
743
+ ops -> get_queue_stats_rx (netdev , i , & rx );
744
+ netdev_nl_stats_add (rx_sum , & rx , sizeof (rx ));
745
+ }
746
+ for (i = tx_start ; i < tx_end ; i ++ ) {
747
+ memset (& tx , 0xff , sizeof (tx ));
748
+ if (ops -> get_queue_stats_tx )
749
+ ops -> get_queue_stats_tx (netdev , i , & tx );
750
+ netdev_nl_stats_add (tx_sum , & tx , sizeof (tx ));
751
+ }
752
+ }
753
+ EXPORT_SYMBOL (netdev_stat_queue_sum );
754
+
711
755
static int
712
756
netdev_nl_stats_by_netdev (struct net_device * netdev , struct sk_buff * rsp ,
713
757
const struct genl_info * info )
714
758
{
715
- struct netdev_queue_stats_rx rx_sum , rx ;
716
- struct netdev_queue_stats_tx tx_sum , tx ;
717
- const struct netdev_stat_ops * ops ;
759
+ struct netdev_queue_stats_rx rx_sum ;
760
+ struct netdev_queue_stats_tx tx_sum ;
718
761
void * hdr ;
719
- int i ;
720
762
721
- ops = netdev -> stat_ops ;
722
763
/* Netdev can't guarantee any complete counters */
723
- if (!ops -> get_base_stats )
764
+ if (!netdev -> stat_ops -> get_base_stats )
724
765
return 0 ;
725
766
726
767
memset (& rx_sum , 0xff , sizeof (rx_sum ));
727
768
memset (& tx_sum , 0xff , sizeof (tx_sum ));
728
769
729
- ops -> get_base_stats (netdev , & rx_sum , & tx_sum );
770
+ netdev -> stat_ops -> get_base_stats (netdev , & rx_sum , & tx_sum );
730
771
731
772
/* The op was there, but nothing reported, don't bother */
732
773
if (!memchr_inv (& rx_sum , 0xff , sizeof (rx_sum )) &&
@@ -739,18 +780,8 @@ netdev_nl_stats_by_netdev(struct net_device *netdev, struct sk_buff *rsp,
739
780
if (nla_put_u32 (rsp , NETDEV_A_QSTATS_IFINDEX , netdev -> ifindex ))
740
781
goto nla_put_failure ;
741
782
742
- for (i = 0 ; i < netdev -> real_num_rx_queues ; i ++ ) {
743
- memset (& rx , 0xff , sizeof (rx ));
744
- if (ops -> get_queue_stats_rx )
745
- ops -> get_queue_stats_rx (netdev , i , & rx );
746
- netdev_nl_stats_add (& rx_sum , & rx , sizeof (rx ));
747
- }
748
- for (i = 0 ; i < netdev -> real_num_tx_queues ; i ++ ) {
749
- memset (& tx , 0xff , sizeof (tx ));
750
- if (ops -> get_queue_stats_tx )
751
- ops -> get_queue_stats_tx (netdev , i , & tx );
752
- netdev_nl_stats_add (& tx_sum , & tx , sizeof (tx ));
753
- }
783
+ netdev_stat_queue_sum (netdev , 0 , netdev -> real_num_rx_queues , & rx_sum ,
784
+ 0 , netdev -> real_num_tx_queues , & tx_sum );
754
785
755
786
if (netdev_nl_stats_write_rx (rsp , & rx_sum ) ||
756
787
netdev_nl_stats_write_tx (rsp , & tx_sum ))
0 commit comments