net/mlx5e: Add interface down dropped packets statistics
authorMoshe Shemesh <moshe@mellanox.com>
Thu, 8 Feb 2018 13:09:57 +0000 (15:09 +0200)
committerSaeed Mahameed <saeedm@mellanox.com>
Mon, 26 Mar 2018 20:47:12 +0000 (13:47 -0700)
Added the following packets drop counter:
Rx interface down dropped packets - counts packets which were received
while the ETH interface was down.
This counter will be shown on ethtool as a new counter called
rx_if_down_packets.

The implementation allocates a q_counter for drop rq which gets all the
received traffic while the interface is down.

Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
drivers/net/ethernet/mellanox/mlx5/core/en_stats.h

index 4c9360b25532b17ce82b24f760f0f45b5c643f51..48e0b2a747d93b537d0668e17a1f043f742bd971 100644 (file)
@@ -781,7 +781,8 @@ struct mlx5e_priv {
        struct net_device         *netdev;
        struct mlx5e_stats         stats;
        struct hwtstamp_config     tstamp;
-       u16 q_counter;
+       u16                        q_counter;
+       u16                        drop_rq_q_counter;
 #ifdef CONFIG_MLX5_CORE_EN_DCB
        struct mlx5e_dcbx          dcbx;
 #endif
index da94c8cba5ee1b7e8f6309d81fa7db29a1db10b6..f8bc3bcdf0460876ef7f853e62a043eff6dc5548 100644 (file)
@@ -615,8 +615,7 @@ static int mlx5e_create_rq(struct mlx5e_rq *rq,
 static int mlx5e_modify_rq_state(struct mlx5e_rq *rq, int curr_state,
                                 int next_state)
 {
-       struct mlx5e_channel *c = rq->channel;
-       struct mlx5_core_dev *mdev = c->mdev;
+       struct mlx5_core_dev *mdev = rq->mdev;
 
        void *in;
        void *rqc;
@@ -1768,14 +1767,16 @@ static void mlx5e_build_rq_param(struct mlx5e_priv *priv,
        param->wq.linear = 1;
 }
 
-static void mlx5e_build_drop_rq_param(struct mlx5_core_dev *mdev,
+static void mlx5e_build_drop_rq_param(struct mlx5e_priv *priv,
                                      struct mlx5e_rq_param *param)
 {
+       struct mlx5_core_dev *mdev = priv->mdev;
        void *rqc = param->rqc;
        void *wq = MLX5_ADDR_OF(rqc, rqc, wq);
 
        MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_LINKED_LIST);
        MLX5_SET(wq, wq, log_wq_stride,    ilog2(sizeof(struct mlx5e_rx_wqe)));
+       MLX5_SET(rqc, rqc, counter_set_id, priv->drop_rq_q_counter);
 
        param->wq.buf_numa_node = dev_to_node(&mdev->pdev->dev);
 }
@@ -2643,15 +2644,16 @@ static int mlx5e_alloc_drop_cq(struct mlx5_core_dev *mdev,
        return mlx5e_alloc_cq_common(mdev, param, cq);
 }
 
-static int mlx5e_open_drop_rq(struct mlx5_core_dev *mdev,
+static int mlx5e_open_drop_rq(struct mlx5e_priv *priv,
                              struct mlx5e_rq *drop_rq)
 {
+       struct mlx5_core_dev *mdev = priv->mdev;
        struct mlx5e_cq_param cq_param = {};
        struct mlx5e_rq_param rq_param = {};
        struct mlx5e_cq *cq = &drop_rq->cq;
        int err;
 
-       mlx5e_build_drop_rq_param(mdev, &rq_param);
+       mlx5e_build_drop_rq_param(priv, &rq_param);
 
        err = mlx5e_alloc_drop_cq(mdev, cq, &cq_param);
        if (err)
@@ -2669,6 +2671,10 @@ static int mlx5e_open_drop_rq(struct mlx5_core_dev *mdev,
        if (err)
                goto err_free_rq;
 
+       err = mlx5e_modify_rq_state(drop_rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY);
+       if (err)
+               mlx5_core_warn(priv->mdev, "modify_rq_state failed, rx_if_down_packets won't be counted %d\n", err);
+
        return 0;
 
 err_free_rq:
@@ -4183,7 +4189,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
        mlx5e_ipsec_build_netdev(priv);
 }
 
-static void mlx5e_create_q_counter(struct mlx5e_priv *priv)
+static void mlx5e_create_q_counters(struct mlx5e_priv *priv)
 {
        struct mlx5_core_dev *mdev = priv->mdev;
        int err;
@@ -4193,14 +4199,21 @@ static void mlx5e_create_q_counter(struct mlx5e_priv *priv)
                mlx5_core_warn(mdev, "alloc queue counter failed, %d\n", err);
                priv->q_counter = 0;
        }
+
+       err = mlx5_core_alloc_q_counter(mdev, &priv->drop_rq_q_counter);
+       if (err) {
+               mlx5_core_warn(mdev, "alloc drop RQ counter failed, %d\n", err);
+               priv->drop_rq_q_counter = 0;
+       }
 }
 
-static void mlx5e_destroy_q_counter(struct mlx5e_priv *priv)
+static void mlx5e_destroy_q_counters(struct mlx5e_priv *priv)
 {
-       if (!priv->q_counter)
-               return;
+       if (priv->q_counter)
+               mlx5_core_dealloc_q_counter(priv->mdev, priv->q_counter);
 
-       mlx5_core_dealloc_q_counter(priv->mdev, priv->q_counter);
+       if (priv->drop_rq_q_counter)
+               mlx5_core_dealloc_q_counter(priv->mdev, priv->drop_rq_q_counter);
 }
 
 static void mlx5e_nic_init(struct mlx5_core_dev *mdev,
@@ -4439,18 +4452,18 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv)
        if (err)
                goto out;
 
-       err = mlx5e_open_drop_rq(mdev, &priv->drop_rq);
+       mlx5e_create_q_counters(priv);
+
+       err = mlx5e_open_drop_rq(priv, &priv->drop_rq);
        if (err) {
                mlx5_core_err(mdev, "open drop rq failed, %d\n", err);
-               goto err_cleanup_tx;
+               goto err_destroy_q_counters;
        }
 
        err = profile->init_rx(priv);
        if (err)
                goto err_close_drop_rq;
 
-       mlx5e_create_q_counter(priv);
-
        if (profile->enable)
                profile->enable(priv);
 
@@ -4459,7 +4472,8 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv)
 err_close_drop_rq:
        mlx5e_close_drop_rq(&priv->drop_rq);
 
-err_cleanup_tx:
+err_destroy_q_counters:
+       mlx5e_destroy_q_counters(priv);
        profile->cleanup_tx(priv);
 
 out:
@@ -4476,9 +4490,9 @@ void mlx5e_detach_netdev(struct mlx5e_priv *priv)
                profile->disable(priv);
        flush_workqueue(priv->wq);
 
-       mlx5e_destroy_q_counter(priv);
        profile->cleanup_rx(priv);
        mlx5e_close_drop_rq(&priv->drop_rq);
+       mlx5e_destroy_q_counters(priv);
        profile->cleanup_tx(priv);
        cancel_delayed_work_sync(&priv->update_stats_work);
 }
index 552510c03ef2b79f5099ddbeb8a161f786633cfa..c0dab9a8969e9eca8dd632bd724d9cca9e0082b4 100644 (file)
@@ -170,11 +170,24 @@ static const struct counter_desc q_stats_desc[] = {
        { MLX5E_DECLARE_STAT(struct mlx5e_qcounter_stats, rx_out_of_buffer) },
 };
 
+static const struct counter_desc drop_rq_stats_desc[] = {
+       { MLX5E_DECLARE_STAT(struct mlx5e_qcounter_stats, rx_if_down_packets) },
+};
+
 #define NUM_Q_COUNTERS                 ARRAY_SIZE(q_stats_desc)
+#define NUM_DROP_RQ_COUNTERS           ARRAY_SIZE(drop_rq_stats_desc)
 
 static int mlx5e_grp_q_get_num_stats(struct mlx5e_priv *priv)
 {
-       return priv->q_counter ? NUM_Q_COUNTERS : 0;
+       int num_stats = 0;
+
+       if (priv->q_counter)
+               num_stats += NUM_Q_COUNTERS;
+
+       if (priv->drop_rq_q_counter)
+               num_stats += NUM_DROP_RQ_COUNTERS;
+
+       return num_stats;
 }
 
 static int mlx5e_grp_q_fill_strings(struct mlx5e_priv *priv, u8 *data, int idx)
@@ -182,7 +195,13 @@ static int mlx5e_grp_q_fill_strings(struct mlx5e_priv *priv, u8 *data, int idx)
        int i;
 
        for (i = 0; i < NUM_Q_COUNTERS && priv->q_counter; i++)
-               strcpy(data + (idx++) * ETH_GSTRING_LEN, q_stats_desc[i].format);
+               strcpy(data + (idx++) * ETH_GSTRING_LEN,
+                      q_stats_desc[i].format);
+
+       for (i = 0; i < NUM_DROP_RQ_COUNTERS && priv->drop_rq_q_counter; i++)
+               strcpy(data + (idx++) * ETH_GSTRING_LEN,
+                      drop_rq_stats_desc[i].format);
+
        return idx;
 }
 
@@ -191,7 +210,11 @@ static int mlx5e_grp_q_fill_stats(struct mlx5e_priv *priv, u64 *data, int idx)
        int i;
 
        for (i = 0; i < NUM_Q_COUNTERS && priv->q_counter; i++)
-               data[idx++] = MLX5E_READ_CTR32_CPU(&priv->stats.qcnt, q_stats_desc, i);
+               data[idx++] = MLX5E_READ_CTR32_CPU(&priv->stats.qcnt,
+                                                  q_stats_desc, i);
+       for (i = 0; i < NUM_DROP_RQ_COUNTERS && priv->drop_rq_q_counter; i++)
+               data[idx++] = MLX5E_READ_CTR32_CPU(&priv->stats.qcnt,
+                                                  drop_rq_stats_desc, i);
        return idx;
 }
 
