From: linux@arm.linux.org.uk (Russell King - ARM Linux)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 3/6] Fix a race in the vfp_notifier() function on SMP systems
Date: Sat, 12 Dec 2009 12:24:47 +0000 [thread overview]
Message-ID: <20091212122447.GA30537@n2100.arm.linux.org.uk> (raw)
In-Reply-To: <20091207141325.30429.13315.stgit@pc1117.cambridge.arm.com>
On Mon, Dec 07, 2009 at 02:13:34PM +0000, Catalin Marinas wrote:
> The vfp_notifier(THREAD_NOTIFY_RELEASE) maybe be called with thread->cpu
> different from the current one, causing a race condition with both the
> THREAD_NOTIFY_SWITCH path and vfp_support_entry().
The only call where thread->cpu may not be the current CPU is in the
THREAD_NOFTIFY_RELEASE case.
When called in the THREAD_NOTIFY_SWITCH case, we are switching to the
specified thread, and thread->cpu better be smp_processor_id() or else
we're saving our CPUs VFP state into some other CPUs currently running
thread.
Not only that, but the thread we're switching away from will still be
'owned' by the CPU we're running on, and can't be scheduled onto another
CPU without this function first completing, nor can it be flushed nor
released.
> @@ -49,14 +50,21 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
>
> #ifdef CONFIG_SMP
BUG_ON(cpu != smp_processor_id());
since it would be very bad if this was any different. Note that this is
also a non-preemptible context - we're called from the scheduler, and the
scheduler can't be preempted mid-thead switch.
> /*
> + * RCU locking is needed in case last_VFP_context[cpu] is
> + * released on a different CPU.
> + */
> + rcu_read_lock();
Given that we're modifying our CPUs last_VFP_context here, I don't see
what the RCU locks give us - the thread we're switching to can _not_
be being released at this time - we can't be switching to a dead task.
Not only that, but this notifier is already called under the RCU lock,
so this is a no-op.
> + vfp = last_VFP_context[cpu];
> + /*
> * On SMP, if VFP is enabled, save the old state in
> * case the thread migrates to a different CPU. The
> * restoring is done lazily.
> */
> - if ((fpexc & FPEXC_EN) && last_VFP_context[cpu]) {
> - vfp_save_state(last_VFP_context[cpu], fpexc);
> - last_VFP_context[cpu]->hard.cpu = cpu;
> + if ((fpexc & FPEXC_EN) && vfp) {
> + vfp_save_state(vfp, fpexc);
> + vfp->hard.cpu = cpu;
> }
> + rcu_read_unlock();
> /*
> * Thread migration, just force the reloading of the
> * state on the new CPU in case the VFP registers
> @@ -91,8 +99,19 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
> }
>
> /* flush and release case: Per-thread VFP cleanup. */
> +#ifndef CONFIG_SMP
> if (last_VFP_context[cpu] == vfp)
> last_VFP_context[cpu] = NULL;
> +#else
> + /*
> + * Since release_thread() may be called from a different CPU, we use
> + * cmpxchg() here to avoid a race with the vfp_support_entry() code
> + * which modifies last_VFP_context[cpu]. Note that on SMP systems, a
> + * STR instruction on a different CPU clears the global exclusive
> + * monitor state.
> + */
> + (void)cmpxchg(&last_VFP_context[cpu], vfp, NULL);
> +#endif
I think this hunk is the only part which makes sense.
next prev parent reply other threads:[~2009-12-12 12:24 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-12-07 14:10 [PATCH 0/6] Bug-fixes and new features for 2.6.34-rc1 Catalin Marinas
2009-12-07 14:10 ` [PATCH 1/6] Global ASID allocation on SMP Catalin Marinas
2009-12-07 14:13 ` [PATCH 2/6] Broadcast the DMA cache operations on ARMv6 SMP hardware Catalin Marinas
2009-12-07 14:13 ` [PATCH 3/6] Fix a race in the vfp_notifier() function on SMP systems Catalin Marinas
2009-12-12 12:24 ` Russell King - ARM Linux [this message]
2009-12-12 13:57 ` Russell King - ARM Linux
2009-12-14 12:21 ` Catalin Marinas
2009-12-14 12:15 ` Catalin Marinas
2009-12-14 16:28 ` [PATCH 3/6] Fix a race in the vfp_notifier() function on SMPsystems Catalin Marinas
2009-12-07 14:13 ` [PATCH 4/6] ARMv7: Use lazy cache flushing if hardware broadcasts cache operations Catalin Marinas
2010-03-08 16:25 ` [PATCH 4/6] ARMv7: Use lazy cache flushing if hardware broadcastscache operations Catalin Marinas
2010-03-08 16:31 ` Russell King - ARM Linux
2010-03-08 16:38 ` [PATCH 4/6] ARMv7: Use lazy cache flushing if hardwarebroadcastscache operations Catalin Marinas
2009-12-07 14:14 ` [PATCH 5/6] ARMv7: Improved page table format with TRE and AFE Catalin Marinas
2009-12-12 11:28 ` Russell King - ARM Linux
2009-12-14 15:50 ` Catalin Marinas
2009-12-14 15:58 ` Catalin Marinas
2009-12-14 16:11 ` Russell King - ARM Linux
2009-12-14 16:16 ` Catalin Marinas
2009-12-07 14:16 ` [PATCH 6/6] Remove the domain switching on ARMv6k/v7 CPUs Catalin Marinas
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=20091212122447.GA30537@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).