All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Bjørn Mork" <bjorn@mork.no>
To: Lars Melin <larsm17@gmail.com>
Cc: Peter Stuge <peter@stuge.se>, Enrico Mioso <mrkiko.rs@gmail.com>,
	David Miller <davem@davemloft.net>,
	netdev@vger.kernel.org, linux-usb@vger.kernel.org,
	alexey.orishko@gmail.com, oliver@neukum.org,
	David.Laight@aculab.com, Greg Suarez <gsuarez@smithmicro.com>
Subject: Re: [PATCH net-next v2 00/12] cdc_ncm: add buffer tuning and stats using ethtool
Date: Tue, 20 May 2014 09:36:57 +0200	[thread overview]
Message-ID: <87tx8k295y.fsf@nemi.mork.no> (raw)
In-Reply-To: <87egzqmd8h.fsf@nemi.mork.no> ("Bjørn Mork"'s message of "Mon, 19 May 2014 09:36:30 +0200")

[-- Attachment #1: Type: text/plain, Size: 2659 bytes --]

[adding Greg Suarez to the Cc list after noticing that he was missing
 from this thread.  Sorry Greg, that was not my intention.  This
 discussion is just as relevant to cdc_mbim as to cdc_ncm, defining a
 new common userspace API for all the cdc_ncm based drivers]

Bjørn Mork <bjorn@mork.no> writes:
> Lars Melin <larsm17@gmail.com> writes:
>
>> Your target audience is embedded systems with limited cpu power and
>> buffer memory, right?
>> If so, then you can't expect them to have ethtool included and their
>> developers are not likely to be happy over having to "waste" another
>> 100KB in order to tune a 20KB driver.
>> My vote goes for sysfs.
>
> That's of course a very good point.
>
> I will argue that you often need ethtool anyway for basic stuff like
> forcing duplex/speed, enabling debug messages, turning on/off pause
> frames etc.  But I don't doubt you know what you are talking about here
> :-)  So I guess many small embedded devices don't include an ethtool
> binary by default.  I do wonder how much we should adapt to that though?
> I understand that you don't see it this way, but others might actually
> see it as an advantage if we're forcing ethtool onto these devices...
>
> Anyway, I'll start looking at an alternative sysfs implementation so we
> can discuss this in terms of actual code.

As this is just a very informal RFC, I'm just attaching the patch to
this mail.  Please test and/or comment.

The patch works for me.  It doesn't remove the ethtool coalescing
support, but I will do that in the final submission if we decide to go
for this sysfs interface instead.

Example output:

 bjorn@nemi:~$ grep . /sys/class/net/wwan0/cdc_ncm/*
 /sys/class/net/wwan0/cdc_ncm/rx_max:16384
 /sys/class/net/wwan0/cdc_ncm/tx_max:4096
 /sys/class/net/wwan0/cdc_ncm/tx_timer_usecs:400

I should probably also add a bit more sanity checking of the input for
the final submission. Maybe even make sure the buffers match the
alignment?  Or should that be up to the user?

But we could add information about the device alignment requirements so
that the end user (or userspace application) can make informed decisions.
The whole NTB parameter struct is vital information which is currently only
available for userspace in a debug log message.  Exporting it as a set
of sysfs read only attributes would be nice.  Maybe?  Or am I just
overdoing things now?

It's also tempting to add the 'timer restart count' to this API.  I left
it out of the ethtool based version because I couldn't make it fit
anywhere.  But it is part of the driver's frame aggregation algorithm.


Bjørn



[-- Attachment #2: 0001-net-cdc_ncm-add-sysfs-support-for-buffer-tuning.patch --]
[-- Type: text/x-diff, Size: 6729 bytes --]

>From 017c9fc8702132ed76b9c28a196203b1788ef4c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
Date: Mon, 19 May 2014 16:08:49 +0200
Subject: [RFC] net: cdc_ncm: add sysfs support for buffer tuning
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Adding a sysfs group to the network device, allowing tuning of
buffers and tx timer.

Signed-off-by: Bjørn Mork <bjorn@mork.no>
---
 drivers/net/usb/cdc_ncm.c | 143 ++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 124 insertions(+), 19 deletions(-)

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index ad2a386a6e92..30b943200ca3 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -191,11 +191,9 @@ static const struct ethtool_ops cdc_ncm_ethtool_ops = {
 	.set_coalesce      = cdc_ncm_set_coalesce,
 };
 
-/* handle rx_max and tx_max changes */
-static void cdc_ncm_update_rxtx_max(struct usbnet *dev, u32 new_rx, u32 new_tx)
+static u32 cdc_ncm_check_rx_max(struct usbnet *dev, u32 new_rx)
 {
 	struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
-	u8 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
 	u32 val, max, min;
 
 	/* clamp new_rx to sane values */
@@ -210,10 +208,125 @@ static void cdc_ncm_update_rxtx_max(struct usbnet *dev, u32 new_rx, u32 new_tx)
 	}
 
 	val = clamp_t(u32, new_rx, min, max);
-	if (val != new_rx) {
-		dev_dbg(&dev->intf->dev, "rx_max must be in the [%u, %u] range. Using %u\n",
-			min, max, val);
-	}
+	if (val != new_rx)
+		dev_dbg(&dev->intf->dev, "rx_max must be in the [%u, %u] range\n", min, max);
+
+	return val;
+}
+
+static u32 cdc_ncm_check_tx_max(struct usbnet *dev, u32 new_tx)
+{
+	struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+	u32 val, max, min;
+
+	/* clamp new_tx to sane values */
+	min = ctx->max_datagram_size + ctx->max_ndp_size + sizeof(struct usb_cdc_ncm_nth16);
+	max = min_t(u32, CDC_NCM_NTB_MAX_SIZE_TX, le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize));
+
+	/* some devices set dwNtbOutMaxSize too low for the above default */
+	min = min(min, max);
+
+	val = clamp_t(u32, new_tx, min, max);
+	if (val != new_tx)
+		dev_dbg(&dev->intf->dev, "tx_max must be in the [%u, %u] range\n", min, max);
+
+	return val;
+}
+
+/* sysfs attributes */
+static ssize_t cdc_ncm_show_rx_max(struct device *d, struct device_attribute *attr, char *buf)
+{
+	struct usbnet *dev = netdev_priv(to_net_dev(d));
+	struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+
+	return sprintf(buf, "%u\n", ctx->rx_max);
+}
+static ssize_t cdc_ncm_show_tx_max(struct device *d, struct device_attribute *attr, char *buf)
+{
+	struct usbnet *dev = netdev_priv(to_net_dev(d));
+	struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+
+	return sprintf(buf, "%u\n", ctx->tx_max);
+}
+static ssize_t cdc_ncm_show_tx_timer_usecs(struct device *d, struct device_attribute *attr, char *buf)
+{
+	struct usbnet *dev = netdev_priv(to_net_dev(d));
+	struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+
+	return sprintf(buf, "%u\n", ctx->timer_interval / (u32)NSEC_PER_USEC);
+}
+
+static ssize_t cdc_ncm_store_rx_max(struct device *d,  struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct usbnet *dev = netdev_priv(to_net_dev(d));
+	struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+	unsigned long val;
+
+	if (kstrtoul(buf, 0, &val) || cdc_ncm_check_rx_max(dev, val) != val)
+		return -EINVAL;
+
+	cdc_ncm_update_rxtx_max(dev, val, ctx->tx_max);
+	return len;
+}
+
+static ssize_t cdc_ncm_store_tx_max(struct device *d,  struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct usbnet *dev = netdev_priv(to_net_dev(d));
+	struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+	unsigned long val;
+
+	if (kstrtoul(buf, 0, &val) || cdc_ncm_check_tx_max(dev, val) != val)
+		return -EINVAL;
+
+	cdc_ncm_update_rxtx_max(dev, ctx->rx_max, val);
+	return len;
+}
+
+static ssize_t cdc_ncm_store_tx_timer_usecs(struct device *d,  struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct usbnet *dev = netdev_priv(to_net_dev(d));
+	struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+	ssize_t ret;
+	unsigned long val;
+
+	ret = kstrtoul(buf, 0, &val);
+	if (ret)
+		return ret;
+	if (val && (val < CDC_NCM_TIMER_INTERVAL_MIN || val > CDC_NCM_TIMER_INTERVAL_MAX))
+		return -EINVAL;
+
+	spin_lock_bh(&ctx->mtx);
+	ctx->timer_interval = val * NSEC_PER_USEC;
+	if (!ctx->timer_interval)
+		ctx->tx_timer_pending = 0;
+	spin_unlock_bh(&ctx->mtx);
+	return len;
+}
+
+static DEVICE_ATTR(rx_max, S_IRUGO | S_IWUSR, cdc_ncm_show_rx_max, cdc_ncm_store_rx_max);
+static DEVICE_ATTR(tx_max, S_IRUGO | S_IWUSR, cdc_ncm_show_tx_max, cdc_ncm_store_tx_max);
+static DEVICE_ATTR(tx_timer_usecs, S_IRUGO | S_IWUSR, cdc_ncm_show_tx_timer_usecs, cdc_ncm_store_tx_timer_usecs);
+
+static struct attribute *cdc_ncm_sysfs_attrs[] = {
+	&dev_attr_rx_max.attr,
+	&dev_attr_tx_max.attr,
+	&dev_attr_tx_timer_usecs.attr,
+	NULL,
+};
+
+static struct attribute_group cdc_ncm_sysfs_attr_group = {
+	.name = "cdc_ncm",
+	.attrs = cdc_ncm_sysfs_attrs,
+};
+
+/* handle rx_max and tx_max changes */
+static void cdc_ncm_update_rxtx_max(struct usbnet *dev, u32 new_rx, u32 new_tx)
+{
+	struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+	u8 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
+	u32 val;
+
+	val = cdc_ncm_check_rx_max(dev, new_rx);
 
 	/* usbnet use these values for sizing rx queues */
 	dev->rx_urb_size = val;
@@ -238,18 +351,7 @@ static void cdc_ncm_update_rxtx_max(struct usbnet *dev, u32 new_rx, u32 new_tx)
 			ctx->rx_max = val;
 	}
 
