aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGraf Yang <graf.yang@analog.com>2010-01-13 01:09:34 -0500
committerMike Frysinger <vapier@gentoo.org>2010-03-09 00:30:49 -0500
commitc6669c223a409199a45bb8f31a2e160ee26d19cc (patch)
treecb46eb31a6ed699ce7ed31e874e965a38f987bd5
parent7e1082b7dbb60081b157d82106da33686cb9ea91 (diff)
Blackfin: fix up mm locking in address dumping
The locking code in the address dumper needs to grab the mm's mmap_sem so that other CPUs do not get an inconsistent view. On UP systems this really wasn't a problem, but it is easy to trigger a race on SMP systems when another CPU removes a mapping. Signed-off-by: Graf Yang <graf.yang@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r--arch/blackfin/kernel/traps.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 870d74b1b407..85766805b03a 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -138,6 +138,12 @@ static void decode_address(char *buf, unsigned long address)
138 if (!mm) 138 if (!mm)
139 continue; 139 continue;
140 140
141 if (!down_read_trylock(&mm->mmap_sem)) {
142 if (!in_atomic)
143 mmput(mm);
144 continue;
145 }
146
141 for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) { 147 for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) {
142 struct vm_area_struct *vma; 148 struct vm_area_struct *vma;
143 149
@@ -177,6 +183,7 @@ static void decode_address(char *buf, unsigned long address)
177 sprintf(buf, "[ %s vma:0x%lx-0x%lx]", 183 sprintf(buf, "[ %s vma:0x%lx-0x%lx]",
178 name, vma->vm_start, vma->vm_end); 184 name, vma->vm_start, vma->vm_end);
179 185
186 up_read(&mm->mmap_sem);
180 if (!in_atomic) 187 if (!in_atomic)
181 mmput(mm); 188 mmput(mm);
182 189
@@ -186,11 +193,16 @@ static void decode_address(char *buf, unsigned long address)
186 goto done; 193 goto done;
187 } 194 }
188 } 195 }
196
197 up_read(&mm->mmap_sem);
189 if (!in_atomic) 198 if (!in_atomic)
190 mmput(mm); 199 mmput(mm);
191 } 200 }
192 201
193 /* we were unable to find this address anywhere */ 202 /*
203 * we were unable to find this address anywhere,
204 * or some MMs were skipped because they were in use.
205 */
194 sprintf(buf, "/* kernel dynamic memory */"); 206 sprintf(buf, "/* kernel dynamic memory */");
195 207
196done: 208done: