diff options
author | Dave Airlie <airlied@redhat.com> | 2010-04-20 14:15:09 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-04-20 14:15:09 +1000 |
commit | 7547a917fa5f3b2406f52c7dcf7ec9ad3c8532eb (patch) | |
tree | 59b0d0e9b6c251c4df5799b93395454592004d57 /drivers/gpu/drm/ttm | |
parent | a8089e849a32c5b6bfd6c88dbd09c0ea4a779b71 (diff) | |
parent | 6b8b1786a8c29ce6e32298b93ac8d4a18a2b11c4 (diff) |
Merge branch 'drm-ttm-unmappable' into drm-core-next
* drm-ttm-unmappable:
drm/radeon/kms: enable use of unmappable VRAM V2
drm/ttm: remove io_ field from TTM V6
drm/vmwgfx: add support for new TTM fault callback V5
drm/nouveau/kms: add support for new TTM fault callback V5
drm/radeon/kms: add support for new fault callback V7
drm/ttm: ttm_fault callback to allow driver to handle bo placement V6
drm/ttm: split no_wait argument in 2 GPU or reserve wait
Conflicts:
drivers/gpu/drm/nouveau/nouveau_bo.c
Diffstat (limited to 'drivers/gpu/drm/ttm')
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_bo.c | 84 | ||||
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_bo_util.c | 122 | ||||
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_bo_vm.c | 41 |
3 files changed, 114 insertions, 133 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index dd47b2a9a79..3b5b094b139 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -79,8 +79,6 @@ static void ttm_mem_type_debug(struct ttm_bo_device *bdev, int mem_type) printk(KERN_ERR TTM_PFX " use_type: %d\n", man->use_type); printk(KERN_ERR TTM_PFX " flags: 0x%08X\n", man->flags); printk(KERN_ERR TTM_PFX " gpu_offset: 0x%08lX\n", man->gpu_offset); - printk(KERN_ERR TTM_PFX " io_offset: 0x%08lX\n", man->io_offset); - printk(KERN_ERR TTM_PFX " io_size: %ld\n", man->io_size); printk(KERN_ERR TTM_PFX " size: %llu\n", man->size); printk(KERN_ERR TTM_PFX " available_caching: 0x%08X\n", man->available_caching); @@ -357,7 +355,8 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc) static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, struct ttm_mem_reg *mem, - bool evict, bool interruptible, bool no_wait) + bool evict, bool interruptible, + bool no_wait_reserve, bool no_wait_gpu) { struct ttm_bo_device *bdev = bo->bdev; bool old_is_pci = ttm_mem_reg_is_pci(bdev, &bo->mem); @@ -402,12 +401,12 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) && !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) - ret = ttm_bo_move_ttm(bo, evict, no_wait, mem); + ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, mem); else if (bdev->driver->move) ret = bdev->driver->move(bo, evict, interruptible, - no_wait, mem); + no_wait_reserve, no_wait_gpu, mem); else - ret = ttm_bo_move_memcpy(bo, evict, no_wait, mem); + ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, mem); if (ret) goto out_err; @@ -606,7 +605,7 @@ void ttm_bo_unref(struct ttm_buffer_object **p_bo) EXPORT_SYMBOL(ttm_bo_unref); static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible, - bool no_wait) + bool no_wait_reserve, bool no_wait_gpu) { struct ttm_bo_device *bdev = bo->bdev; struct ttm_bo_global *glob = bo->glob; @@ -615,7 +614,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible, int ret = 0; spin_lock(&bo->lock); - ret = ttm_bo_wait(bo, false, interruptible, no_wait); + ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu); spin_unlock(&bo->lock); if (unlikely(ret != 0)) { @@ -631,6 +630,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible, evict_mem = bo->mem; evict_mem.mm_node = NULL; + evict_mem.bus.io_reserved = false; placement.fpfn = 0; placement.lpfn = 0; @@ -638,7 +638,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible, placement.num_busy_placement = 0; bdev->driver->evict_flags(bo, &placement); ret = ttm_bo_mem_space(bo, &placement, &evict_mem, interruptible, - no_wait); + no_wait_reserve, no_wait_gpu); if (ret) { if (ret != -ERESTARTSYS) { printk(KERN_ERR TTM_PFX @@ -650,7 +650,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible, } ret = ttm_bo_handle_move_mem(bo, &evict_mem, true, interruptible, - no_wait); + no_wait_reserve, no_wait_gpu); if (ret) { if (ret != -ERESTARTSYS) printk(KERN_ERR TTM_PFX "Buffer eviction failed\n"); @@ -670,7 +670,8 @@ out: static int ttm_mem_evict_first(struct ttm_bo_device *bdev, uint32_t mem_type, - bool interruptible, bool no_wait) + bool interruptible, bool no_wait_reserve, + bool no_wait_gpu) { struct ttm_bo_global *glob = bdev->glob; struct ttm_mem_type_manager *man = &bdev->man[mem_type]; @@ -687,11 +688,11 @@ retry: bo = list_first_entry(&man->lru, struct ttm_buffer_object, lru); kref_get(&bo->list_kref); - ret = ttm_bo_reserve_locked(bo, false, true, false, 0); + ret = ttm_bo_reserve_locked(bo, false, no_wait_reserve, false, 0); if (unlikely(ret == -EBUSY)) { spin_unlock(&glob->lru_lock); - if (likely(!no_wait)) + if (likely(!no_wait_gpu)) ret = ttm_bo_wait_unreserved(bo, interruptible); kref_put(&bo->list_kref, ttm_bo_release_list); @@ -713,7 +714,7 @@ retry: while (put_count--) kref_put(&bo->list_kref, ttm_bo_ref_bug); - ret = ttm_bo_evict(bo, interruptible, no_wait); + ret = ttm_bo_evict(bo, interruptible, no_wait_reserve, no_wait_gpu); ttm_bo_unreserve(bo); kref_put(&bo->list_kref, ttm_bo_release_list); @@ -764,7 +765,9 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, uint32_t mem_type, struct ttm_placement *placement, struct ttm_mem_reg *mem, - bool interruptible, bool no_wait) + bool interruptible, + bool no_wait_reserve, + bool no_wait_gpu) { struct ttm_bo_device *bdev = bo->bdev; struct ttm_bo_global *glob = bdev->glob; @@ -785,7 +788,7 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, } spin_unlock(&glob->lru_lock); ret = ttm_mem_evict_first(bdev, mem_type, interruptible, - no_wait); + no_wait_reserve, no_wait_gpu); if (unlikely(ret != 0)) return ret; } while (1); @@ -855,7 +858,8 @@ static bool ttm_bo_mt_compatible(struct ttm_mem_type_manager *man, int ttm_bo_mem_space(struct ttm_buffer_object *bo, struct ttm_placement *placement, struct ttm_mem_reg *mem, - bool interruptible, bool no_wait) + bool interruptible, bool no_wait_reserve, + bool no_wait_gpu) { struct ttm_bo_device *bdev = bo->bdev; struct ttm_mem_type_manager *man; @@ -952,7 +956,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, } ret = ttm_bo_mem_force_space(bo, mem_type, placement, mem, - interruptible, no_wait); + interruptible, no_wait_reserve, no_wait_gpu); if (ret == 0 && mem->mm_node) { mem->placement = cur_flags; mem->mm_node->private = bo; @@ -978,7 +982,8 @@ EXPORT_SYMBOL(ttm_bo_wait_cpu); int ttm_bo_move_buffer(struct ttm_buffer_object *bo, struct ttm_placement *placement, - bool interruptible, bool no_wait) + bool interruptible, bool no_wait_reserve, + bool no_wait_gpu) { struct ttm_bo_global *glob = bo->glob; int ret = 0; @@ -992,20 +997,21 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo, * instead of doing it here. */ spin_lock(&bo->lock); - ret = ttm_bo_wait(bo, false, interruptible, no_wait); + ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu); spin_unlock(&bo->lock); if (ret) return ret; mem.num_pages = bo->num_pages; mem.size = mem.num_pages << PAGE_SHIFT; mem.page_alignment = bo->mem.page_alignment; + mem.bus.io_reserved = false; /* * Determine where to move the buffer. */ - ret = ttm_bo_mem_space(bo, placement, &mem, interruptible, no_wait); + ret = ttm_bo_mem_space(bo, placement, &mem, interruptible, no_wait_reserve, no_wait_gpu); if (ret) goto out_unlock; - ret = ttm_bo_handle_move_mem(bo, &mem, false, interruptible, no_wait); + ret = ttm_bo_handle_move_mem(bo, &mem, false, interruptible, no_wait_reserve, no_wait_gpu); out_unlock: if (ret && mem.mm_node) { spin_lock(&glob->lru_lock); @@ -1039,7 +1045,8 @@ static int ttm_bo_mem_compat(struct ttm_placement *placement, int ttm_bo_validate(struct ttm_buffer_object *bo, struct ttm_placement *placement, - bool interruptible, bool no_wait) + bool interruptible, bool no_wait_reserve, + bool no_wait_gpu) { int ret; @@ -1054,7 +1061,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, */ ret = ttm_bo_mem_compat(placement, &bo->mem); if (ret < 0) { - ret = ttm_bo_move_buffer(bo, placement, interruptible, no_wait); + ret = ttm_bo_move_buffer(bo, placement, interruptible, no_wait_reserve, no_wait_gpu); if (ret) return ret; } else { @@ -1153,6 +1160,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev, bo->mem.num_pages = bo->num_pages; bo->mem.mm_node = NULL; bo->mem.page_alignment = page_alignment; + bo->mem.bus.io_reserved = false; bo->buffer_start = buffer_start & PAGE_MASK; bo->priv_flags = 0; bo->mem.placement = (TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED); @@ -1175,7 +1183,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev, goto out_err; } - ret = ttm_bo_validate(bo, placement, interruptible, false); + ret = ttm_bo_validate(bo, placement, interruptible, false, false); if (ret) goto out_err; @@ -1249,7 +1257,7 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev, spin_lock(&glob->lru_lock); while (!list_empty(&man->lru)) { spin_unlock(&glob->lru_lock); - ret = ttm_mem_evict_first(bdev, mem_type, false, false); + ret = ttm_mem_evict_first(bdev, mem_type, false, false, false); if (ret) { if (allow_errors) { return ret; @@ -1553,26 +1561,6 @@ bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) return true; } -int ttm_bo_pci_offset(struct ttm_bo_device *bdev, - struct ttm_mem_reg *mem, - unsigned long *bus_base, - unsigned long *bus_offset, unsigned long *bus_size) -{ - struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; - - *bus_size = 0; - if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) - return -EINVAL; - - if (ttm_mem_reg_is_pci(bdev, mem)) { - *bus_offset = mem->mm_node->start << PAGE_SHIFT; - *bus_size = mem->num_pages << PAGE_SHIFT; - *bus_base = man->io_offset; - } - - return 0; -} - void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo) { struct ttm_bo_device *bdev = bo->bdev; @@ -1581,8 +1569,8 @@ void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo) if (!bdev->dev_mapping) return; - unmap_mapping_range(bdev->dev_mapping, offset, holelen, 1); + ttm_mem_io_free(bdev, &bo->mem); } EXPORT_SYMBOL(ttm_bo_unmap_virtual); @@ -1839,7 +1827,7 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink) evict_mem.mem_type = TTM_PL_SYSTEM; ret = ttm_bo_handle_move_mem(bo, &evict_mem, true, - false, false); + false, false, false); if (unlikely(ret != 0)) goto out; } diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index d764e82e799..a37a94872a1 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -50,7 +50,8 @@ void ttm_bo_free_old_node(struct ttm_buffer_object *bo) } int ttm_bo_move_ttm(struct ttm_buffer_object *bo, - bool evict, bool no_wait, struct ttm_mem_reg *new_mem) + bool evict, bool no_wait_reserve, + bool no_wait_gpu, struct ttm_mem_reg *new_mem) { struct ttm_tt *ttm = bo->ttm; struct ttm_mem_reg *old_mem = &bo->mem; @@ -81,30 +82,51 @@ int ttm_bo_move_ttm(struct ttm_buffer_object *bo, } EXPORT_SYMBOL(ttm_bo_move_ttm); +int ttm_mem_io_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) +{ + int ret; + + if (!mem->bus.io_reserved) { + mem->bus.io_reserved = true; + ret = bdev->driver->io_mem_reserve(bdev, mem); + if (unlikely(ret != 0)) + return ret; + } + return 0; +} + +void ttm_mem_io_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) +{ + if (bdev->driver->io_mem_reserve) { + if (mem->bus.io_reserved) { + mem->bus.io_reserved = false; + bdev->driver->io_mem_free(bdev, mem); + } + } +} + int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, void **virtual) { - struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; - unsigned long bus_offset; - unsigned long bus_size; - unsigned long bus_base; int ret; void *addr; *virtual = NULL; - ret = ttm_bo_pci_offset(bdev, mem, &bus_base, &bus_offset, &bus_size); - if (ret || bus_size == 0) + ret = ttm_mem_io_reserve(bdev, mem); + if (ret) return ret; - if (!(man->flags & TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) - addr = (void *)(((u8 *) man->io_addr) + bus_offset); - else { + if (mem->bus.addr) { + addr = mem->bus.addr; + } else { if (mem->placement & TTM_PL_FLAG_WC) - addr = ioremap_wc(bus_base + bus_offset, bus_size); + addr = ioremap_wc(mem->bus.base + mem->bus.offset, mem->bus.size); else - addr = ioremap_nocache(bus_base + bus_offset, bus_size); - if (!addr) + addr = ioremap_nocache(mem->bus.base + mem->bus.offset, mem->bus.size); + if (!addr) { + ttm_mem_io_free(bdev, mem); return -ENOMEM; + } } *virtual = addr; return 0; @@ -117,8 +139,9 @@ void ttm_mem_reg_iounmap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, man = &bdev->man[mem->mem_type]; - if (virtual && (man->flags & TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) + if (virtual && mem->bus.addr == NULL) iounmap(virtual); + ttm_mem_io_free(bdev, mem); } static int ttm_copy_io_page(void *dst, void *src, unsigned long page) @@ -208,7 +231,8 @@ static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst, } int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, - bool evict, bool no_wait, struct ttm_mem_reg *new_mem) + bool evict, bool no_wait_reserve, bool no_wait_gpu, + struct ttm_mem_reg *new_mem) { struct ttm_bo_device *bdev = bo->bdev; struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type]; @@ -369,26 +393,23 @@ pgprot_t ttm_io_prot(uint32_t caching_flags, pgprot_t tmp) EXPORT_SYMBOL(ttm_io_prot); static int ttm_bo_ioremap(struct ttm_buffer_object *bo, - unsigned long bus_base, - unsigned long bus_offset, - unsigned long bus_size, + unsigned long offset, + unsigned long size, struct ttm_bo_kmap_obj *map) { - struct ttm_bo_device *bdev = bo->bdev; struct ttm_mem_reg *mem = &bo->mem; - struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; - if (!(man->flags & TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) { + if (bo->mem.bus.addr) { map->bo_kmap_type = ttm_bo_map_premapped; - map->virtual = (void *)(((u8 *) man->io_addr) + bus_offset); + map->virtual = (void *)(((u8 *)bo->mem.bus.addr) + offset); } else { map->bo_kmap_type = ttm_bo_map_iomap; if (mem->placement & TTM_PL_FLAG_WC) - map->virtual = ioremap_wc(bus_base + bus_offset, - bus_size); + map->virtual = ioremap_wc(bo->mem.bus.base + bo->mem.bus.offset + offset, + size); else - map->virtual = ioremap_nocache(bus_base + bus_offset, - bus_size); + map->virtual = ioremap_nocache(bo->mem.bus.base + bo->mem.bus.offset + offset, + size); } return (!map->virtual) ? -ENOMEM : 0; } @@ -441,13 +462,12 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page, unsigned long num_pages, struct ttm_bo_kmap_obj *map) { + unsigned long offset, size; int ret; - unsigned long bus_base; - unsigned long bus_offset; - unsigned long bus_size; BUG_ON(!list_empty(&bo->swap)); map->virtual = NULL; + map->bo = bo; if (num_pages > bo->num_pages) return -EINVAL; if (start_page > bo->num_pages) @@ -456,16 +476,15 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, if (num_pages > 1 && !DRM_SUSER(DRM_CURPROC)) return -EPERM; #endif - ret = ttm_bo_pci_offset(bo->bdev, &bo->mem, &bus_base, - &bus_offset, &bus_size); + ret = ttm_mem_io_reserve(bo->bdev, &bo->mem); if (ret) return ret; - if (bus_size == 0) { + if (!bo->mem.bus.is_iomem) { return ttm_bo_kmap_ttm(bo, start_page, num_pages, map); } else { - bus_offset += start_page << PAGE_SHIFT; - bus_size = num_pages << PAGE_SHIFT; - return ttm_bo_ioremap(bo, bus_base, bus_offset, bus_size, map); + offset = start_page << PAGE_SHIFT; + size = num_pages << PAGE_SHIFT; + return ttm_bo_ioremap(bo, offset, size, map); } } EXPORT_SYMBOL(ttm_bo_kmap); @@ -477,6 +496,7 @@ void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map) switch (map->bo_kmap_type) { case ttm_bo_map_iomap: iounmap(map->virtual); + ttm_mem_io_free(map->bo->bdev, &map->bo->mem); break; case ttm_bo_map_vmap: vunmap(map->virtual); @@ -494,39 +514,11 @@ void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map) } EXPORT_SYMBOL(ttm_bo_kunmap); -int ttm_bo_pfn_prot(struct ttm_buffer_object *bo, - unsigned long dst_offset, - unsigned long *pfn, pgprot_t *prot) -{ - struct ttm_mem_reg *mem = &bo->mem; - struct ttm_bo_device *bdev = bo->bdev; - unsigned long bus_offset; - unsigned long bus_size; - unsigned long bus_base; - int ret; - ret = ttm_bo_pci_offset(bdev, mem, &bus_base, &bus_offset, - &bus_size); - if (ret) - return -EINVAL; - if (bus_size != 0) - *pfn = (bus_base + bus_offset + dst_offset) >> PAGE_SHIFT; - else - if (!bo->ttm) - return -EINVAL; - else - *pfn = page_to_pfn(ttm_tt_get_page(bo->ttm, - dst_offset >> - PAGE_SHIFT)); - *prot = (mem->placement & TTM_PL_FLAG_CACHED) ? - PAGE_KERNEL : ttm_io_prot(mem->placement, PAGE_KERNEL); - - return 0; -} - int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, void *sync_obj, void *sync_obj_arg, - bool evict, bool no_wait, + bool evict, bool no_wait_reserve, + bool no_wait_gpu, struct ttm_mem_reg *new_mem) { struct ttm_bo_device *bdev = bo->bdev; diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 668dbe8b8dd..fe6cb77899f 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -74,9 +74,6 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) struct ttm_buffer_object *bo = (struct ttm_buffer_object *) vma->vm_private_data; struct ttm_bo_device *bdev = bo->bdev; - unsigned long bus_base; - unsigned long bus_offset; - unsigned long bus_size; unsigned long page_offset; unsigned long page_last; unsigned long pfn; @@ -84,7 +81,6 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) struct page *page; int ret; int i; - bool is_iomem; unsigned long address = (unsigned long)vmf->virtual_address; int retval = VM_FAULT_NOPAGE; @@ -101,8 +97,21 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) return VM_FAULT_NOPAGE; } - if (bdev->driver->fault_reserve_notify) - bdev->driver->fault_reserve_notify(bo); + if (bdev->driver->fault_reserve_notify) { + ret = bdev->driver->fault_reserve_notify(bo); + switch (ret) { + case 0: + break; + case -EBUSY: + set_need_resched(); + case -ERESTARTSYS: + retval = VM_FAULT_NOPAGE; + goto out_unlock; + default: + retval = VM_FAULT_SIGBUS; + goto out_unlock; + } + } /* * Wait for buffer data in transit, due to a pipelined @@ -122,15 +131,12 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) spin_unlock(&bo->lock); - ret = ttm_bo_pci_offset(bdev, &bo->mem, &bus_base, &bus_offset, - &bus_size); - if (unlikely(ret != 0)) { + ret = ttm_mem_io_reserve(bdev, &bo->mem); + if (ret) { retval = VM_FAULT_SIGBUS; goto out_unlock; } - is_iomem = (bus_size != 0); - page_offset = ((address - vma->vm_start) >> PAGE_SHIFT) + bo->vm_node->start - vma->vm_pgoff; page_last = ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) + @@ -154,8 +160,7 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) * vma->vm_page_prot when the object changes caching policy, with * the correct locks held. */ - - if (is_iomem) { + if (bo->mem.bus.is_iomem) { vma->vm_page_prot = ttm_io_prot(bo->mem.placement, vma->vm_page_prot); } else { @@ -171,10 +176,8 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) */ for (i = 0; i < TTM_BO_VM_NUM_PREFAULT; ++i) { - - if (is_iomem) - pfn = ((bus_base + bus_offset) >> PAGE_SHIFT) + - page_offset; + if (bo->mem.bus.is_iomem) + pfn = ((bo->mem.bus.base + bo->mem.bus.offset) >> PAGE_SHIFT) + page_offset; else { page = ttm_tt_get_page(ttm, page_offset); if (unlikely(!page && i == 0)) { @@ -198,7 +201,6 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) retval = (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS; goto out_unlock; - } address += PAGE_SIZE; @@ -221,8 +223,7 @@ static void ttm_bo_vm_open(struct vm_area_struct *vma) static void ttm_bo_vm_close(struct vm_area_struct *vma) { - struct ttm_buffer_object *bo = - (struct ttm_buffer_object *)vma->vm_private_data; + struct ttm_buffer_object *bo = (struct ttm_buffer_object *)vma->vm_private_data; ttm_bo_unref(&bo); vma->vm_private_data = NULL; |