@@ -199,16 +222,17 @@ static void mlx5e_grp_q_update_stats(struct mlx5e_priv *priv)
 {
        struct mlx5e_qcounter_stats *qcnt = &priv->stats.qcnt;
        u32 out[MLX5_ST_SZ_DW(query_q_counter_out)];
-       int err;
-
-       if (!priv->q_counter)
-               return;
-
-       err = mlx5_core_query_q_counter(priv->mdev, priv->q_counter, 0, out, sizeof(out));
-       if (err)
-               return;
 
-       qcnt->rx_out_of_buffer = MLX5_GET(query_q_counter_out, out, out_of_buffer);
+       if (priv->q_counter &&
+           !mlx5_core_query_q_counter(priv->mdev, priv->q_counter, 0, out,
+                                      sizeof(out)))
+               qcnt->rx_out_of_buffer = MLX5_GET(query_q_counter_out,
+                                                 out, out_of_buffer);
+       if (priv->drop_rq_q_counter &&
+           !mlx5_core_query_q_counter(priv->mdev, priv->drop_rq_q_counter, 0,
+                                      out, sizeof(out)))
+               qcnt->rx_if_down_packets = MLX5_GET(query_q_counter_out, out,
+                                                   out_of_buffer);
 }
 
 #define VNIC_ENV_OFF(c) MLX5_BYTE_OFF(query_vnic_env_out, c)
index 847388ff8ca842cbe17f60b653c75fedad91c1db..43a72efa28c052b34e684fe19fefbddb7d359aad 100644 (file)
@@ -97,6 +97,7 @@ struct mlx5e_sw_stats {
 
 struct mlx5e_qcounter_stats {
        u32 rx_out_of_buffer;
+       u32 rx_if_down_packets;
 };
 
 struct mlx5e_vnic_env_stats {