From 970c941acb9fc2556ea5b7c5a8225a7935692652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?= Date: Sun, 25 Aug 2013 15:15:55 +0000 Subject: [PATCH] drm/ttm: Fix unmap of buffer object Add a new ttm_bo_release_mmap() function to unmap pages in a vm_object_t. Pages are freed when the buffer object is later released. This function is called in ttm_bo_unmap_virtual_locked(), replacing Linux' unmap_mapping_range(). In particular this is called when a buffer object is about to be moved, so that its mapping is invalidated. However, we don't use this function in ttm_bo_vm_dtor(), because the vm_object_t is already marked as OBJ_DEAD and the pages will be unmapped. Approved by: kib@ --- sys/dev/drm2/ttm/ttm_bo.c | 7 +------ sys/dev/drm2/ttm/ttm_bo_vm.c | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/sys/dev/drm2/ttm/ttm_bo.c b/sys/dev/drm2/ttm/ttm_bo.c index 8bd8af930963..d7b1d3066b21 100644 --- a/sys/dev/drm2/ttm/ttm_bo.c +++ b/sys/dev/drm2/ttm/ttm_bo.c @@ -1634,13 +1634,8 @@ bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) void ttm_bo_unmap_virtual_locked(struct ttm_buffer_object *bo) { - struct ttm_bo_device *bdev = bo->bdev; - /* off_t offset = (off_t)bo->addr_space_offset;XXXKIB */ - /* off_t holelen = ((off_t)bo->mem.num_pages) << PAGE_SHIFT;XXXKIB */ - if (!bdev->dev_mapping) - return; - /* unmap_mapping_range(bdev->dev_mapping, offset, holelen, 1); XXXKIB */ + ttm_bo_release_mmap(bo); ttm_mem_io_free_vm(bo); } diff --git a/sys/dev/drm2/ttm/ttm_bo_vm.c b/sys/dev/drm2/ttm/ttm_bo_vm.c index f420fd5b93aa..8674551f7f70 100644 --- a/sys/dev/drm2/ttm/ttm_bo_vm.c +++ b/sys/dev/drm2/ttm/ttm_bo_vm.c @@ -361,6 +361,33 @@ out_unref: return ret; } +void +ttm_bo_release_mmap(struct ttm_buffer_object *bo) +{ + vm_object_t vm_obj; + vm_page_t m; + int i; + + vm_obj = cdev_pager_lookup(bo); + if (vm_obj == NULL) { + return; + } + + VM_OBJECT_WLOCK(vm_obj); +retry: + for (i = 0; i < bo->num_pages; i++) { + m = vm_page_lookup(vm_obj, i); + if (m == NULL) + continue; + if (vm_page_sleep_if_busy(m, "ttm_unm")) + goto retry; + cdev_pager_free_page(vm_obj, m); + } + VM_OBJECT_WUNLOCK(vm_obj); + + vm_object_deallocate(vm_obj); +} + #if 0 int ttm_fbdev_mmap(struct vm_area_struct *vma, struct ttm_buffer_object *bo) {