lkml.org 
[lkml]   [2010]   [Apr]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: [PATCH -v2] rmap: make anon_vma_prepare link in all the anon_vmas of a mergeable VMA


On Sun, 11 Apr 2010, Linus Torvalds wrote:
>
> I'll see if I can come up with a patch to do the same kind of validation
> on page->mapping as on the anon-vma chains themselves.

Ok, this may or may not work. It hasn't triggered for me, which may be
because it's broken, but maybe it's because I'm not doing whatever it is
you are doing to break our VM.

It checks each anonymous page at unmap time against the vma it gets
unmapped from. It depends on the previous vma_verify debugging patch, and
it would be interesting to hear whether this patch causes any new warnngs
for you..

If the warnings do happen, they are not going to be printing out any
hugely informative data apart from the fact that the bad case happened at
all. But If they do trigger, I can try to improve on them - it's just not
worth trying to make them any more interesting if they never trigger.

Linus

---
mm/memory.c | 21 +++++++++++++++++++++
mm/mmap.c | 2 +-
2 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/mm/memory.c b/mm/memory.c
index 833952d..5d2df59 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -890,6 +890,25 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
return ret;
}

+extern void verify_vma(struct vm_area_struct *);
+
+static void verify_anon_page(struct vm_area_struct *vma, struct page *page)
+{
+ struct anon_vma *anon_vma = vma->anon_vma;
+ struct anon_vma *need_anon_vma = page_anon_vma(page);
+ struct anon_vma_chain *avc;
+
+ verify_vma(vma);
+ if (WARN_ONCE(!anon_vma, "anonymous page in vma without anon_vma"))
+ return;
+ list_for_each_entry(avc, &vma->anon_vma_chain, same_vma) {
+ WARN_ONCE(avc->vma != vma, "anon_vma_chain vma entry doesn't match");
+ if (avc->anon_vma == need_anon_vma)
+ return;
+ }
+ WARN_ONCE(1, "page->mapping does not exist in vma chain");
+}
+
static unsigned long zap_pte_range(struct mmu_gather *tlb,
struct vm_area_struct *vma, pmd_t *pmd,
unsigned long addr, unsigned long end,
@@ -940,6 +959,8 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
tlb_remove_tlb_entry(tlb, pte, addr);
if (unlikely(!page))
continue;
+ if (PageAnon(page))
+ verify_anon_page(vma, page);
if (unlikely(details) && details->nonlinear_vma
&& linear_page_index(details->nonlinear_vma,
addr) != page->index)
diff --git a/mm/mmap.c b/mm/mmap.c
index 890c169..461f59c 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1565,7 +1565,7 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,

EXPORT_SYMBOL(get_unmapped_area);

-static void verify_vma(struct vm_area_struct *vma)
+void verify_vma(struct vm_area_struct *vma)
{
if (vma->anon_vma) {
struct anon_vma_chain *avc;

\
 
 \ /
  Last update: 2010-04-12 03:11    [W:0.367 / U:0.048 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site