diff options
Diffstat (limited to 'drivers/gpu/drm/ttm/ttm_bo.c')
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_bo.c | 427 |
1 files changed, 73 insertions, 354 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 101a68dc615b..cfd0b9292397 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -44,21 +44,6 @@ #include "ttm_module.h" -static void ttm_bo_global_kobj_release(struct kobject *kobj); - -/* - * ttm_global_mutex - protecting the global BO state - */ -DEFINE_MUTEX(ttm_global_mutex); -unsigned ttm_bo_glob_use_count; -struct ttm_bo_global ttm_bo_glob; -EXPORT_SYMBOL(ttm_bo_glob); - -static struct attribute ttm_bo_count = { - .name = "bo_count", - .mode = S_IRUGO -}; - /* default destructor */ static void ttm_bo_default_destroy(struct ttm_buffer_object *bo) { @@ -84,41 +69,14 @@ static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo, } } -static ssize_t ttm_bo_global_show(struct kobject *kobj, - struct attribute *attr, - char *buffer) -{ - struct ttm_bo_global *glob = - container_of(kobj, struct ttm_bo_global, kobj); - - return snprintf(buffer, PAGE_SIZE, "%d\n", - atomic_read(&glob->bo_count)); -} - -static struct attribute *ttm_bo_global_attrs[] = { - &ttm_bo_count, - NULL -}; - -static const struct sysfs_ops ttm_bo_global_ops = { - .show = &ttm_bo_global_show -}; - -static struct kobj_type ttm_bo_glob_kobj_type = { - .release = &ttm_bo_global_kobj_release, - .sysfs_ops = &ttm_bo_global_ops, - .default_attrs = ttm_bo_global_attrs -}; - static void ttm_bo_del_from_lru(struct ttm_buffer_object *bo) { - struct ttm_bo_device *bdev = bo->bdev; + struct ttm_device *bdev = bo->bdev; - list_del_init(&bo->swap); list_del_init(&bo->lru); - if (bdev->driver->del_from_lru_notify) - bdev->driver->del_from_lru_notify(bo); + if (bdev->funcs->del_from_lru_notify) + bdev->funcs->del_from_lru_notify(bo); } static void ttm_bo_bulk_move_set_pos(struct ttm_lru_bulk_move_pos *pos, @@ -133,7 +91,7 @@ void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo, struct ttm_resource *mem, struct ttm_lru_bulk_move *bulk) { - struct ttm_bo_device *bdev = bo->bdev; + struct ttm_device *bdev = bo->bdev; struct ttm_resource_manager *man; if (!bo->deleted) @@ -146,17 +104,9 @@ void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo, man = ttm_manager_type(bdev, mem->mem_type); list_move_tail(&bo->lru, &man->lru[bo->priority]); - if (man->use_tt && bo->ttm && - !(bo->ttm->page_flags & (TTM_PAGE_FLAG_SG | - TTM_PAGE_FLAG_SWAPPED))) { - struct list_head *swap; - - swap = &ttm_bo_glob.swap_lru[bo->priority]; - list_move_tail(&bo->swap, swap); - } - if (bdev->driver->del_from_lru_notify) - bdev->driver->del_from_lru_notify(bo); + if (bdev->funcs->del_from_lru_notify) + bdev->funcs->del_from_lru_notify(bo); if (bulk && !bo->pin_count) { switch (bo->mem.mem_type) { @@ -168,9 +118,6 @@ void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo, ttm_bo_bulk_move_set_pos(&bulk->vram[bo->priority], bo); break; } - if (bo->ttm && !(bo->ttm->page_flags & - (TTM_PAGE_FLAG_SG | TTM_PAGE_FLAG_SWAPPED))) - ttm_bo_bulk_move_set_pos(&bulk->swap[bo->priority], bo); } } EXPORT_SYMBOL(ttm_bo_move_to_lru_tail); @@ -208,20 +155,6 @@ void ttm_bo_bulk_move_lru_tail(struct ttm_lru_bulk_move *bulk) list_bulk_move_tail(&man->lru[i], &pos->first->lru, &pos->last->lru); } - - for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) { - struct ttm_lru_bulk_move_pos *pos = &bulk->swap[i]; - struct list_head *lru; - - if (!pos->first) - continue; - - dma_resv_assert_held(pos->first->base.resv); - dma_resv_assert_held(pos->last->base.resv); - - lru = &ttm_bo_glob.swap_lru[i]; - list_bulk_move_tail(lru, &pos->first->swap, &pos->last->swap); - } } EXPORT_SYMBOL(ttm_bo_bulk_move_lru_tail); @@ -230,7 +163,7 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx, struct ttm_place *hop) { - struct ttm_bo_device *bdev = bo->bdev; + struct ttm_device *bdev = bo->bdev; struct ttm_resource_manager *old_man = ttm_manager_type(bdev, bo->mem.mem_type); struct ttm_resource_manager *new_man = ttm_manager_type(bdev, mem->mem_type); int ret; @@ -256,7 +189,7 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, } } - ret = bdev->driver->move(bo, evict, ctx, mem, hop); + ret = bdev->funcs->move(bo, evict, ctx, mem, hop); if (ret) { if (ret == -EMULTIHOP) return ret; @@ -284,8 +217,8 @@ out_err: static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo) { - if (bo->bdev->driver->delete_mem_notify) - bo->bdev->driver->delete_mem_notify(bo); + if (bo->bdev->funcs->delete_mem_notify) + bo->bdev->funcs->delete_mem_notify(bo); ttm_bo_tt_destroy(bo); ttm_resource_free(bo, &bo->mem); @@ -310,9 +243,9 @@ static int ttm_bo_individualize_resv(struct ttm_buffer_object *bo) * reference it any more. The only tricky case is the trylock on * the resv object while holding the lru_lock. */ - spin_lock(&ttm_bo_glob.lru_lock); + spin_lock(&bo->bdev->lru_lock); bo->base.resv = &bo->base._resv; - spin_unlock(&ttm_bo_glob.lru_lock); + spin_unlock(&bo->bdev->lru_lock); } return r; @@ -371,7 +304,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, if (unlock_resv) dma_resv_unlock(bo->base.resv); - spin_unlock(&ttm_bo_glob.lru_lock); + spin_unlock(&bo->bdev->lru_lock); lret = dma_resv_wait_timeout_rcu(resv, true, interruptible, 30 * HZ); @@ -381,7 +314,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, else if (lret == 0) return -EBUSY; - spin_lock(&ttm_bo_glob.lru_lock); + spin_lock(&bo->bdev->lru_lock); if (unlock_resv && !dma_resv_trylock(bo->base.resv)) { /* * We raced, and lost, someone else holds the reservation now, @@ -391,7 +324,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, * delayed destruction would succeed, so just return success * here. */ - spin_unlock(&ttm_bo_glob.lru_lock); + spin_unlock(&bo->bdev->lru_lock); return 0; } ret = 0; @@ -400,13 +333,13 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, if (ret || unlikely(list_empty(&bo->ddestroy))) { if (unlock_resv) dma_resv_unlock(bo->base.resv); - spin_unlock(&ttm_bo_glob.lru_lock); + spin_unlock(&bo->bdev->lru_lock); return ret; } ttm_bo_del_from_lru(bo); list_del_init(&bo->ddestroy); - spin_unlock(&ttm_bo_glob.lru_lock); + spin_unlock(&bo->bdev->lru_lock); ttm_bo_cleanup_memtype_use(bo); if (unlock_resv) @@ -421,15 +354,14 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, * Traverse the delayed list, and call ttm_bo_cleanup_refs on all * encountered buffers. */ -static bool ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all) +bool ttm_bo_delayed_delete(struct ttm_device *bdev, bool remove_all) { - struct ttm_bo_global *glob = &ttm_bo_glob; struct list_head removed; bool empty; INIT_LIST_HEAD(&removed); - spin_lock(&glob->lru_lock); + spin_lock(&bdev->lru_lock); while (!list_empty(&bdev->ddestroy)) { struct ttm_buffer_object *bo; @@ -440,44 +372,33 @@ static bool ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all) continue; if (remove_all || bo->base.resv != &bo->base._resv) { - spin_unlock(&glob->lru_lock); + spin_unlock(&bdev->lru_lock); dma_resv_lock(bo->base.resv, NULL); - spin_lock(&glob->lru_lock); + spin_lock(&bdev->lru_lock); ttm_bo_cleanup_refs(bo, false, !remove_all, true); } else if (dma_resv_trylock(bo->base.resv)) { ttm_bo_cleanup_refs(bo, false, !remove_all, true); } else { - spin_unlock(&glob->lru_lock); + spin_unlock(&bdev->lru_lock); } ttm_bo_put(bo); - spin_lock(&glob->lru_lock); + spin_lock(&bdev->lru_lock); } list_splice_tail(&removed, &bdev->ddestroy); empty = list_empty(&bdev->ddestroy); - spin_unlock(&glob->lru_lock); + spin_unlock(&bdev->lru_lock); return empty; } -static void ttm_bo_delayed_workqueue(struct work_struct *work) -{ - struct ttm_bo_device *bdev = - container_of(work, struct ttm_bo_device, wq.work); - - if (!ttm_bo_delayed_delete(bdev, false)) - schedule_delayed_work(&bdev->wq, - ((HZ / 100) < 1) ? 1 : HZ / 100); -} - static void ttm_bo_release(struct kref *kref) { struct ttm_buffer_object *bo = container_of(kref, struct ttm_buffer_object, kref); - struct ttm_bo_device *bdev = bo->bdev; - size_t acc_size = bo->acc_size; + struct ttm_device *bdev = bo->bdev; int ret; if (!bo->deleted) { @@ -490,8 +411,8 @@ static void ttm_bo_release(struct kref *kref) 30 * HZ); } - if (bo->bdev->driver->release_notify) - bo->bdev->driver->release_notify(bo); + if (bo->bdev->funcs->release_notify) + bo->bdev->funcs->release_notify(bo); drm_vma_offset_remove(bdev->vma_manager, &bo->base.vma_node); ttm_mem_io_free(bdev, &bo->mem); @@ -503,7 +424,7 @@ static void ttm_bo_release(struct kref *kref) ttm_bo_flush_all_fences(bo); bo->deleted = true; - spin_lock(&ttm_bo_glob.lru_lock); + spin_lock(&bo->bdev->lru_lock); /* * Make pinned bos immediately available to @@ -520,27 +441,26 @@ static void ttm_bo_release(struct kref *kref) kref_init(&bo->kref); list_add_tail(&bo->ddestroy, &bdev->ddestroy); - spin_unlock(&ttm_bo_glob.lru_lock); + spin_unlock(&bo->bdev->lru_lock); schedule_delayed_work(&bdev->wq, ((HZ / 100) < 1) ? 1 : HZ / 100); return; } - spin_lock(&ttm_bo_glob.lru_lock); + spin_lock(&bo->bdev->lru_lock); ttm_bo_del_from_lru(bo); list_del(&bo->ddestroy); - spin_unlock(&ttm_bo_glob.lru_lock); + spin_unlock(&bo->bdev->lru_lock); ttm_bo_cleanup_memtype_use(bo); dma_resv_unlock(bo->base.resv); - atomic_dec(&ttm_bo_glob.bo_count); + atomic_dec(&ttm_glob.bo_count); dma_fence_put(bo->moving); if (!ttm_bo_uses_embedded_gem_object(bo)) dma_resv_fini(&bo->base._resv); bo->destroy(bo); - ttm_mem_global_free(&ttm_mem_glob, acc_size); } void ttm_bo_put(struct ttm_buffer_object *bo) @@ -549,13 +469,13 @@ void ttm_bo_put(struct ttm_buffer_object *bo) } EXPORT_SYMBOL(ttm_bo_put); -int ttm_bo_lock_delayed_workqueue(struct ttm_bo_device *bdev) +int ttm_bo_lock_delayed_workqueue(struct ttm_device *bdev) { return cancel_delayed_work_sync(&bdev->wq); } EXPORT_SYMBOL(ttm_bo_lock_delayed_workqueue); -void ttm_bo_unlock_delayed_workqueue(struct ttm_bo_device *bdev, int resched) +void ttm_bo_unlock_delayed_workqueue(struct ttm_device *bdev, int resched) { if (resched) schedule_delayed_work(&bdev->wq, @@ -566,7 +486,7 @@ EXPORT_SYMBOL(ttm_bo_unlock_delayed_workqueue); static int ttm_bo_evict(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx) { - struct ttm_bo_device *bdev = bo->bdev; + struct ttm_device *bdev = bo->bdev; struct ttm_resource evict_mem; struct ttm_placement placement; struct ttm_place hop; @@ -578,7 +498,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, placement.num_placement = 0; placement.num_busy_placement = 0; - bdev->driver->evict_flags(bo, &placement); + bdev->funcs->evict_flags(bo, &placement); if (!placement.num_placement && !placement.num_busy_placement) { ttm_bo_wait(bo, false, false); @@ -694,7 +614,7 @@ static int ttm_mem_evict_wait_busy(struct ttm_buffer_object *busy_bo, return r == -EDEADLK ? -EBUSY : r; } -int ttm_mem_evict_first(struct ttm_bo_device *bdev, +int ttm_mem_evict_first(struct ttm_device *bdev, struct ttm_resource_manager *man, const struct ttm_place *place, struct ttm_operation_ctx *ctx, @@ -705,7 +625,7 @@ int ttm_mem_evict_first(struct ttm_bo_device *bdev, unsigned i; int ret; - spin_lock(&ttm_bo_glob.lru_lock); + spin_lock(&bdev->lru_lock); for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) { list_for_each_entry(bo, &man->lru[i], lru) { bool busy; @@ -718,7 +638,7 @@ int ttm_mem_evict_first(struct ttm_bo_device *bdev, continue; } - if (place && !bdev->driver->eviction_valuable(bo, + if (place && !bdev->funcs->eviction_valuable(bo, place)) { if (locked) dma_resv_unlock(bo->base.resv); @@ -742,7 +662,7 @@ int ttm_mem_evict_first(struct ttm_bo_device *bdev, if (!bo) { if (busy_bo && !ttm_bo_get_unless_zero(busy_bo)) busy_bo = NULL; - spin_unlock(&ttm_bo_glob.lru_lock); + spin_unlock(&bdev->lru_lock); ret = ttm_mem_evict_wait_busy(busy_bo, ctx, ticket); if (busy_bo) ttm_bo_put(busy_bo); @@ -756,7 +676,7 @@ int ttm_mem_evict_first(struct ttm_bo_device *bdev, return ret; } - spin_unlock(&ttm_bo_glob.lru_lock); + spin_unlock(&bdev->lru_lock); ret = ttm_bo_evict(bo, ctx); if (locked) @@ -785,8 +705,9 @@ static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo, return 0; if (no_wait_gpu) { + ret = dma_fence_is_signaled(fence) ? 0 : -EBUSY; dma_fence_put(fence); - return -EBUSY; + return ret; } dma_resv_add_shared_fence(bo->base.resv, fence); @@ -811,7 +732,7 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, struct ttm_resource *mem, struct ttm_operation_ctx *ctx) { - struct ttm_bo_device *bdev = bo->bdev; + struct ttm_device *bdev = bo->bdev; struct ttm_resource_manager *man = ttm_manager_type(bdev, mem->mem_type); struct ww_acquire_ctx *ticket; int ret; @@ -846,7 +767,7 @@ static int ttm_bo_mem_placement(struct ttm_buffer_object *bo, const struct ttm_place *place, struct ttm_resource *mem) { - struct ttm_bo_device *bdev = bo->bdev; + struct ttm_device *bdev = bo->bdev; struct ttm_resource_manager *man; man = ttm_manager_type(bdev, place->mem_type); @@ -856,10 +777,9 @@ static int ttm_bo_mem_placement(struct ttm_buffer_object *bo, mem->mem_type = place->mem_type; mem->placement = place->flags; - spin_lock(&ttm_bo_glob.lru_lock); + spin_lock(&bo->bdev->lru_lock); ttm_bo_move_to_lru_tail(bo, mem, NULL); - spin_unlock(&ttm_bo_glob.lru_lock); - + spin_unlock(&bo->bdev->lru_lock); return 0; } @@ -876,7 +796,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, struct ttm_resource *mem, struct ttm_operation_ctx *ctx) { - struct ttm_bo_device *bdev = bo->bdev; + struct ttm_device *bdev = bo->bdev; bool type_found = false; int i, ret; @@ -1097,38 +1017,25 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, } EXPORT_SYMBOL(ttm_bo_validate); -int ttm_bo_init_reserved(struct ttm_bo_device *bdev, +int ttm_bo_init_reserved(struct ttm_device *bdev, struct ttm_buffer_object *bo, size_t size, enum ttm_bo_type type, struct ttm_placement *placement, uint32_t page_alignment, struct ttm_operation_ctx *ctx, - size_t acc_size, struct sg_table *sg, struct dma_resv *resv, void (*destroy) (struct ttm_buffer_object *)) { - struct ttm_mem_global *mem_glob = &ttm_mem_glob; bool locked; int ret = 0; - ret = ttm_mem_global_alloc(mem_glob, acc_size, ctx); - if (ret) { - pr_err("Out of kernel memory\n"); - if (destroy) - (*destroy)(bo); - else - kfree(bo); - return -ENOMEM; - } - bo->destroy = destroy ? destroy : ttm_bo_default_destroy; kref_init(&bo->kref); INIT_LIST_HEAD(&bo->lru); INIT_LIST_HEAD(&bo->ddestroy); - INIT_LIST_HEAD(&bo->swap); bo->bdev = bdev; bo->type = type; bo->mem.mem_type = TTM_PL_SYSTEM; @@ -1139,7 +1046,6 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, bo->mem.bus.addr = NULL; bo->moving = NULL; bo->mem.placement = 0; - bo->acc_size = acc_size; bo->pin_count = 0; bo->sg = sg; if (resv) { @@ -1157,7 +1063,7 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, dma_resv_init(&bo->base._resv); drm_vma_node_reset(&bo->base.vma_node); } - atomic_inc(&ttm_bo_glob.bo_count); + atomic_inc(&ttm_glob.bo_count); /* * For ttm_bo_type_device buffers, allocate @@ -1193,14 +1099,13 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, } EXPORT_SYMBOL(ttm_bo_init_reserved); -int ttm_bo_init(struct ttm_bo_device *bdev, +int ttm_bo_init(struct ttm_device *bdev, struct ttm_buffer_object *bo, size_t size, enum ttm_bo_type type, struct ttm_placement *placement, uint32_t page_alignment, bool interruptible, - size_t acc_size, struct sg_table *sg, struct dma_resv *resv, void (*destroy) (struct ttm_buffer_object *)) @@ -1209,8 +1114,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev, int ret; ret = ttm_bo_init_reserved(bdev, bo, size, type, placement, - page_alignment, &ctx, acc_size, - sg, resv, destroy); + page_alignment, &ctx, sg, resv, destroy); if (ret) return ret; @@ -1221,171 +1125,13 @@ int ttm_bo_init(struct ttm_bo_device *bdev, } EXPORT_SYMBOL(ttm_bo_init); -size_t ttm_bo_dma_acc_size(struct ttm_bo_device *bdev, - unsigned long bo_size, - unsigned struct_size) -{ - unsigned npages = (PAGE_ALIGN(bo_size)) >> PAGE_SHIFT; - size_t size = 0; - - size += ttm_round_pot(struct_size); - size += ttm_round_pot(npages * (2*sizeof(void *) + sizeof(dma_addr_t))); - size += ttm_round_pot(sizeof(struct ttm_tt)); - return size; -} -EXPORT_SYMBOL(ttm_bo_dma_acc_size); - -static void ttm_bo_global_kobj_release(struct kobject *kobj) -{ - struct ttm_bo_global *glob = - container_of(kobj, struct ttm_bo_global, kobj); - - __free_page(glob->dummy_read_page); -} - -static void ttm_bo_global_release(void) -{ - struct ttm_bo_global *glob = &ttm_bo_glob; - - mutex_lock(&ttm_global_mutex); - if (--ttm_bo_glob_use_count > 0) - goto out; - - kobject_del(&glob->kobj); - kobject_put(&glob->kobj); - ttm_mem_global_release(&ttm_mem_glob); - memset(glob, 0, sizeof(*glob)); -out: - mutex_unlock(&ttm_global_mutex); -} - -static int ttm_bo_global_init(void) -{ - struct ttm_bo_global *glob = &ttm_bo_glob; - int ret = 0; - unsigned i; - - mutex_lock(&ttm_global_mutex); - if (++ttm_bo_glob_use_count > 1) - goto out; - - ret = ttm_mem_global_init(&ttm_mem_glob); - if (ret) - goto out; - - spin_lock_init(&glob->lru_lock); - glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32); - - if (unlikely(glob->dummy_read_page == NULL)) { - ret = -ENOMEM; - goto out; - } - - for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) - INIT_LIST_HEAD(&glob->swap_lru[i]); - INIT_LIST_HEAD(&glob->device_list); - atomic_set(&glob->bo_count, 0); - - ret = kobject_init_and_add( - &glob->kobj, &ttm_bo_glob_kobj_type, ttm_get_kobj(), "buffer_objects"); - if (unlikely(ret != 0)) - kobject_put(&glob->kobj); -out: - mutex_unlock(&ttm_global_mutex); - return ret; -} - -int ttm_bo_device_release(struct ttm_bo_device *bdev) -{ - struct ttm_bo_global *glob = &ttm_bo_glob; - int ret = 0; - unsigned i; - struct ttm_resource_manager *man; - - man = ttm_manager_type(bdev, TTM_PL_SYSTEM); - ttm_resource_manager_set_used(man, false); - ttm_set_driver_manager(bdev, TTM_PL_SYSTEM, NULL); - - mutex_lock(&ttm_global_mutex); - list_del(&bdev->device_list); - mutex_unlock(&ttm_global_mutex); - - cancel_delayed_work_sync(&bdev->wq); - - if (ttm_bo_delayed_delete(bdev, true)) - pr_debug("Delayed destroy list was clean\n"); - - spin_lock(&glob->lru_lock); - for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) - if (list_empty(&man->lru[0])) - pr_debug("Swap list %d was clean\n", i); - spin_unlock(&glob->lru_lock); - - ttm_pool_fini(&bdev->pool); - - if (!ret) - ttm_bo_global_release(); - - return ret; -} -EXPORT_SYMBOL(ttm_bo_device_release); - -static void ttm_bo_init_sysman(struct ttm_bo_device *bdev) -{ - struct ttm_resource_manager *man = &bdev->sysman; - - /* - * Initialize the system memory buffer type. - * Other types need to be driver / IOCTL initialized. - */ - man->use_tt = true; - - ttm_resource_manager_init(man, 0); - ttm_set_driver_manager(bdev, TTM_PL_SYSTEM, man); - ttm_resource_manager_set_used(man, true); -} - -int ttm_bo_device_init(struct ttm_bo_device *bdev, - struct ttm_bo_driver *driver, - struct device *dev, - struct address_space *mapping, - struct drm_vma_offset_manager *vma_manager, - bool use_dma_alloc, bool use_dma32) -{ - struct ttm_bo_global *glob = &ttm_bo_glob; - int ret; - - if (WARN_ON(vma_manager == NULL)) - return -EINVAL; - - ret = ttm_bo_global_init(); - if (ret) - return ret; - - bdev->driver = driver; - - ttm_bo_init_sysman(bdev); - ttm_pool_init(&bdev->pool, dev, use_dma_alloc, use_dma32); - - bdev->vma_manager = vma_manager; - INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue); - INIT_LIST_HEAD(&bdev->ddestroy); - bdev->dev_mapping = mapping; - mutex_lock(&ttm_global_mutex); - list_add_tail(&bdev->device_list, &glob->device_list); - mutex_unlock(&ttm_global_mutex); - - return 0; -} -EXPORT_SYMBOL(ttm_bo_device_init); - /* * buffer object vm functions. */ void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo) { - struct ttm_bo_device *bdev = bo->bdev; + struct ttm_device *bdev = bo->bdev; drm_vma_node_unmap(&bo->base.vma_node, bdev->dev_mapping); ttm_mem_io_free(bdev, &bo->mem); @@ -1417,56 +1163,34 @@ int ttm_bo_wait(struct ttm_buffer_object *bo, } EXPORT_SYMBOL(ttm_bo_wait); -/* - * A buffer object shrink method that tries to swap out the first - * buffer object on the bo_global::swap_lru list. - */ -int ttm_bo_swapout(struct ttm_operation_ctx *ctx) +int ttm_bo_swapout(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx, + gfp_t gfp_flags) { - struct ttm_bo_global *glob = &ttm_bo_glob; - struct ttm_buffer_object *bo; - int ret = -EBUSY; bool locked; - unsigned i; - - spin_lock(&glob->lru_lock); - for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) { - list_for_each_entry(bo, &glob->swap_lru[i], swap) { - if (!ttm_bo_evict_swapout_allowable(bo, ctx, &locked, - NULL)) - continue; - - if (!ttm_bo_get_unless_zero(bo)) { - if (locked) - dma_resv_unlock(bo->base.resv); - continue; - } + int ret; - ret = 0; - break; - } - if (!ret) - break; - } + if (!ttm_bo_evict_swapout_allowable(bo, ctx, &locked, NULL)) + return -EBUSY; - if (ret) { - spin_unlock(&glob->lru_lock); - return ret; + if (!ttm_bo_get_unless_zero(bo)) { + if (locked) + dma_resv_unlock(bo->base.resv); + return -EBUSY; } if (bo->deleted) { - ret = ttm_bo_cleanup_refs(bo, false, false, locked); + ttm_bo_cleanup_refs(bo, false, false, locked); ttm_bo_put(bo); - return ret; + return 0; } ttm_bo_del_from_lru(bo); - spin_unlock(&glob->lru_lock); + /* TODO: Cleanup the locking */ + spin_unlock(&bo->bdev->lru_lock); - /** + /* * Move to system cached */ - if (bo->mem.mem_type != TTM_PL_SYSTEM) { struct ttm_operation_ctx ctx = { false, false }; struct ttm_resource evict_mem; @@ -1486,29 +1210,26 @@ int ttm_bo_swapout(struct ttm_operation_ctx *ctx) } } - /** + /* * Make sure BO is idle. */ - ret = ttm_bo_wait(bo, false, false); if (unlikely(ret != 0)) goto out; ttm_bo_unmap_virtual(bo); - /** + /* * Swap out. Buffer will be swapped in again as soon as * anyone tries to access a ttm page. */ + if (bo->bdev->funcs->swap_notify) + bo->bdev->funcs->swap_notify(bo); - if (bo->bdev->driver->swap_notify) - bo->bdev->driver->swap_notify(bo); - - ret = ttm_tt_swapout(bo->bdev, bo->ttm); + ret = ttm_tt_swapout(bo->bdev, bo->ttm, gfp_flags); out: - /** - * + /* * Unreserve without putting on LRU to avoid swapping out an * already swapped buffer. */ @@ -1517,7 +1238,6 @@ out: ttm_bo_put(bo); return ret; } -EXPORT_SYMBOL(ttm_bo_swapout); void ttm_bo_tt_destroy(struct ttm_buffer_object *bo) { @@ -1527,4 +1247,3 @@ void ttm_bo_tt_destroy(struct ttm_buffer_object *bo) ttm_tt_destroy(bo->bdev, bo->ttm); bo->ttm = NULL; } - |