From: khilman@deeprootsystems.com (Kevin Hilman)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 12/35] davinci: clock framework: remove spinlock usage
Date: Mon, 11 Jan 2010 07:27:01 -0800 [thread overview]
Message-ID: <87d41gr7ay.fsf@deeprootsystems.com> (raw)
In-Reply-To: <20100108170601.GH32558@n2100.arm.linux.org.uk> (Russell King's message of "Fri\, 8 Jan 2010 17\:06\:01 +0000")
Russell King - ARM Linux <linux@arm.linux.org.uk> writes:
> 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.
Russell,
Thanks for the feedback. I'll drop this patch while we rework this in
a different way.
Thanks,
Kevin
> 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.
next prev parent reply other threads:[~2010-01-11 15:27 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 ` [PATCH 12/35] davinci: clock framework: remove spinlock usage Russell King - ARM Linux
2010-01-11 15:27 ` Kevin Hilman [this message]
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=87d41gr7ay.fsf@deeprootsystems.com \
--to=khilman@deeprootsystems.com \
--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).