All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sakari Ailus <sakari.ailus@iki.fi>
To: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Cc: linux-media@vger.kernel.org, Hans Verkuil <hans.verkuil@cisco.com>
Subject: Re: [PATCHv13 03/28] media-request: implement media requests
Date: Tue, 8 May 2018 13:52:33 +0300	[thread overview]
Message-ID: <20180508105233.kuuzas77w3s73xio@valkosipuli.retiisi.org.uk> (raw)
In-Reply-To: <20180508072116.265756e1@vento.lan>

Hi Mauro, Hans,

On Tue, May 08, 2018 at 07:21:16AM -0300, Mauro Carvalho Chehab wrote:
> Em Fri, 4 May 2018 15:27:50 +0300
> Sakari Ailus <sakari.ailus@iki.fi> escreveu:
> 
> > Hi Hans,
> > 
> > I've read this patch a large number of times and I think also the details
> > begin to seem sound. A few comments below.
> 
> I'm sending this after analyzing the other patches in this series,
> as this is the core of the changes. So, although I wrote the comments
> early, I wanted to read first all other patches before sending it.
> 
> > 
> > On Thu, May 03, 2018 at 04:52:53PM +0200, Hans Verkuil wrote:
> > > From: Hans Verkuil <hans.verkuil@cisco.com>
> > > 
> > > Add initial media request support:
> > > 
> > > 1) Add MEDIA_IOC_REQUEST_ALLOC ioctl support to media-device.c
> > > 2) Add struct media_request to store request objects.
> > > 3) Add struct media_request_object to represent a request object.
> > > 4) Add MEDIA_REQUEST_IOC_QUEUE/REINIT ioctl support.
> > > 
> > > Basic lifecycle: the application allocates a request, adds
> > > objects to it, queues the request, polls until it is completed
> > > and can then read the final values of the objects at the time
> > > of completion. When it closes the file descriptor the request
> > > memory will be freed (actually, when the last user of that request
> > > releases the request).
> > > 
> > > Drivers will bind an object to a request (the 'adds objects to it'
> > > phase), when MEDIA_REQUEST_IOC_QUEUE is called the request is
> > > validated (req_validate op), then queued (the req_queue op).
> > > 
> > > When done with an object it can either be unbound from the request
> > > (e.g. when the driver has finished with a vb2 buffer) or marked as
> > > completed (e.g. for controls associated with a buffer). When all
> > > objects in the request are completed (or unbound), then the request
> > > fd will signal an exception (poll).
> > > 
> > > Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> 
> Hmm... As you're adding Copyrights from Intel/Google in this patch, that
> indicates that part of the stuff you're adding here were authored by
> others. So, you should use Co-developed-by: tag here, and get the SOBs
> from the other developers that did part of the work[1].
> 
> [1] except if your work was sponsored by Cisco, Intel and Google, but
>     I think this is not the case.

I think this could be appropriate:

    Co-developed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
    Co-developed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
    Co-developed-by: Alexandre Courbot <acourbot@chromium.org>

...

