Add a read-only buffer_pools sysfs attribute under the VIO device that
lists size, buff_size, active, and available for every RX queue and
pool: runtime per-queue buffer pressure during MQ operation. ethtool -S
pool%d_* (previous patch) reports queue-0 static probe geometry only;
sysfs is the right place for dynamic per-queue pool state at scale.

Signed-off-by: Mingming Cao <[email protected]>
Reviewed-by: Dave Marquardt <[email protected]>
---
 drivers/net/ethernet/ibm/ibmveth.c | 56 ++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/net/ethernet/ibm/ibmveth.c 
b/drivers/net/ethernet/ibm/ibmveth.c
index 4e3f49b6346f..ecc472ee8f71 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -2896,6 +2896,52 @@ static const struct net_device_ops ibmveth_netdev_ops = {
 #endif
 };
 
+static const struct attribute_group ibmveth_attr_group;
+
+static ssize_t buffer_pools_show(struct device *dev,
+                                struct device_attribute *attr,
+                                char *buf)
+{
+       struct net_device *netdev = dev_get_drvdata(dev);
+       struct ibmveth_adapter *adapter = netdev_priv(netdev);
+       int len = 0;
+       int i, j;
+
+       len += scnprintf(buf + len, PAGE_SIZE - len,
+                        "Queue  Pool  Size  BuffSize  Active  Available\n");
+       len += scnprintf(buf + len, PAGE_SIZE - len,
+                        "-----  ----  ----  --------  ------  ---------\n");
+
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               for (j = 0; j < IBMVETH_NUM_BUFF_POOLS; j++) {
+                       struct ibmveth_buff_pool *pool =
+                               &adapter->rx_buff_pool[i][j];
+
+                       len += scnprintf(buf + len, PAGE_SIZE - len,
+                                        "%5d  %4d  %4u  %8u  %6d  %9d\n",
+                                        i, j, pool->size, pool->buff_size,
+                                        pool->active,
+                                        atomic_read(&pool->available));
+
+                       if (len >= PAGE_SIZE - 100)
+                               goto out;
+               }
+       }
+
+out:
+       return len;
+}
+static DEVICE_ATTR_RO(buffer_pools);
+
+static struct attribute *ibmveth_attrs[] = {
+       &dev_attr_buffer_pools.attr,
+       NULL,
+};
+
+static const struct attribute_group ibmveth_attr_group = {
+       .attrs = ibmveth_attrs,
+};
+
 static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
 {
        int rc, i, mac_len;
@@ -3056,6 +3102,14 @@ static int ibmveth_probe(struct vio_dev *dev, const 
struct vio_device_id *id)
 
        netdev_dbg(netdev, "registered\n");
 
+       rc = sysfs_create_group(&dev->dev.kobj, &ibmveth_attr_group);
+       if (rc) {
+               netdev_err(netdev, "failed to create sysfs attributes rc=%d\n", 
rc);
+               unregister_netdev(netdev);
+               free_netdev(netdev);
+               return rc;
+       }
+
        return 0;
 }
 
@@ -3067,6 +3121,8 @@ static void ibmveth_remove(struct vio_dev *dev)
 
        cancel_work_sync(&adapter->work);
 
+       sysfs_remove_group(&dev->dev.kobj, &ibmveth_attr_group);
+
        for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++)
                kobject_put(&adapter->rx_buff_pool[0][i].kobj);
 
-- 
2.39.3 (Apple Git-146)


Reply via email to