Skip to content

Commit 4498159

Browse files
Michal Swiatkowskianguy11
authored andcommitted
ice: count representor stats
Removing control plane VSI result in no information about slow-path statistic. In current solution statistics need to be counted in driver. Patch is based on similar implementation done by Simon Horman in nfp: commit eadfa4c ("nfp: add stats and xmit helpers for representors") Add const modifier to netdev parameter in ice_netdev_to_repr(). It isn't (and shouldn't be) modified in the function. Reviewed-by: Marcin Szycik <[email protected]> Signed-off-by: Michal Swiatkowski <[email protected]> Tested-by: Sujai Buvaneswaran <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 44ba608 commit 4498159

File tree

4 files changed

+98
-30
lines changed

4 files changed

+98
-30
lines changed

drivers/net/ethernet/intel/ice/ice_eswitch.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,13 +192,18 @@ netdev_tx_t
192192
ice_eswitch_port_start_xmit(struct sk_buff *skb, struct net_device *netdev)
193193
{
194194
struct ice_repr *repr = ice_netdev_to_repr(netdev);
195+
unsigned int len = skb->len;
196+
int ret;
195197

196198
skb_dst_drop(skb);
197199
dst_hold((struct dst_entry *)repr->dst);
198200
skb_dst_set(skb, (struct dst_entry *)repr->dst);
199201
skb->dev = repr->dst->u.port_info.lower_dev;
200202

201-
return dev_queue_xmit(skb);
203+
ret = dev_queue_xmit(skb);
204+
ice_repr_inc_tx_stats(repr, len, ret);
205+
206+
return ret;
202207
}
203208

204209
/**

drivers/net/ethernet/intel/ice/ice_repr.c

Lines changed: 75 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/
148184
static int
149185
ice_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
*/
292330
static 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);
356403
err_alloc:
357404
kfree(repr);
358405
return ERR_PTR(err);

drivers/net/ethernet/intel/ice/ice_repr.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,22 @@
66

77
#include <net/dst_metadata.h>
88

9+
struct ice_repr_pcpu_stats {
10+
struct u64_stats_sync syncp;
11+
u64 rx_packets;
12+
u64 rx_bytes;
13+
u64 tx_packets;
14+
u64 tx_bytes;
15+
u64 tx_drops;
16+
};
17+
918
struct ice_repr {
1019
struct ice_vsi *src_vsi;
1120
struct ice_vf *vf;
1221
struct net_device *netdev;
1322
struct metadata_dst *dst;
1423
struct ice_esw_br_port *br_port;
24+
struct ice_repr_pcpu_stats __percpu *stats;
1525
u32 id;
1626
u8 parent_mac[ETH_ALEN];
1727
};
@@ -22,8 +32,12 @@ void ice_repr_rem_vf(struct ice_repr *repr);
2232
void ice_repr_start_tx_queues(struct ice_repr *repr);
2333
void ice_repr_stop_tx_queues(struct ice_repr *repr);
2434

25-
struct ice_repr *ice_netdev_to_repr(struct net_device *netdev);
35+
struct ice_repr *ice_netdev_to_repr(const struct net_device *netdev);
2636
bool ice_is_port_repr_netdev(const struct net_device *netdev);
2737

2838
struct ice_repr *ice_repr_get_by_vsi(struct ice_vsi *vsi);
39+
40+
void ice_repr_inc_tx_stats(struct ice_repr *repr, unsigned int len,
41+
int xmit_status);
42+
void ice_repr_inc_rx_stats(struct net_device *netdev, unsigned int len);
2943
#endif

drivers/net/ethernet/intel/ice/ice_txrx_lib.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@ ice_process_skb_fields(struct ice_rx_ring *rx_ring,
240240
struct net_device *netdev = ice_eswitch_get_target(rx_ring,
241241
rx_desc);
242242

243+
if (ice_is_port_repr_netdev(netdev))
244+
ice_repr_inc_rx_stats(netdev, skb->len);
243245
skb->protocol = eth_type_trans(skb, netdev);
244246
} else {
245247
skb->protocol = eth_type_trans(skb, rx_ring->netdev);

0 commit comments

Comments
 (0)