> > > +static long media_request_ioctl_queue(struct media_request *req)
> > > +{
> > > +	struct media_device *mdev = req->mdev;
> > > +	enum media_request_state state;
> > > +	unsigned long flags;
> > > +	int ret = 0;  
> > 
> > ret is unconditionally assigned below, no need to initialise here.
> > 
> > > +
> > > +	dev_dbg(mdev->dev, "request: queue %s\n", req->debug_str);
> > > +
> > > +	/*
> > > +	 * Ensure the request that is validated will be the one that gets queued
> > > +	 * next by serialising the queueing process. This mutex is also used
> > > +	 * to serialize with canceling a vb2 queue and with setting values such
> > > +	 * as controls in a request.
> > > +	 */
> > > +	mutex_lock(&mdev->req_queue_mutex);
> > > +
> > > +	spin_lock_irqsave(&req->lock, flags);
> > > +	state = atomic_cmpxchg(&req->state, MEDIA_REQUEST_STATE_IDLE,
> > > +			       MEDIA_REQUEST_STATE_VALIDATING);
> > > +	spin_unlock_irqrestore(&req->lock, flags);
> 
> It looks weird to serialize access to it with a mutex, a spin lock and 
> an atomic call.

req->lock is needed for state changes from idle to other states as also
other struct members need to be serialised with that, with the request
state. Which is kind of in line with my earlier point: there's little
if any benefit in making this field atomic.

The mutex is there to ensure only a single request remains in validating
state, i.e. we will be changing the state of the device request tip one
request at a time.

> 
> IMHO, locking is still an issue here. I would love to test the 
> locks with some tool that would randomize syscalls, issuing close(),
> poll() and read() at wrong times and inverting the order of some calls, 
> in order to do some empiric test that all locks are at the right places.
> 
> Complex locking schemas like that usually tend to cause a lot of
> troubles.
> 
> > > +	if (state != MEDIA_REQUEST_STATE_IDLE) {
> > > +		dev_dbg(mdev->dev,
> > > +			"request: unable to queue %s, request in state %s\n",
> > > +			req->debug_str, media_request_state_str(state));
> > > +		mutex_unlock(&mdev->req_queue_mutex);
> > > +		return -EBUSY;
> > > +	}
> > > +
> > > +	ret = mdev->ops->req_validate(req);
> > > +
> > > +	/*
> > > +	 * 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);
> 
> Why are you changing state also when ret fails?
> 
> Also, why you had to use a spin lock earlier in this function just 
> to change the req->state but you don't need to use it here?

The reason is subtle: the operations that need spinlock protection can take
place in request states other than "validating".

...

> > > +/**
> > > + * struct media_request_object_ops - Media request object operations
> > > + * @prepare: Validate and prepare the request object, optional.
> > > + * @unprepare: Unprepare the request object, optional.
> > > + * @queue: Queue the request object, optional.
> > > + * @unbind: Unbind the request object, optional.
> > > + * @release: Release the request object, required.
> > > + */
> > > +struct media_request_object_ops {
> > > +	int (*prepare)(struct media_request_object *object);
> > > +	void (*unprepare)(struct media_request_object *object);
> > > +	void (*queue)(struct media_request_object *object);
> > > +	void (*unbind)(struct media_request_object *object);
> > > +	void (*release)(struct media_request_object *object);
> > > +};
> > > +
> > > +/**
> > > + * struct media_request_object - An opaque object that belongs to a media
> > > + *				 request
> > > + *
> > > + * @ops: object's operations
> > > + * @priv: object's priv pointer
> > > + * @req: the request this object belongs to (can be NULL)
> > > + * @list: List entry of the object for @struct media_request
> > > + * @kref: Reference count of the object, acquire before releasing req->lock
> > > + * @completed: If true, then this object was completed.
> > > + *
> > > + * An object related to the request. This struct is embedded in the
> > > + * larger object data.
> 
> what do you mean by "the larger object data"? What struct is "the" struct?

There is no particular type: the API offers generic binding of objects to a
request. The objects are later retrieved when validating, queueing and
implementing that request.

-- 
Sakari Ailus
e-mail: sakari.ailus@iki.fi

  reply	other threads:[~2018-05-08 10:52 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-03 14:52 [PATCHv13 00/28] Request API Hans Verkuil
2018-05-03 14:52 ` [PATCHv13 01/28] v4l2-device.h: always expose mdev Hans Verkuil
2018-05-04 10:51   ` Sakari Ailus
2018-05-07 15:46     ` Mauro Carvalho Chehab
2018-05-08  8:34       ` Hans Verkuil
2018-05-16  3:40   ` Laurent Pinchart
2018-05-03 14:52 ` [PATCHv13 02/28] uapi/linux/media.h: add request API Hans Verkuil
2018-05-04 10:51   ` Sakari Ailus
2018-05-18 14:49   ` Laurent Pinchart
2018-05-03 14:52 ` [PATCHv13 03/28] media-request: implement media requests Hans Verkuil
2018-05-04 12:27   ` Sakari Ailus
2018-05-08 10:21     ` Mauro Carvalho Chehab
2018-05-08 10:52       ` Sakari Ailus [this message]
2018-05-08 12:41         ` Mauro Carvalho Chehab
2018-05-08 13:21           ` Sakari Ailus
2018-05-24 11:19       ` Hans Verkuil
2018-05-24  9:26     ` Hans Verkuil
2018-05-03 14:52 ` [PATCHv13 04/28] media-request: add media_request_get_by_fd Hans Verkuil
2018-05-04 12:26   ` Sakari Ailus
2018-05-07 17:01   ` Mauro Carvalho Chehab
2018-05-08  7:34     ` Hans Verkuil
2018-05-08 10:38       ` Mauro Carvalho Chehab
2018-05-03 14:52 ` [PATCHv13 05/28] media-request: add media_request_object_find Hans Verkuil
2018-05-04 12:43   ` Sakari Ailus
2018-05-07 17:05     ` Mauro Carvalho Chehab
2018-05-24  9:36       ` Hans Verkuil
2018-05-08 10:54     ` Sakari Ailus
2018-05-24  9:28     ` Hans Verkuil
2018-05-03 14:52 ` [PATCHv13 06/28] v4l2-dev: lock req_queue_mutex Hans Verkuil
2018-05-07 17:20   ` Mauro Carvalho Chehab
2018-05-08  7:45     ` Hans Verkuil
2018-05-08 10:45       ` Mauro Carvalho Chehab
2018-05-24  9:51         ` Hans Verkuil
2018-05-03 14:52 ` [PATCHv13 07/28] videodev2.h: add request_fd field to v4l2_ext_controls Hans Verkuil
2018-05-03 14:52 ` [PATCHv13 08/28] v4l2-ctrls: v4l2_ctrl_add_handler: add from_other_dev Hans Verkuil
2018-05-03 14:52 ` [PATCHv13 09/28] v4l2-ctrls: prepare internal structs for request API Hans Verkuil
2018-05-07 17:35   ` Mauro Carvalho Chehab
2018-05-08  7:49     ` Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 10/28] v4l2-ctrls: alloc memory for p_req Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 11/28] v4l2-ctrls: use ref in helper instead of ctrl Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 12/28] v4l2-ctrls: add core request support Hans Verkuil
2018-05-07 18:06   ` Mauro Carvalho Chehab
2018-05-08  8:07     ` Hans Verkuil
2018-05-08 10:49       ` Mauro Carvalho Chehab
2018-05-24 10:27         ` Hans Verkuil
2018-05-16 10:19   ` Sakari Ailus
2018-05-16 10:46     ` Sakari Ailus
2018-05-16 10:55     ` Hans Verkuil
2018-05-16 11:18   ` Sakari Ailus
2018-05-03 14:53 ` [PATCHv13 13/28] v4l2-ctrls: support g/s_ext_ctrls for requests Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 14/28] videodev2.h: Add request_fd field to v4l2_buffer Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 15/28] vb2: store userspace data in vb2_v4l2_buffer Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 16/28] videobuf2-core: embed media_request_object Hans Verkuil
2018-05-08  9:54   ` Mauro Carvalho Chehab
2018-05-03 14:53 ` [PATCHv13 17/28] videobuf2-core: integrate with media requests Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 18/28] videobuf2-v4l2: " Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 19/28] videobuf2-core: add request helper functions Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 20/28] videobuf2-v4l2: add vb2_request_queue/validate helpers Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 21/28] v4l2-mem2mem: add vb2_m2m_request_queue Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 22/28] Documentation: v4l: document request API Hans Verkuil
2018-05-18 14:46   ` Laurent Pinchart
2018-05-24  4:32     ` Tomasz Figa
2018-05-24  7:55       ` Hans Verkuil
2018-05-24 14:46     ` Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 23/28] media: vim2m: add media device Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 24/28] vim2m: use workqueue Hans Verkuil
2018-05-04 11:34   ` Sakari Ailus
2018-05-03 14:53 ` [PATCHv13 25/28] vim2m: support requests Hans Verkuil
2018-05-17 20:41   ` Sakari Ailus
2018-05-03 14:53 ` [PATCHv13 26/28] vivid: add mc Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 27/28] vivid: add request support Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 28/28] RFC: media-requests: add debugfs node Hans Verkuil
2018-05-08 10:26 ` [PATCHv13 00/28] Request API Mauro Carvalho Chehab

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=20180508105233.kuuzas77w3s73xio@valkosipuli.retiisi.org.uk \
    --to=sakari.ailus@iki.fi \
    --cc=hans.verkuil@cisco.com \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab+samsung@kernel.org \
    /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.