From: Randy Vinson <rvinson@mvista.com>
To: "linuxppc-dev@ozlabs.org" <linuxppc-dev@ozlabs.org>
Subject: [PATCH v3] E500 Make steal_context SMP-safe.
Date: Fri, 11 Apr 2008 13:32:13 -0700 [thread overview]
Message-ID: <47FFCACD.3030700@mvista.com> (raw)
In-Reply-To: <AB49B020-E993-4107-A97B-E41FD0272BCA@kernel.crashing.org>
When steal_context is used on SMP systems, it can steal a context in
use by one of the other processors leading to random page faults,
hung processors and general badness. This patch adds context tracking
as suggested by BenH.
Signed-off-by: Randy Vinson <rvinson@mvista.com>
---
arch/powerpc/mm/mmu_context_32.c | 35
++++++++++++++++++++++++++---------
include/asm-powerpc/mmu_context.h | 5 +++++
2 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/mm/mmu_context_32.c
b/arch/powerpc/mm/mmu_context_32.c
index cc32ba4..e3c119c 100644
--- a/arch/powerpc/mm/mmu_context_32.c
+++ b/arch/powerpc/mm/mmu_context_32.c
@@ -34,6 +34,8 @@ unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG
+ 1];
atomic_t nr_free_contexts;
struct mm_struct *context_mm[LAST_CONTEXT+1];
void steal_context(void);
+DEFINE_SPINLOCK(mm_lock);
+DEFINE_PER_CPU(struct mm_struct *, curr_mm);
#endif /* FEW_CONTEXTS */
/*
@@ -42,6 +44,9 @@ void steal_context(void);
void __init
mmu_context_init(void)
{
+#ifdef FEW_CONTEXTS
+ int cpu;
+#endif
/*
* Some processors have too few contexts to reserve one for
* init_mm, and require using context 0 for a normal task.
@@ -52,16 +57,15 @@ mmu_context_init(void)
next_mmu_context = FIRST_CONTEXT;
#ifdef FEW_CONTEXTS
atomic_set(&nr_free_contexts, LAST_CONTEXT - FIRST_CONTEXT + 1);
+ for_each_possible_cpu(cpu)
+ per_cpu(curr_mm, cpu) = NULL;
#endif /* FEW_CONTEXTS */
}
#ifdef FEW_CONTEXTS
/*
* Steal a context from a task that has one at the moment.
- * This is only used on 8xx and 4xx and we presently assume that
- * they don't do SMP. If they do then this will have to check
- * whether the MM we steal is in use.
- * We also assume that this is only used on systems that don't
+ * We assume that this is only used on systems that don't
* use an MMU hash table - this is true for 8xx and 4xx.
* This isn't an LRU system, it just frees up each context in
* turn (sort-of pseudo-random replacement :). This would be the
@@ -72,12 +76,25 @@ void
steal_context(void)
{
struct mm_struct *mm;
+ int cpu;
+
+ do {
+ /* free up context `next_mmu_context' */
+ /* if we shouldn't free context 0, don't... */
+ if (next_mmu_context < FIRST_CONTEXT)
+ next_mmu_context = FIRST_CONTEXT;
+ mm = context_mm[next_mmu_context];
+ for_each_online_cpu(cpu) {
+ if ((cpu != smp_processor_id()) &&
+ per_cpu(curr_mm, cpu) == mm) {
+ mm = NULL;
+ next_mmu_context = (next_mmu_context + 1) &
+ LAST_CONTEXT;
+ break;
+ }
+ }
+ } while(!mm);
- /* free up context `next_mmu_context' */
- /* if we shouldn't free context 0, don't... */
- if (next_mmu_context < FIRST_CONTEXT)
- next_mmu_context = FIRST_CONTEXT;
- mm = context_mm[next_mmu_context];
flush_tlb_mm(mm);
destroy_context(mm);
}
diff --git a/include/asm-powerpc/mmu_context.h
b/include/asm-powerpc/mmu_context.h
index 9102b8b..e083b25 100644
--- a/include/asm-powerpc/mmu_context.h
+++ b/include/asm-powerpc/mmu_context.h
@@ -113,6 +113,8 @@ extern unsigned long next_mmu_context;
extern atomic_t nr_free_contexts;
extern struct mm_struct *context_mm[LAST_CONTEXT+1];
extern void steal_context(void);
+extern spinlock_t mm_lock;
+DECLARE_PER_CPU(struct mm_struct *, curr_mm);
#endif
/*
@@ -125,6 +127,7 @@ static inline void get_mmu_context(struct mm_struct *mm)
if (mm->context.id != NO_CONTEXT)
return;
#ifdef FEW_CONTEXTS
+ spin_lock(&mm_lock);
while (atomic_dec_if_positive(&nr_free_contexts) < 0)
steal_context();
#endif
@@ -138,6 +141,8 @@ static inline void get_mmu_context(struct mm_struct *mm)
mm->context.id = ctx;
#ifdef FEW_CONTEXTS
context_mm[ctx] = mm;
+ per_cpu(curr_mm, smp_processor_id()) = mm;
+ spin_unlock(&mm_lock);
#endif
}
--
1.5.4.4.551.g1658c
prev parent reply other threads:[~2008-04-11 20:32 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-03 16:46 [PATCH v2] E500 Make steal_context SMP-safe Randy Vinson
2008-04-10 15:31 ` Kumar Gala
2008-04-11 20:32 ` Randy Vinson [this message]
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=47FFCACD.3030700@mvista.com \
--to=rvinson@mvista.com \
--cc=linuxppc-dev@ozlabs.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.