Linux Documentation
 help / color / mirror / Atom feed
From: Krishna Kurapati PSSNV <quic_kriskura@quicinc.com>
To: "Maciej Żenczykowski" <maze@google.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	onathan Corbet <corbet@lwn.net>,
	Linyu Yuan <quic_linyyuan@quicinc.com>,
	<linux-usb@vger.kernel.org>, <linux-doc@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <quic_ppratap@quicinc.com>,
	<quic_wcheng@quicinc.com>, <quic_jackp@quicinc.com>
Subject: Re: [PATCH 2/2] usb: gadget: ncm: Add support to update wMaxSegmentSize via configfs
Date: Tue, 10 Oct 2023 10:08:10 +0530	[thread overview]
Message-ID: <d19d9d08-c119-4991-b460-49925f601d15@quicinc.com> (raw)
In-Reply-To: <CANP3RGdY4LsOA6U5kuccApHCzL0_jBnY=pLOYrUuYtMZFTvnbw@mail.gmail.com>



On 10/10/2023 6:07 AM, Maciej Żenczykowski wrote:
> On Mon, Oct 9, 2023 at 5:20 PM Maciej Żenczykowski <maze@google.com> wrote:
>>
>> On Mon, Oct 9, 2023 at 5:17 PM Maciej Żenczykowski <maze@google.com> wrote:
>>>
>>> On Mon, Oct 9, 2023 at 7:20 AM Krishna Kurapati
>>> <quic_kriskura@quicinc.com> wrote:
>>>>
>>>> Currently the NCM driver restricts wMaxSegmentSize that indicates
>>>> the datagram size coming from network layer to 1514. However the
>>>> spec doesn't have any limitation. For P2P connections over NCM,
>>>> increasing MTU helps increasing throughput.
>>>>
>>>> Add support to configure this value before configfs symlink is
>>>> created. Also since the NTB Out/In buffer sizes are fixed at 16384
>>>> bytes, limit the segment size to an upper cap of 15014. Set the
>>>> default MTU size for the ncm interface during function bind before
>>>> network interface is registered allowing MTU to be set in parity
>>>> with wMaxSegmentSize.
>>>>
>>>> Signed-off-by: Krishna Kurapati <quic_kriskura@quicinc.com>
>>>> ---
>>>>   drivers/usb/gadget/function/f_ncm.c | 51 +++++++++++++++++++++++++++++
>>>>   drivers/usb/gadget/function/u_ncm.h |  2 ++
>>>>   2 files changed, 53 insertions(+)
>>>>
>>>> diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c
>>>> index feccf4c8cc4f..eab297b22200 100644
>>>> --- a/drivers/usb/gadget/function/f_ncm.c
>>>> +++ b/drivers/usb/gadget/function/f_ncm.c
>>>> @@ -103,6 +103,8 @@ static inline struct f_ncm *func_to_ncm(struct usb_function *f)
>>>>   /* Delay for the transmit to wait before sending an unfilled NTB frame. */
>>>>   #define TX_TIMEOUT_NSECS       300000
>>>>
>>>> +#define MAX_DATAGRAM_SIZE      15014
>>>> +
>>>>   #define FORMATS_SUPPORTED      (USB_CDC_NCM_NTB16_SUPPORTED |  \
>>>>                                   USB_CDC_NCM_NTB32_SUPPORTED)
>>>>
>>>> @@ -1408,6 +1410,7 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
>>>>          ncm_opts = container_of(f->fi, struct f_ncm_opts, func_inst);
>>>>
>>>>          if (cdev->use_os_string) {
>>>> +               ncm_opts->net->mtu = (ncm_opts->max_segment_size - ETH_HLEN);
>>>>                  f->os_desc_table = kzalloc(sizeof(*f->os_desc_table),
>>>>                                             GFP_KERNEL);
>>>>                  if (!f->os_desc_table)
>>>> @@ -1469,6 +1472,8 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
>>>>
>>>>          status = -ENODEV;
>>>>
>>>> +       ecm_desc.wMaxSegmentSize = ncm_opts->max_segment_size;
>>>
>>> I think you need byte swap here.
>>>
>>>> +
>>>>          /* allocate instance-specific endpoints */
>>>>          ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_in_desc);
>>>>          if (!ep)
>>>> @@ -1569,11 +1574,56 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(ncm);
>>>>   /* f_ncm_opts_ifname */
>>>>   USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(ncm);
>>>>
>>>> +static ssize_t ncm_opts_max_segment_size_show(struct config_item *item,
>>>> +                                             char *page)
>>>> +{
>>>> +       struct f_ncm_opts *opts = to_f_ncm_opts(item);
>>>> +       u32 segment_size;
>>>> +
>>>> +       mutex_lock(&opts->lock);
>>>> +       segment_size = opts->max_segment_size;
>>>> +       mutex_unlock(&opts->lock);
>>>> +
>>>> +       return sprintf(page, "%u\n", segment_size);
>>>> +}
>>>> +
>>>> +static ssize_t ncm_opts_max_segment_size_store(struct config_item *item,
>>>> +                                              const char *page, size_t len)
>>>> +{
>>>> +       struct f_ncm_opts *opts = to_f_ncm_opts(item);
>>>> +       int ret;
>>>> +       u32 segment_size;
>>>> +
>>>> +       mutex_lock(&opts->lock);
>>>> +       if (opts->refcnt) {
>>>> +               ret = -EBUSY;
>>>> +               goto out;
>>>> +       }
>>>> +
>>>> +       ret = kstrtou32(page, 0, &segment_size);
>>>> +       if (ret)
>>>> +               goto out;
>>>> +
>>>> +       if (segment_size > MAX_DATAGRAM_SIZE) {
>>>> +               ret = -EINVAL;
>>>> +               goto out;
>>>> +       }
>>>> +
>>>> +       opts->max_segment_size = segment_size;
>>>> +       ret = len;
>>>> +out:
>>>> +       mutex_unlock(&opts->lock);
>>>> +       return ret;
>>>> +}
>>>> +
>>>> +CONFIGFS_ATTR(ncm_opts_, max_segment_size);
>>>> +
>>>>   static struct configfs_attribute *ncm_attrs[] = {
>>>>          &ncm_opts_attr_dev_addr,
>>>>          &ncm_opts_attr_host_addr,
>>>>          &ncm_opts_attr_qmult,
>>>>          &ncm_opts_attr_ifname,
>>>> +       &ncm_opts_attr_max_segment_size,
>>>>          NULL,
>>>>   };
>>>>
>>>> @@ -1616,6 +1666,7 @@ static struct usb_function_instance *ncm_alloc_inst(void)
>>>>                  kfree(opts);
>>>>                  return ERR_CAST(net);
>>>>          }
>>>> +       opts->max_segment_size = cpu_to_le16(ETH_FRAME_LEN);
>>>
>>> and not here.  ie. max_segment_size should be native endian
>>>
>>>>          INIT_LIST_HEAD(&opts->ncm_os_desc.ext_prop);
>>>>
>>>>          descs[0] = &opts->ncm_os_desc;
>>>> diff --git a/drivers/usb/gadget/function/u_ncm.h b/drivers/usb/gadget/function/u_ncm.h
>>>> index 5408854d8407..d3403cf13f17 100644
>>>> --- a/drivers/usb/gadget/function/u_ncm.h
>>>> +++ b/drivers/usb/gadget/function/u_ncm.h
>>>> @@ -31,6 +31,8 @@ struct f_ncm_opts {
>>>>           */
>>>>          struct mutex                    lock;
>>>>          int                             refcnt;
>>>> +
>>>> +       u32                             max_segment_size;
>>>>   };
>>>>
>>>>   #endif /* U_NCM_H */
>>>> --
>>>> 2.42.0
>>>>
>>>
>>> That said, I don't really follow what this is doing...
>>
>> Also
>>
>> static struct usb_cdc_ether_desc ecm_desc = {
>> ...
>> .wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN),
>>
>> ^ I think this should be deleted now, right?  since it's always overwritten?
>> And if it isn't always overwritten, that would be a bug I think, cause
>> what happens if you bring up 2 ncm devices and only change the setting
>> on the 1st?
> 
> One last thing...
> 
> static int ncm_unwrap_ntb(struct gether *port,
> ...
> unsigned frame_max = le16_to_cpu(ecm_desc.wMaxSegmentSize);
> 
> ^ is this a problem now if we have >1 gadget?
> how does it work then?


You are right. This would effect unwrap call and the wMaxSegmentSize is 
used directly. Thanks for the catch. I didn't test with 2 NCM interfaces 
and hence I wasn't able to find this bug. Perhaps changing this to 
opts->max_segment_size would fix the implementation as unwrap would 
anyways be called after bind.

Regards,
Krishna,

  reply	other threads:[~2023-10-10  4:38 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-09 14:20 [PATCH 1/2] Documentation: usb: Update NCM configfs parameters Krishna Kurapati
2023-10-09 14:20 ` [PATCH 2/2] usb: gadget: ncm: Add support to update wMaxSegmentSize via configfs Krishna Kurapati
2023-10-09 15:08   ` Greg Kroah-Hartman
2023-10-09 15:32     ` Krishna Kurapati PSSNV
2023-10-09 17:54       ` Greg Kroah-Hartman
2023-10-09 18:27         ` Krishna Kurapati PSSNV
2023-10-10  0:17   ` Maciej Żenczykowski
2023-10-10  0:20     ` Maciej Żenczykowski
2023-10-10  0:37       ` Maciej Żenczykowski
2023-10-10  4:38         ` Krishna Kurapati PSSNV [this message]
2023-10-12  8:48           ` Krishna Kurapati PSSNV
2023-10-12 12:32             ` Maciej Żenczykowski
2023-10-12 15:40               ` Krishna Kurapati PSSNV
2023-10-13 18:39                 ` Maciej Żenczykowski
2023-10-13 18:40                   ` Maciej Żenczykowski
2023-10-13 19:58                   ` Krishna Kurapati PSSNV
2023-10-13 22:35                     ` Maciej Żenczykowski
2023-10-14  7:02                       ` Krishna Kurapati PSSNV
2023-10-14  8:23                         ` Krishna Kurapati PSSNV
2023-10-16  1:19                           ` Maciej Żenczykowski
2023-10-16  3:48                             ` Krishna Kurapati PSSNV
2023-10-10  4:34       ` Krishna Kurapati PSSNV
2023-10-10  4:27     ` Krishna Kurapati PSSNV
2023-10-10 22:26   ` kernel test robot
2023-10-09 15:05 ` [PATCH 1/2] Documentation: usb: Update NCM configfs parameters Greg Kroah-Hartman
2023-10-09 15:10   ` Krishna Kurapati PSSNV
2023-10-09 15:21     ` Greg Kroah-Hartman
2023-10-09 15:33       ` Krishna Kurapati PSSNV
2023-10-09 15:42         ` Greg Kroah-Hartman

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=d19d9d08-c119-4991-b460-49925f601d15@quicinc.com \
    --to=quic_kriskura@quicinc.com \
    --cc=corbet@lwn.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=maze@google.com \
    --cc=quic_jackp@quicinc.com \
    --cc=quic_linyyuan@quicinc.com \
    --cc=quic_ppratap@quicinc.com \
    --cc=quic_wcheng@quicinc.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox