]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net: atlantic: per-TC queue statistics
authorMark Starovoytov <mstarovoitov@marvell.com>
Fri, 22 May 2020 08:19:41 +0000 (11:19 +0300)
committerDavid S. Miller <davem@davemloft.net>
Fri, 22 May 2020 21:08:28 +0000 (14:08 -0700)
This patch adds support for per-TC queue statistics.

By default (single TC), the output is the same as it used to be, e.g.:
     Queue[0] InPackets: 2
     Queue[0] OutPackets: 8
     Queue[0] Restarts: 0
     Queue[0] InJumboPackets: 0
     Queue[0] InLroPackets: 0
     Queue[0] InErrors: 0

If several TCs are enabled, then each queue statistics line is prefixed
with TC number, e.g.:
     TC0 Queue[0] InPackets: 6
     TC0 Queue[0] OutPackets: 11
Queue numbering is end-to-end, so:
     TC1 Queue[4] InPackets: 0
     TC1 Queue[4] OutPackets: 22

Signed-off-by: Mark Starovoytov <mstarovoitov@marvell.com>
Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
drivers/net/ethernet/aquantia/atlantic/aq_nic.c
drivers/net/ethernet/aquantia/atlantic/aq_vec.c
drivers/net/ethernet/aquantia/atlantic/aq_vec.h

index 86fc77d85fdae9e3090488dc2a65f4d173e56ca4..440a7d1298486687d0d10f4605f175797b825fd7 100644 (file)
@@ -88,13 +88,13 @@ static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
        "InDroppedDma",
 };
 
