Commit 1e57c2186fc204ecd5e47f279d00eba3c3db245c
Exists in
master
and in
7 other branches
Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
…/git/tip/linux-2.6-tip * 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: lockdep: Avoid out of bounds array reference in save_trace() futex: Take mmap_sem for get_user_pages in fault_in_user_writeable lockstat: Add usage info to Documentation/lockstat.txt lockstat: Fix min, max times in /proc/lock_stats
Showing 3 changed files Side-by-side Diff
Documentation/lockstat.txt
... | ... | @@ -62,7 +62,19 @@ |
62 | 62 | It also tracks 4 contention points per class. A contention point is a call site |
63 | 63 | that had to wait on lock acquisition. |
64 | 64 | |
65 | + - CONFIGURATION | |
66 | + | |
67 | +Lock statistics are enabled via CONFIG_LOCK_STATS. | |
68 | + | |
65 | 69 | - USAGE |
70 | + | |
71 | +Enable collection of statistics: | |
72 | + | |
73 | +# echo 1 >/proc/sys/kernel/lock_stat | |
74 | + | |
75 | +Disable collection of statistics: | |
76 | + | |
77 | +# echo 0 >/proc/sys/kernel/lock_stat | |
66 | 78 | |
67 | 79 | Look at the current lock statistics: |
68 | 80 |
kernel/futex.c
... | ... | @@ -304,8 +304,14 @@ |
304 | 304 | */ |
305 | 305 | static int fault_in_user_writeable(u32 __user *uaddr) |
306 | 306 | { |
307 | - int ret = get_user_pages(current, current->mm, (unsigned long)uaddr, | |
308 | - 1, 1, 0, NULL, NULL); | |
307 | + struct mm_struct *mm = current->mm; | |
308 | + int ret; | |
309 | + | |
310 | + down_read(&mm->mmap_sem); | |
311 | + ret = get_user_pages(current, mm, (unsigned long)uaddr, | |
312 | + 1, 1, 0, NULL, NULL); | |
313 | + up_read(&mm->mmap_sem); | |
314 | + | |
309 | 315 | return ret < 0 ? ret : 0; |
310 | 316 | } |
311 | 317 |
kernel/lockdep.c
... | ... | @@ -168,7 +168,7 @@ |
168 | 168 | if (time > lt->max) |
169 | 169 | lt->max = time; |
170 | 170 | |
171 | - if (time < lt->min || !lt->min) | |
171 | + if (time < lt->min || !lt->nr) | |
172 | 172 | lt->min = time; |
173 | 173 | |
174 | 174 | lt->total += time; |
... | ... | @@ -177,8 +177,15 @@ |
177 | 177 | |
178 | 178 | static inline void lock_time_add(struct lock_time *src, struct lock_time *dst) |
179 | 179 | { |
180 | - dst->min += src->min; | |
181 | - dst->max += src->max; | |
180 | + if (!src->nr) | |
181 | + return; | |
182 | + | |
183 | + if (src->max > dst->max) | |
184 | + dst->max = src->max; | |
185 | + | |
186 | + if (src->min < dst->min || !dst->nr) | |
187 | + dst->min = src->min; | |
188 | + | |
182 | 189 | dst->total += src->total; |
183 | 190 | dst->nr += src->nr; |
184 | 191 | } |
... | ... | @@ -379,7 +386,8 @@ |
379 | 386 | * complete trace that maxes out the entries provided will be reported |
380 | 387 | * as incomplete, friggin useless </rant> |
381 | 388 | */ |
382 | - if (trace->entries[trace->nr_entries-1] == ULONG_MAX) | |
389 | + if (trace->nr_entries != 0 && | |
390 | + trace->entries[trace->nr_entries-1] == ULONG_MAX) | |
383 | 391 | trace->nr_entries--; |
384 | 392 | |
385 | 393 | trace->max_entries = trace->nr_entries; |