linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Felipe Balbi <balbi@kernel.org>
To: Andrey Konovalov <andreyknvl@google.com>
Cc: USB list <linux-usb@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jonathan Corbet <corbet@lwn.net>,
	Alan Stern <stern@rowland.harvard.edu>,
	Dmitry Vyukov <dvyukov@google.com>,
	Alexander Potapenko <glider@google.com>,
	Marco Elver <elver@google.com>
Subject: Re: [PATCH v5 1/1] usb: gadget: add raw-gadget interface
Date: Wed, 05 Feb 2020 18:42:41 +0200	[thread overview]
Message-ID: <87tv4556ke.fsf@kernel.org> (raw)
In-Reply-To: <CAAeHK+zNuqwmHG4NJwZNtQHizdaOpriHxoQffZHMffeke_hsGQ@mail.gmail.com>

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


Hi,

Andrey Konovalov <andreyknvl@google.com> writes:
>> >> > +static int raw_event_queue_add(struct raw_event_queue *queue,
>> >> > +     enum usb_raw_event_type type, size_t length, const void *data)
>> >> > +{
>> >> > +     unsigned long flags;
>> >> > +     struct usb_raw_event *event;
>> >> > +
>> >> > +     spin_lock_irqsave(&queue->lock, flags);
>> >> > +     if (WARN_ON(queue->size >= RAW_EVENT_QUEUE_SIZE)) {
>> >> > +             spin_unlock_irqrestore(&queue->lock, flags);
>> >> > +             return -ENOMEM;
>> >> > +     }
>> >> > +     event = kmalloc(sizeof(*event) + length, GFP_ATOMIC);
>> >>
>> >> I would very much prefer dropping GFP_ATOMIC here. Must you have this
>> >> allocation under a spinlock?
>> >
>> > The issue here is not the spinlock, but that this might be called in
>> > interrupt context. The number of atomic allocations here is restricted
>> > by 128, and we can reduce the limit even further (until some point in
>> > the future when and if we'll report more different events). Another
>> > option would be to preallocate the required number of objects
>> > (although we don't know the required size in advance, so we'll waste
>> > some memory) and use those. What would you prefer?
>>
>> I think you shouldn't do either :-) Here's what I think you should do:
>>
>> 1. support O_NONBLOCK. This just means conditionally removing your
>>    wait_for_completion_interruptible().
>
> I don't think non blocking read/writes will work for us. We do
> coverage-guided fuzzing and need to collect coverage for each syscall.
> In the USB case "syscall" means processing a USB request from start to
> end, and thus we need to wait until the kernel finishes processing it,
> otherwise we'll fail to associate coverage properly (It's actually a
> bit more complex, as we collect coverage for the whole initial
> enumeration process as for one "syscall", but the general idea stands,
> that we need to wait until the operation finishes.)

Fair enough, but if the only use case that this covers, is a testing
scenario, we don't gain much from accepting this upstream, right? We can
still support both block and nonblock, but let's at least give the
option.

>> 2. Every time user calls write(), you usb_ep_alloc(), allocate a buffer
>>    with the write size, copy buffer to kernel space,
>>    usb_ep_queue(). When complete() callback is called, then you free the
>>    request. This would allow us to amortize the cost of copy_from_user()
>>    with several requests being queued to USB controller.
>
> I'm not sure I really get this part. We'll still need to call
> copy_from_user() and usb_ep_queue() once per each operation/request.
> How does it get amortized? Or do you mean that having multiple
> requests queued will allow USB controller to process them in bulk?

yes :-)

> This makes sense, but again, we"ll then have an issue with coverage
> association.

You can still enqueue one by one, but this would turn your raw-gadget
interface more interesting for other use cases.

>> 3. Have a pre-allocated list of requests (128?) for read(). Enqueue them
>>    all during set_alt(). When user calls read() you will:
>>
>>    a) check if there are completed requests to be copied over to
>>       userspace. Recycle the request.
>>
>>    b) if there are no completed requests, then it depends on O_NONBLOCK
>>
>>       i) If O_NONBLOCK, return -EWOULDBLOCK
>>       ii) otherwise, wait_for_completion
>
> See response to #1, if we prequeue requests, then the kernel will
> start handling them before we do read(), and we'll fail to associate
> coverage properly. (This will also require adding another ioctl to
> imitate set_alt(), like the USB_RAW_IOCTL_CONFIGURE that we have.)

set_alt() needs to be supported if we're aiming at providing support for
various USB classes to be implemented on top of what you created :-)

>> I think this can all be done without any GFP_ATOMIC allocations.
>
> Overall, supporting O_NONBLOCK might be a useful feature for people
> who are doing something else other than fuzzing, We can account for
> potential future extensions that'll support it, so detecting
> O_NONBLOCK and returning an error for now makes sense.
>
> WDYT?

If that's the way you want to go, that's okay. But let's, then, prepare
the code for extension later on. For example, let's add an IOCTL which
returns the "version" of the ABI. Based on that, userspace can detect
features and so on.

cheers

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

  reply	other threads:[~2020-02-05 16:42 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-14 13:24 [PATCH v5 0/1] usb: gadget: add raw-gadget interface Andrey Konovalov
2020-01-14 13:24 ` [PATCH v5 1/1] " Andrey Konovalov
2020-01-14 14:00   ` Greg Kroah-Hartman
2020-01-22 14:37   ` Andrey Konovalov
2020-01-22 14:50     ` Greg Kroah-Hartman
2020-01-27 12:27       ` Andrey Konovalov
2020-01-31 13:42   ` Felipe Balbi
2020-01-31 14:43     ` Andrey Konovalov
2020-01-31 15:22       ` Felipe Balbi
2020-02-03 18:08         ` Andrey Konovalov
2020-02-05 16:42           ` Felipe Balbi [this message]
2020-02-05 17:25             ` Andrey Konovalov
2020-02-05 21:18               ` Greg Kroah-Hartman
2020-02-06  6:19               ` Felipe Balbi
2020-02-06 19:21                 ` Andrey Konovalov
2020-02-05 21:18             ` Greg Kroah-Hartman
2020-02-06  6:14               ` Felipe Balbi
2020-01-31 21: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=87tv4556ke.fsf@kernel.org \
    --to=balbi@kernel.org \
    --cc=andreyknvl@google.com \
    --cc=corbet@lwn.net \
    --cc=dvyukov@google.com \
    --cc=elver@google.com \
    --cc=glider@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=stern@rowland.harvard.edu \
    /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;
as well as URLs for NNTP newsgroup(s).