From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Linux Media Mailing List <linux-media@vger.kernel.org>,
Sylwester Nawrocki <sylvester.nawrocki@gmail.com>,
Hans Verkuil <hverkuil@xs4all.nl>,
Sylwester Nawrocki <s.nawrocki@samsung.com>,
Magnus Damm <magnus.damm@gmail.com>,
linux-sh@vger.kernel.org
Subject: Re: [PATCH v2] media: V4L2: add temporary clock helpers
Date: Mon, 12 Nov 2012 11:04:16 +0000 [thread overview]
Message-ID: <2036621.k9xkWqC1fF@avalon> (raw)
In-Reply-To: <Pine.LNX.4.64.1210311307550.9048@axis700.grange>
Hi Guennadi,
On Wednesday 31 October 2012 14:02:54 Guennadi Liakhovetski wrote:
> On Wed, 31 Oct 2012, Laurent Pinchart wrote:
> > On Tuesday 30 October 2012 15:18:38 Guennadi Liakhovetski wrote:
> > > Typical video devices like camera sensors require an external clock
> > > source. Many such devices cannot even access their hardware registers
> > > without a running clock. These clock sources should be controlled by
> > > their consumers. This should be performed, using the generic clock
> > > framework. Unfortunately so far only very few systems have been ported
> > > to that framework. This patch adds a set of temporary helpers, mimicking
> > > the generic clock API, to V4L2. Platforms, adopting the clock API,
> > > should switch to using it. Eventually this temporary API should be
> > > removed.
> > >
> > > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > ---
> > >
> > > v2: integrated most fixes from Sylwester & Laurent,
> > >
> > > (1) do not register identical clocks
> > > (2) add clock refcounting
> > > (3) more robust locking
> > > (4) duplicate strings to prevent dereferencing invalid memory
> > > (5) add a private data pointer
> > > (6) return an error in get_rate() / set_rate() if clock isn't enabled
> > > (7) support .id=NULL per subdevice
> > >
> > > Thanks to all reviewers!
> > >
> > > drivers/media/v4l2-core/Makefile | 2 +-
> > > drivers/media/v4l2-core/v4l2-clk.c | 169 +++++++++++++++++++++++++++++
> > > include/media/v4l2-clk.h | 51 +++++++++++
> > > 3 files changed, 221 insertions(+), 1 deletions(-)
> > > create mode 100644 drivers/media/v4l2-core/v4l2-clk.c
> > > create mode 100644 include/media/v4l2-clk.h
[snip]
> > > +int v4l2_clk_enable(struct v4l2_clk *clk)
> > > +{
> > > + if (atomic_inc_return(&clk->enable) = 1 && clk->ops->enable) {
> > > + int ret = clk->ops->enable(clk);
> > > + if (ret < 0)
> > > + atomic_dec(&clk->enable);
> > > + return ret;
> > > + }
> >
> > I think you need a spinlock here instead of atomic operations. You could
> > get preempted after atomic_inc_return() and before clk->ops->enable() by
> > another process that would call v4l2_clk_enable(). The function would
> > return with enabling the clock.
>
> Sorry, what's the problem then? "Our" instance will succeed and call
> ->enable() and the preempting instance will see the enable count > 1 and
> just return.
CPU 0 CPU 1
-----------------------------------------------------------------------------
v4l2_clk_enable()
atomic_inc_return() returns 1
v4l2_clk_enable()
atomic_inc_return() returns 2
returns 0 to caller, clock is not enabled
caller uses the clock and fails
clk->ops->enable()
This could also happen on a non-SMP system if the first task is interrupted
between the atomic_inc_return() and clk->ops->enable() calls.
> > One solution would be to add a spinlock to struct v4l2_clk and modify the
> > enable field from atomic_t to plain unsigned int.
> >
> > > + return 0;
> > > +}
> > > +EXPORT_SYMBOL(v4l2_clk_enable);
> > > +
> > > +void v4l2_clk_disable(struct v4l2_clk *clk)
> > > +{
> > > + int enable = atomic_dec_return(&clk->enable);
> > > +
> > > + if (WARN(enable < 0, "Unbalanced %s()!\n", __func__)) {
> >
> > Could you add the clock name to the debug message ?
>
> You mean device / connection IDs? Could do, yes.
Yes.
> > > + atomic_inc(&clk->enable);
> > > + return;
> > > + }
> > > +
> > > + if (!enable && clk->ops->disable)
> > > + clk->ops->disable(clk);
> > > +}
> > > +EXPORT_SYMBOL(v4l2_clk_disable);
[snip]
> > > +void v4l2_clk_unregister(struct v4l2_clk *clk)
> > > +{
> > > + WARN(atomic_read(&clk->enable),
> > > + "Unregistering still enabled %s:%s clock!\n", clk->dev_id,
> > > clk->id);
> >
> > Shouldn't this warning be based on a get/put refcount instead of an enable
> > refcount ?
>
> In principle - yes, so, you vote for one more counter?...
Either one more counter, or dropping the warning.
> > I would also turn it into a BUG_ON. The kernel will crash later anyway
> > when the clock user will try to disable the clock, as you free the clock
> > object here.
>
> s/when/if/ ;-) With BUG_ON() you, probably, only get one stack dump here,
> with WARN() you get both - one with the _unregister() stack and one with
> the _disable() and / or _put() stack... Don't you think the latter option
> is more informative?
What bothers me is that the later disable/put might not crash immediately but
could lead to memory corruption with potential severe consequences if the
memory has been reallocated.
> > > + mutex_lock(&clk_lock);
> > > + list_del(&clk->list);
> > > + mutex_unlock(&clk_lock);
> > > +
> > > + kfree(clk->id);
> > > + kfree(clk->dev_id);
> > > + kfree(clk);
--
Regards,
Laurent Pinchart
WARNING: multiple messages have this Message-ID (diff)
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Linux Media Mailing List <linux-media@vger.kernel.org>,
Sylwester Nawrocki <sylvester.nawrocki@gmail.com>,
Hans Verkuil <hverkuil@xs4all.nl>,
Sylwester Nawrocki <s.nawrocki@samsung.com>,
Magnus Damm <magnus.damm@gmail.com>,
linux-sh@vger.kernel.org
Subject: Re: [PATCH v2] media: V4L2: add temporary clock helpers
Date: Mon, 12 Nov 2012 12:04:16 +0100 [thread overview]
Message-ID: <2036621.k9xkWqC1fF@avalon> (raw)
In-Reply-To: <Pine.LNX.4.64.1210311307550.9048@axis700.grange>
Hi Guennadi,
On Wednesday 31 October 2012 14:02:54 Guennadi Liakhovetski wrote:
> On Wed, 31 Oct 2012, Laurent Pinchart wrote:
> > On Tuesday 30 October 2012 15:18:38 Guennadi Liakhovetski wrote:
> > > Typical video devices like camera sensors require an external clock
> > > source. Many such devices cannot even access their hardware registers
> > > without a running clock. These clock sources should be controlled by
> > > their consumers. This should be performed, using the generic clock
> > > framework. Unfortunately so far only very few systems have been ported
> > > to that framework. This patch adds a set of temporary helpers, mimicking
> > > the generic clock API, to V4L2. Platforms, adopting the clock API,
> > > should switch to using it. Eventually this temporary API should be
> > > removed.
> > >
> > > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > ---
> > >
> > > v2: integrated most fixes from Sylwester & Laurent,
> > >
> > > (1) do not register identical clocks
> > > (2) add clock refcounting
> > > (3) more robust locking
> > > (4) duplicate strings to prevent dereferencing invalid memory
> > > (5) add a private data pointer
> > > (6) return an error in get_rate() / set_rate() if clock isn't enabled
> > > (7) support .id=NULL per subdevice
> > >
> > > Thanks to all reviewers!
> > >
> > > drivers/media/v4l2-core/Makefile | 2 +-
> > > drivers/media/v4l2-core/v4l2-clk.c | 169 +++++++++++++++++++++++++++++
> > > include/media/v4l2-clk.h | 51 +++++++++++
> > > 3 files changed, 221 insertions(+), 1 deletions(-)
> > > create mode 100644 drivers/media/v4l2-core/v4l2-clk.c
> > > create mode 100644 include/media/v4l2-clk.h
[snip]
> > > +int v4l2_clk_enable(struct v4l2_clk *clk)
> > > +{
> > > + if (atomic_inc_return(&clk->enable) == 1 && clk->ops->enable) {
> > > + int ret = clk->ops->enable(clk);
> > > + if (ret < 0)
> > > + atomic_dec(&clk->enable);
> > > + return ret;
> > > + }
> >
> > I think you need a spinlock here instead of atomic operations. You could
> > get preempted after atomic_inc_return() and before clk->ops->enable() by
> > another process that would call v4l2_clk_enable(). The function would
> > return with enabling the clock.
>
> Sorry, what's the problem then? "Our" instance will succeed and call
> ->enable() and the preempting instance will see the enable count > 1 and
> just return.
CPU 0 CPU 1
-----------------------------------------------------------------------------
v4l2_clk_enable()
atomic_inc_return() returns 1
v4l2_clk_enable()
atomic_inc_return() returns 2
returns 0 to caller, clock is not enabled
caller uses the clock and fails
clk->ops->enable()
This could also happen on a non-SMP system if the first task is interrupted
between the atomic_inc_return() and clk->ops->enable() calls.
> > One solution would be to add a spinlock to struct v4l2_clk and modify the
> > enable field from atomic_t to plain unsigned int.
> >
> > > + return 0;
> > > +}
> > > +EXPORT_SYMBOL(v4l2_clk_enable);
> > > +
> > > +void v4l2_clk_disable(struct v4l2_clk *clk)
> > > +{
> > > + int enable = atomic_dec_return(&clk->enable);
> > > +
> > > + if (WARN(enable < 0, "Unbalanced %s()!\n", __func__)) {
> >
> > Could you add the clock name to the debug message ?
>
> You mean device / connection IDs? Could do, yes.
Yes.
> > > + atomic_inc(&clk->enable);
> > > + return;
> > > + }
> > > +
> > > + if (!enable && clk->ops->disable)
> > > + clk->ops->disable(clk);
> > > +}
> > > +EXPORT_SYMBOL(v4l2_clk_disable);
[snip]
> > > +void v4l2_clk_unregister(struct v4l2_clk *clk)
> > > +{
> > > + WARN(atomic_read(&clk->enable),
> > > + "Unregistering still enabled %s:%s clock!\n", clk->dev_id,
> > > clk->id);
> >
> > Shouldn't this warning be based on a get/put refcount instead of an enable
> > refcount ?
>
> In principle - yes, so, you vote for one more counter?...
Either one more counter, or dropping the warning.
> > I would also turn it into a BUG_ON. The kernel will crash later anyway
> > when the clock user will try to disable the clock, as you free the clock
> > object here.
>
> s/when/if/ ;-) With BUG_ON() you, probably, only get one stack dump here,
> with WARN() you get both - one with the _unregister() stack and one with
> the _disable() and / or _put() stack... Don't you think the latter option
> is more informative?
What bothers me is that the later disable/put might not crash immediately but
could lead to memory corruption with potential severe consequences if the
memory has been reallocated.
> > > + mutex_lock(&clk_lock);
> > > + list_del(&clk->list);
> > > + mutex_unlock(&clk_lock);
> > > +
> > > + kfree(clk->id);
> > > + kfree(clk->dev_id);
> > > + kfree(clk);
--
Regards,
Laurent Pinchart
next prev parent reply other threads:[~2012-11-12 11:04 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-30 14:18 [PATCH v2] media: V4L2: add temporary clock helpers Guennadi Liakhovetski
2012-10-30 14:18 ` Guennadi Liakhovetski
2012-10-31 9:15 ` Laurent Pinchart
2012-10-31 9:15 ` Laurent Pinchart
2012-10-31 13:02 ` Guennadi Liakhovetski
2012-10-31 13:02 ` Guennadi Liakhovetski
2012-11-11 22:33 ` Sakari Ailus
2012-11-11 22:33 ` Sakari Ailus
2012-11-12 11:06 ` Laurent Pinchart
2012-11-12 11:06 ` Laurent Pinchart
2012-11-12 23:37 ` Sakari Ailus
2012-11-12 23:37 ` Sakari Ailus
2012-11-14 13:06 ` Laurent Pinchart
2012-11-14 13:06 ` Laurent Pinchart
2012-11-22 22:52 ` Sylwester Nawrocki
2012-11-22 22:52 ` Sylwester Nawrocki
2012-11-25 11:04 ` Sakari Ailus
2012-11-25 11:04 ` Sakari Ailus
2012-11-27 14:18 ` Laurent Pinchart
2012-11-27 14:18 ` Laurent Pinchart
2012-11-12 11:04 ` Laurent Pinchart [this message]
2012-11-12 11:04 ` Laurent Pinchart
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=2036621.k9xkWqC1fF@avalon \
--to=laurent.pinchart@ideasonboard.com \
--cc=g.liakhovetski@gmx.de \
--cc=hverkuil@xs4all.nl \
--cc=linux-media@vger.kernel.org \
--cc=linux-sh@vger.kernel.org \
--cc=magnus.damm@gmail.com \
--cc=s.nawrocki@samsung.com \
--cc=sylvester.nawrocki@gmail.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 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.