Re: [RFCv12 PATCH 03/29] media-request: implement media requests

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

 



On 03/05/18 12:12, Sakari Ailus wrote:
> On Thu, May 03, 2018 at 10:21:32AM +0200, Hans Verkuil wrote:
>> On 03/05/18 00:24, Sakari Ailus wrote:
>>> Hi Hans,
>>>
>>> On Tue, May 01, 2018 at 11:00:25AM +0200, Hans Verkuil wrote:
> ...
>>>> +
>>>> +static int media_request_close(struct inode *inode, struct file *filp)
>>>> +{
>>>> +	struct media_request *req = filp->private_data;
>>>> +
>>>> +	media_request_put(req);
>>>
>>> A newline would be nice here.
>>
>> Why? I do not see it adding anything of value. Some of your other 'newline'
>> comments make it indeed more readable, but I don't see any benefit from it
>> here.
> 
> I'd think it's nice to have an empty line before return if it's detached
> from everything else.
> 
>>
>>>
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static unsigned int media_request_poll(struct file *filp,
>>>> +				       struct poll_table_struct *wait)
>>>> +{
>>>> +	struct media_request *req = filp->private_data;
>>>> +	unsigned long flags;
>>>> +	unsigned int ret = 0;
>>>> +	enum media_request_state state;
>>>> +
>>>> +	if (!(poll_requested_events(wait) & POLLPRI))
>>>> +		return 0;
>>>> +
>>>> +	spin_lock_irqsave(&req->lock, flags);
>>>> +	state = atomic_read(&req->state);
>>>> +
>>>> +	if (state == MEDIA_REQUEST_STATE_COMPLETE) {
>>>> +		ret = POLLPRI;
>>>> +		goto unlock;
>>>> +	}
>>>> +	if (state == MEDIA_REQUEST_STATE_IDLE) {
>>>
>>> Should this be just anything else than QUEUE or VALIDATING? You're missing
>>> CLEANING here, for instance.
>>
>> I changed it to != QUEUED. I don't think it is a good idea to include VALIDATING
>> in this. It only makes sense to poll for the result if the request is fully queued.
> 
> Sounds good.
> 
> ...
> 
>>>> +	/*
>>>> +	 * If the req_validate was successful, then we mark the state as QUEUED
>>>> +	 * and call req_queue. The reason we set the state first is that this
>>>> +	 * allows req_queue to unbind or complete the queued objects in case
>>>> +	 * they are immediately 'consumed'. State changes from QUEUED to another
>>>> +	 * state can only happen if either the driver changes the state or if
>>>> +	 * the user cancels the vb2 queue. The driver can only change the state
>>>> +	 * after each object is queued through the req_queue op (and note that
>>>> +	 * that op cannot fail), so setting the state to QUEUED up front is
>>>> +	 * safe.
>>>> +	 *
>>>> +	 * The other reason for changing the state is if the vb2 queue is
>>>> +	 * canceled, and that uses the req_queue_mutex which is still locked
>>>> +	 * while req_queue is called, so that's safe as well.
>>>> +	 */
>>>> +	atomic_set(&req->state,
>>>> +		   ret ? MEDIA_REQUEST_STATE_IDLE : MEDIA_REQUEST_STATE_QUEUED);
>>>> +
>>>> +	if (!ret)
>>>> +		mdev->ops->req_queue(req);
>>>> +
>>>> +	mutex_unlock(&mdev->req_queue_mutex);
>>>> +
>>>> +	if (ret) {
>>>> +		dev_dbg(mdev->dev, "request: can't queue %s (%d)\n",
>>>> +			req->debug_str, ret);
>>>> +	} else {
>>>> +		media_request_get(req);
>>>
>>> You'll need to get a reference before you queue the request. Otherwise it's
>>> possible that it completes before you get here, and you end up accessing
>>> released memory. The request refcount might be also under 0 before that
>>> though.
>>
>> No, that can't happen. This function implements the QUEUE ioctl, which can only
>> be called by userspace through the request fd, so there is always at least one
>> reference open.
> 
> Indeed, you're right.
> 
> The curly braces are unnecessary above btw.
> 
> ...
> 
>>>> diff --git a/include/media/media-device.h b/include/media/media-device.h
>>>> index bcc6ec434f1f..ae846208be51 100644
>>>> --- a/include/media/media-device.h
>>>> +++ b/include/media/media-device.h
>>>> @@ -27,6 +27,7 @@
>>>>  
>>>>  struct ida;
>>>>  struct device;
>>>> +struct media_device;
>>>>  
>>>>  /**
>>>>   * struct media_entity_notify - Media Entity Notify
>>>> @@ -50,10 +51,22 @@ struct media_entity_notify {
>>>>   * struct media_device_ops - Media device operations
>>>>   * @link_notify: Link state change notification callback. This callback is
>>>>   *		 called with the graph_mutex held.
>>>> + * @req_alloc: Allocate a request
>>>> + * @req_free: Free a request
>>>> + * @req_validate: Validate a request, but do not queue yet
>>>> + * @req_queue: Queue a validated request, cannot fail. If something goes
>>>> + *	       wrong when queueing this request then it should be marked
>>>> + *	       as such internally in the driver and any related buffers
>>>> + *	       will eventually return to userspace with V4L2_BUF_FLAG_ERROR
>>>> + *	       set.
>>>
>>> Note that this is MC; I think the reference is fine but I'd make it
>>> explicit this is V4L2, and possibly that it's an example.
>>
>> I've changed the last line to:
>>
>> "must eventually return to vb2 with state VB2_BUF_STATE_ERROR."
>>
>> Since this is really a vb2 thing, not V4L2.
>>
>> It's not an example, based on what I know this should really be done like
>> this. If reality proves to be different, then the comment will need to change.
> 
> Yes, but this is not a place for VB2 documentation nor a conclusive
> document of what a failing queue operation would mean on whichever possible
> other non-MC subsystem. So the VB2 related matter here remains an example
> only.
> 
> We don't seem to have other than V4L2 using MC after more than five years
> but I'd still be wary of thinking this is bound to V4L2 only.
> 

It's all very tightly coupled to vb2 and I think we should just be honest in the
comment. Nor do I see this ever being used in other subsystems: they have their
own streaming etc. models.

I'll keep this in unless other people complain about this.

Regards,

	Hans



[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