-static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = {
-       "Queue[%d] InPackets",
-       "Queue[%d] OutPackets",
-       "Queue[%d] Restarts",
-       "Queue[%d] InJumboPackets",
-       "Queue[%d] InLroPackets",
-       "Queue[%d] InErrors",
+static const char * const aq_ethtool_queue_stat_names[] = {
+       "%sQueue[%d] InPackets",
+       "%sQueue[%d] OutPackets",
+       "%sQueue[%d] Restarts",
+       "%sQueue[%d] InJumboPackets",
+       "%sQueue[%d] InLroPackets",
+       "%sQueue[%d] InErrors",
 };
 
 #if IS_ENABLED(CONFIG_MACSEC)
@@ -166,7 +166,8 @@ static u32 aq_ethtool_n_stats(struct net_device *ndev)
        struct aq_nic_s *nic = netdev_priv(ndev);
        struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(nic);
        u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
-                     ARRAY_SIZE(aq_ethtool_queue_stat_names) * cfg->vecs;
+                     ARRAY_SIZE(aq_ethtool_queue_stat_names) * cfg->vecs *
+                       cfg->tcs;
 
 #if IS_ENABLED(CONFIG_MACSEC)
        if (nic->macsec_cfg) {
@@ -223,7 +224,7 @@ static void aq_ethtool_get_drvinfo(struct net_device *ndev,
 static void aq_ethtool_get_strings(struct net_device *ndev,
                                   u32 stringset, u8 *data)
 {
-       struct aq_nic_s *aq_nic = netdev_priv(ndev);
+       struct aq_nic_s *nic = netdev_priv(ndev);
        struct aq_nic_cfg_s *cfg;
        u8 *p = data;
        int i, si;
@@ -231,24 +232,35 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
        int sa;
 #endif
 
-       cfg = aq_nic_get_cfg(aq_nic);
+       cfg = aq_nic_get_cfg(nic);
 
        switch (stringset) {
-       case ETH_SS_STATS:
+       case ETH_SS_STATS: {
+               const int stat_cnt = ARRAY_SIZE(aq_ethtool_queue_stat_names);
+               char tc_string[8];
+               int tc;
+
+               memset(tc_string, 0, sizeof(tc_string));
                memcpy(p, aq_ethtool_stat_names,
                       sizeof(aq_ethtool_stat_names));
                p = p + sizeof(aq_ethtool_stat_names);
-               for (i = 0; i < cfg->vecs; i++) {
-                       for (si = 0;
-                               si < ARRAY_SIZE(aq_ethtool_queue_stat_names);
-                               si++) {
-                               snprintf(p, ETH_GSTRING_LEN,
-                                        aq_ethtool_queue_stat_names[si], i);
-                               p += ETH_GSTRING_LEN;
+
+               for (tc = 0; tc < cfg->tcs; tc++) {
+                       if (cfg->is_qos)
+                               snprintf(tc_string, 8, "TC%d ", tc);
+
+                       for (i = 0; i < cfg->vecs; i++) {
+                               for (si = 0; si < stat_cnt; si++) {
+                                       snprintf(p, ETH_GSTRING_LEN,
+                                            aq_ethtool_queue_stat_names[si],
+                                            tc_string,
+                                            AQ_NIC_TCVEC2RING(nic, tc, i));
+                                       p += ETH_GSTRING_LEN;
+                               }
                        }
                }
 #if IS_ENABLED(CONFIG_MACSEC)
-               if (!aq_nic->macsec_cfg)
+               if (!nic->macsec_cfg)
                        break;
 
                memcpy(p, aq_macsec_stat_names, sizeof(aq_macsec_stat_names));
@@ -256,7 +268,7 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
                for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
                        struct aq_macsec_txsc *aq_txsc;
 
-                       if (!(test_bit(i, &aq_nic->macsec_cfg->txsc_idx_busy)))
+                       if (!(test_bit(i, &nic->macsec_cfg->txsc_idx_busy)))
                                continue;
 
                        for (si = 0;
@@ -266,7 +278,7 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
                                         aq_macsec_txsc_stat_names[si], i);
                                p += ETH_GSTRING_LEN;
                        }
-                       aq_txsc = &aq_nic->macsec_cfg->aq_txsc[i];
+                       aq_txsc = &nic->macsec_cfg->aq_txsc[i];
                        for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
                                if (!(test_bit(sa, &aq_txsc->tx_sa_idx_busy)))
                                        continue;
@@ -283,10 +295,10 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
                for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
                        struct aq_macsec_rxsc *aq_rxsc;
 
-                       if (!(test_bit(i, &aq_nic->macsec_cfg->rxsc_idx_busy)))
+                       if (!(test_bit(i, &nic->macsec_cfg->rxsc_idx_busy)))
                                continue;
 
-                       aq_rxsc = &aq_nic->macsec_cfg->aq_rxsc[i];
+                       aq_rxsc = &nic->macsec_cfg->aq_rxsc[i];
                        for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
                                if (!(test_bit(sa, &aq_rxsc->rx_sa_idx_busy)))
                                        continue;
@@ -302,6 +314,7 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
                }
 #endif
                break;
+       }
        case ETH_SS_PRIV_FLAGS:
                memcpy(p, aq_ethtool_priv_flag_names,
                       sizeof(aq_ethtool_priv_flag_names));
index da781082be3269023bb9caf3fc7350550a182d06..851f22aadea1c585f73b358728b9f7f5c267403f 100644 (file)
@@ -855,6 +855,7 @@ u64 *aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
        struct aq_stats_s *stats;
        unsigned int count = 0U;
        unsigned int i = 0U;
+       unsigned int tc;
 
        if (self->aq_fw_ops->update_stats) {
                mutex_lock(&self->fwreq_mutex);
@@ -893,10 +894,13 @@ u64 *aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
 
        data += i;
 
-       for (i = 0U, aq_vec = self->aq_vec[0];
-               aq_vec && self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
-               data += count;
-               aq_vec_get_sw_stats(aq_vec, data, &count);
+       for (tc = 0U; tc < self->aq_nic_cfg.tcs; tc++) {
+               for (i = 0U, aq_vec = self->aq_vec[0];
+                    aq_vec && self->aq_vecs > i;
+                    ++i, aq_vec = self->aq_vec[i]) {
+                       data += count;
+                       aq_vec_get_sw_stats(aq_vec, tc, data, &count);
+               }
        }
 
        data += count;
index d5650cd6e236cd855c7e5a412beb8860f46d3337..41826c10700f389f077b7fb707761df922f4955e 100644 (file)
@@ -348,16 +348,14 @@ cpumask_t *aq_vec_get_affinity_mask(struct aq_vec_s *self)
        return &self->aq_ring_param.affinity_mask;
 }
 
-void aq_vec_add_stats(struct aq_vec_s *self,
-                     struct aq_ring_stats_rx_s *stats_rx,
-                     struct aq_ring_stats_tx_s *stats_tx)
+static void aq_vec_add_stats(struct aq_vec_s *self,
+                            const unsigned int tc,
+                            struct aq_ring_stats_rx_s *stats_rx,
+                            struct aq_ring_stats_tx_s *stats_tx)
 {
-       struct aq_ring_s *ring = NULL;
-       unsigned int r = 0U;
+       struct aq_ring_s *ring = self->ring[tc];
 
-       for (r = 0U, ring = self->ring[0];
-               self->tx_rings > r; ++r, ring = self->ring[r]) {
-               struct aq_ring_stats_tx_s *tx = &ring[AQ_VEC_TX_ID].stats.tx;
+       if (tc < self->rx_rings) {
                struct aq_ring_stats_rx_s *rx = &ring[AQ_VEC_RX_ID].stats.rx;
 
                stats_rx->packets += rx->packets;
@@ -368,6 +366,10 @@ void aq_vec_add_stats(struct aq_vec_s *self,
                stats_rx->pg_losts += rx->pg_losts;
                stats_rx->pg_flips += rx->pg_flips;
                stats_rx->pg_reuses += rx->pg_reuses;
+       }
+
+       if (tc < self->tx_rings) {
+               struct aq_ring_stats_tx_s *tx = &ring[AQ_VEC_TX_ID].stats.tx;
 
                stats_tx->packets += tx->packets;
                stats_tx->bytes += tx->bytes;
@@ -376,7 +378,8 @@ void aq_vec_add_stats(struct aq_vec_s *self,
        }
 }
 
-int aq_vec_get_sw_stats(struct aq_vec_s *self, u64 *data, unsigned int *p_count)
+int aq_vec_get_sw_stats(struct aq_vec_s *self, const unsigned int tc, u64 *data,
+                       unsigned int *p_count)
 {
        struct aq_ring_stats_rx_s stats_rx;
        struct aq_ring_stats_tx_s stats_tx;
@@ -384,7 +387,8 @@ int aq_vec_get_sw_stats(struct aq_vec_s *self, u64 *data, unsigned int *p_count)
 
        memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s));
        memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s));
-       aq_vec_add_stats(self, &stats_rx, &stats_tx);
+
+       aq_vec_add_stats(self, tc, &stats_rx, &stats_tx);
 
        /* This data should mimic aq_ethtool_queue_stat_names structure
         */
index 0ee86b26df8ad921cb9f2f2c0cc85d2198de0909..541af85e6510a697b59a9b02403e4bca9a5bb1a1 100644 (file)
@@ -35,10 +35,7 @@ void aq_vec_ring_free(struct aq_vec_s *self);
 int aq_vec_start(struct aq_vec_s *self);
 void aq_vec_stop(struct aq_vec_s *self);
 cpumask_t *aq_vec_get_affinity_mask(struct aq_vec_s *self);
-int aq_vec_get_sw_stats(struct aq_vec_s *self, u64 *data,
+int aq_vec_get_sw_stats(struct aq_vec_s *self, const unsigned int tc, u64 *data,
                        unsigned int *p_count);
-void aq_vec_add_stats(struct aq_vec_s *self,
-                     struct aq_ring_stats_rx_s *stats_rx,
-                     struct aq_ring_stats_tx_s *stats_tx);
 
 #endif /* AQ_VEC_H */