For both anon_vma_clone() and unlink_anon_vmas(), if the source VMA or the VMA to be linked are unfaulted (e.g. !vma->anon_vma), then the functions do nothing. Simply exit early in these cases. In the unlink_anon_vmas() case we can also remove a conditional that checks whether vma->anon_vma is set. Signed-off-by: Lorenzo Stoakes --- mm/rmap.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/mm/rmap.c b/mm/rmap.c index 0e34c0a69fbc..9332d1cbc643 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -309,6 +309,9 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src) struct anon_vma_chain *avc, *pavc; struct anon_vma *root = NULL; + if (!src->anon_vma) + return 0; + check_anon_vma_clone(dst, src); list_for_each_entry_reverse(pavc, &src->anon_vma_chain, same_vma) { @@ -441,7 +444,8 @@ void unlink_anon_vmas(struct vm_area_struct *vma) mmap_assert_locked(vma->vm_mm); /* Unfaulted is a no-op. */ - VM_WARN_ON_ONCE(!vma->anon_vma && !list_empty(&vma->anon_vma_chain)); + if (!vma->anon_vma) + return; /* * Unlink each anon_vma chained to the VMA. This list is ordered @@ -465,15 +469,13 @@ void unlink_anon_vmas(struct vm_area_struct *vma) list_del(&avc->same_vma); anon_vma_chain_free(avc); } - if (vma->anon_vma) { - vma->anon_vma->num_active_vmas--; - /* - * vma would still be needed after unlink, and anon_vma will be prepared - * when handle fault. - */ - vma->anon_vma = NULL; - } + vma->anon_vma->num_active_vmas--; + /* + * vma would still be needed after unlink, and anon_vma will be prepared + * when handle fault. + */ + vma->anon_vma = NULL; unlock_anon_vma_root(root); /* -- 2.52.0