diff options
author | Graf Yang <graf.yang@analog.com> | 2010-01-13 01:09:34 -0500 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2010-03-09 00:30:49 -0500 |
commit | c6669c223a409199a45bb8f31a2e160ee26d19cc (patch) | |
tree | cb46eb31a6ed699ce7ed31e874e965a38f987bd5 /arch/blackfin/kernel | |
parent | 7e1082b7dbb60081b157d82106da33686cb9ea91 (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>
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r-- | arch/blackfin/kernel/traps.c | 14 |
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 | ||
196 | done: | 208 | done: |