From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C63DBC433F5 for ; Tue, 16 Nov 2021 04:48:49 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 689A060F22 for ; Tue, 16 Nov 2021 04:48:49 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 689A060F22 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=linux-foundation.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=kvack.org Received: by kanga.kvack.org (Postfix) id C5E316B00A8; Mon, 15 Nov 2021 23:48:48 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id C0E536B00A9; Mon, 15 Nov 2021 23:48:48 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id AD5FB6B00AA; Mon, 15 Nov 2021 23:48:48 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0245.hostedemail.com [216.40.44.245]) by kanga.kvack.org (Postfix) with ESMTP id 9DAC96B00A8 for ; Mon, 15 Nov 2021 23:48:48 -0500 (EST) Received: from smtpin13.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with ESMTP id 488B8180C3C66 for ; Tue, 16 Nov 2021 04:48:48 +0000 (UTC) X-FDA: 78813563136.13.F10D106 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by imf28.hostedemail.com (Postfix) with ESMTP id 67D6090000B2 for ; Tue, 16 Nov 2021 04:48:45 +0000 (UTC) Received: by mail.kernel.org (Postfix) with ESMTPSA id 526E961C14; Tue, 16 Nov 2021 04:48:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linux-foundation.org; s=korg; t=1637038124; bh=PdWkT3fEJ2JRdNOFrwV/g5qBebbyUBBaFKLRli0LTnU=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=Bcfg5PxwN4mu1S+FiPKHF85mqEJqbnLtlWXm6L4NIXoP/i8ClBRVtAup+cFM7zT/Z unqYPCp6C7QP7ZiNl2QSu8WpUUz+8nS2iBtmB9yOhEbNPNJaiU6BO4aycQYMY94v5L G5mMwOjiVRH0/Y3D/pDK+3BfV/aDNNQ8YxRdVlc0= Date: Mon, 15 Nov 2021 20:48:42 -0800 From: Andrew Morton To: Alistair Popple Cc: Jason Gunthorpe , , , , , , , Subject: Re: [PATCH] mm/hmm.c: Allow VM_MIXEDMAP to work with hmm_range_fault Message-Id: <20211115204842.78180ec7f4b0f51b538bbf55@linux-foundation.org> In-Reply-To: <5535346.2Y9IAguWGx@nvdebian> References: <20211104012001.2555676-1-apopple@nvidia.com> <20211105122557.GA2744544@nvidia.com> <5535346.2Y9IAguWGx@nvdebian> X-Mailer: Sylpheed 3.5.1 (GTK+ 2.24.31; x86_64-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Authentication-Results: imf28.hostedemail.com; dkim=pass header.d=linux-foundation.org header.s=korg header.b=Bcfg5Pxw; dmarc=none; spf=pass (imf28.hostedemail.com: domain of akpm@linux-foundation.org designates 198.145.29.99 as permitted sender) smtp.mailfrom=akpm@linux-foundation.org X-Rspamd-Server: rspam02 X-Rspamd-Queue-Id: 67D6090000B2 X-Stat-Signature: mt3che1eqdruxw4wcrn4opy5kk4umpke X-HE-Tag: 1637038125-963747 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: On Mon, 8 Nov 2021 18:58:01 +1100 Alistair Popple wrote: > On Friday, 5 November 2021 11:25:57 PM AEDT Jason Gunthorpe wrote: > > On Thu, Nov 04, 2021 at 12:20:01PM +1100, Alistair Popple wrote: > > > hmm_range_fault() can be used instead of get_user_pages() for devices > > > which allow faulting however unlike get_user_pages() it will return an > > > error when used on a VM_MIXEDMAP range. > > > > > > To make hmm_range_fault() more closely match get_user_pages() remove > > > this restriction. This requires dealing with the !ARCH_HAS_PTE_SPECIAL > > > case in hmm_vma_handle_pte(). Rather than replicating the logic of > > > vm_normal_page() call it directly and do a check for the zero pfn > > > similar to what get_user_pages() currently does. > > > > > > Also add a test to hmm selftest to verify functionality. > > > > Please add a fixes line > > This has been the case since hmm_vma_get_pfns() was first introduced. Therefore > the fixes line is: > > Fixes: da4c3c735ea4 ("mm/hmm/mirror: helper to snapshot CPU page table") > > Should I send a v2 adding that tag or does Andrew normally pick these up along > with the Reviewed-by? I got it. It needed a bit of rework due to the newly-added !pte_devmap() change in hmm_vma_handle_pte(). Please check carefully? From: Alistair Popple Subject: mm/hmm.c: Allow VM_MIXEDMAP to work with hmm_range_fault hmm_range_fault() can be used instead of get_user_pages() for devices which allow faulting however unlike get_user_pages() it will return an error when used on a VM_MIXEDMAP range. To make hmm_range_fault() more closely match get_user_pages() remove this restriction. This requires dealing with the !ARCH_HAS_PTE_SPECIAL case in hmm_vma_handle_pte(). Rather than replicating the logic of vm_normal_page() call it directly and do a check for the zero pfn similar to what get_user_pages() currently does. Also add a test to hmm selftest to verify functionality. Link: https://lkml.kernel.org/r/20211104012001.2555676-1-apopple@nvidia.com Fixes: da4c3c735ea4 ("mm/hmm/mirror: helper to snapshot CPU page table") Signed-off-by: Alistair Popple Reviewed-by: Jason Gunthorpe Cc: Jerome Glisse Cc: John Hubbard Cc: Zi Yan Cc: Ralph Campbell Cc: Felix Kuehling Signed-off-by: Andrew Morton --- lib/test_hmm.c | 24 +++++++++++++ mm/hmm.c | 5 +- tools/testing/selftests/vm/hmm-tests.c | 42 +++++++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) --- a/lib/test_hmm.c~mm-hmmc-allow-vm_mixedmap-to-work-with-hmm_range_fault +++ a/lib/test_hmm.c @@ -1086,9 +1086,33 @@ static long dmirror_fops_unlocked_ioctl( return 0; } +static int dmirror_fops_mmap(struct file *file, struct vm_area_struct *vma) +{ + unsigned long addr; + + for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) { + struct page *page; + int ret; + + page = alloc_page(GFP_KERNEL | __GFP_ZERO); + if (!page) + return -ENOMEM; + + ret = vm_insert_page(vma, addr, page); + if (ret) { + __free_page(page); + return ret; + } + put_page(page); + } + + return 0; +} + static const struct file_operations dmirror_fops = { .open = dmirror_fops_open, .release = dmirror_fops_release, + .mmap = dmirror_fops_mmap, .unlocked_ioctl = dmirror_fops_unlocked_ioctl, .llseek = default_llseek, .owner = THIS_MODULE, --- a/mm/hmm.c~mm-hmmc-allow-vm_mixedmap-to-work-with-hmm_range_fault +++ a/mm/hmm.c @@ -300,7 +300,8 @@ static int hmm_vma_handle_pte(struct mm_ * Since each architecture defines a struct page for the zero page, just * fall through and treat it like a normal page. */ - if (pte_special(pte) && !pte_devmap(pte) && + if (!vm_normal_page(walk->vma, addr, pte) && + !pte_devmap(pte) && !is_zero_pfn(pte_pfn(pte))) { if (hmm_pte_need_fault(hmm_vma_walk, pfn_req_flags, 0)) { pte_unmap(ptep); @@ -518,7 +519,7 @@ static int hmm_vma_walk_test(unsigned lo struct hmm_range *range = hmm_vma_walk->range; struct vm_area_struct *vma = walk->vma; - if (!(vma->vm_flags & (VM_IO | VM_PFNMAP | VM_MIXEDMAP)) && + if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)) && vma->vm_flags & VM_READ) return 0; --- a/tools/testing/selftests/vm/hmm-tests.c~mm-hmmc-allow-vm_mixedmap-to-work-with-hmm_range_fault +++ a/tools/testing/selftests/vm/hmm-tests.c @@ -1251,6 +1251,48 @@ TEST_F(hmm, anon_teardown) /* * Test memory snapshot without faulting in pages accessed by the device. */ +TEST_F(hmm, mixedmap) +{ + struct hmm_buffer *buffer; + unsigned long npages; + unsigned long size; + unsigned char *m; + int ret; + + npages = 1; + size = npages << self->page_shift; + + buffer = malloc(sizeof(*buffer)); + ASSERT_NE(buffer, NULL); + + buffer->fd = -1; + buffer->size = size; + buffer->mirror = malloc(npages); + ASSERT_NE(buffer->mirror, NULL); + + + /* Reserve a range of addresses. */ + buffer->ptr = mmap(NULL, size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE, + self->fd, 0); + ASSERT_NE(buffer->ptr, MAP_FAILED); + + /* Simulate a device snapshotting CPU pagetables. */ + ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages); + ASSERT_EQ(ret, 0); + ASSERT_EQ(buffer->cpages, npages); + + /* Check what the device saw. */ + m = buffer->mirror; + ASSERT_EQ(m[0], HMM_DMIRROR_PROT_READ); + + hmm_buffer_free(buffer); +} + +/* + * Test memory snapshot without faulting in pages accessed by the device. + */ TEST_F(hmm2, snapshot) { struct hmm_buffer *buffer; _