-	/* clamp new_tx to sane values */
-	min = ctx->max_datagram_size + ctx->max_ndp_size + sizeof(struct usb_cdc_ncm_nth16);
-	max = min_t(u32, CDC_NCM_NTB_MAX_SIZE_TX, le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize));
-
-	/* some devices set dwNtbOutMaxSize too low for the above default */
-	min = min(min, max);
-
-	val = clamp_t(u32, new_tx, min, max);
-	if (val != new_tx) {
-		dev_dbg(&dev->intf->dev, "tx_max must be in the [%u, %u] range. Using %u\n",
-			min, max, val);
-	}
+	val = cdc_ncm_check_tx_max(dev, new_tx);
 	if (val != ctx->tx_max)
 		dev_info(&dev->intf->dev, "setting tx_max = %u\n", val);
 
@@ -743,6 +845,9 @@ advance:
 	/* override ethtool_ops */
 	dev->net->ethtool_ops = &cdc_ncm_ethtool_ops;
 
+	/* add our sysfs attrs */
+	dev->net->sysfs_groups[0] = &cdc_ncm_sysfs_attr_group;
+
 	return 0;
 
 error2:
-- 
2.0.0.rc2


  reply	other threads:[~2014-05-20  7:38 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-16 19:48 [PATCH net-next v2 00/12] cdc_ncm: add buffer tuning and stats using ethtool Bjørn Mork
2014-05-16 19:48 ` [PATCH net-next v2 01/12] net: cdc_ncm: split out rx_max/tx_max update of setup Bjørn Mork
2014-05-16 19:48 ` [PATCH net-next v2 02/12] net: cdc_ncm: factor out one-time device initialization Bjørn Mork
2014-05-16 19:48 ` [PATCH net-next v2 03/12] net: cdc_ncm: split .bind " Bjørn Mork
2014-05-16 19:48 ` [PATCH net-next v2 04/12] net: cdc_ncm: support rx_max/tx_max updates when running Bjørn Mork
2014-05-16 19:48 ` [PATCH net-next v2 05/12] net: cdc_ncm: use ethtool to tune coalescing settings Bjørn Mork
2014-05-16 19:48 ` [PATCH net-next v2 06/12] net: cdc_ncm: use true max dgram count for header estimates Bjørn Mork
     [not found] ` <1400269709-18854-1-git-send-email-bjorn-yOkvZcmFvRU@public.gmane.org>
2014-05-16 19:48   ` [PATCH net-next v2 07/12] net: cdc_ncm: set reasonable padding limits Bjørn Mork
2014-05-16 19:48   ` [PATCH net-next v2 08/12] net: cdc_ncm/cdc_mbim: adding NCM protocol statistics Bjørn Mork
2014-05-16 19:48   ` [PATCH net-next v2 09/12] net: cdc_ncm: use sane defaults for rx/tx buffers Bjørn Mork
2014-05-17  2:40   ` [PATCH net-next v2 00/12] cdc_ncm: add buffer tuning and stats using ethtool David Miller
     [not found]     ` <20140516.224032.2301577488192248796.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
2014-05-17  6:46       ` Bjørn Mork
     [not found]         ` <87d2fcoqay.fsf-lbf33ChDnrE/G1V5fR+Y7Q@public.gmane.org>
2014-05-18  1:19           ` Peter Stuge
2014-05-18  9:57             ` Enrico Mioso
     [not found]               ` <alpine.LNX.2.03.1405181155310.7743-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2014-05-18 14:50                 ` Bjørn Mork
2014-05-18 17:10                   ` Lars Melin
2014-05-19  7:36                     ` Bjørn Mork
2014-05-20  7:36                       ` Bjørn Mork [this message]
     [not found]                       ` <87egzqmd8h.fsf-lbf33ChDnrE/G1V5fR+Y7Q@public.gmane.org>
2014-06-08 22:02                         ` Ben Hutchings
2014-05-18 22:08                   ` David Miller
2014-05-16 19:48 ` [PATCH net-next v2 10/12] net: cdc_ncm: fix argument alignment Bjørn Mork
2014-05-16 19:48 ` [PATCH net-next v2 11/12] net: cdc_ncm: remove redundant "disconnected" flag Bjørn Mork
2014-05-16 19:48 ` [PATCH net-next v2 12/12] net: cdc_ncm: do not start timer on an empty skb Bjørn Mork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87tx8k295y.fsf@nemi.mork.no \
    --to=bjorn@mork.no \
    --cc=David.Laight@aculab.com \
    --cc=alexey.orishko@gmail.com \
    --cc=davem@davemloft.net \
    --cc=gsuarez@smithmicro.com \
    --cc=larsm17@gmail.com \
    --cc=linux-usb@vger.kernel.org \
    --cc=mrkiko.rs@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=oliver@neukum.org \
    --cc=peter@stuge.se \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.