mlx4: Use netif_stats for ifstat
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 16 Nov 2017 16:09:57 +0000 (11:09 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 16 Nov 2017 17:19:59 +0000 (12:19 -0500)
Linux drivers have a way of exporting their stats to a struct netif_stats.
We have a way to parse netif_stats when we cat ether/ifstats.  Put those
together and you have a simple way to get stats from any Linux driver.

For mlx4, I had to turn on a few bits of code that we had commented out.
There were minor issues with the MAC address changing, but I think we can
ignore that for now.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/drivers/net/mlx4/en_netdev.c
kern/drivers/net/mlx4/en_port.c
kern/drivers/net/mlx4/main.c

index 3892d9f..0a9ac75 100644 (file)
@@ -1331,7 +1331,7 @@ static void mlx4_en_tx_timeout(struct ether *dev)
 }
 
 
 }
 
 
-static struct netif_stats *mlx4_en_get_stats(struct ether *dev)
+struct netif_stats *mlx4_en_get_stats(struct ether *dev)
 {
        struct mlx4_en_priv *priv = netdev_priv(dev);
 
 {
        struct mlx4_en_priv *priv = netdev_priv(dev);
 
@@ -1389,8 +1389,6 @@ static void mlx4_en_set_default_moderation(struct mlx4_en_priv *priv)
 
 static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
 {
 
 static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
 {
-       panic("Disabled");
-#if 0 // AKAROS_PORT
        unsigned long period = (unsigned long) (jiffies - priv->last_moder_jiffies);
        struct mlx4_en_cq *cq;
        unsigned long packets;
        unsigned long period = (unsigned long) (jiffies - priv->last_moder_jiffies);
        struct mlx4_en_cq *cq;
        unsigned long packets;
@@ -1450,13 +1448,10 @@ static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
        }
 
        priv->last_moder_jiffies = jiffies;
        }
 
        priv->last_moder_jiffies = jiffies;
-#endif
 }
 
 static void mlx4_en_do_get_stats(struct work_struct *work)
 {
 }
 
 static void mlx4_en_do_get_stats(struct work_struct *work)
 {
-       panic("Disabled");
-#if 0 // AKAROS_PORT
        struct delayed_work *delay = to_delayed_work(work);
        struct mlx4_en_priv *priv = container_of(delay, struct mlx4_en_priv,
                                                 stats_task);
        struct delayed_work *delay = to_delayed_work(work);
        struct mlx4_en_priv *priv = container_of(delay, struct mlx4_en_priv,
                                                 stats_task);
@@ -1475,12 +1470,13 @@ static void mlx4_en_do_get_stats(struct work_struct *work)
 
                queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
        }
 
                queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
        }
+#if 0 // AKAROS_PORT
        if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) {
                mlx4_en_do_set_mac(priv, priv->current_mac);
                mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0;
        }
        if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) {
                mlx4_en_do_set_mac(priv, priv->current_mac);
                mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0;
        }
-       qunlock(&mdev->state_lock);
 #endif
 #endif
+       qunlock(&mdev->state_lock);
 }
 
 /* mlx4_en_service_task - Run service task for tasks that needed to be done
 }
 
 /* mlx4_en_service_task - Run service task for tasks that needed to be done
@@ -1931,10 +1927,8 @@ static void mlx4_en_clear_stats(struct ether *dev)
        struct mlx4_en_dev *mdev = priv->mdev;
        int i;
 
        struct mlx4_en_dev *mdev = priv->mdev;
        int i;
 
-#if 0 // AKAROS_PORT
        if (mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 1))
                en_dbg(HW, priv, "Failed dumping statistics\n");
        if (mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 1))
                en_dbg(HW, priv, "Failed dumping statistics\n");
-#endif
 
        memset(&priv->stats, 0, sizeof(priv->stats));
        memset(&priv->pstats, 0, sizeof(priv->pstats));
 
        memset(&priv->stats, 0, sizeof(priv->stats));
        memset(&priv->pstats, 0, sizeof(priv->pstats));
@@ -3066,9 +3060,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
                en_err(priv, "Failed Initializing port\n");
                goto out;
        }
                en_err(priv, "Failed Initializing port\n");
                goto out;
        }
-#if 0 // AKAROS_PORT
        queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
        queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
-#endif
 
        if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
                queue_delayed_work(mdev->workqueue, &priv->service_task,
 
        if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
                queue_delayed_work(mdev->workqueue, &priv->service_task,
index d29b814..0973540 100644 (file)
@@ -150,8 +150,6 @@ static unsigned long en_stats_adder(__be64 *start, __be64 *next, int num)
 int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, uint8_t port,
                           uint8_t reset)
 {
 int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, uint8_t port,
                           uint8_t reset)
 {
-       panic("Disabled");
-#if 0 // AKAROS_PORT
        struct mlx4_en_stat_out_mbox *mlx4_en_stats;
        struct mlx4_en_stat_out_flow_control_mbox *flowstats;
        struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]);
        struct mlx4_en_stat_out_mbox *mlx4_en_stats;
        struct mlx4_en_stat_out_flow_control_mbox *flowstats;
        struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]);
@@ -351,6 +349,5 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, uint8_t port,
 out:
        mlx4_free_cmd_mailbox(mdev->dev, mailbox);
        return err;
 out:
        mlx4_free_cmd_mailbox(mdev->dev, mailbox);
        return err;
-#endif
 }
 
 }
 
index 943c9a9..9d87e8e 100644 (file)
@@ -3886,8 +3886,10 @@ extern void mlx4_transmit(struct ether *edev);
 
 static long mlx4_ifstat(struct ether *edev, void *a, long n, uint32_t offset)
 {
 
 static long mlx4_ifstat(struct ether *edev, void *a, long n, uint32_t offset)
 {
-       printk("edev %p a %p n %d offset %u\n", edev, a, n, offset);
-       return 0;
+       /* From Linux's net_device_ops */
+       extern struct netif_stats *mlx4_en_get_stats(struct ether *dev);
+
+       return linux_ifstat(mlx4_en_get_stats(edev), a, n, offset);
 }
 
 static long mlx4_ctl(struct ether *edev, void *buf, long n)
 }
 
 static long mlx4_ctl(struct ether *edev, void *buf, long n)