Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp8991869ybi; Tue, 23 Jul 2019 19:36:56 -0700 (PDT) X-Google-Smtp-Source: APXvYqz5IjZ5vERiht4Mpx7RYA8lfo2/5pH90oZufHMwdNh5j95/Kj2xxKbP75+M2sp4ZHo4eyZP X-Received: by 2002:a17:902:9a85:: with SMTP id w5mr83576022plp.221.1563935816099; Tue, 23 Jul 2019 19:36:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1563935816; cv=none; d=google.com; s=arc-20160816; b=XygcHr1e1enPW7+ylozsXze4Yg2M8nRcu6OeTJPYy4zlkk3dxbdaASqFw+Y9pnnae1 bhaWajhUDe16BrbFwMQ3Mf5lFQizcoBIJfR5NryiPniwhilMmZDJ+WmQWJO0XJ1zmxVT m5Gue49xuoZ4qhZe2l/g3JZS7fNc74tvLuHDK25wo00jeFGpO3iGB1Q+90b0jtcsBsbY LmIiVCdLNh7A4Z0W5zhvEIMLX+13ZyPpiQri8zVbDP/ANuurGfUkkF3Gmskh3+C1rU+l P9PHlFz9vXP5jCb1/LTNXjJvunLiV4aSGDpFSAi+hM9oaqNUIJ9zByDYzEP+VBpjk/jw bvhw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:dkim-signature:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from; bh=hfYQ/qkPLZjADPYtK9Vb0H/HyTmNQ/JXBO+v+y3qqYE=; b=RxLFpBLFaAuobXOBMiRhx3OZFRg5M32/GflE4gStHGRuIVD2g5ID8b5semROes66Ee nMeixwl2ryRGU7ou6kWXEjUbbeAwsotK1mLZDUjykzAjLeKwwJRyAnhGLTJ9nO9g2vpg jIttQn5IQGiegZlPZyg/JhEFDQ3RtG7KE0Fngz2vfYIbwFJTWBcq6dNEK3mKeQfSKEbm jQbXWkBdLRDbK9+oJjgxqjyf4WNn45/rwV8C8TO+Tj809iPk2Weijj0f3nT5xO8katNI opq9AxElHekDhuWD/rEpBWXA4uCF3bs5VXaIXHf/WOCgJZP04ve5lPzFwn3+ufyThCKP O2ag== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@nvidia.com header.s=n1 header.b=PmsQaM0N; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h61si13220518plb.256.2019.07.23.19.36.41; Tue, 23 Jul 2019 19:36:56 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@nvidia.com header.s=n1 header.b=PmsQaM0N; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726941AbfGWXaa (ORCPT + 99 others); Tue, 23 Jul 2019 19:30:30 -0400 Received: from hqemgate15.nvidia.com ([216.228.121.64]:11788 "EHLO hqemgate15.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726888AbfGWXa2 (ORCPT ); Tue, 23 Jul 2019 19:30:28 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqemgate15.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Tue, 23 Jul 2019 16:30:33 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Tue, 23 Jul 2019 16:30:25 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Tue, 23 Jul 2019 16:30:25 -0700 Received: from HQMAIL110.nvidia.com (172.18.146.15) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Tue, 23 Jul 2019 23:30:25 +0000 Received: from HQMAIL107.nvidia.com (172.20.187.13) by hqmail110.nvidia.com (172.18.146.15) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Tue, 23 Jul 2019 23:30:22 +0000 Received: from hqnvemgw01.nvidia.com (172.20.150.20) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Tue, 23 Jul 2019 23:30:22 +0000 Received: from rcampbell-dev.nvidia.com (Not Verified[10.110.48.66]) by hqnvemgw01.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Tue, 23 Jul 2019 16:30:22 -0700 From: Ralph Campbell To: CC: , Ralph Campbell , =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= , Jason Gunthorpe , Christoph Hellwig Subject: [PATCH 2/2] mm/hmm: make full use of walk_page_range() Date: Tue, 23 Jul 2019 16:30:16 -0700 Message-ID: <20190723233016.26403-3-rcampbell@nvidia.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190723233016.26403-1-rcampbell@nvidia.com> References: <20190723233016.26403-1-rcampbell@nvidia.com> MIME-Version: 1.0 X-NVConfidentiality: public Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1563924633; bh=hfYQ/qkPLZjADPYtK9Vb0H/HyTmNQ/JXBO+v+y3qqYE=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:MIME-Version:X-NVConfidentiality: Content-Type:Content-Transfer-Encoding; b=PmsQaM0NskBkOCohdJNR6vE+X7fr8YGHD0BPSKxxNAJnBiGfOZ1OFbMAFpmkyrDbQ 6OIHTMYlKoxkmxvcrLuprnPuX+OrTtZO6EwF/To/OZV1rV3wuHcNktrWn7lQAoX0kK TDT/0oErWbbFW/yVSuvuDm7kbleyInsG3qcmOec9w2f8zmKcm4bEptqYbUp6Susg2x lVcD9xVRYZwVTqTDuoEaanbD0JS4BuzLOFaC1tilqfNCm3HXySfjyhl36wy27Xx+7R FtJjCAaQuNRlp0l7xWfGkzCpOQ+e0/71SddSGIEJOH8IA2PlsTQKSRco/RfdzeNzd7 s0QTQ7eJSd3jg== Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org hmm_range_snapshot() and hmm_range_fault() both call find_vma() and walk_page_range() in a loop. This is unnecessary duplication since walk_page_range() calls find_vma() in a loop already. Simplify hmm_range_snapshot() and hmm_range_fault() by defining a walk_test() callback function to filter unhandled vmas. Signed-off-by: Ralph Campbell Cc: "J=C3=A9r=C3=B4me Glisse" Cc: Jason Gunthorpe Cc: Christoph Hellwig --- mm/hmm.c | 197 ++++++++++++++++++++----------------------------------- 1 file changed, 70 insertions(+), 127 deletions(-) diff --git a/mm/hmm.c b/mm/hmm.c index 8271f110c243..218557451070 100644 --- a/mm/hmm.c +++ b/mm/hmm.c @@ -839,13 +839,40 @@ static int hmm_vma_walk_hugetlb_entry(pte_t *pte, uns= igned long hmask, #endif } =20 -static void hmm_pfns_clear(struct hmm_range *range, - uint64_t *pfns, - unsigned long addr, - unsigned long end) +static int hmm_vma_walk_test(unsigned long start, + unsigned long end, + struct mm_walk *walk) { - for (; addr < end; addr +=3D PAGE_SIZE, pfns++) - *pfns =3D range->values[HMM_PFN_NONE]; + const unsigned long device_vma =3D VM_IO | VM_PFNMAP | VM_MIXEDMAP; + struct hmm_vma_walk *hmm_vma_walk =3D walk->private; + struct hmm_range *range =3D hmm_vma_walk->range; + struct vm_area_struct *vma =3D walk->vma; + + /* If range is no longer valid, force retry. */ + if (!range->valid) + return -EBUSY; + + if (vma->vm_flags & device_vma) + return -EFAULT; + + if (is_vm_hugetlb_page(vma)) { + if (huge_page_shift(hstate_vma(vma)) !=3D range->page_shift && + range->page_shift !=3D PAGE_SHIFT) + return -EINVAL; + } else { + if (range->page_shift !=3D PAGE_SHIFT) + return -EINVAL; + } + + /* + * If vma does not allow read access, then assume that it does not + * allow write access, either. HMM does not support architectures + * that allow write without read. + */ + if (!(vma->vm_flags & VM_READ)) + return -EPERM; + + return 0; } =20 /* @@ -949,65 +976,28 @@ EXPORT_SYMBOL(hmm_range_unregister); */ long hmm_range_snapshot(struct hmm_range *range) { - const unsigned long device_vma =3D VM_IO | VM_PFNMAP | VM_MIXEDMAP; - unsigned long start =3D range->start, end; - struct hmm_vma_walk hmm_vma_walk; + unsigned long start =3D range->start; + struct hmm_vma_walk hmm_vma_walk =3D {}; struct hmm *hmm =3D range->hmm; - struct vm_area_struct *vma; - struct mm_walk mm_walk; + struct mm_walk mm_walk =3D {}; + int ret; =20 lockdep_assert_held(&hmm->mm->mmap_sem); - do { - /* If range is no longer valid force retry. */ - if (!range->valid) - return -EBUSY; =20 - vma =3D find_vma(hmm->mm, start); - if (vma =3D=3D NULL || (vma->vm_flags & device_vma)) - return -EFAULT; - - if (is_vm_hugetlb_page(vma)) { - if (huge_page_shift(hstate_vma(vma)) !=3D - range->page_shift && - range->page_shift !=3D PAGE_SHIFT) - return -EINVAL; - } else { - if (range->page_shift !=3D PAGE_SHIFT) - return -EINVAL; - } + hmm_vma_walk.range =3D range; + hmm_vma_walk.last =3D start; + mm_walk.private =3D &hmm_vma_walk; =20 - if (!(vma->vm_flags & VM_READ)) { - /* - * If vma do not allow read access, then assume that it - * does not allow write access, either. HMM does not - * support architecture that allow write without read. - */ - hmm_pfns_clear(range, range->pfns, - range->start, range->end); - return -EPERM; - } + mm_walk.mm =3D hmm->mm; + mm_walk.pud_entry =3D hmm_vma_walk_pud; + mm_walk.pmd_entry =3D hmm_vma_walk_pmd; + mm_walk.pte_hole =3D hmm_vma_walk_hole; + mm_walk.hugetlb_entry =3D hmm_vma_walk_hugetlb_entry; + mm_walk.test_walk =3D hmm_vma_walk_test; =20 - range->vma =3D vma; - hmm_vma_walk.pgmap =3D NULL; - hmm_vma_walk.last =3D start; - hmm_vma_walk.fault =3D false; - hmm_vma_walk.range =3D range; - mm_walk.private =3D &hmm_vma_walk; - end =3D min(range->end, vma->vm_end); - - mm_walk.vma =3D vma; - mm_walk.mm =3D vma->vm_mm; - mm_walk.pte_entry =3D NULL; - mm_walk.test_walk =3D NULL; - mm_walk.hugetlb_entry =3D NULL; - mm_walk.pud_entry =3D hmm_vma_walk_pud; - mm_walk.pmd_entry =3D hmm_vma_walk_pmd; - mm_walk.pte_hole =3D hmm_vma_walk_hole; - mm_walk.hugetlb_entry =3D hmm_vma_walk_hugetlb_entry; - - walk_page_range(start, end, &mm_walk); - start =3D end; - } while (start < range->end); + ret =3D walk_page_range(start, range->end, &mm_walk); + if (ret) + return ret; =20 return (hmm_vma_walk.last - range->start) >> PAGE_SHIFT; } @@ -1043,83 +1033,36 @@ EXPORT_SYMBOL(hmm_range_snapshot); */ long hmm_range_fault(struct hmm_range *range, bool block) { - const unsigned long device_vma =3D VM_IO | VM_PFNMAP | VM_MIXEDMAP; - unsigned long start =3D range->start, end; - struct hmm_vma_walk hmm_vma_walk; + unsigned long start =3D range->start; + struct hmm_vma_walk hmm_vma_walk =3D {}; struct hmm *hmm =3D range->hmm; - struct vm_area_struct *vma; - struct mm_walk mm_walk; + struct mm_walk mm_walk =3D {}; int ret; =20 lockdep_assert_held(&hmm->mm->mmap_sem); =20 - do { - /* If range is no longer valid force retry. */ - if (!range->valid) - return -EBUSY; + hmm_vma_walk.range =3D range; + hmm_vma_walk.last =3D start; + hmm_vma_walk.fault =3D true; + hmm_vma_walk.block =3D block; + mm_walk.private =3D &hmm_vma_walk; =20 - vma =3D find_vma(hmm->mm, start); - if (vma =3D=3D NULL || (vma->vm_flags & device_vma)) - return -EFAULT; - - if (is_vm_hugetlb_page(vma)) { - if (huge_page_shift(hstate_vma(vma)) !=3D - range->page_shift && - range->page_shift !=3D PAGE_SHIFT) - return -EINVAL; - } else { - if (range->page_shift !=3D PAGE_SHIFT) - return -EINVAL; - } + mm_walk.mm =3D hmm->mm; + mm_walk.pud_entry =3D hmm_vma_walk_pud; + mm_walk.pmd_entry =3D hmm_vma_walk_pmd; + mm_walk.pte_hole =3D hmm_vma_walk_hole; + mm_walk.hugetlb_entry =3D hmm_vma_walk_hugetlb_entry; + mm_walk.test_walk =3D hmm_vma_walk_test; =20 - if (!(vma->vm_flags & VM_READ)) { - /* - * If vma do not allow read access, then assume that it - * does not allow write access, either. HMM does not - * support architecture that allow write without read. - */ - hmm_pfns_clear(range, range->pfns, - range->start, range->end); - return -EPERM; - } + do { + ret =3D walk_page_range(start, range->end, &mm_walk); + start =3D hmm_vma_walk.last; =20 - range->vma =3D vma; - hmm_vma_walk.pgmap =3D NULL; - hmm_vma_walk.last =3D start; - hmm_vma_walk.fault =3D true; - hmm_vma_walk.block =3D block; - hmm_vma_walk.range =3D range; - mm_walk.private =3D &hmm_vma_walk; - end =3D min(range->end, vma->vm_end); - - mm_walk.vma =3D vma; - mm_walk.mm =3D vma->vm_mm; - mm_walk.pte_entry =3D NULL; - mm_walk.test_walk =3D NULL; - mm_walk.hugetlb_entry =3D NULL; - mm_walk.pud_entry =3D hmm_vma_walk_pud; - mm_walk.pmd_entry =3D hmm_vma_walk_pmd; - mm_walk.pte_hole =3D hmm_vma_walk_hole; - mm_walk.hugetlb_entry =3D hmm_vma_walk_hugetlb_entry; - - do { - ret =3D walk_page_range(start, end, &mm_walk); - start =3D hmm_vma_walk.last; - - /* Keep trying while the range is valid. */ - } while (ret =3D=3D -EBUSY && range->valid); - - if (ret) { - unsigned long i; - - i =3D (hmm_vma_walk.last - range->start) >> PAGE_SHIFT; - hmm_pfns_clear(range, &range->pfns[i], - hmm_vma_walk.last, range->end); - return ret; - } - start =3D end; + /* Keep trying while the range is valid. */ + } while (ret =3D=3D -EBUSY && range->valid); =20 - } while (start < range->end); + if (ret) + return ret; =20 return (hmm_vma_walk.last - range->start) >> PAGE_SHIFT; } --=20 2.20.1