diff mbox series

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

Message ID alpine.LRH.2.23.451.2007192357400.30908@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.inter
State Superseded
Delegated to: David Miller
Headers show
Series [v2,net-next] net: hyperv: Add attributes to show TX indirection table | expand

Commit Message

Chi Song July 20, 2020, 7:12 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>
---
v2: remove RX as it's in ethtool already, show single value in each file,
 and update description.

Thank you for comments. Let me know, if I miss something.

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

+
 static int netvsc_probe(struct hv_device *dev,
 			const struct hv_vmbus_device_id *dev_id)
 {
@@ -2396,6 +2445,7 @@ static int netvsc_probe(struct hv_device *dev,
 			   net_device_ctx->msg_enable);

 	hv_set_drvdata(dev, net);
+	netvsc_attrs_init();

 	INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change);

@@ -2410,6 +2460,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 */
@@ -2533,6 +2584,7 @@ static int netvsc_remove(struct hv_device *dev)

 	rtnl_unlock();

+	netvsc_attrs_exit();
 	hv_set_drvdata(dev, NULL);

 	free_percpu(ndev_ctx->vf_stats);
@@ -2683,6 +2735,7 @@ static int __init netvsc_drv_init(void)
 		return ret;

 	register_netdevice_notifier(&netvsc_netdev_notifier);
+
 	return 0;
 }

Comments

Stephen Hemminger July 20, 2020, 5:24 p.m. UTC | #1
On Mon, 20 Jul 2020 00:12:10 -0700 (PDT)
Chi Song <chisong@linux.microsoft.com> wrote:

> 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>
> ---


> v2: remove RX as it's in ethtool already, show single value in each file,
>  and update description.
> 
> Thank you for comments. Let me know, if I miss something.
> 
> ---
>  drivers/net/hyperv/netvsc_drv.c | 53 +++++++++++++++++++++++++++++++++
>  1 file changed, 53 insertions(+)
> 
> diff --git a/drivers/net/hyperv/netvsc_drv.c
> b/drivers/net/hyperv/netvsc_drv.c
> index 6267f706e8ee..222c2fad9300 100644
> --- a/drivers/net/hyperv/netvsc_drv.c
> +++ b/drivers/net/hyperv/netvsc_drv.c
> @@ -2370,6 +2370,55 @@ 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 = NULL,
> +	.attrs = netvsc_dev_attrs,
> +};
> +
> +static ssize_t tx_indirection_table_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);
> +	ssize_t offset = 0;

useless initialization

> +	int index = dev_attr - dev_attr_netvsc_dev_attrs;
> +
> +	offset = sprintf(buf, "%u\n", ndc->tx_table[index]);
> +
> +	return offset;
why not just
	return sprintf(buf, "%u\n", ndc->tx_table[index]);
> +}
> +
> +static void netvsc_attrs_init(void)
> +{
> +	int i;
> +	char buffer[32];
> +
> +	for (i = 0; i < VRSS_SEND_TAB_SIZE; i++) {
> +		sprintf(buffer, "tx_indirection_table_%02u", i);

Although this has one value per file it leads to a mess.
Why not put it in a separate directory (/sys/class/net/eth0/tx_indirection/N)?
diff mbox series

Patch

diff --git a/drivers/net/hyperv/netvsc_drv.c
b/drivers/net/hyperv/netvsc_drv.c
index 6267f706e8ee..222c2fad9300 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -2370,6 +2370,55 @@  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 = NULL,
+	.attrs = netvsc_dev_attrs,
+};
+
+static ssize_t tx_indirection_table_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);
+	ssize_t offset = 0;
+	int index = dev_attr - dev_attr_netvsc_dev_attrs;
+
+	offset = sprintf(buf, "%u\n", ndc->tx_table[index]);
+
+	return offset;
+}
+
+static void netvsc_attrs_init(void)
+{
+	int i;
+	char buffer[32];
+
+	for (i = 0; i < VRSS_SEND_TAB_SIZE; i++) {
+		sprintf(buffer, "tx_indirection_table_%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_table_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);
+}