linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: linux@arm.linux.org.uk (Russell King - ARM Linux)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 12/35] davinci: clock framework: remove spinlock usage
Date: Fri, 8 Jan 2010 17:06:01 +0000	[thread overview]
Message-ID: <20100108170601.GH32558@n2100.arm.linux.org.uk> (raw)
In-Reply-To: <1262802737-6601-13-git-send-email-khilman@deeprootsystems.com>

On Wed, Jan 06, 2010 at 10:31:54AM -0800, Kevin Hilman wrote:
> From: Sekhar Nori <nsekhar@ti.com>
> 
> Currently, the spinlock in DaVinci clock framework is being
> used to:
> 
> 1) Protect clock structure variables usecount and rate against
> concurrent modification.
> 
> 2) Protect against simultaneous PSC enables/disables ie.
> serialize davinci_psc_config().
> 
> 3) Serialize clk_set_rate():
> 	i.	Prevent simultaneous setting of clock rates
> 	ii.	Ensure clock list remains sane during rate
> 		propagation (also in clk_set_parent).
> 
> Remove the spinlock usage in clock framework by:
> 
> 1) Making clock rate and usecount as atomic variables.
> 
> 2) Making davinci_psc_config() protect itself instead of
> relying on serialization by caller.
> 
> 3) (i) Allowing the clk->set_rate to serialize itself. There
> should be no need to serialize all clock rate settings.
> Currently the only user of rate setting is cpufreq driver on
> DA850. cpufreq naturally serializes the calls to set CPU rate.
> Also, there appears no need to lock IRQs during CPU rate
> transtitions. If required, IRQs can be locked in the actual
> set_rate function.
> 
> 3) (ii) Use the mutex already in place for serialzing clock list
> manipulation for serializing clock rate propagation as well.
> 
> Apart from the general benefit of reducing locking granurlarity,
> the main motivation behind this change is to enable usage of
> clock framework for off-chip clock synthesizers. One such
> synthesizer, CDCE949, is present on DM6467 EVM. Access to the
> synthesizer happens through I2C bus - accessing which can lead to
> CPU sleep. Having IRQs locked in clk_set_rate prevents the
> clk->set_rate function from sleeping.

This patch is extremely bogus.  Just because something is called 'atomic'
does not make it so.

atomic_set()..atomic_read() are NOT atomic.  They are just plain write
and read of the underlying atomic value - the former is intended for
one-time initialization, and the latter is intended for debugging.

> @@ -41,15 +40,16 @@ static void __clk_enable(struct clk *clk)
>  {
>  	if (clk->parent)
>  		__clk_enable(clk->parent);
> -	if (clk->usecount++ == 0 && (clk->flags & CLK_PSC))
> +	if (atomic_read(&clk->usecount) == 0 && (clk->flags & CLK_PSC))
>  		davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 1);
> +	atomic_inc(&clk->usecount);

This is wrong on two levels.  Firstly, consider a simultaneous clk_enable
and clk_disable.

CPU0						CPU1
__clk_disable

atomic_dec_and_test(&clk->usecount) -> true

						__clk_enable
						atomic_read(&clk->usecount) returns zero
						davinci_psc_config(..., 1);
						atomic_inc(&clk->usecount);
davinci_psc_config(..., 0);

The result is that we now have the situation where the usecount is nonzero
but the clock is disabled.

Similar bogosities can arise when an already enabled clock tries to be
simultaneously enabled for a second time and disabled.

Secondly, davinci_psc_config() does a lot of read-modify-writing.  With
the spinlock gone, what's the protection against simultaneous r-m-w on
these registers?

> @@ -88,7 +80,7 @@ unsigned long clk_get_rate(struct clk *clk)
>  	if (clk == NULL || IS_ERR(clk))
>  		return -EINVAL;
>  
> -	return clk->rate;
> +	return atomic_read(&clk->rate);

atomic here doesn't make clk->rate magically right.  This is precisely
equivalent to reading clk->rate directly.

