mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 11:03:43 +02:00
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 eadfa4c3be ("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 <marcin.szycik@linux.intel.com>
Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Tested-by: Sujai Buvaneswaran <sujai.buvaneswaran@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
parent
44ba608db5
commit
4498159a50
|
|
@ -192,13 +192,18 @@ netdev_tx_t
|
|||
ice_eswitch_port_start_xmit(struct sk_buff *skb, struct net_device *netdev)
|
||||
{
|
||||
struct ice_repr *repr = ice_netdev_to_repr(netdev);
|
||||
unsigned int len = skb->len;
|
||||
int ret;
|
||||
|
||||
skb_dst_drop(skb);
|
||||
dst_hold((struct dst_entry *)repr->dst);
|
||||
skb_dst_set(skb, (struct dst_entry *)repr->dst);
|
||||
skb->dev = repr->dst->u.port_info.lower_dev;
|
||||
|
||||
return dev_queue_xmit(skb);
|
||||
ret = dev_queue_xmit(skb);
|
||||
ice_repr_inc_tx_stats(repr, len, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -41,6 +41,47 @@ ice_repr_get_phys_port_name(struct net_device *netdev, char *buf, size_t len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_repr_inc_tx_stats - increment Tx statistic by one packet
|
||||
* @repr: repr to increment stats on
|
||||
* @len: length of the packet
|
||||
* @xmit_status: value returned by xmit function
|
||||
*/
|
||||
void ice_repr_inc_tx_stats(struct ice_repr *repr, unsigned int len,
|
||||
int xmit_status)
|
||||
{
|
||||
struct ice_repr_pcpu_stats *stats;
|
||||
|
||||
if (unlikely(xmit_status != NET_XMIT_SUCCESS &&
|
||||
xmit_status != NET_XMIT_CN)) {
|
||||
this_cpu_inc(repr->stats->tx_drops);
|
||||
return;
|
||||
}
|
||||
|
||||
stats = this_cpu_ptr(repr->stats);
|
||||
u64_stats_update_begin(&stats->syncp);
|
||||
stats->tx_packets++;
|
||||
stats->tx_bytes += len;
|
||||
u64_stats_update_end(&stats->syncp);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_repr_inc_rx_stats - increment Rx statistic by one packet
|
||||
* @netdev: repr netdev to increment stats on
|
||||
* @len: length of the packet
|
||||
*/
|
||||
void ice_repr_inc_rx_stats(struct net_device *netdev, unsigned int len)
|
||||
{
|
||||
struct ice_repr *repr = ice_netdev_to_repr(netdev);
|
||||
struct ice_repr_pcpu_stats *stats;
|
||||
|
||||
stats = this_cpu_ptr(repr->stats);
|
||||
u64_stats_update_begin(&stats->syncp);
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += len;
|
||||
u64_stats_update_end(&stats->syncp);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_repr_get_stats64 - get VF stats for VFPR use
|
||||
* @netdev: pointer to port representor netdev
|
||||
|
|
@ -76,7 +117,7 @@ ice_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
|
|||
* ice_netdev_to_repr - Get port representor for given netdevice
|
||||
* @netdev: pointer to port representor netdev
|
||||
*/
|
||||
struct ice_repr *ice_netdev_to_repr(struct net_device *netdev)
|
||||
struct ice_repr *ice_netdev_to_repr(const struct net_device *netdev)
|
||||
{
|
||||
struct ice_netdev_priv *np = netdev_priv(netdev);
|
||||
|
||||
|
|
@ -139,38 +180,35 @@ static int ice_repr_stop(struct net_device *netdev)
|
|||
* ice_repr_sp_stats64 - get slow path stats for port representor
|
||||
* @dev: network interface device structure
|
||||
* @stats: netlink stats structure
|
||||
*
|
||||
* RX/TX stats are being swapped here to be consistent with VF stats. In slow
|
||||
* path, port representor receives data when the corresponding VF is sending it
|
||||
* (and vice versa), TX and RX bytes/packets are effectively swapped on port
|
||||
* representor.
|
||||
*/
|
||||
static int
|
||||
ice_repr_sp_stats64(const struct net_device *dev,
|
||||
struct rtnl_link_stats64 *stats)
|
||||
{
|
||||
struct ice_netdev_priv *np = netdev_priv(dev);
|
||||
int vf_id = np->repr->vf->vf_id;
|
||||
struct ice_tx_ring *tx_ring;
|
||||
struct ice_rx_ring *rx_ring;
|
||||
u64 pkts, bytes;
|
||||
struct ice_repr *repr = ice_netdev_to_repr(dev);
|
||||
int i;
|
||||
|
||||
tx_ring = np->vsi->tx_rings[vf_id];
|
||||
ice_fetch_u64_stats_per_ring(&tx_ring->ring_stats->syncp,
|
||||
tx_ring->ring_stats->stats,
|
||||
&pkts, &bytes);
|
||||
stats->rx_packets = pkts;
|
||||
stats->rx_bytes = bytes;
|
||||
for_each_possible_cpu(i) {
|
||||
u64 tbytes, tpkts, tdrops, rbytes, rpkts;
|
||||
struct ice_repr_pcpu_stats *repr_stats;
|
||||
unsigned int start;
|
||||
|
||||
rx_ring = np->vsi->rx_rings[vf_id];
|
||||
ice_fetch_u64_stats_per_ring(&rx_ring->ring_stats->syncp,
|
||||
rx_ring->ring_stats->stats,
|
||||
&pkts, &bytes);
|
||||
stats->tx_packets = pkts;
|
||||
stats->tx_bytes = bytes;
|
||||
stats->tx_dropped = rx_ring->ring_stats->rx_stats.alloc_page_failed +
|
||||
rx_ring->ring_stats->rx_stats.alloc_buf_failed;
|
||||
repr_stats = per_cpu_ptr(repr->stats, i);
|
||||
do {
|
||||
start = u64_stats_fetch_begin(&repr_stats->syncp);
|
||||
tbytes = repr_stats->tx_bytes;
|
||||
tpkts = repr_stats->tx_packets;
|
||||
tdrops = repr_stats->tx_drops;
|
||||
rbytes = repr_stats->rx_bytes;
|
||||
rpkts = repr_stats->rx_packets;
|
||||
} while (u64_stats_fetch_retry(&repr_stats->syncp, start));
|
||||
|
||||
stats->tx_bytes += tbytes;
|
||||
stats->tx_packets += tpkts;
|
||||
stats->tx_dropped += tdrops;
|
||||
stats->rx_bytes += rbytes;
|
||||
stats->rx_packets += rpkts;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -291,6 +329,7 @@ static void ice_repr_remove_node(struct devlink_port *devlink_port)
|
|||
*/
|
||||
static void ice_repr_rem(struct ice_repr *repr)
|
||||
{
|
||||
free_percpu(repr->stats);
|
||||
free_netdev(repr->netdev);
|
||||
kfree(repr);
|
||||
}
|
||||
|
|
@ -344,6 +383,12 @@ ice_repr_add(struct ice_pf *pf, struct ice_vsi *src_vsi, const u8 *parent_mac)
|
|||
goto err_alloc;
|
||||
}
|
||||
|
||||
repr->stats = netdev_alloc_pcpu_stats(struct ice_repr_pcpu_stats);
|
||||
if (!repr->stats) {
|
||||
err = -ENOMEM;
|
||||
goto err_stats;
|
||||
}
|
||||
|
||||
repr->src_vsi = src_vsi;
|
||||
repr->id = src_vsi->vsi_num;
|
||||
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)
|
|||
|
||||
return repr;
|
||||
|
||||
err_stats:
|
||||
free_netdev(repr->netdev);
|
||||
err_alloc:
|
||||
kfree(repr);
|
||||
return ERR_PTR(err);
|
||||
|
|
|
|||
|
|
@ -6,12 +6,22 @@
|
|||
|
||||
#include <net/dst_metadata.h>
|
||||
|
||||
struct ice_repr_pcpu_stats {
|
||||
struct u64_stats_sync syncp;
|
||||
u64 rx_packets;
|
||||
u64 rx_bytes;
|
||||
u64 tx_packets;
|
||||
u64 tx_bytes;
|
||||
u64 tx_drops;
|
||||
};
|
||||
|
||||
struct ice_repr {
|
||||
struct ice_vsi *src_vsi;
|
||||
struct ice_vf *vf;
|
||||
struct net_device *netdev;
|
||||
struct metadata_dst *dst;
|
||||
struct ice_esw_br_port *br_port;
|
||||
struct ice_repr_pcpu_stats __percpu *stats;
|
||||
u32 id;
|
||||
u8 parent_mac[ETH_ALEN];
|
||||
};
|
||||
|
|
@ -22,8 +32,12 @@ void ice_repr_rem_vf(struct ice_repr *repr);
|
|||
void ice_repr_start_tx_queues(struct ice_repr *repr);
|
||||
void ice_repr_stop_tx_queues(struct ice_repr *repr);
|
||||
|
||||
struct ice_repr *ice_netdev_to_repr(struct net_device *netdev);
|
||||
struct ice_repr *ice_netdev_to_repr(const struct net_device *netdev);
|
||||
bool ice_is_port_repr_netdev(const struct net_device *netdev);
|
||||
|
||||
struct ice_repr *ice_repr_get_by_vsi(struct ice_vsi *vsi);
|
||||
|
||||
void ice_repr_inc_tx_stats(struct ice_repr *repr, unsigned int len,
|
||||
int xmit_status);
|
||||
void ice_repr_inc_rx_stats(struct net_device *netdev, unsigned int len);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -240,6 +240,8 @@ ice_process_skb_fields(struct ice_rx_ring *rx_ring,
|
|||
struct net_device *netdev = ice_eswitch_get_target(rx_ring,
|
||||
rx_desc);
|
||||
|
||||
if (ice_is_port_repr_netdev(netdev))
|
||||
ice_repr_inc_rx_stats(netdev, skb->len);
|
||||
skb->protocol = eth_type_trans(skb, netdev);
|
||||
} else {
|
||||
skb->protocol = eth_type_trans(skb, rx_ring->netdev);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user