diff options
author | Konstantin Khlebnikov <khlebnikov@openvz.org> | 2012-03-21 19:33:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-21 20:54:55 -0400 |
commit | c3f0327f8e9d7a503f0d64573c311eddd61f197d (patch) | |
tree | ebc59003d3bef08dd41d073eced2b53970e13662 | |
parent | dc3f21eadeea6d9898271ff32d35d5e00c6872ea (diff) |
mm: add rss counters consistency check
Warn about non-zero rss counters at final mmdrop.
This check will prevent reoccurences of bugs such as that fixed in "mm:
fix rss count leakage during migration".
I didn't hide this check under CONFIG_VM_DEBUG because it rather small and
rss counters cover whole page-table management, so this is a good
invariant.
Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | kernel/fork.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index c4f38a849436..a9e99f3c18e0 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -511,6 +511,23 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p) | |||
511 | return NULL; | 511 | return NULL; |
512 | } | 512 | } |
513 | 513 | ||
514 | static void check_mm(struct mm_struct *mm) | ||
515 | { | ||
516 | int i; | ||
517 | |||
518 | for (i = 0; i < NR_MM_COUNTERS; i++) { | ||
519 | long x = atomic_long_read(&mm->rss_stat.count[i]); | ||
520 | |||
521 | if (unlikely(x)) | ||
522 | printk(KERN_ALERT "BUG: Bad rss-counter state " | ||
523 | "mm:%p idx:%d val:%ld\n", mm, i, x); | ||
524 | } | ||
525 | |||
526 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
527 | VM_BUG_ON(mm->pmd_huge_pte); | ||
528 | #endif | ||
529 | } | ||
530 | |||
514 | /* | 531 | /* |
515 | * Allocate and initialize an mm_struct. | 532 | * Allocate and initialize an mm_struct. |
516 | */ | 533 | */ |
@@ -538,9 +555,7 @@ void __mmdrop(struct mm_struct *mm) | |||
538 | mm_free_pgd(mm); | 555 | mm_free_pgd(mm); |
539 | destroy_context(mm); | 556 | destroy_context(mm); |
540 | mmu_notifier_mm_destroy(mm); | 557 | mmu_notifier_mm_destroy(mm); |
541 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 558 | check_mm(mm); |
542 | VM_BUG_ON(mm->pmd_huge_pte); | ||
543 | #endif | ||
544 | free_mm(mm); | 559 | free_mm(mm); |
545 | } | 560 | } |
546 | EXPORT_SYMBOL_GPL(__mmdrop); | 561 | EXPORT_SYMBOL_GPL(__mmdrop); |