From: "Thomas Hellström (VMware)" <thomas_os@shipmail.org> To: linux-mm@kvack.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org Cc: pv-drivers@vmware.com, linux-graphics-maintainer@vmware.com, "Thomas Hellstrom" <thellstrom@vmware.com>, "Andrew Morton" <akpm@linux-foundation.org>, "Michal Hocko" <mhocko@suse.com>, "Matthew Wilcox (Oracle)" <willy@infradead.org>, "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>, "Ralph Campbell" <rcampbell@nvidia.com>, "Jérôme Glisse" <jglisse@redhat.com>, "Christian König" <christian.koenig@amd.com> Subject: [PATCH 5/8] drm/vmwgfx: Support huge page faults Date: Tue, 3 Dec 2019 14:22:36 +0100 [thread overview] Message-ID: <20191203132239.5910-6-thomas_os@shipmail.org> (raw) In-Reply-To: <20191203132239.5910-1-thomas_os@shipmail.org> From: Thomas Hellstrom <thellstrom@vmware.com> With vmwgfx dirty-tracking we need a specialized huge_fault callback. Implement and hook it up. Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Michal Hocko <mhocko@suse.com> Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> Cc: Ralph Campbell <rcampbell@nvidia.com> Cc: "Jérôme Glisse" <jglisse@redhat.com> Cc: "Christian König" <christian.koenig@amd.com> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 2 + drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c | 66 +++++++++++++++++++++- drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c | 1 + 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index a31e726d6d71..8656a97448c3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -1428,6 +1428,8 @@ void vmw_bo_dirty_unmap(struct vmw_buffer_object *vbo, pgoff_t start, pgoff_t end); vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf); vm_fault_t vmw_bo_vm_mkwrite(struct vm_fault *vmf); +vm_fault_t vmw_bo_vm_huge_fault(struct vm_fault *vmf, + enum page_entry_size pe_size); /** * VMW_DEBUG_KMS - Debug output for kernel mode-setting diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c index 17a5dca7b921..6f76a97ad969 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c @@ -473,7 +473,7 @@ vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf) * a lot of unnecessary write faults. */ if (vbo->dirty && vbo->dirty->method == VMW_BO_DIRTY_MKWRITE) - prot = vma->vm_page_prot; + prot = vm_get_page_prot(vma->vm_flags & ~VM_SHARED); else prot = vm_get_page_prot(vma->vm_flags); @@ -486,3 +486,67 @@ vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf) return ret; } + +vm_fault_t vmw_bo_vm_huge_fault(struct vm_fault *vmf, + enum page_entry_size pe_size) +{ + struct vm_area_struct *vma = vmf->vma; + struct ttm_buffer_object *bo = (struct ttm_buffer_object *) + vma->vm_private_data; + struct vmw_buffer_object *vbo = + container_of(bo, struct vmw_buffer_object, base); + pgprot_t prot; + vm_fault_t ret; + pgoff_t fault_page_size; + + switch (pe_size) { + case PE_SIZE_PMD: + fault_page_size = HPAGE_PMD_SIZE >> PAGE_SHIFT; + break; + case PE_SIZE_PUD: + fault_page_size = HPAGE_PUD_SIZE >> PAGE_SHIFT; + break; + default: + WARN_ON_ONCE(1); + return VM_FAULT_FALLBACK; + } + + /* Always do write dirty-tracking on PTE level. */ + if (READ_ONCE(vbo->dirty) && (vmf->flags & FAULT_FLAG_WRITE)) + return VM_FAULT_FALLBACK; + + ret = ttm_bo_vm_reserve(bo, vmf); + if (ret) + return ret; + + if (vbo->dirty) { + pgoff_t allowed_prefault; + unsigned long page_offset; + + page_offset = vmf->pgoff - + drm_vma_node_start(&bo->base.vma_node); + if (page_offset >= bo->num_pages || + vmw_resources_clean(vbo, page_offset, + page_offset + PAGE_SIZE, + &allowed_prefault)) { + ret = VM_FAULT_SIGBUS; + goto out_unlock; + } + + /* + * Write protect, so we get a new fault on write, and can + * split. + */ + prot = vm_get_page_prot(vma->vm_flags & ~VM_SHARED); + } else { + prot = vm_get_page_prot(vma->vm_flags); + } + ret = ttm_bo_vm_fault_reserved(vmf, prot, 1, fault_page_size); + if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) + return ret; + +out_unlock: + dma_resv_unlock(bo->base.resv); + + return ret; +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c index ce288756531b..de838ba88a97 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c @@ -33,6 +33,7 @@ int vmw_mmap(struct file *filp, struct vm_area_struct *vma) .pfn_mkwrite = vmw_bo_vm_mkwrite, .page_mkwrite = vmw_bo_vm_mkwrite, .fault = vmw_bo_vm_fault, + .huge_fault = vmw_bo_vm_huge_fault, .open = ttm_bo_vm_open, .close = ttm_bo_vm_close }; -- 2.21.0
WARNING: multiple messages have this Message-ID (diff)
From: "Thomas Hellström (VMware)" <thomas_os@shipmail.org> To: linux-mm@kvack.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org Cc: "Thomas Hellstrom" <thellstrom@vmware.com>, "Michal Hocko" <mhocko@suse.com>, pv-drivers@vmware.com, "Ralph Campbell" <rcampbell@nvidia.com>, "Matthew Wilcox (Oracle)" <willy@infradead.org>, "Jérôme Glisse" <jglisse@redhat.com>, linux-graphics-maintainer@vmware.com, "Andrew Morton" <akpm@linux-foundation.org>, "Christian König" <christian.koenig@amd.com>, "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> Subject: [PATCH 5/8] drm/vmwgfx: Support huge page faults Date: Tue, 3 Dec 2019 14:22:36 +0100 [thread overview] Message-ID: <20191203132239.5910-6-thomas_os@shipmail.org> (raw) In-Reply-To: <20191203132239.5910-1-thomas_os@shipmail.org> From: Thomas Hellstrom <thellstrom@vmware.com> With vmwgfx dirty-tracking we need a specialized huge_fault callback. Implement and hook it up. Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Michal Hocko <mhocko@suse.com> Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> Cc: Ralph Campbell <rcampbell@nvidia.com> Cc: "Jérôme Glisse" <jglisse@redhat.com> Cc: "Christian König" <christian.koenig@amd.com> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 2 + drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c | 66 +++++++++++++++++++++- drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c | 1 + 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index a31e726d6d71..8656a97448c3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -1428,6 +1428,8 @@ void vmw_bo_dirty_unmap(struct vmw_buffer_object *vbo, pgoff_t start, pgoff_t end); vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf); vm_fault_t vmw_bo_vm_mkwrite(struct vm_fault *vmf); +vm_fault_t vmw_bo_vm_huge_fault(struct vm_fault *vmf, + enum page_entry_size pe_size); /** * VMW_DEBUG_KMS - Debug output for kernel mode-setting diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c index 17a5dca7b921..6f76a97ad969 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c @@ -473,7 +473,7 @@ vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf) * a lot of unnecessary write faults. */ if (vbo->dirty && vbo->dirty->method == VMW_BO_DIRTY_MKWRITE) - prot = vma->vm_page_prot; + prot = vm_get_page_prot(vma->vm_flags & ~VM_SHARED); else prot = vm_get_page_prot(vma->vm_flags); @@ -486,3 +486,67 @@ vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf) return ret; } + +vm_fault_t vmw_bo_vm_huge_fault(struct vm_fault *vmf, + enum page_entry_size pe_size) +{ + struct vm_area_struct *vma = vmf->vma; + struct ttm_buffer_object *bo = (struct ttm_buffer_object *) + vma->vm_private_data; + struct vmw_buffer_object *vbo = + container_of(bo, struct vmw_buffer_object, base); + pgprot_t prot; + vm_fault_t ret; + pgoff_t fault_page_size; + + switch (pe_size) { + case PE_SIZE_PMD: + fault_page_size = HPAGE_PMD_SIZE >> PAGE_SHIFT; + break; + case PE_SIZE_PUD: + fault_page_size = HPAGE_PUD_SIZE >> PAGE_SHIFT; + break; + default: + WARN_ON_ONCE(1); + return VM_FAULT_FALLBACK; + } + + /* Always do write dirty-tracking on PTE level. */ + if (READ_ONCE(vbo->dirty) && (vmf->flags & FAULT_FLAG_WRITE)) + return VM_FAULT_FALLBACK; + + ret = ttm_bo_vm_reserve(bo, vmf); + if (ret) + return ret; + + if (vbo->dirty) { + pgoff_t allowed_prefault; + unsigned long page_offset; + + page_offset = vmf->pgoff - + drm_vma_node_start(&bo->base.vma_node); + if (page_offset >= bo->num_pages || + vmw_resources_clean(vbo, page_offset, + page_offset + PAGE_SIZE, + &allowed_prefault)) { + ret = VM_FAULT_SIGBUS; + goto out_unlock; + } + + /* + * Write protect, so we get a new fault on write, and can + * split. + */ + prot = vm_get_page_prot(vma->vm_flags & ~VM_SHARED); + } else { + prot = vm_get_page_prot(vma->vm_flags); + } + ret = ttm_bo_vm_fault_reserved(vmf, prot, 1, fault_page_size); + if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) + return ret; + +out_unlock: + dma_resv_unlock(bo->base.resv); + + return ret; +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c index ce288756531b..de838ba88a97 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c @@ -33,6 +33,7 @@ int vmw_mmap(struct file *filp, struct vm_area_struct *vma) .pfn_mkwrite = vmw_bo_vm_mkwrite, .page_mkwrite = vmw_bo_vm_mkwrite, .fault = vmw_bo_vm_fault, + .huge_fault = vmw_bo_vm_huge_fault, .open = ttm_bo_vm_open, .close = ttm_bo_vm_close }; -- 2.21.0 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2019-12-03 13:23 UTC|newest] Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-12-03 13:22 [PATCH 0/8] Huge page-table entries for TTM Thomas Hellström (VMware) 2019-12-03 13:22 ` Thomas Hellström (VMware) 2019-12-03 13:22 ` [PATCH 1/8] mm: Introduce vma_is_special_huge Thomas Hellström (VMware) 2019-12-03 13:22 ` Thomas Hellström (VMware) 2020-03-01 4:04 ` Andrew Morton 2020-03-01 4:04 ` Andrew Morton 2019-12-03 13:22 ` [PATCH 2/8] mm: Split huge pages on write-notify or COW Thomas Hellström (VMware) 2019-12-03 13:22 ` Thomas Hellström (VMware) 2020-03-01 4:04 ` Andrew Morton 2020-03-01 4:04 ` Andrew Morton 2019-12-03 13:22 ` [PATCH 3/8] mm: Add vmf_insert_pfn_xxx_prot() for huge page-table entries Thomas Hellström (VMware) 2019-12-03 13:22 ` Thomas Hellström (VMware) 2019-12-03 13:22 ` [PATCH 4/8] drm/ttm, drm/vmwgfx: Support huge TTM pagefaults Thomas Hellström (VMware) 2019-12-03 13:22 ` Thomas Hellström (VMware) 2019-12-03 13:22 ` Thomas Hellström (VMware) [this message] 2019-12-03 13:22 ` [PATCH 5/8] drm/vmwgfx: Support huge page faults Thomas Hellström (VMware) 2019-12-03 13:22 ` [PATCH 6/8] drm: Add a drm_get_unmapped_area() helper Thomas Hellström (VMware) 2019-12-03 13:22 ` Thomas Hellström (VMware) 2019-12-04 11:11 ` Christian König 2019-12-04 11:11 ` Christian König 2019-12-04 11:36 ` Thomas Hellström (VMware) 2019-12-04 11:36 ` Thomas Hellström (VMware) 2019-12-04 12:08 ` Christian König 2019-12-04 12:08 ` Christian König 2019-12-04 12:32 ` Thomas Hellström (VMware) 2019-12-04 12:32 ` Thomas Hellström (VMware) 2019-12-04 14:40 ` Christian König 2019-12-04 14:40 ` Christian König 2019-12-04 15:36 ` Thomas Hellström (VMware) 2019-12-04 15:36 ` Thomas Hellström (VMware) 2019-12-03 13:22 ` [PATCH 7/8] drm/ttm: Introduce a huge page aligning TTM range manager Thomas Hellström (VMware) 2019-12-03 13:22 ` Thomas Hellström (VMware) 2019-12-04 11:13 ` Christian König 2019-12-04 11:13 ` Christian König 2019-12-04 11:45 ` Thomas Hellström (VMware) 2019-12-04 11:45 ` Thomas Hellström (VMware) 2019-12-04 12:16 ` Christian König 2019-12-04 12:16 ` Christian König 2019-12-04 13:18 ` Thomas Hellström (VMware) 2019-12-04 13:18 ` Thomas Hellström (VMware) 2019-12-04 14:02 ` Christian König 2019-12-04 14:02 ` Christian König 2019-12-03 13:22 ` [PATCH 8/8] drm/vmwgfx: Hook up the helpers to align buffer objects Thomas Hellström (VMware) 2019-12-03 13:22 ` Thomas Hellström (VMware) 2020-03-01 4:04 ` [PATCH 0/8] Huge page-table entries for TTM Andrew Morton 2020-03-01 4:04 ` Andrew Morton
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20191203132239.5910-6-thomas_os@shipmail.org \ --to=thomas_os@shipmail.org \ --cc=akpm@linux-foundation.org \ --cc=christian.koenig@amd.com \ --cc=dri-devel@lists.freedesktop.org \ --cc=jglisse@redhat.com \ --cc=kirill.shutemov@linux.intel.com \ --cc=linux-graphics-maintainer@vmware.com \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mm@kvack.org \ --cc=mhocko@suse.com \ --cc=pv-drivers@vmware.com \ --cc=rcampbell@nvidia.com \ --cc=thellstrom@vmware.com \ --cc=willy@infradead.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.