diff mbox series

[v4,net-next] net: hyperv: Add attributes to show TX indirection table

Message ID HK0P153MB02751820DD4F8892DEFA13D098780@HK0P153MB0275.APCP153.PROD.OUTLOOK.COM
State Changes Requested
Delegated to: David Miller
Headers show
Series [v4,net-next] net: hyperv: Add attributes to show TX indirection table | expand

Commit Message

Chi Song July 21, 2020, 2:37 a.m. UTC
An imbalanced TX indirection table causes netvsc to have low
performance. This table is created and managed during runtime. To help
better diagnose performance issues caused by imbalanced tables, add
device attributes to show the content of TX indirection tables.

Signed-off-by: Chi Song <chisong@microsoft.com>
---
v4: use a separated group to organize tx_indirection better, change 
 location of init, exit to drve

---
 drivers/net/hyperv/netvsc_drv.c | 49 +++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

Comments

David Miller July 21, 2020, 3:14 a.m. UTC | #1
From: Chi Song <Song.Chi@microsoft.com>
Date: Tue, 21 Jul 2020 02:37:42 +0000

> +static ssize_t tx_indirection_show(struct device *dev,
> +				   struct device_attribute *dev_attr, char *buf)
> +{
> +	struct net_device *ndev = to_net_dev(dev);
> +	struct net_device_context *ndc = netdev_priv(ndev);
> +	int index = dev_attr - dev_attr_netvsc_dev_attrs;

Reverse christmas tree ordering for local variables please.

> +static void netvsc_attrs_init(void)
> +{
> +	int i;
> +	char buffer[4];

Likewise.
diff mbox series

Patch

diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 6267f706e8ee..280de1067f40 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -2370,6 +2370,51 @@  static int netvsc_unregister_vf(struct net_device *vf_netdev)
 	return NOTIFY_OK;
 }
 
+static struct device_attribute dev_attr_netvsc_dev_attrs[VRSS_SEND_TAB_SIZE];
+static struct attribute *netvsc_dev_attrs[VRSS_SEND_TAB_SIZE + 1];
+
+const struct attribute_group netvsc_dev_group = {
+	.name = "tx_indirection",
+	.attrs = netvsc_dev_attrs,
+};
+
+static ssize_t tx_indirection_show(struct device *dev,
+				   struct device_attribute *dev_attr, char *buf)
+{
+	struct net_device *ndev = to_net_dev(dev);
+	struct net_device_context *ndc = netdev_priv(ndev);
+	int index = dev_attr - dev_attr_netvsc_dev_attrs;
+
+	return sprintf(buf, "%u\n", ndc->tx_table[index]);
+}
+
+static void netvsc_attrs_init(void)
+{
+	int i;
+	char buffer[4];
+
+	for (i = 0; i < VRSS_SEND_TAB_SIZE; i++) {
+		sprintf(buffer, "%02u", i);
+		dev_attr_netvsc_dev_attrs[i].attr.name =
+			kstrdup(buffer, GFP_KERNEL);
+		dev_attr_netvsc_dev_attrs[i].attr.mode = 0444;
+		sysfs_attr_init(&dev_attr_netvsc_dev_attrs[i].attr);
+
+		dev_attr_netvsc_dev_attrs[i].show = tx_indirection_show;
+		dev_attr_netvsc_dev_attrs[i].store = NULL;
+		netvsc_dev_attrs[i] = &dev_attr_netvsc_dev_attrs[i].attr;
+	}
+	netvsc_dev_attrs[VRSS_SEND_TAB_SIZE] = NULL;
+}
+
+static void netvsc_attrs_exit(void)
+{
+	int i;
+
+	for (i = 0; i < VRSS_SEND_TAB_SIZE; i++)
+		kfree(dev_attr_netvsc_dev_attrs[i].attr.name);
+}
+
 static int netvsc_probe(struct hv_device *dev,
 			const struct hv_vmbus_device_id *dev_id)
 {
@@ -2410,6 +2455,7 @@  static int netvsc_probe(struct hv_device *dev,
 
 	net->netdev_ops = &device_ops;
 	net->ethtool_ops = &ethtool_ops;
+	net->sysfs_groups[0] = &netvsc_dev_group;
 	SET_NETDEV_DEV(net, &dev->device);
 
 	/* We always need headroom for rndis header */
@@ -2665,6 +2711,7 @@  static void __exit netvsc_drv_exit(void)
 {
 	unregister_netdevice_notifier(&netvsc_netdev_notifier);
 	vmbus_driver_unregister(&netvsc_drv);
+	netvsc_attrs_exit();
 }
 
 static int __init netvsc_drv_init(void)
@@ -2678,6 +2725,8 @@  static int __init netvsc_drv_init(void)
 	}
 	netvsc_ring_bytes = ring_size * PAGE_SIZE;
 
+	netvsc_attrs_init();
+
 	ret = vmbus_driver_register(&netvsc_drv);
 	if (ret)
 		return ret;