@@ -41,6 +41,47 @@ ice_repr_get_phys_port_name(struct net_device *netdev, char *buf, size_t len)
4141 return 0 ;
4242}
4343
44+ /**
45+ * ice_repr_inc_tx_stats - increment Tx statistic by one packet
46+ * @repr: repr to increment stats on
47+ * @len: length of the packet
48+ * @xmit_status: value returned by xmit function
49+ */
50+ void ice_repr_inc_tx_stats (struct ice_repr * repr , unsigned int len ,
51+ int xmit_status )
52+ {
53+ struct ice_repr_pcpu_stats * stats ;
54+
55+ if (unlikely (xmit_status != NET_XMIT_SUCCESS &&
56+ xmit_status != NET_XMIT_CN )) {
57+ this_cpu_inc (repr -> stats -> tx_drops );
58+ return ;
59+ }
60+
61+ stats = this_cpu_ptr (repr -> stats );
62+ u64_stats_update_begin (& stats -> syncp );
63+ stats -> tx_packets ++ ;
64+ stats -> tx_bytes += len ;
65+ u64_stats_update_end (& stats -> syncp );
66+ }
67+
68+ /**
69+ * ice_repr_inc_rx_stats - increment Rx statistic by one packet
70+ * @netdev: repr netdev to increment stats on
71+ * @len: length of the packet
72+ */
73+ void ice_repr_inc_rx_stats (struct net_device * netdev , unsigned int len )
74+ {
75+ struct ice_repr * repr = ice_netdev_to_repr (netdev );
76+ struct ice_repr_pcpu_stats * stats ;
77+
78+ stats = this_cpu_ptr (repr -> stats );
79+ u64_stats_update_begin (& stats -> syncp );
80+ stats -> rx_packets ++ ;
81+ stats -> rx_bytes += len ;
82+ u64_stats_update_end (& stats -> syncp );
83+ }
84+
4485/**
4586 * ice_repr_get_stats64 - get VF stats for VFPR use
4687 * @netdev: pointer to port representor netdev
@@ -76,7 +117,7 @@ ice_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
76117 * ice_netdev_to_repr - Get port representor for given netdevice
77118 * @netdev: pointer to port representor netdev
78119 */
79- struct ice_repr * ice_netdev_to_repr (struct net_device * netdev )
120+ struct ice_repr * ice_netdev_to_repr (const struct net_device * netdev )
80121{
81122 struct ice_netdev_priv * np = netdev_priv (netdev );
82123
@@ -139,38 +180,35 @@ static int ice_repr_stop(struct net_device *netdev)
139180 * ice_repr_sp_stats64 - get slow path stats for port representor
140181 * @dev: network interface device structure
141182 * @stats: netlink stats structure
142- *
143- * RX/TX stats are being swapped here to be consistent with VF stats. In slow
144- * path, port representor receives data when the corresponding VF is sending it
145- * (and vice versa), TX and RX bytes/packets are effectively swapped on port
146- * representor.
147183 */
148184static int
149185ice_repr_sp_stats64 (const struct net_device * dev ,
150186 struct rtnl_link_stats64 * stats )
151187{
152- struct ice_netdev_priv * np = netdev_priv (dev );
153- int vf_id = np -> repr -> vf -> vf_id ;
154- struct ice_tx_ring * tx_ring ;
155- struct ice_rx_ring * rx_ring ;
156- u64 pkts , bytes ;
157-
158- tx_ring = np -> vsi -> tx_rings [vf_id ];
159- ice_fetch_u64_stats_per_ring (& tx_ring -> ring_stats -> syncp ,
160- tx_ring -> ring_stats -> stats ,
161- & pkts , & bytes );
162- stats -> rx_packets = pkts ;
163- stats -> rx_bytes = bytes ;
164-
165- rx_ring = np -> vsi -> rx_rings [vf_id ];
166- ice_fetch_u64_stats_per_ring (& rx_ring -> ring_stats -> syncp ,
167- rx_ring -> ring_stats -> stats ,
168- & pkts , & bytes );
169- stats -> tx_packets = pkts ;
170- stats -> tx_bytes = bytes ;
171- stats -> tx_dropped = rx_ring -> ring_stats -> rx_stats .alloc_page_failed +
172- rx_ring -> ring_stats -> rx_stats .alloc_buf_failed ;
173-
188+ struct ice_repr * repr = ice_netdev_to_repr (dev );
189+ int i ;
190+
191+ for_each_possible_cpu (i ) {
192+ u64 tbytes , tpkts , tdrops , rbytes , rpkts ;
193+ struct ice_repr_pcpu_stats * repr_stats ;
194+ unsigned int start ;
195+
196+ repr_stats = per_cpu_ptr (repr -> stats , i );
197+ do {
198+ start = u64_stats_fetch_begin (& repr_stats -> syncp );
199+ tbytes = repr_stats -> tx_bytes ;
200+ tpkts = repr_stats -> tx_packets ;
201+ tdrops = repr_stats -> tx_drops ;
202+ rbytes = repr_stats -> rx_bytes ;
203+ rpkts = repr_stats -> rx_packets ;
204+ } while (u64_stats_fetch_retry (& repr_stats -> syncp , start ));
205+
206+ stats -> tx_bytes += tbytes ;
207+ stats -> tx_packets += tpkts ;
208+ stats -> tx_dropped += tdrops ;
209+ stats -> rx_bytes += rbytes ;
210+ stats -> rx_packets += rpkts ;
211+ }
174212 return 0 ;
175213}
176214
@@ -291,6 +329,7 @@ static void ice_repr_remove_node(struct devlink_port *devlink_port)
291329 */
292330static void ice_repr_rem (struct ice_repr * repr )
293331{
332+ free_percpu (repr -> stats );
294333 free_netdev (repr -> netdev );
295334 kfree (repr );
296335}
@@ -344,6 +383,12 @@ ice_repr_add(struct ice_pf *pf, struct ice_vsi *src_vsi, const u8 *parent_mac)
344383 goto err_alloc ;
345384 }
346385
386+ repr -> stats = netdev_alloc_pcpu_stats (struct ice_repr_pcpu_stats );
387+ if (!repr -> stats ) {
388+ err = - ENOMEM ;
389+ goto err_stats ;
390+ }
391+
347392 repr -> src_vsi = src_vsi ;
348393 repr -> id = src_vsi -> vsi_num ;
349394 np = netdev_priv (repr -> netdev );
@@ -353,6 +398,8 @@ ice_repr_add(struct ice_pf *pf, struct ice_vsi *src_vsi, const u8 *parent_mac)
353398
354399 return repr ;
355400
401+ err_stats :
402+ free_netdev (repr -> netdev );
356403err_alloc :
357404 kfree (repr );
358405 return ERR_PTR (err );
0 commit comments