From patchwork Thu May 10 18:11:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Souptick Joarder X-Patchwork-Id: 10392171 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D999A6028E for ; Thu, 10 May 2018 18:09:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C460328CF4 for ; Thu, 10 May 2018 18:09:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B839128CF7; Thu, 10 May 2018 18:09:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C356C28CF4 for ; Thu, 10 May 2018 18:09:19 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 751136B0635; Thu, 10 May 2018 14:09:18 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 700E16B0636; Thu, 10 May 2018 14:09:18 -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 5A1D56B0637; Thu, 10 May 2018 14:09:18 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pl0-f72.google.com (mail-pl0-f72.google.com [209.85.160.72]) by kanga.kvack.org (Postfix) with ESMTP id 082C76B0635 for ; Thu, 10 May 2018 14:09:18 -0400 (EDT) Received: by mail-pl0-f72.google.com with SMTP id a6-v6so1599913pll.22 for ; Thu, 10 May 2018 11:09:17 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:dkim-signature:date:from:to:cc:subject :message-id:mime-version:content-disposition:user-agent; bh=gHFwnbOU053ofEPgXlGr51OR50cEKpfm0Zg3QmgIFHM=; b=H99fIdQpBjZi6bgbDylCKIlpj+AXET9+/9j3jvSJ8KmQ/mGI1M2lO8Oy+dZCyPwZ70 rWwHUwBef7nxv2SGtYmSrr6PeuLCI8INSDUHXKACYxMdCgBcavcPx54WkgrIEm8/opna Apx9lrBaYjyK3tyzttMEYZG7tQZsfOSHxpipaWQyNvFYusaq+d4rN+A2ZFDwdJjHfgFJ KYMo2thy1EoCLfAJ6wrGQX6AzW3N+vL5uDWXFt5kzrzN8SGdjOB7Jb6I8Nkn6zkAuS0P Ok1am3onY1Jt2He80+GRSjH4y9ax4ZYB8VwfSaVxCXm8vbrYi/s9cv3u+/dnSrXSygQZ 4hTA== X-Gm-Message-State: ALKqPwdqJx+cVW6PnfEb9/x7mdMzLpuATeBuyrUTFzQImfiruSm9SdJK GI072X3p5Q7aEpug23N+0YGzX5ylFb3Th6o58w4TgEtX+MAiwMSPz3v7HS9hahtGAw2rl4CKEb2 XblmzFogo+X9ZJppBTF9NfVbom+wS0MgPXmFqEyNTnmhwO7GlRdPt/1R0xWiJTSbSs86ew5lvhy r2fRhnFFX+5baU25rzce/fVHEfiMV3/gQFBkrQSZCKXinZ58xsBmjUpOuiTQRX4hustjldXt62g siIXXxNtmOPnQWog5DFLUIiNxoB85onJDiTxV6YDEW3rGJUqjp4rhxAcnBaFPvi/+l8DUQi/3pP MdJmcWiuo9U8SO2iZBvDiaPIfJJCkdI8jqBVein14b7kPYcpDg/1k2xbE1DW3+IUD+enKRWBHWl W X-Received: by 2002:a62:f55b:: with SMTP id n88-v6mr2328398pfh.208.1525975757652; Thu, 10 May 2018 11:09:17 -0700 (PDT) X-Received: by 2002:a62:f55b:: with SMTP id n88-v6mr2328339pfh.208.1525975756262; Thu, 10 May 2018 11:09:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525975756; cv=none; d=google.com; s=arc-20160816; b=gZjzvqtUnhymTzpgAa3KHecVAmdmrRXqUOydkJYm6qHNFAx/269JAkbGgyC1GJZAu+ TgWIBNNYXezJNgPfmTyRARuOhbEU9PiOBqIOCYV1XFolXlpE3LWvsZvIoNAvn07bv9lr Noya9wFc3drJxS4WF7O+KfrBsvncIFhpVAIxoshTxgn8ZPo5mnPWhhIlblQRlrGW8LQA k8P0Um0bGSN2d1t9eRwAH1in11AqYogHeeDX74NnhDTMItlBH2UbafYcNAcOr2T86KUo 3rlkaXqJr3MGg4p3oY6iKXLYdoKFJNo/1QJJr3tSL4PGDEmcX1yqsLtncCy6xMzSGAEf VqOQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=user-agent:content-disposition:mime-version:message-id:subject:cc :to:from:date:dkim-signature:arc-authentication-results; bh=gHFwnbOU053ofEPgXlGr51OR50cEKpfm0Zg3QmgIFHM=; b=lIkpWrWPRdOVKrBm3hmPh8Cp63HBIYiZUj+XaJt0X+YG2bO1BlIrWAoxMFNniu76W9 9XlYiePueaZj01cyVkyDcjFSdQ8P4fAUnb8Uyl6jcmnbMquU1p5RkasqmrSwSDrxISyZ gW42Lh4j0K9Zw+XgifW17ZmcbQlSL0sDE5dHYT9FvJieIL/T3eX4IPe2pKGtZONdwc9D HpH7dwRPxdo7H/JHIjYHB2wV9oWLErnUvGwiHZWs8CNE9INe8WlR6FN1Ywe0PHebG0Ox 5CRUPKKIzpr7Re30HWWI4ftaSVIum6EGSHVmrd3vFCGHcj91YlxF3iJbNYdyE0elMVGE IYtA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=h0rqPRfr; spf=pass (google.com: domain of jrdr.linux@gmail.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=jrdr.linux@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id h19-v6sor425466pfa.36.2018.05.10.11.09.16 for (Google Transport Security); Thu, 10 May 2018 11:09:16 -0700 (PDT) Received-SPF: pass (google.com: domain of jrdr.linux@gmail.com designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=h0rqPRfr; spf=pass (google.com: domain of jrdr.linux@gmail.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=jrdr.linux@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :user-agent; bh=gHFwnbOU053ofEPgXlGr51OR50cEKpfm0Zg3QmgIFHM=; b=h0rqPRfrNjJ2qtO6I6AdGUX/zTHBquckBYYdszzKLeVPKb1UW8TXB0iVACChMnEwu9 /pYmBeeB9mrAFBsYg96cByuUfn+EnwlKv5RtntF7+RBP3RuhvhZvqsQylAQYbl6lylck b693tW/+vpCl0bII+ENnofTjUHeNaPR1KdmTn/MXLjrjT4iv2OGsd7RjjI9TdA53hdzN JKD9a46wqctQAAZOdLHcU2FITVQavkb4VFjeQobeo6mvNbe2nFyZGCZ1xebCK72Lr1aM ONi05uvCuEowJMcnQvZWc46k2I6ps46YCxlfhe8Q+t6UxSpVtfroDtQyewaIR66O2S2C 66RQ== X-Google-Smtp-Source: AB8JxZotTh1NgAIxydixWWJrJ5EmQSqi9kNHCmFvlOeEILP/pjMf+YMe4RjtUXsD4kYtpvt7vMWffw== X-Received: by 2002:a62:59d1:: with SMTP id k78-v6mr2326140pfj.54.1525975755567; Thu, 10 May 2018 11:09:15 -0700 (PDT) Received: from jordon-HP-15-Notebook-PC ([49.205.218.138]) by smtp.gmail.com with ESMTPSA id s9-v6sm3622200pfa.141.2018.05.10.11.09.13 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 10 May 2018 11:09:13 -0700 (PDT) Date: Thu, 10 May 2018 23:41:21 +0530 From: Souptick Joarder To: willy@infradead.org, jack@suse.cz, viro@zeniv.linux.org.uk, ross.zwisler@linux.intel.com, akpm@linux-foundation.org, dan.j.williams@intel.com, mhocko@suse.com, kirill.shutemov@linux.intel.com Cc: linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH v7] fs: dax: Adding new return type vm_fault_t Message-ID: <20180510181121.GA15239@jordon-HP-15-Notebook-PC> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) 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: X-Virus-Scanned: ClamAV using ClamSMTP Use new return type vm_fault_t for fault handler. For now, this is just documenting that the function returns a VM_FAULT value rather than an errno. Once all instances are converted, vm_fault_t will become a distinct type. commit 1c8f422059ae ("mm: change return type to vm_fault_t") There was an existing bug inside dax_load_hole() if vm_insert_mixed had failed to allocate a page table, we'd return VM_FAULT_NOPAGE instead of VM_FAULT_OOM. With new vmf_insert_mixed() this issue is addressed. vm_insert_mixed_mkwrite has inefficiency when it returns an error value, driver has to convert it to vm_fault_t type. With new vmf_insert_mixed_mkwrite() this limitation will be addressed. Signed-off-by: Souptick Joarder Reviewed-by: Jan Kara Reviewed-by: Matthew Wilcox Reviewed-by: Ross Zwisler --- v2: vm_insert_mixed_mkwrite is replaced by new vmf_insert_mixed_mkwrite v3: Addressed Matthew's comment. One patch which changes both at the same time. The history should be bisectable so that it compiles and works at every point. v4: Updated the change log v5: Updated the change log v6: Added comment in source file v7: Reviewed by Ross Zwisler fs/dax.c | 78 +++++++++++++++++++++++++---------------------------- include/linux/dax.h | 4 +-- include/linux/mm.h | 4 +-- mm/memory.c | 21 ++++++++++++--- 4 files changed, 58 insertions(+), 49 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index aaec72de..821986c 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -905,12 +905,12 @@ static int dax_iomap_pfn(struct iomap *iomap, loff_t pos, size_t size, * If this page is ever written to we will re-fault and change the mapping to * point to real DAX storage instead. */ -static int dax_load_hole(struct address_space *mapping, void *entry, +static vm_fault_t dax_load_hole(struct address_space *mapping, void *entry, struct vm_fault *vmf) { struct inode *inode = mapping->host; unsigned long vaddr = vmf->address; - int ret = VM_FAULT_NOPAGE; + vm_fault_t ret = VM_FAULT_NOPAGE; struct page *zero_page; void *entry2; pfn_t pfn; @@ -929,7 +929,7 @@ static int dax_load_hole(struct address_space *mapping, void *entry, goto out; } - vm_insert_mixed(vmf->vma, vaddr, pfn); + ret = vmf_insert_mixed(vmf->vma, vaddr, pfn); out: trace_dax_load_hole(inode, vmf, ret); return ret; @@ -1112,7 +1112,7 @@ int __dax_zero_page_range(struct block_device *bdev, } EXPORT_SYMBOL_GPL(dax_iomap_rw); -static int dax_fault_return(int error) +static vm_fault_t dax_fault_return(int error) { if (error == 0) return VM_FAULT_NOPAGE; @@ -1132,7 +1132,7 @@ static bool dax_fault_is_synchronous(unsigned long flags, && (iomap->flags & IOMAP_F_DIRTY); } -static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp, +static vm_fault_t dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp, int *iomap_errp, const struct iomap_ops *ops) { struct vm_area_struct *vma = vmf->vma; @@ -1145,18 +1145,18 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp, int error, major = 0; bool write = vmf->flags & FAULT_FLAG_WRITE; bool sync; - int vmf_ret = 0; + vm_fault_t ret = 0; void *entry; pfn_t pfn; - trace_dax_pte_fault(inode, vmf, vmf_ret); + trace_dax_pte_fault(inode, vmf, ret); /* * Check whether offset isn't beyond end of file now. Caller is supposed * to hold locks serializing us with truncate / punch hole so this is * a reliable test. */ if (pos >= i_size_read(inode)) { - vmf_ret = VM_FAULT_SIGBUS; + ret = VM_FAULT_SIGBUS; goto out; } @@ -1165,7 +1165,7 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp, entry = grab_mapping_entry(mapping, vmf->pgoff, 0); if (IS_ERR(entry)) { - vmf_ret = dax_fault_return(PTR_ERR(entry)); + ret = dax_fault_return(PTR_ERR(entry)); goto out; } @@ -1176,7 +1176,7 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp, * retried. */ if (pmd_trans_huge(*vmf->pmd) || pmd_devmap(*vmf->pmd)) { - vmf_ret = VM_FAULT_NOPAGE; + ret = VM_FAULT_NOPAGE; goto unlock_entry; } @@ -1189,7 +1189,7 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp, if (iomap_errp) *iomap_errp = error; if (error) { - vmf_ret = dax_fault_return(error); + ret = dax_fault_return(error); goto unlock_entry; } if (WARN_ON_ONCE(iomap.offset + iomap.length < pos + PAGE_SIZE)) { @@ -1219,9 +1219,9 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp, goto error_finish_iomap; __SetPageUptodate(vmf->cow_page); - vmf_ret = finish_fault(vmf); - if (!vmf_ret) - vmf_ret = VM_FAULT_DONE_COW; + ret = finish_fault(vmf); + if (!ret) + ret = VM_FAULT_DONE_COW; goto finish_iomap; } @@ -1257,23 +1257,20 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp, goto error_finish_iomap; } *pfnp = pfn; - vmf_ret = VM_FAULT_NEEDDSYNC | major; + ret = VM_FAULT_NEEDDSYNC | major; goto finish_iomap; } trace_dax_insert_mapping(inode, vmf, entry); if (write) - error = vm_insert_mixed_mkwrite(vma, vaddr, pfn); + ret = vmf_insert_mixed_mkwrite(vma, vaddr, pfn); else - error = vm_insert_mixed(vma, vaddr, pfn); + ret = vmf_insert_mixed(vma, vaddr, pfn); - /* -EBUSY is fine, somebody else faulted on the same PTE */ - if (error == -EBUSY) - error = 0; - break; + goto finish_iomap; case IOMAP_UNWRITTEN: case IOMAP_HOLE: if (!write) { - vmf_ret = dax_load_hole(mapping, entry, vmf); + ret = dax_load_hole(mapping, entry, vmf); goto finish_iomap; } /*FALLTHRU*/ @@ -1284,12 +1281,12 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp, } error_finish_iomap: - vmf_ret = dax_fault_return(error) | major; + ret = dax_fault_return(error); finish_iomap: if (ops->iomap_end) { int copied = PAGE_SIZE; - if (vmf_ret & VM_FAULT_ERROR) + if (ret & VM_FAULT_ERROR) copied = 0; /* * The fault is done by now and there's no way back (other @@ -1302,12 +1299,12 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp, unlock_entry: put_locked_mapping_entry(mapping, vmf->pgoff); out: - trace_dax_pte_fault_done(inode, vmf, vmf_ret); - return vmf_ret; + trace_dax_pte_fault_done(inode, vmf, ret); + return ret | major; } #ifdef CONFIG_FS_DAX_PMD -static int dax_pmd_load_hole(struct vm_fault *vmf, struct iomap *iomap, +static vm_fault_t dax_pmd_load_hole(struct vm_fault *vmf, struct iomap *iomap, void *entry) { struct address_space *mapping = vmf->vma->vm_file->f_mapping; @@ -1348,7 +1345,7 @@ static int dax_pmd_load_hole(struct vm_fault *vmf, struct iomap *iomap, return VM_FAULT_FALLBACK; } -static int dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp, +static vm_fault_t dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp, const struct iomap_ops *ops) { struct vm_area_struct *vma = vmf->vma; @@ -1358,7 +1355,7 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp, bool sync; unsigned int iomap_flags = (write ? IOMAP_WRITE : 0) | IOMAP_FAULT; struct inode *inode = mapping->host; - int result = VM_FAULT_FALLBACK; + vm_fault_t result = VM_FAULT_FALLBACK; struct iomap iomap = { 0 }; pgoff_t max_pgoff, pgoff; void *entry; @@ -1509,7 +1506,7 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp, return result; } #else -static int dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp, +static vm_fault_t dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp, const struct iomap_ops *ops) { return VM_FAULT_FALLBACK; @@ -1529,7 +1526,7 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp, * has done all the necessary locking for page fault to proceed * successfully. */ -int dax_iomap_fault(struct vm_fault *vmf, enum page_entry_size pe_size, +vm_fault_t dax_iomap_fault(struct vm_fault *vmf, enum page_entry_size pe_size, pfn_t *pfnp, int *iomap_errp, const struct iomap_ops *ops) { switch (pe_size) { @@ -1553,14 +1550,14 @@ int dax_iomap_fault(struct vm_fault *vmf, enum page_entry_size pe_size, * DAX file. It takes care of marking corresponding radix tree entry as dirty * as well. */ -static int dax_insert_pfn_mkwrite(struct vm_fault *vmf, +static vm_fault_t dax_insert_pfn_mkwrite(struct vm_fault *vmf, enum page_entry_size pe_size, pfn_t pfn) { struct address_space *mapping = vmf->vma->vm_file->f_mapping; void *entry, **slot; pgoff_t index = vmf->pgoff; - int vmf_ret, error; + vm_fault_t ret; xa_lock_irq(&mapping->i_pages); entry = get_unlocked_mapping_entry(mapping, index, &slot); @@ -1579,21 +1576,20 @@ static int dax_insert_pfn_mkwrite(struct vm_fault *vmf, xa_unlock_irq(&mapping->i_pages); switch (pe_size) { case PE_SIZE_PTE: - error = vm_insert_mixed_mkwrite(vmf->vma, vmf->address, pfn); - vmf_ret = dax_fault_return(error); + ret = vmf_insert_mixed_mkwrite(vmf->vma, vmf->address, pfn); break; #ifdef CONFIG_FS_DAX_PMD case PE_SIZE_PMD: - vmf_ret = vmf_insert_pfn_pmd(vmf->vma, vmf->address, vmf->pmd, + ret = vmf_insert_pfn_pmd(vmf->vma, vmf->address, vmf->pmd, pfn, true); break; #endif default: - vmf_ret = VM_FAULT_FALLBACK; + ret = VM_FAULT_FALLBACK; } put_locked_mapping_entry(mapping, index); - trace_dax_insert_pfn_mkwrite(mapping->host, vmf, vmf_ret); - return vmf_ret; + trace_dax_insert_pfn_mkwrite(mapping->host, vmf, ret); + return ret; } /** @@ -1606,8 +1602,8 @@ static int dax_insert_pfn_mkwrite(struct vm_fault *vmf, * stored persistently on the media and handles inserting of appropriate page * table entry. */ -int dax_finish_sync_fault(struct vm_fault *vmf, enum page_entry_size pe_size, - pfn_t pfn) +vm_fault_t dax_finish_sync_fault(struct vm_fault *vmf, + enum page_entry_size pe_size, pfn_t pfn) { int err; loff_t start = ((loff_t)vmf->pgoff) << PAGE_SHIFT; diff --git a/include/linux/dax.h b/include/linux/dax.h index f9eb22a..7fddea8 100644 --- a/include/linux/dax.h +++ b/include/linux/dax.h @@ -124,8 +124,8 @@ ssize_t dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter, const struct iomap_ops *ops); int dax_iomap_fault(struct vm_fault *vmf, enum page_entry_size pe_size, pfn_t *pfnp, int *errp, const struct iomap_ops *ops); -int dax_finish_sync_fault(struct vm_fault *vmf, enum page_entry_size pe_size, - pfn_t pfn); +vm_fault_t dax_finish_sync_fault(struct vm_fault *vmf, + enum page_entry_size pe_size, pfn_t pfn); int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index); int dax_invalidate_mapping_entry_sync(struct address_space *mapping, pgoff_t index); diff --git a/include/linux/mm.h b/include/linux/mm.h index 1ac1f06..9fe441c 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2423,8 +2423,8 @@ int vm_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, pgprot_t pgprot); int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, pfn_t pfn); -int vm_insert_mixed_mkwrite(struct vm_area_struct *vma, unsigned long addr, - pfn_t pfn); +vm_fault_t vmf_insert_mixed_mkwrite(struct vm_area_struct *vma, + unsigned long addr, pfn_t pfn); int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len); static inline vm_fault_t vmf_insert_page(struct vm_area_struct *vma, diff --git a/mm/memory.c b/mm/memory.c index 01f5464..6a97893 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1955,12 +1955,25 @@ int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, } EXPORT_SYMBOL(vm_insert_mixed); -int vm_insert_mixed_mkwrite(struct vm_area_struct *vma, unsigned long addr, - pfn_t pfn) +/* + * If the insertion of PTE failed because someone else already added a + * different entry in the mean time, we treat that as success as we assume + * the same entry was actually inserted. + */ + +vm_fault_t vmf_insert_mixed_mkwrite(struct vm_area_struct *vma, + unsigned long addr, pfn_t pfn) { - return __vm_insert_mixed(vma, addr, pfn, true); + int err; + + err = __vm_insert_mixed(vma, addr, pfn, true); + if (err == -ENOMEM) + return VM_FAULT_OOM; + if (err < 0 && err != -EBUSY) + return VM_FAULT_SIGBUS; + return VM_FAULT_NOPAGE; } -EXPORT_SYMBOL(vm_insert_mixed_mkwrite); +EXPORT_SYMBOL(vmf_insert_mixed_mkwrite); /* * maps a range of physical memory into the requested pages. the old