>  int clk_set_rate(struct clk *clk, unsigned long rate)
>  {
> -	unsigned long flags;
>  	int ret = -EINVAL;
>  
>  	if (clk == NULL || IS_ERR(clk))
>  		return ret;
>  
> -	spin_lock_irqsave(&clockfw_lock, flags);
>  	if (clk->set_rate)
>  		ret = clk->set_rate(clk, rate);
>  	if (ret == 0) {
>  		if (clk->recalc)
> -			clk->rate = clk->recalc(clk);
> +			atomic_set(&clk->rate, clk->recalc(clk));

This atomic_set does nothing to protect you from races.  You might as
well be writing directly to clk->rate.

  parent reply	other threads:[~2010-01-08 17:06 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-01-06 18:31 [PATCH 00/35] davinci updates queued for 2.6.34 Kevin Hilman
2010-01-06 18:31 ` [PATCH 01/35] davinci: da8xx/omapl1: add support for the second sysconfig module Kevin Hilman
2010-01-06 18:31   ` [PATCH 02/35] davinci: move PLL wait time values to clock.h Kevin Hilman
2010-01-06 18:31     ` [PATCH 03/35] davinci: move DDR2 controller defines to memory.h Kevin Hilman
2010-01-06 18:31       ` [PATCH 04/35] davinci: move PSC register definitions from psc.c to psc.h Kevin Hilman
2010-01-06 18:31         ` [PATCH 05/35] davinci: make it possible to include clock.h and psc.h in assembly code Kevin Hilman
2010-01-06 18:31           ` [PATCH 06/35] davinci: cpuidle: move mapping of DDR2 controller registers out of driver Kevin Hilman
2010-01-06 18:31             ` [PATCH 07/35] davinci: da850/omap-l138: unlock PLL registers during init Kevin Hilman
2010-01-06 18:31               ` [PATCH 08/35] davinci: da850/omap-l138: create static map for SRAM Kevin Hilman
2010-01-06 18:31                 ` [PATCH 09/35] davinci: explain CLOCK_TICK_RATE of 27MHz in include/mach/timex.h Kevin Hilman
2010-01-06 18:31                   ` [PATCH 10/35] davinci: board-dm646x-evm.c: arrange related code together Kevin Hilman
2010-01-06 18:31                     ` [PATCH 11/35] davinci: add support for DM6467T EVM Kevin Hilman
2010-01-06 18:31                       ` [PATCH 12/35] davinci: clock framework: remove spinlock usage Kevin Hilman
2010-01-06 18:31                         ` [PATCH 13/35] davinci: make /proc/davinci_clocks display multi-rooted clock tree Kevin Hilman
2010-01-06 18:31                           ` [PATCH 14/35] davinci: move /proc/davinci_clocks to debugfs Kevin Hilman
2010-01-06 18:31                             ` [PATCH 15/35] davinci: da850/omap-l138: Modify NOR partition info Kevin Hilman
2010-01-06 18:31                               ` [PATCH 16/35] davinci: da850/omap-l138: Enable 4-bit ecc Kevin Hilman
2010-01-06 18:31                                 ` [PATCH 17/35] TI Davinci EMAC : Re-use driver for other platforms Kevin Hilman
2010-01-06 18:32                                   ` [PATCH 18/35] TI Davinci EMAC : add platform specific interrupt enable/disable logic Kevin Hilman
2010-01-06 18:32                                     ` [PATCH 19/35] TI Davinci EMAC : Abstract Buffer address translation logic Kevin Hilman
2010-01-06 18:32                                       ` [PATCH 20/35] davinci: clock: Check CLK_PSC flag before disabling PSC Kevin Hilman
2010-01-06 18:32                                         ` [PATCH 21/35] DaVinci: DM365: Changing default queue for DM365 Kevin Hilman
2010-01-06 18:32                                           ` [PATCH 22/35] davinci: add power management support Kevin Hilman
2010-01-06 18:32                                             ` [PATCH 23/35] davinci: da850/omap-l138: add support for SoC suspend Kevin Hilman
2010-01-06 18:32                                               ` [PATCH 24/35] davinci: da850/omap-l138 EVM: register for suspend support Kevin Hilman
2010-01-06 18:32                                                 ` [PATCH 25/35] davinci: add support for CDCE949 clock synthesizer Kevin Hilman
2010-01-06 18:32                                                   ` [PATCH 26/35] davinci: add CDCE949 support on DM6467 EVM Kevin Hilman
2010-01-06 18:32                                                     ` [PATCH 27/35] davinci: Correct return value of edma_alloc_channel api Kevin Hilman
2010-01-06 18:32                                                       ` [PATCH 28/35] davinci: Keep count of channel controllers on a platform Kevin Hilman
2010-01-06 18:32                                                         ` [PATCH 29/35] davinci: Fix edma_alloc_channel api for EDMA_CHANNEL_ANY case Kevin Hilman
2010-01-06 18:32                                                           ` [PATCH 30/35] davinci: build list of unused EDMA events dynamically Kevin Hilman
2010-01-06 18:32                                                             ` [PATCH 31/35] davinci: support for EDMA resource sharing Kevin Hilman
2010-01-06 18:32                                                               ` [PATCH 32/35] davinci: da8xx/omap-l1xx: Add EDMA platform data for da850/omap-l138 Kevin Hilman
2010-01-06 18:32                                                                 ` [PATCH 33/35] davinci: da830/omapl137: Specify reserved channels/slots Kevin Hilman
2010-01-06 18:32                                                                   ` [PATCH 34/35] davinci: da850/omapl138: " Kevin Hilman
2010-01-06 18:32                                                                     ` [PATCH 35/35] davinci: dm646x: Specify reserved EDMA channel/slots for DM646x Kevin Hilman
2010-01-08 17:06                         ` Russell King - ARM Linux [this message]
2010-01-11 15:27                           ` [PATCH 12/35] davinci: clock framework: remove spinlock usage Kevin Hilman
2010-01-10 13:59 ` [PATCH 00/35] davinci updates queued for 2.6.34 Russell King - ARM Linux
2010-01-11 15:31   ` Kevin Hilman

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=20100108170601.GH32558@n2100.arm.linux.org.uk \
    --to=linux@arm.linux.org.uk \
    --cc=linux-arm-kernel@lists.infradead.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 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).