From patchwork Fri Jul 17 02:47:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miaohe Lin X-Patchwork-Id: 11668855 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AB56760D for ; Fri, 17 Jul 2020 02:45:16 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 80AD92173E for ; Fri, 17 Jul 2020 02:45:16 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 80AD92173E Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 715AD8D000F; Thu, 16 Jul 2020 22:45:15 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 6C5CB8D0003; Thu, 16 Jul 2020 22:45:15 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 5B4C28D000F; Thu, 16 Jul 2020 22:45:15 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id 454D48D0003 for ; Thu, 16 Jul 2020 22:45:15 -0400 (EDT) Received: from smtpin03.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with ESMTP id D9FB5181AC9CB for ; Fri, 17 Jul 2020 02:45:14 +0000 (UTC) X-FDA: 77046026148.03.gold89_45127d126f07 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin03.hostedemail.com (Postfix) with ESMTP id A93E4232F6 for ; Fri, 17 Jul 2020 02:45:14 +0000 (UTC) X-Spam-Summary: 1,0,0,,d41d8cd98f00b204,linmiaohe@huawei.com,,RULES_HIT:30006:30036:30054:30070:30090,0,RBL:45.249.212.191:@huawei.com:.lbl8.mailshell.net-64.95.201.95 62.18.2.100;04y8i35xmexawjs7dsxky6cz7c8grypoe5m7ftq7ctp6qbwhcadjmppif5ykurq.juc9hgzeg8p994mu73e4eq58174oqmfpbq787tkyjffmns4h5fiw3dww3fg1a8w.o-lbl8.mailshell.net-223.238.255.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:23,LUA_SUMMARY:none X-HE-Tag: gold89_45127d126f07 X-Filterd-Recvd-Size: 3302 Received: from huawei.com (szxga05-in.huawei.com [45.249.212.191]) by imf33.hostedemail.com (Postfix) with ESMTP for ; Fri, 17 Jul 2020 02:45:13 +0000 (UTC) Received: from DGGEMS411-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 6BC5A9B27D54AE6BFB6B; Fri, 17 Jul 2020 10:45:10 +0800 (CST) Received: from huawei.com (10.175.101.6) by DGGEMS411-HUB.china.huawei.com (10.3.19.211) with Microsoft SMTP Server id 14.3.487.0; Fri, 17 Jul 2020 10:45:01 +0800 From: linmiaohe To: CC: , , Subject: [PATCH v2] mm: mmap: Merge vma after call_mmap() if possible Date: Fri, 17 Jul 2020 10:47:45 +0800 Message-ID: <1594954065-23733-1-git-send-email-linmiaohe@huawei.com> X-Mailer: git-send-email 1.8.3.1 MIME-Version: 1.0 X-Originating-IP: [10.175.101.6] X-CFilter-Loop: Reflected X-Rspamd-Queue-Id: A93E4232F6 X-Spamd-Result: default: False [0.00 / 100.00] X-Rspamd-Server: rspam01 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: From: Miaohe Lin The vm_flags may be changed after call_mmap() because drivers may set some flags for their own purpose. As a result, we failed to merge the adjacent vma due to the different vm_flags as userspace can't pass in the same one. Try to merge vma after call_mmap() to fix this issue. Signed-off-by: Hongxiang Lou Signed-off-by: Miaohe Lin --- Changes in v2: update vm_flags and possible addr to pick up the change --- mm/mmap.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/mm/mmap.c b/mm/mmap.c index 59a4682ebf3f..720721877b89 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1689,7 +1689,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, struct list_head *uf) { struct mm_struct *mm = current->mm; - struct vm_area_struct *vma, *prev; + struct vm_area_struct *vma, *prev, *merge; int error; struct rb_node **rb_link, *rb_parent; unsigned long charged = 0; @@ -1773,6 +1773,25 @@ unsigned long mmap_region(struct file *file, unsigned long addr, if (error) goto unmap_and_free_vma; + /* If vm_flags changed after call_mmap(), we should try merge vma again + * as we may succeed this time. + */ + if (unlikely(vm_flags != vma->vm_flags && prev)) { + merge = vma_merge(mm, prev, vma->vm_start, vma->vm_end, vma->vm_flags, + NULL, vma->vm_file, vma->vm_pgoff, NULL, NULL_VM_UFFD_CTX); + if (merge) { + fput(file); + vm_area_free(vma); + vma = merge; + /* Update vm_flags and possible addr to pick up the change. We don't + * warn here if addr changed as the vma is not linked by vma_link(). + */ + addr = vma->vm_start; + vm_flags = vma->vm_flags; + goto unmap_writable; + } + } + /* Can addr have changed?? * * Answer: Yes, several device drivers can do it in their @@ -1795,6 +1814,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, vma_link(mm, vma, prev, rb_link, rb_parent); /* Once vma denies write, undo our temporary denial count */ if (file) { +unmap_writable: if (vm_flags & VM_SHARED) mapping_unmap_writable(file->f_mapping); if (vm_flags & VM_DENYWRITE)