Re: [RFC] Request API questions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 17/08/18 12:02, Tomasz Figa wrote:
> On Thu, Aug 16, 2018 at 8:15 PM Mauro Carvalho Chehab
> <mchehab+samsung@xxxxxxxxxx> wrote:
>>
>> Em Thu, 16 Aug 2018 12:25:25 +0200
>> Hans Verkuil <hverkuil@xxxxxxxxx> escreveu:
>>
>>> Laurent raised a few API issues/questions in his review of the documentation.
>>>
>>> I've consolidated those in this RFC. I would like to know what others think
>>> and if I should make changes.
> 
> Thanks Hans for a nice summary and Mauro for initial input. :)
> 
>>>
>>> 1) Should you be allowed to set controls directly if they are also used in
>>>    requests? Right now this is allowed, although we warn in the spec that
>>>    this can lead to undefined behavior.
>>>
>>>    In my experience being able to do this is very useful while testing,
>>>    and restricting this is not all that easy to implement. I also think it is
>>>    not our job. It is not as if something will break when you do this.
>>>
>>>    If there really is a good reason why you can't mix this for a specific
>>>    control, then the driver can check this and return -EBUSY.
>>
>> IMHO, there's not much sense on preventing it. Just having a warning
>> at the spec is enough.
>>
> 
> I tend to agree with Mauro on this.
> 
> Besides testing, there are some legit use cases where a carefully
> programmed user space may want to choose between setting controls
> directly and via a request, depending on circumstances. For example,
> one may want to set focus position alone (potentially a big step,
> taking time), before even attempting to capture any frames and then,
> when the capture starts, move the position gradually (in small steps,
> not taking too much time) with subsequent requests, to obtain a set of
> frames with different focus position.
> 
>> +.. caution::
>> +
>> +   Setting the same control through a request and also directly can lead to
>> +   undefined behavior!
>>
>> It is already warned with a caution. Anyone that decides to ignore a
>> warning like that will deserve his faith if things stop work.
>>
>>>
>>> 2) If request_fd in QBUF or the control ioctls is not a request fd, then we
>>>    now return ENOENT. Laurent suggests using EBADR ('Invalid request descriptor')
>>>    instead. This seems like a good idea to me. Should I change this?
>>
>> I don't have a strong opinion, but EBADR value seems to be arch-dependent:
>>
>> arch/alpha/include/uapi/asm/errno.h:#define     EBADR           98      /* Invalid request descriptor */
>> arch/mips/include/uapi/asm/errno.h:#define EBADR                51      /* Invalid request descriptor */
>> arch/parisc/include/uapi/asm/errno.h:#define    EBADR           161     /* Invalid request descriptor */
>> arch/sparc/include/uapi/asm/errno.h:#define     EBADR           103     /* Invalid request descriptor */
>> include/uapi/asm-generic/errno.h:#define        EBADR           53      /* Invalid request descriptor */
>>
>> Also, just because its name says "invalid request", it doesn't mean that it
>> is the right error code. In this specific case, we're talking about a file
>> descriptor. Invalid file descriptors is something that the FS subsystem
>> has already a defined set of return codes. We should stick with whatever
>> FS uses when a file descriptor is invalid.
>>
>> Where the VFS code returns EBADR? Does it make sense for our use cases?
>>
> 
> DMA-buf framework seems to return -EINVAL if a non-DMA-buf FD is
> passed to dma_buf_get():
> https://elixir.bootlin.com/linux/v4.18.1/source/drivers/dma-buf/dma-buf.c#L497
> 
>>>
>>> 3) Calling VIDIOC_G_EXT_CTRLS for a request that has not been queued yet will
>>>    return either the value of the control you set earlier in the request, or
>>>    the current HW control value if it was never set in the request.
>>>
>>>    I believe it makes sense to return what was set in the request previously
>>>    (if you set it, you should be able to get it), but it is an idea to return
>>>    ENOENT when calling this for controls that are NOT in the request.
>>>
>>>    I'm inclined to implement that. Opinions?
>>
>> Return the request "cached" value, IMO, doesn't make sense. If the
>> application needs such cache, it can implement itself.
> 
> Can we think about any specific use cases for a user space that first
> sets a control value to a request and then needs to ask the kernel to
> get the value back? After all, it was the user space which set the
> value, so I'm not sure if there is any need for the kernel to be an
> intermediary here.
> 
>>
>> Return an error code if the request has not yet completed makes
>> sense. Not sure what would be the best error code here... if the
>> request is queued already (but not processed), EBUSY seems to be the
>> better choice, but, if it was not queued yet, I'm not sure. I guess
>> ENOENT would work.
> 
> IMHO, as far as we assign unique error codes for different conditions
> and document them well, we should be okay with any not absurdly
> mismatched code. After all, most of those codes are defined for file
> system operations and don't really map directly to anything else.
> 
> FYI, VIDIOC_G_(EXT_)CTRL returns EINVAL if an unsupported control is
> queried, so if we decided to keep the "cache" functionality after all,
> perhaps we should stay consistent with it?
> Reference: https://www.kernel.org/doc/html/latest/media/uapi/v4l/vidioc-g-ext-ctrls.html#return-value
> 
> My suggestion would be:
>  - EINVAL: the control was not in the request, (if we keep the cache
> functionality)
>  - EPERM: the value is not ready, (we selected this code for Decoder
> Interface to mean that CAPTURE format is not ready, which is similar;
> perhaps that could be consistent?)
> 
> Note that EINVAL would only apply to writable controls, while EPERM
> only to volatile controls, since the latter can only change due to
> request completion (non-volatile controls can only change as an effect
> of user space action).
> 

I'm inclined to just always return EPERM when calling G_EXT_CTRLS for
a request. We can always relax this in the future.

So when a request is not yet queued G_EXT_CTRLS returns EPERM, when
queued but not completed it returns EBUSY and once completed it will
work as it does today.

Regards,

	Hans

>>
>>>
>>> 4) When queueing a buffer to a request with VIDIOC_QBUF you set V4L2_BUF_FLAG_REQUEST_FD
>>>    to indicate a valid request_fd. For other queue ioctls that take a struct v4l2_buffer
>>>    this flag and the request_fd field are just ignored. Should we return EINVAL
>>>    instead if the flag is set for those ioctls?
>>>
>>>    The argument for just ignoring it is that older kernels that do not know about
>>>    this flag will ignore it as well. There is no check against unknown flags.
>>
>> As I answered before, I don't see any need to add extra code for checking invalid
>> flags.
>>
>> It might make sense to ask users to clean the flag if not QBUF, just at the
>> eventual remote case we might want to use it on other ioctls.
> 
> Agreed with Mauro on this.
> 
> Best regards,
> Tomasz
> 




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux