ice: Add slow path offload stats on port representor in switchdev
authorMarcin Szycik <marcin.szycik@linux.intel.com>
Thu, 27 Jan 2022 15:04:26 +0000 (16:04 +0100)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Wed, 9 Mar 2022 16:02:58 +0000 (08:02 -0800)
Implement callbacks to check for stats and fetch port representor stats.
Stats are taken from RX/TX ring corresponding to port representor and show
the number of bytes/packets that were not offloaded.

To see slow path stats run:
ifstat -x cpu_hits -a

Signed-off-by: Marcin Szycik <marcin.szycik@linux.intel.com>
Tested-by: Sandeep Penigalapati <sandeep.penigalapati@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/ice/ice.h
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_repr.c

index dc42ff92dbadddd3371c21fd0a76bd20fe78e9ea..f9ebd6084474211701695c6e71061a8ac1b1329f 100644 (file)
@@ -833,6 +833,9 @@ u16 ice_get_avail_rxq_count(struct ice_pf *pf);
 int ice_vsi_recfg_qs(struct ice_vsi *vsi, int new_rx, int new_tx);
 void ice_update_vsi_stats(struct ice_vsi *vsi);
 void ice_update_pf_stats(struct ice_pf *pf);
+void
+ice_fetch_u64_stats_per_ring(struct u64_stats_sync *syncp,
+                            struct ice_q_stats stats, u64 *pkts, u64 *bytes);
 int ice_up(struct ice_vsi *vsi);
 int ice_down(struct ice_vsi *vsi);
 int ice_vsi_cfg(struct ice_vsi *vsi);
index 289e5c99e3130bbaa56b01527837f092d06f23cf..ca22c60636b9d7387a3aad5e5308be1c3d5ae469 100644 (file)
@@ -6113,9 +6113,9 @@ int ice_up(struct ice_vsi *vsi)
  * This function fetches stats from the ring considering the atomic operations
  * that needs to be performed to read u64 values in 32 bit machine.
  */
-static void
-ice_fetch_u64_stats_per_ring(struct u64_stats_sync *syncp, struct ice_q_stats stats,
-                            u64 *pkts, u64 *bytes)
+void
+ice_fetch_u64_stats_per_ring(struct u64_stats_sync *syncp,
+                            struct ice_q_stats stats, u64 *pkts, u64 *bytes)
 {
        unsigned int start;
 
index 2adfaf21e0561f35c0184636467ce41b0567e323..f8db3ca521da8fe7e12c6bb1b37973002399b31e 100644 (file)
@@ -142,6 +142,59 @@ ice_repr_get_devlink_port(struct net_device *netdev)
        return &repr->vf->devlink_port;
 }
 
+/**
+ * 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;
+
+       tx_ring = np->vsi->tx_rings[vf_id];
+       ice_fetch_u64_stats_per_ring(&tx_ring->syncp, tx_ring->stats,
+                                    &pkts, &bytes);
+       stats->rx_packets = pkts;
+       stats->rx_bytes = bytes;
+
+       rx_ring = np->vsi->rx_rings[vf_id];
+       ice_fetch_u64_stats_per_ring(&rx_ring->syncp, rx_ring->stats,
+                                    &pkts, &bytes);
+       stats->tx_packets = pkts;
+       stats->tx_bytes = bytes;
+       stats->tx_dropped = rx_ring->rx_stats.alloc_page_failed +
+                           rx_ring->rx_stats.alloc_buf_failed;
+
+       return 0;
+}
+
+static bool
+ice_repr_ndo_has_offload_stats(const struct net_device *dev, int attr_id)
+{
+       return attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT;
+}
+
+static int
+ice_repr_ndo_get_offload_stats(int attr_id, const struct net_device *dev,
+                              void *sp)
+{
+       if (attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT)
+               return ice_repr_sp_stats64(dev, (struct rtnl_link_stats64 *)sp);
+
+       return -EINVAL;
+}
+
 static int
 ice_repr_setup_tc_cls_flower(struct ice_repr *repr,
                             struct flow_cls_offload *flower)
@@ -199,6 +252,8 @@ static const struct net_device_ops ice_repr_netdev_ops = {
        .ndo_start_xmit = ice_eswitch_port_start_xmit,
        .ndo_get_devlink_port = ice_repr_get_devlink_port,
        .ndo_setup_tc = ice_repr_setup_tc,
+       .ndo_has_offload_stats = ice_repr_ndo_has_offload_stats,
+       .ndo_get_offload_stats = ice_repr_ndo_get_offload_stats,
 };
 
 /**