From 1fd4a5a36f9f10aaad5d9b1b329c2c057d80a0e5 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 17 Nov 2022 10:28:45 +0100 Subject: drm/connector: Rename legacy TV property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current tv_mode has driver-specific values that don't allow to easily share code using it, either at the userspace or kernel level. Since we're going to introduce a new, generic, property that fit the same purpose, let's rename this one to legacy_tv_mode to make it obvious we should move away from it. Acked-by: Thomas Zimmermann Reviewed-by: Lyude Paul # nouveau Reviewed-by: Noralf Trønnes Tested-by: Mateusz Kwiatkowski Acked-in-principle-or-something-like-that-by: Daniel Vetter Link: https://lore.kernel.org/r/20220728-rpi-analog-tv-properties-v10-2-256dad125326@cerno.tech Signed-off-by: Maxime Ripard --- drivers/gpu/drm/i915/display/intel_tv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c index 4d2101ca1692..5a0483d173d8 100644 --- a/drivers/gpu/drm/i915/display/intel_tv.c +++ b/drivers/gpu/drm/i915/display/intel_tv.c @@ -1908,7 +1908,7 @@ static void intel_tv_add_properties(struct drm_connector *connector) drm_mode_create_tv_properties(&i915->drm, i, tv_format_names); drm_object_attach_property(&connector->base, - i915->drm.mode_config.tv_mode_property, + i915->drm.mode_config.legacy_tv_mode_property, conn_state->tv.mode); drm_object_attach_property(&connector->base, i915->drm.mode_config.tv_left_margin_property, -- cgit From 80ed86d4b6d7cf91f4fd588bd7be2fa382724d2d Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 17 Nov 2022 10:28:47 +0100 Subject: drm/connector: Rename drm_mode_create_tv_properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drm_mode_create_tv_properties(), among other things, will create the "mode" property that stores the analog TV mode that connector is supposed to output. However, that property is getting deprecated, so let's rename that function to mention it's deprecated. We'll introduce a new variant of that function creating the property superseeding it in a later patch. Reviewed-by: Lyude Paul # nouveau Reviewed-by: Noralf Trønnes Tested-by: Mateusz Kwiatkowski Acked-in-principle-or-something-like-that-by: Daniel Vetter Link: https://lore.kernel.org/r/20220728-rpi-analog-tv-properties-v10-4-256dad125326@cerno.tech Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_connector.c | 12 ++++++------ drivers/gpu/drm/gud/gud_connector.c | 4 ++-- drivers/gpu/drm/i2c/ch7006_drv.c | 2 +- drivers/gpu/drm/i915/display/intel_tv.c | 2 +- drivers/gpu/drm/nouveau/dispnv04/tvnv17.c | 2 +- drivers/gpu/drm/vc4/vc4_vec.c | 5 +++-- include/drm/drm_connector.h | 6 +++--- 7 files changed, 17 insertions(+), 16 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 78fcffae100b..06e737ed15f5 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1604,7 +1604,7 @@ EXPORT_SYMBOL(drm_connector_attach_tv_margin_properties); * Called by a driver's HDMI connector initialization routine, this function * creates the TV margin properties for a given device. No need to call this * function for an SDTV connector, it's already called from - * drm_mode_create_tv_properties(). + * drm_mode_create_tv_properties_legacy(). * * Returns: * 0 on success or a negative error code on failure. @@ -1639,7 +1639,7 @@ int drm_mode_create_tv_margin_properties(struct drm_device *dev) EXPORT_SYMBOL(drm_mode_create_tv_margin_properties); /** - * drm_mode_create_tv_properties - create TV specific connector properties + * drm_mode_create_tv_properties_legacy - create TV specific connector properties * @dev: DRM device * @num_modes: number of different TV formats (modes) supported * @modes: array of pointers to strings containing name of each format @@ -1652,9 +1652,9 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties); * Returns: * 0 on success or a negative error code on failure. */ -int drm_mode_create_tv_properties(struct drm_device *dev, - unsigned int num_modes, - const char * const modes[]) +int drm_mode_create_tv_properties_legacy(struct drm_device *dev, + unsigned int num_modes, + const char * const modes[]) { struct drm_property *tv_selector; struct drm_property *tv_subconnector; @@ -1737,7 +1737,7 @@ int drm_mode_create_tv_properties(struct drm_device *dev, nomem: return -ENOMEM; } -EXPORT_SYMBOL(drm_mode_create_tv_properties); +EXPORT_SYMBOL(drm_mode_create_tv_properties_legacy); /** * drm_mode_create_scaling_mode_property - create scaling mode property diff --git a/drivers/gpu/drm/gud/gud_connector.c b/drivers/gpu/drm/gud/gud_connector.c index 86e992b2108b..034e78360d4f 100644 --- a/drivers/gpu/drm/gud/gud_connector.c +++ b/drivers/gpu/drm/gud/gud_connector.c @@ -400,7 +400,7 @@ static int gud_connector_add_tv_mode(struct gud_device *gdrm, struct drm_connect for (i = 0; i < num_modes; i++) modes[i] = &buf[i * GUD_CONNECTOR_TV_MODE_NAME_LEN]; - ret = drm_mode_create_tv_properties(connector->dev, num_modes, modes); + ret = drm_mode_create_tv_properties_legacy(connector->dev, num_modes, modes); free: kfree(buf); if (ret < 0) @@ -539,7 +539,7 @@ static int gud_connector_add_properties(struct gud_device *gdrm, struct gud_conn fallthrough; case GUD_PROPERTY_TV_HUE: /* This is a no-op if already added. */ - ret = drm_mode_create_tv_properties(drm, 0, NULL); + ret = drm_mode_create_tv_properties_legacy(drm, 0, NULL); if (ret) goto out; break; diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c index 9aff24e8e3b2..b9788218b2ec 100644 --- a/drivers/gpu/drm/i2c/ch7006_drv.c +++ b/drivers/gpu/drm/i2c/ch7006_drv.c @@ -250,7 +250,7 @@ static int ch7006_encoder_create_resources(struct drm_encoder *encoder, struct drm_device *dev = encoder->dev; struct drm_mode_config *conf = &dev->mode_config; - drm_mode_create_tv_properties(dev, NUM_TV_NORMS, ch7006_tv_norm_names); + drm_mode_create_tv_properties_legacy(dev, NUM_TV_NORMS, ch7006_tv_norm_names); priv->scale_property = drm_property_create_range(dev, 0, "scale", 0, 2); if (!priv->scale_property) diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c index 5a0483d173d8..b986bf075889 100644 --- a/drivers/gpu/drm/i915/display/intel_tv.c +++ b/drivers/gpu/drm/i915/display/intel_tv.c @@ -1905,7 +1905,7 @@ static void intel_tv_add_properties(struct drm_connector *connector) tv_format_names[i] = tv_modes[i].name; } - drm_mode_create_tv_properties(&i915->drm, i, tv_format_names); + drm_mode_create_tv_properties_legacy(&i915->drm, i, tv_format_names); drm_object_attach_property(&connector->base, i915->drm.mode_config.legacy_tv_mode_property, diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c index 1a15534adc60..e5480dab55e3 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c @@ -653,7 +653,7 @@ static int nv17_tv_create_resources(struct drm_encoder *encoder, tv_enc->tv_norm = i; } - drm_mode_create_tv_properties(dev, num_tv_norms, nv17_tv_norm_names); + drm_mode_create_tv_properties_legacy(dev, num_tv_norms, nv17_tv_norm_names); drm_object_attach_property(&connector->base, conf->tv_select_subconnector_property, diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c index e6043cf5d40e..adc9bf99e3fd 100644 --- a/drivers/gpu/drm/vc4/vc4_vec.c +++ b/drivers/gpu/drm/vc4/vc4_vec.c @@ -514,8 +514,9 @@ static int vc4_vec_bind(struct device *dev, struct device *master, void *data) struct vc4_vec *vec; int ret; - ret = drm_mode_create_tv_properties(drm, ARRAY_SIZE(tv_mode_names), - tv_mode_names); + ret = drm_mode_create_tv_properties_legacy(drm, + ARRAY_SIZE(tv_mode_names), + tv_mode_names); if (ret) return ret; diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 16e47201aaeb..572bd6487247 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1820,9 +1820,9 @@ int drm_mode_create_dvi_i_properties(struct drm_device *dev); void drm_connector_attach_dp_subconnector_property(struct drm_connector *connector); int drm_mode_create_tv_margin_properties(struct drm_device *dev); -int drm_mode_create_tv_properties(struct drm_device *dev, - unsigned int num_modes, - const char * const modes[]); +int drm_mode_create_tv_properties_legacy(struct drm_device *dev, + unsigned int num_modes, + const char * const modes[]); void drm_connector_attach_tv_margin_properties(struct drm_connector *conn); int drm_mode_create_scaling_mode_property(struct drm_device *dev); int drm_connector_attach_content_type_property(struct drm_connector *dev); -- cgit From 9bff18d13473a9fdf81d5158248472a9d8ecf2bd Mon Sep 17 00:00:00 2001 From: Christian König Date: Wed, 23 Nov 2022 10:14:56 +0100 Subject: drm/ttm: use per BO cleanup workers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of a single worker going over the list of delete BOs in regular intervals use a per BO worker which blocks for the resv object and locking of the BO. This not only simplifies the handling massively, but also results in much better response time when cleaning up buffers. Signed-off-by: Christian König Reviewed-by: Felix Kuehling Reviewed-by: Arunpravin Paneer Selvam Link: https://patchwork.freedesktop.org/patch/msgid/20221125102137.1801-3-christian.koenig@amd.com --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/intel_region_ttm.c | 2 +- drivers/gpu/drm/ttm/ttm_bo.c | 112 +++++++++++------------------ drivers/gpu/drm/ttm/ttm_bo_util.c | 1 - drivers/gpu/drm/ttm/ttm_device.c | 24 +++---- include/drm/ttm/ttm_bo_api.h | 18 ++--- include/drm/ttm/ttm_device.h | 7 +- 8 files changed, 57 insertions(+), 111 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 2b1db37e25c1..74ccbd566777 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3984,7 +3984,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) amdgpu_fence_driver_hw_fini(adev); if (adev->mman.initialized) - flush_delayed_work(&adev->mman.bdev.wq); + drain_workqueue(adev->mman.bdev.wq); if (adev->pm_sysfs_en) amdgpu_pm_sysfs_fini(adev); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8468ca9885fd..c38306f156d6 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1099,7 +1099,7 @@ void i915_gem_drain_freed_objects(struct drm_i915_private *i915) { while (atomic_read(&i915->mm.free_count)) { flush_work(&i915->mm.free_work); - flush_delayed_work(&i915->bdev.wq); + drain_workqueue(i915->bdev.wq); rcu_barrier(); } } diff --git a/drivers/gpu/drm/i915/intel_region_ttm.c b/drivers/gpu/drm/i915/intel_region_ttm.c index cf89d0c2a2d9..657bbc16a48a 100644 --- a/drivers/gpu/drm/i915/intel_region_ttm.c +++ b/drivers/gpu/drm/i915/intel_region_ttm.c @@ -132,7 +132,7 @@ int intel_region_ttm_fini(struct intel_memory_region *mem) break; msleep(20); - flush_delayed_work(&mem->i915->bdev.wq); + drain_workqueue(mem->i915->bdev.wq); } /* If we leaked objects, Don't free the region causing use after free */ diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index b77262a623e0..4749b65bedc4 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -280,14 +280,13 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, ret = 0; } - if (ret || unlikely(list_empty(&bo->ddestroy))) { + if (ret) { if (unlock_resv) dma_resv_unlock(bo->base.resv); spin_unlock(&bo->bdev->lru_lock); return ret; } - list_del_init(&bo->ddestroy); spin_unlock(&bo->bdev->lru_lock); ttm_bo_cleanup_memtype_use(bo); @@ -300,47 +299,21 @@ 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. + * Block for the dma_resv object to become idle, lock the buffer and clean up + * the resource and tt object. */ -bool ttm_bo_delayed_delete(struct ttm_device *bdev, bool remove_all) +static void ttm_bo_delayed_delete(struct work_struct *work) { - struct list_head removed; - bool empty; - - INIT_LIST_HEAD(&removed); - - spin_lock(&bdev->lru_lock); - while (!list_empty(&bdev->ddestroy)) { - struct ttm_buffer_object *bo; - - bo = list_first_entry(&bdev->ddestroy, struct ttm_buffer_object, - ddestroy); - list_move_tail(&bo->ddestroy, &removed); - if (!ttm_bo_get_unless_zero(bo)) - continue; - - if (remove_all || bo->base.resv != &bo->base._resv) { - spin_unlock(&bdev->lru_lock); - dma_resv_lock(bo->base.resv, NULL); - - 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(&bdev->lru_lock); - } + struct ttm_buffer_object *bo; - ttm_bo_put(bo); - spin_lock(&bdev->lru_lock); - } - list_splice_tail(&removed, &bdev->ddestroy); - empty = list_empty(&bdev->ddestroy); - spin_unlock(&bdev->lru_lock); + bo = container_of(work, typeof(*bo), delayed_delete); - return empty; + dma_resv_wait_timeout(bo->base.resv, DMA_RESV_USAGE_BOOKKEEP, false, + MAX_SCHEDULE_TIMEOUT); + dma_resv_lock(bo->base.resv, NULL); + ttm_bo_cleanup_memtype_use(bo); + dma_resv_unlock(bo->base.resv); + ttm_bo_put(bo); } static void ttm_bo_release(struct kref *kref) @@ -369,44 +342,40 @@ static void ttm_bo_release(struct kref *kref) drm_vma_offset_remove(bdev->vma_manager, &bo->base.vma_node); ttm_mem_io_free(bdev, bo->resource); - } - - if (!dma_resv_test_signaled(bo->base.resv, DMA_RESV_USAGE_BOOKKEEP) || - !dma_resv_trylock(bo->base.resv)) { - /* The BO is not idle, resurrect it for delayed destroy */ - ttm_bo_flush_all_fences(bo); - bo->deleted = true; - spin_lock(&bo->bdev->lru_lock); + if (!dma_resv_test_signaled(bo->base.resv, + DMA_RESV_USAGE_BOOKKEEP) || + !dma_resv_trylock(bo->base.resv)) { + /* The BO is not idle, resurrect it for delayed destroy */ + ttm_bo_flush_all_fences(bo); + bo->deleted = true; - /* - * Make pinned bos immediately available to - * shrinkers, now that they are queued for - * destruction. - * - * FIXME: QXL is triggering this. Can be removed when the - * driver is fixed. - */ - if (bo->pin_count) { - bo->pin_count = 0; - ttm_resource_move_to_lru_tail(bo->resource); - } + spin_lock(&bo->bdev->lru_lock); - kref_init(&bo->kref); - list_add_tail(&bo->ddestroy, &bdev->ddestroy); - spin_unlock(&bo->bdev->lru_lock); + /* + * Make pinned bos immediately available to + * shrinkers, now that they are queued for + * destruction. + * + * FIXME: QXL is triggering this. Can be removed when the + * driver is fixed. + */ + if (bo->pin_count) { + bo->pin_count = 0; + ttm_resource_move_to_lru_tail(bo->resource); + } - schedule_delayed_work(&bdev->wq, - ((HZ / 100) < 1) ? 1 : HZ / 100); - return; - } + kref_init(&bo->kref); + spin_unlock(&bo->bdev->lru_lock); - spin_lock(&bo->bdev->lru_lock); - list_del(&bo->ddestroy); - spin_unlock(&bo->bdev->lru_lock); + INIT_WORK(&bo->delayed_delete, ttm_bo_delayed_delete); + queue_work(bdev->wq, &bo->delayed_delete); + return; + } - ttm_bo_cleanup_memtype_use(bo); - dma_resv_unlock(bo->base.resv); + ttm_bo_cleanup_memtype_use(bo); + dma_resv_unlock(bo->base.resv); + } atomic_dec(&ttm_glob.bo_count); bo->destroy(bo); @@ -946,7 +915,6 @@ int ttm_bo_init_reserved(struct ttm_device *bdev, struct ttm_buffer_object *bo, int ret; kref_init(&bo->kref); - INIT_LIST_HEAD(&bo->ddestroy); bo->bdev = bdev; bo->type = type; bo->page_alignment = alignment; diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index ba3aa0a0fc43..ae4b7922ee1a 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -230,7 +230,6 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, */ atomic_inc(&ttm_glob.bo_count); - INIT_LIST_HEAD(&fbo->base.ddestroy); drm_vma_node_reset(&fbo->base.base.vma_node); kref_init(&fbo->base.kref); diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c index e7147e304637..e9bedca4dfdc 100644 --- a/drivers/gpu/drm/ttm/ttm_device.c +++ b/drivers/gpu/drm/ttm/ttm_device.c @@ -175,16 +175,6 @@ int ttm_device_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx, } EXPORT_SYMBOL(ttm_device_swapout); -static void ttm_device_delayed_workqueue(struct work_struct *work) -{ - struct ttm_device *bdev = - container_of(work, struct ttm_device, wq.work); - - if (!ttm_bo_delayed_delete(bdev, false)) - schedule_delayed_work(&bdev->wq, - ((HZ / 100) < 1) ? 1 : HZ / 100); -} - /** * ttm_device_init * @@ -215,15 +205,19 @@ int ttm_device_init(struct ttm_device *bdev, struct ttm_device_funcs *funcs, if (ret) return ret; + bdev->wq = alloc_workqueue("ttm", WQ_MEM_RECLAIM | WQ_HIGHPRI, 16); + if (!bdev->wq) { + ttm_global_release(); + return -ENOMEM; + } + bdev->funcs = funcs; ttm_sys_man_init(bdev); ttm_pool_init(&bdev->pool, dev, use_dma_alloc, use_dma32); bdev->vma_manager = vma_manager; - INIT_DELAYED_WORK(&bdev->wq, ttm_device_delayed_workqueue); spin_lock_init(&bdev->lru_lock); - INIT_LIST_HEAD(&bdev->ddestroy); INIT_LIST_HEAD(&bdev->pinned); bdev->dev_mapping = mapping; mutex_lock(&ttm_global_mutex); @@ -247,10 +241,8 @@ void ttm_device_fini(struct ttm_device *bdev) 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"); + drain_workqueue(bdev->wq); + destroy_workqueue(bdev->wq); spin_lock(&bdev->lru_lock); for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 7758347c461c..69e62bbb01e3 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -92,7 +92,6 @@ struct ttm_tt; * @ttm: TTM structure holding system pages. * @evicted: Whether the object was evicted without user-space knowing. * @deleted: True if the object is only a zombie and already deleted. - * @ddestroy: List head for the delayed destroy list. * @swap: List head for swap LRU list. * @offset: The current GPU offset, which can have different meanings * depending on the memory type. For SYSTEM type memory, it should be 0. @@ -135,19 +134,14 @@ struct ttm_buffer_object { struct ttm_tt *ttm; bool deleted; struct ttm_lru_bulk_move *bulk_move; + unsigned priority; + unsigned pin_count; /** - * Members protected by the bdev::lru_lock. - */ - - struct list_head ddestroy; - - /** - * Members protected by a bo reservation. + * @delayed_delete: Work item used when we can't delete the BO + * immediately */ - - unsigned priority; - unsigned pin_count; + struct work_struct delayed_delete; /** * Special members that are protected by the reserve lock @@ -448,8 +442,6 @@ void ttm_bo_vm_close(struct vm_area_struct *vma); int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr, void *buf, int len, int write); -bool ttm_bo_delayed_delete(struct ttm_device *bdev, bool remove_all); - vm_fault_t ttm_bo_vm_dummy_page(struct vm_fault *vmf, pgprot_t prot); #endif diff --git a/include/drm/ttm/ttm_device.h b/include/drm/ttm/ttm_device.h index 95b3c04b1ab9..4f3e81eac6f3 100644 --- a/include/drm/ttm/ttm_device.h +++ b/include/drm/ttm/ttm_device.h @@ -251,11 +251,6 @@ struct ttm_device { */ spinlock_t lru_lock; - /** - * @ddestroy: Destroyed but not yet cleaned up buffer objects. - */ - struct list_head ddestroy; - /** * @pinned: Buffer objects which are pinned and so not on any LRU list. */ @@ -270,7 +265,7 @@ struct ttm_device { /** * @wq: Work queue structure for the delayed delete workqueue. */ - struct delayed_work wq; + struct workqueue_struct *wq; }; int ttm_global_swapout(struct ttm_operation_ctx *ctx, gfp_t gfp_flags); -- cgit From a3185f91d0579b61a0a0dce3df1c67d6e324ebc8 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 9 May 2022 21:13:35 +0200 Subject: drm/ttm: merge ttm_bo_api.h and ttm_bo_driver.h v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge and cleanup the two headers into a single description of the object API. Also move all the documentation to the implementation and drop unnecessary includes from the header. No functional change. v2: minimal checkpatch.pl cleanup Signed-off-by: Christian König Reviewed-by: Arunpravin Paneer Selvam Link: https://patchwork.freedesktop.org/patch/msgid/20221125102137.1801-4-christian.koenig@amd.com --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_cs.h | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 1 + drivers/gpu/drm/drm_gem_ttm_helper.c | 2 + drivers/gpu/drm/drm_gem_vram_helper.c | 1 + drivers/gpu/drm/i915/gem/i915_gem_object_types.h | 2 +- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c | 2 +- drivers/gpu/drm/i915/i915_deps.c | 2 +- drivers/gpu/drm/i915/i915_ttm_buddy_manager.c | 2 +- drivers/gpu/drm/i915/intel_region_ttm.c | 1 - drivers/gpu/drm/nouveau/nouveau_bo.c | 1 + drivers/gpu/drm/nouveau/nouveau_bo.h | 3 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 3 +- drivers/gpu/drm/nouveau/nouveau_mem.c | 3 +- drivers/gpu/drm/nouveau/nouveau_mem.h | 2 +- drivers/gpu/drm/nouveau/nouveau_prime.c | 1 + drivers/gpu/drm/nouveau/nouveau_sgdma.c | 1 + drivers/gpu/drm/qxl/qxl_drv.h | 3 +- drivers/gpu/drm/qxl/qxl_ttm.c | 4 +- drivers/gpu/drm/radeon/radeon.h | 3 +- drivers/gpu/drm/radeon/radeon_prime.c | 2 + drivers/gpu/drm/radeon/radeon_ttm.c | 4 +- drivers/gpu/drm/ttm/ttm_bo.c | 81 +++- drivers/gpu/drm/ttm/ttm_bo_util.c | 110 +++++- drivers/gpu/drm/ttm/ttm_bo_vm.c | 19 +- drivers/gpu/drm/ttm/ttm_device.c | 2 +- drivers/gpu/drm/ttm/ttm_execbuf_util.c | 6 +- drivers/gpu/drm/ttm/ttm_pool.c | 3 +- drivers/gpu/drm/ttm/ttm_range_manager.c | 2 +- drivers/gpu/drm/ttm/ttm_resource.c | 3 +- drivers/gpu/drm/ttm/ttm_tt.c | 3 +- drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_system_manager.c | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 1 - include/drm/drm_gem_ttm_helper.h | 3 +- include/drm/drm_gem_vram_helper.h | 4 +- include/drm/ttm/ttm_bo.h | 430 ++++++++++++++++++++++ include/drm/ttm/ttm_bo_api.h | 447 ----------------------- include/drm/ttm/ttm_bo_driver.h | 303 --------------- include/drm/ttm/ttm_execbuf_util.h | 4 +- 56 files changed, 676 insertions(+), 823 deletions(-) create mode 100644 include/drm/ttm/ttm_bo.h delete mode 100644 include/drm/ttm/ttm_bo_api.h delete mode 100644 include/drm/ttm/ttm_bo_driver.h (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 6b74df446694..2644cd991210 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -52,8 +52,7 @@ #include #include -#include -#include +#include #include #include diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index 3a763916a5a1..ab450f12c445 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "amdgpu_object.h" #include "amdgpu_gem.h" diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h index e4d78491bcc7..ededdc01ca28 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h @@ -28,6 +28,8 @@ struct hmm_range; +struct drm_file; + struct amdgpu_device; struct amdgpu_bo; struct amdgpu_bo_va; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 8516c814bc9b..8b7a09b392ac 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -32,6 +32,8 @@ #include #include +#include + #include "amdgpu_cs.h" #include "amdgpu.h" #include "amdgpu_trace.h" diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.h index 113f39510a72..fb3e3d56d427 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.h @@ -23,6 +23,8 @@ #ifndef __AMDGPU_CS_H__ #define __AMDGPU_CS_H__ +#include + #include "amdgpu_job.h" #include "amdgpu_bo_list.h" #include "amdgpu_ring.h" diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index 271e30e34d93..0c001bb8fc2b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -37,6 +37,7 @@ #include "amdgpu_dma_buf.h" #include "amdgpu_xgmi.h" #include +#include #include #include #include diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.h index 41a4c7056729..e86834bfea1d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.h @@ -30,7 +30,6 @@ #include #include #include -#include #include #include "amdgpu_sync.h" diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index a0780a4e3e61..f8f9d68d69ff 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "amdgpu.h" #include "amdgpu_display.h" diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index 4365ede42855..3169a942dbbb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -35,6 +35,7 @@ #include "amdgpu_xgmi.h" #include +#include /** * amdgpu_gmc_pdb0_alloc - allocate vram for pdb0 diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 7b5074e776f4..068c2d8495fd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -44,10 +44,10 @@ #include #include -#include -#include +#include #include #include +#include #include #include diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 003aa9e47085..fea25519227f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -33,6 +33,7 @@ #include #include +#include #include "amdgpu.h" #include "amdgpu_trace.h" #include "amdgpu_amdkfd.h" diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 6546e786bf00..44157c6c0804 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include "amdgpu_sync.h" diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index 814f99888ab1..37219198d518 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -23,6 +23,7 @@ #include #include +#include #include "amdgpu_sync.h" #include "amdgpu_object.h" #include "amdgpu_vm.h" diff --git a/drivers/gpu/drm/drm_gem_ttm_helper.c b/drivers/gpu/drm/drm_gem_ttm_helper.c index d5962a34c01d..3734aa2d1c5b 100644 --- a/drivers/gpu/drm/drm_gem_ttm_helper.c +++ b/drivers/gpu/drm/drm_gem_ttm_helper.c @@ -3,6 +3,8 @@ #include #include +#include +#include /** * DOC: overview diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index b6c7e3803bb3..f59adffd938a 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -19,6 +19,7 @@ #include #include +#include static const struct drm_gem_object_funcs drm_gem_vram_object_funcs; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h index d0d6772e6f36..a7b70701617a 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include "i915_active.h" diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 1e50fb0d6bfc..5247d88b3c13 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -5,8 +5,8 @@ #include -#include #include +#include #include #include "i915_drv.h" diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c index f59f812dc6d2..2ebaaf4d663c 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c @@ -3,7 +3,7 @@ * Copyright © 2021 Intel Corporation */ -#include +#include #include "i915_deps.h" #include "i915_drv.h" diff --git a/drivers/gpu/drm/i915/i915_deps.c b/drivers/gpu/drm/i915/i915_deps.c index 297b8e4e42ee..91c61864285a 100644 --- a/drivers/gpu/drm/i915/i915_deps.c +++ b/drivers/gpu/drm/i915/i915_deps.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include "i915_deps.h" diff --git a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c index 7e611476c7a4..a72698a2dbc8 100644 --- a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c +++ b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c @@ -5,8 +5,8 @@ #include -#include #include +#include #include diff --git a/drivers/gpu/drm/i915/intel_region_ttm.c b/drivers/gpu/drm/i915/intel_region_ttm.c index 657bbc16a48a..4dc0702081b8 100644 --- a/drivers/gpu/drm/i915/intel_region_ttm.c +++ b/drivers/gpu/drm/i915/intel_region_ttm.c @@ -2,7 +2,6 @@ /* * Copyright © 2021 Intel Corporation */ -#include #include #include diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index a11871e3119c..335fa91ca4ad 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -28,6 +28,7 @@ */ #include +#include #include "nouveau_drv.h" #include "nouveau_chan.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h index c2d3f9c48eba..774dd93ca76b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.h +++ b/drivers/gpu/drm/nouveau/nouveau_bo.h @@ -1,8 +1,9 @@ /* SPDX-License-Identifier: MIT */ #ifndef __NOUVEAU_BO_H__ #define __NOUVEAU_BO_H__ -#include #include +#include +#include struct nouveau_channel; struct nouveau_cli; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index d6dd07bfa64a..b5de312a523f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -51,8 +51,7 @@ #include #include -#include -#include +#include #include #include diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 1fde3a5d7c32..25f31d5169e5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -19,11 +19,12 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ +#include + #include "nouveau_mem.h" #include "nouveau_drv.h" #include "nouveau_bo.h" -#include #include #include diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.h b/drivers/gpu/drm/nouveau/nouveau_mem.h index 1ee6cdb9ad9b..76c86d8bb01e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.h +++ b/drivers/gpu/drm/nouveau/nouveau_mem.h @@ -1,6 +1,6 @@ #ifndef __NOUVEAU_MEM_H__ #define __NOUVEAU_MEM_H__ -#include +#include struct ttm_tt; #include diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c index 9608121e49b7..f42c2b1b0363 100644 --- a/drivers/gpu/drm/nouveau/nouveau_prime.c +++ b/drivers/gpu/drm/nouveau/nouveau_prime.c @@ -23,6 +23,7 @@ */ #include +#include #include "nouveau_drv.h" #include "nouveau_gem.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 85c03c83259b..b14895f75b3c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT #include #include +#include #include "nouveau_drv.h" #include "nouveau_mem.h" diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 76f060810f63..ea993d7162e8 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -42,8 +42,7 @@ #include #include #include -#include -#include +#include #include #include diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index ee95001e6b5e..a92a5b0d4c25 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -29,10 +29,10 @@ #include #include #include -#include -#include +#include #include #include +#include #include "qxl_drv.h" #include "qxl_object.h" diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 2e7161acd443..57e20780a458 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -73,8 +73,7 @@ #include #endif -#include -#include +#include #include #include diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/radeon/radeon_prime.c index 42a87948e28c..b3cfc99f4d7e 100644 --- a/drivers/gpu/drm/radeon/radeon_prime.c +++ b/drivers/gpu/drm/radeon/radeon_prime.c @@ -29,6 +29,8 @@ #include #include +#include + #include "radeon.h" #include "radeon_prime.h" diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 30402b5ce4c5..1e8e287e113c 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -42,10 +42,10 @@ #include #include #include -#include -#include +#include #include #include +#include #include "radeon_reg.h" #include "radeon.h" diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 4749b65bedc4..f9d9fd2d865d 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -31,8 +31,10 @@ #define pr_fmt(fmt) "[TTM] " fmt -#include +#include #include +#include + #include #include #include @@ -381,6 +383,13 @@ static void ttm_bo_release(struct kref *kref) bo->destroy(bo); } +/** + * ttm_bo_put + * + * @bo: The buffer object. + * + * Unreference a buffer object. + */ void ttm_bo_put(struct ttm_buffer_object *bo) { kref_put(&bo->kref, ttm_bo_release); @@ -467,6 +476,14 @@ out: return ret; } +/** + * ttm_bo_eviction_valuable + * + * @bo: The buffer object to evict + * @place: the placement we need to make room for + * + * Check if it is valuable to evict the BO to make room for the given placement. + */ bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, const struct ttm_place *place) { @@ -726,13 +743,23 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, return ttm_bo_add_move_fence(bo, man, *mem, ctx->no_wait_gpu); } -/* - * Creates space for memory region @mem according to its type. +/** + * ttm_bo_mem_space * - * This function first searches for free space in compatible memory types in - * the priority order defined by the driver. If free space isn't found, then - * ttm_bo_mem_force_space is attempted in priority order to evict and find - * space. + * @bo: Pointer to a struct ttm_buffer_object. the data of which + * we want to allocate space for. + * @proposed_placement: Proposed new placement for the buffer object. + * @mem: A struct ttm_resource. + * @ctx: if and how to sleep, lock buffers and alloc memory + * + * Allocate memory space for the buffer object pointed to by @bo, using + * the placement flags in @placement, potentially evicting other idle buffer objects. + * This function may sleep while waiting for space to become available. + * Returns: + * -EBUSY: No space available (only if no_wait == 1). + * -ENOMEM: Could not allocate memory for the buffer object, either due to + * fragmentation or concurrent allocators. + * -ERESTARTSYS: An interruptible sleep was interrupted by a signal. */ int ttm_bo_mem_space(struct ttm_buffer_object *bo, struct ttm_placement *placement, @@ -838,6 +865,21 @@ out: return ret; } +/** + * ttm_bo_validate + * + * @bo: The buffer object. + * @placement: Proposed placement for the buffer object. + * @ctx: validation parameters. + * + * Changes placement and caching policy of the buffer object + * according proposed placement. + * Returns + * -EINVAL on invalid proposed placement. + * -ENOMEM on out-of-memory condition. + * -EBUSY if no_wait is true and buffer busy. + * -ERESTARTSYS if interrupted by a signal. + */ int ttm_bo_validate(struct ttm_buffer_object *bo, struct ttm_placement *placement, struct ttm_operation_ctx *ctx) @@ -1030,6 +1072,11 @@ EXPORT_SYMBOL(ttm_bo_init_validate); * buffer object vm functions. */ +/** + * ttm_bo_unmap_virtual + * + * @bo: tear down the virtual mappings for this BO + */ void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo) { struct ttm_device *bdev = bo->bdev; @@ -1039,6 +1086,20 @@ void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo) } EXPORT_SYMBOL(ttm_bo_unmap_virtual); +/** + * ttm_bo_wait - wait for buffer idle. + * + * @bo: The buffer object. + * @interruptible: Use interruptible wait. + * @no_wait: Return immediately if buffer is busy. + * + * This function must be called with the bo::mutex held, and makes + * sure any previous rendering to the buffer is completed. + * Note: It might be necessary to block validations before the + * wait by reserving the buffer. + * Returns -EBUSY if no_wait is true and the buffer is busy. + * Returns -ERESTARTSYS if interrupted by a signal. + */ int ttm_bo_wait(struct ttm_buffer_object *bo, bool interruptible, bool no_wait) { @@ -1063,6 +1124,12 @@ int ttm_bo_wait(struct ttm_buffer_object *bo, } EXPORT_SYMBOL(ttm_bo_wait); +int ttm_bo_wait_ctx(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx) +{ + return ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu); +} +EXPORT_SYMBOL(ttm_bo_wait_ctx); + int ttm_bo_swapout(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx, gfp_t gfp_flags) { diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index ae4b7922ee1a..fee7c20775c0 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -29,18 +29,11 @@ * Authors: Thomas Hellstrom */ -#include +#include #include +#include + #include -#include -#include -#include -#include -#include -#include -#include -#include -#include struct ttm_transfer_obj { struct ttm_buffer_object base; @@ -128,6 +121,23 @@ void ttm_move_memcpy(bool clear, } EXPORT_SYMBOL(ttm_move_memcpy); +/** + * ttm_bo_move_memcpy + * + * @bo: A pointer to a struct ttm_buffer_object. + * @interruptible: Sleep interruptible if waiting. + * @no_wait_gpu: Return immediately if the GPU is busy. + * @new_mem: struct ttm_resource indicating where to move. + * + * Fallback move function for a mappable buffer object in mappable memory. + * The function will, if successful, + * free any old aperture space, and set (@new_mem)->mm_node to NULL, + * and update the (@bo)->mem placement flags. If unsuccessful, the old + * data remains untouched, and it's up to the caller to free the + * memory space indicated by @new_mem. + * Returns: + * !0: Failure. + */ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx, struct ttm_resource *dst_mem) @@ -266,6 +276,16 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, return 0; } +/** + * ttm_io_prot + * + * bo: ttm buffer object + * res: ttm resource object + * @tmp: Page protection flag for a normal, cached mapping. + * + * Utility function that returns the pgprot_t that should be used for + * setting up a PTE with the caching model indicated by @c_state. + */ pgprot_t ttm_io_prot(struct ttm_buffer_object *bo, struct ttm_resource *res, pgprot_t tmp) { @@ -347,6 +367,22 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo, return (!map->virtual) ? -ENOMEM : 0; } +/** + * ttm_bo_kmap + * + * @bo: The buffer object. + * @start_page: The first page to map. + * @num_pages: Number of pages to map. + * @map: pointer to a struct ttm_bo_kmap_obj representing the map. + * + * Sets up a kernel virtual mapping, using ioremap, vmap or kmap to the + * data in the buffer object. The ttm_kmap_obj_virtual function can then be + * used to obtain a virtual address to the data. + * + * Returns + * -ENOMEM: Out of memory. + * -EINVAL: Invalid range. + */ int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page, unsigned long num_pages, struct ttm_bo_kmap_obj *map) @@ -374,6 +410,13 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, } EXPORT_SYMBOL(ttm_bo_kmap); +/** + * ttm_bo_kunmap + * + * @map: Object describing the map to unmap. + * + * Unmaps a kernel map set up by ttm_bo_kmap. + */ void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map) { if (!map->virtual) @@ -399,6 +442,20 @@ void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map) } EXPORT_SYMBOL(ttm_bo_kunmap); +/** + * ttm_bo_vmap + * + * @bo: The buffer object. + * @map: pointer to a struct iosys_map representing the map. + * + * Sets up a kernel virtual mapping, using ioremap or vmap to the + * data in the buffer object. The parameter @map returns the virtual + * address as struct iosys_map. Unmap the buffer with ttm_bo_vunmap(). + * + * Returns + * -ENOMEM: Out of memory. + * -EINVAL: Invalid range. + */ int ttm_bo_vmap(struct ttm_buffer_object *bo, struct iosys_map *map) { struct ttm_resource *mem = bo->resource; @@ -460,6 +517,14 @@ int ttm_bo_vmap(struct ttm_buffer_object *bo, struct iosys_map *map) } EXPORT_SYMBOL(ttm_bo_vmap); +/** + * ttm_bo_vunmap + * + * @bo: The buffer object. + * @map: Object describing the map to unmap. + * + * Unmaps a kernel map set up by ttm_bo_vmap(). + */ void ttm_bo_vunmap(struct ttm_buffer_object *bo, struct iosys_map *map) { struct ttm_resource *mem = bo->resource; @@ -553,6 +618,22 @@ static void ttm_bo_move_pipeline_evict(struct ttm_buffer_object *bo, ttm_resource_free(bo, &bo->resource); } +/** + * ttm_bo_move_accel_cleanup. + * + * @bo: A pointer to a struct ttm_buffer_object. + * @fence: A fence object that signals when moving is complete. + * @evict: This is an evict move. Don't return until the buffer is idle. + * @pipeline: evictions are to be pipelined. + * @new_mem: struct ttm_resource indicating where to move. + * + * Accelerated move function to be called when an accelerated move + * has been scheduled. The function will create a new temporary buffer object + * representing the old placement, and put the sync object on both buffer + * objects. After that the newly created buffer object is unref'd to be + * destroyed when the move is complete. This will help pipeline + * buffer moves. + */ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, struct dma_fence *fence, bool evict, @@ -581,6 +662,15 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, } EXPORT_SYMBOL(ttm_bo_move_accel_cleanup); +/** + * ttm_bo_move_sync_cleanup. + * + * @bo: A pointer to a struct ttm_buffer_object. + * @new_mem: struct ttm_resource indicating where to move. + * + * Special case of ttm_bo_move_accel_cleanup where the bo is guaranteed + * by the caller to be idle. Typically used after memcpy buffer moves. + */ void ttm_bo_move_sync_cleanup(struct ttm_buffer_object *bo, struct ttm_resource *new_mem) { diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 5a3e4b891377..3ecda6db24b8 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -31,17 +31,12 @@ #define pr_fmt(fmt) "[TTM] " fmt -#include +#include #include -#include +#include + #include #include -#include -#include -#include -#include -#include -#include static vm_fault_t ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo, struct vm_fault *vmf) @@ -446,6 +441,14 @@ static const struct vm_operations_struct ttm_bo_vm_ops = { .access = ttm_bo_vm_access, }; +/** + * ttm_bo_mmap_obj - mmap memory backed by a ttm buffer object. + * + * @vma: vma as input from the fbdev mmap method. + * @bo: The bo backing the address space. + * + * Maps a buffer object. + */ int ttm_bo_mmap_obj(struct vm_area_struct *vma, struct ttm_buffer_object *bo) { /* Enforce no COW since would have really strange behavior with it. */ diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c index e9bedca4dfdc..c7a1862f322a 100644 --- a/drivers/gpu/drm/ttm/ttm_device.c +++ b/drivers/gpu/drm/ttm/ttm_device.c @@ -29,10 +29,10 @@ #include +#include #include #include #include -#include #include "ttm_module.h" diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c index dbee34a058df..f1c60fa80c2d 100644 --- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c +++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c @@ -27,11 +27,7 @@ **************************************************************************/ #include -#include -#include -#include -#include -#include +#include static void ttm_eu_backoff_reservation_reverse(struct list_head *list, struct ttm_validate_buffer *entry) diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c index 9f6764bf3b15..aa116a7bbae3 100644 --- a/drivers/gpu/drm/ttm/ttm_pool.c +++ b/drivers/gpu/drm/ttm/ttm_pool.c @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -41,8 +42,8 @@ #endif #include -#include #include +#include #include "ttm_module.h" diff --git a/drivers/gpu/drm/ttm/ttm_range_manager.c b/drivers/gpu/drm/ttm/ttm_range_manager.c index 0a8bc0b7f380..ae11d07eb63a 100644 --- a/drivers/gpu/drm/ttm/ttm_range_manager.c +++ b/drivers/gpu/drm/ttm/ttm_range_manager.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c index 328391bb1d87..b8a826a24fb2 100644 --- a/drivers/gpu/drm/ttm/ttm_resource.c +++ b/drivers/gpu/drm/ttm/ttm_resource.c @@ -26,8 +26,9 @@ #include #include +#include +#include #include -#include /** * ttm_lru_bulk_move_init - initialize a bulk move structure diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index d505603930a7..ab725d9d14a6 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -36,7 +36,8 @@ #include #include #include -#include +#include +#include #include "ttm_module.h" diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c index 3c06df2a5474..2b843ff4b437 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include "vmwgfx_drv.h" diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index bd02cb0e6837..9ad28346aff7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index b062b020b378..4b612fc9758c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -37,8 +37,10 @@ #include #include -#include #include +#include +#include +#include #include "ttm_object.h" diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index a5379f6fb5ab..43cec8e37e4d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -29,7 +29,7 @@ #include "vmwgfx_drv.h" #include "vmwgfx_reg.h" -#include +#include #include #include "vmwgfx_so.h" #include "vmwgfx_binding.h" diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c index c482e5298e11..20158a92acc7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c @@ -25,7 +25,6 @@ * **************************************************************************/ -#include #include "vmwgfx_drv.h" diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c index abd5e3323ebf..ceb4d3d3b965 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c @@ -29,7 +29,6 @@ */ #include "vmwgfx_drv.h" -#include #include #include #include diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_system_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_system_manager.c index d3007bf1b8f5..ee7964cbdaca 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_system_manager.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_system_manager.c @@ -26,7 +26,6 @@ #include "vmwgfx_drv.h" -#include #include #include #include diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c index 4e3938e62c08..856a352a72a6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c @@ -26,7 +26,6 @@ **************************************************************************/ #include "vmwgfx_drv.h" -#include #include static const struct ttm_place vram_placement_flags = { diff --git a/include/drm/drm_gem_ttm_helper.h b/include/drm/drm_gem_ttm_helper.h index 4c003b4f173e..7b53d673ae7e 100644 --- a/include/drm/drm_gem_ttm_helper.h +++ b/include/drm/drm_gem_ttm_helper.h @@ -7,8 +7,7 @@ #include #include -#include -#include +#include struct iosys_map; diff --git a/include/drm/drm_gem_vram_helper.h b/include/drm/drm_gem_vram_helper.h index c083a1d71cf4..d3e8920c0b64 100644 --- a/include/drm/drm_gem_vram_helper.h +++ b/include/drm/drm_gem_vram_helper.h @@ -8,8 +8,8 @@ #include #include #include -#include -#include +#include +#include #include #include diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h new file mode 100644 index 000000000000..d87232472435 --- /dev/null +++ b/include/drm/ttm/ttm_bo.h @@ -0,0 +1,430 @@ +/************************************************************************** + * + * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + +#ifndef _TTM_BO_API_H_ +#define _TTM_BO_API_H_ + +#include + +#include +#include + +#include "ttm_device.h" + +/* Default number of pre-faulted pages in the TTM fault handler */ +#define TTM_BO_VM_NUM_PREFAULT 16 + +struct iosys_map; + +struct ttm_global; +struct ttm_device; +struct ttm_placement; +struct ttm_place; +struct ttm_resource; +struct ttm_resource_manager; +struct ttm_tt; + +/** + * enum ttm_bo_type + * + * @ttm_bo_type_device: These are 'normal' buffers that can + * be mmapped by user space. Each of these bos occupy a slot in the + * device address space, that can be used for normal vm operations. + * + * @ttm_bo_type_kernel: These buffers are like ttm_bo_type_device buffers, + * but they cannot be accessed from user-space. For kernel-only use. + * + * @ttm_bo_type_sg: Buffer made from dmabuf sg table shared with another + * driver. + */ +enum ttm_bo_type { + ttm_bo_type_device, + ttm_bo_type_kernel, + ttm_bo_type_sg +}; + +/** + * struct ttm_buffer_object + * + * @base: drm_gem_object superclass data. + * @bdev: Pointer to the buffer object device structure. + * @type: The bo type. + * @page_alignment: Page alignment. + * @destroy: Destruction function. If NULL, kfree is used. + * @kref: Reference count of this buffer object. When this refcount reaches + * zero, the object is destroyed or put on the delayed delete list. + * @resource: structure describing current placement. + * @ttm: TTM structure holding system pages. + * @deleted: True if the object is only a zombie and already deleted. + * + * Base class for TTM buffer object, that deals with data placement and CPU + * mappings. GPU mappings are really up to the driver, but for simpler GPUs + * the driver can usually use the placement offset @offset directly as the + * GPU virtual address. For drivers implementing multiple + * GPU memory manager contexts, the driver should manage the address space + * in these contexts separately and use these objects to get the correct + * placement and caching for these GPU maps. This makes it possible to use + * these objects for even quite elaborate memory management schemes. + * The destroy member, the API visibility of this object makes it possible + * to derive driver specific types. + */ +struct ttm_buffer_object { + struct drm_gem_object base; + + /* + * Members constant at init. + */ + struct ttm_device *bdev; + enum ttm_bo_type type; + uint32_t page_alignment; + void (*destroy) (struct ttm_buffer_object *); + + /* + * Members not needing protection. + */ + struct kref kref; + + /* + * Members protected by the bo::resv::reserved lock. + */ + struct ttm_resource *resource; + struct ttm_tt *ttm; + bool deleted; + struct ttm_lru_bulk_move *bulk_move; + unsigned priority; + unsigned pin_count; + + /** + * @delayed_delete: Work item used when we can't delete the BO + * immediately + */ + struct work_struct delayed_delete; + + /** + * Special members that are protected by the reserve lock + * and the bo::lock when written to. Can be read with + * either of these locks held. + */ + struct sg_table *sg; +}; + +/** + * struct ttm_bo_kmap_obj + * + * @virtual: The current kernel virtual address. + * @page: The page when kmap'ing a single page. + * @bo_kmap_type: Type of bo_kmap. + * + * Object describing a kernel mapping. Since a TTM bo may be located + * in various memory types with various caching policies, the + * mapping can either be an ioremap, a vmap, a kmap or part of a + * premapped region. + */ +#define TTM_BO_MAP_IOMEM_MASK 0x80 +struct ttm_bo_kmap_obj { + void *virtual; + struct page *page; + enum { + ttm_bo_map_iomap = 1 | TTM_BO_MAP_IOMEM_MASK, + ttm_bo_map_vmap = 2, + ttm_bo_map_kmap = 3, + ttm_bo_map_premapped = 4 | TTM_BO_MAP_IOMEM_MASK, + } bo_kmap_type; + struct ttm_buffer_object *bo; +}; + +/** + * struct ttm_operation_ctx + * + * @interruptible: Sleep interruptible if sleeping. + * @no_wait_gpu: Return immediately if the GPU is busy. + * @gfp_retry_mayfail: Set the __GFP_RETRY_MAYFAIL when allocation pages. + * @allow_res_evict: Allow eviction of reserved BOs. Can be used when multiple + * BOs share the same reservation object. + * @force_alloc: Don't check the memory account during suspend or CPU page + * faults. Should only be used by TTM internally. + * @resv: Reservation object to allow reserved evictions with. + * + * Context for TTM operations like changing buffer placement or general memory + * allocation. + */ +struct ttm_operation_ctx { + bool interruptible; + bool no_wait_gpu; + bool gfp_retry_mayfail; + bool allow_res_evict; + bool force_alloc; + struct dma_resv *resv; + uint64_t bytes_moved; +}; + +/** + * ttm_bo_get - reference a struct ttm_buffer_object + * + * @bo: The buffer object. + */ +static inline void ttm_bo_get(struct ttm_buffer_object *bo) +{ + kref_get(&bo->kref); +} + +/** + * ttm_bo_get_unless_zero - reference a struct ttm_buffer_object unless + * its refcount has already reached zero. + * @bo: The buffer object. + * + * Used to reference a TTM buffer object in lookups where the object is removed + * from the lookup structure during the destructor and for RCU lookups. + * + * Returns: @bo if the referencing was successful, NULL otherwise. + */ +static inline __must_check struct ttm_buffer_object * +ttm_bo_get_unless_zero(struct ttm_buffer_object *bo) +{ + if (!kref_get_unless_zero(&bo->kref)) + return NULL; + return bo; +} + +/** + * ttm_bo_reserve: + * + * @bo: A pointer to a struct ttm_buffer_object. + * @interruptible: Sleep interruptible if waiting. + * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY. + * @ticket: ticket used to acquire the ww_mutex. + * + * Locks a buffer object for validation. (Or prevents other processes from + * locking it for validation), while taking a number of measures to prevent + * deadlocks. + * + * Returns: + * -EDEADLK: The reservation may cause a deadlock. + * Release all buffer reservations, wait for @bo to become unreserved and + * try again. + * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by + * a signal. Release all buffer reservations and return to user-space. + * -EBUSY: The function needed to sleep, but @no_wait was true + * -EALREADY: Bo already reserved using @ticket. This error code will only + * be returned if @use_ticket is set to true. + */ +static inline int ttm_bo_reserve(struct ttm_buffer_object *bo, + bool interruptible, bool no_wait, + struct ww_acquire_ctx *ticket) +{ + int ret = 0; + + if (no_wait) { + bool success; + + if (WARN_ON(ticket)) + return -EBUSY; + + success = dma_resv_trylock(bo->base.resv); + return success ? 0 : -EBUSY; + } + + if (interruptible) + ret = dma_resv_lock_interruptible(bo->base.resv, ticket); + else + ret = dma_resv_lock(bo->base.resv, ticket); + if (ret == -EINTR) + return -ERESTARTSYS; + return ret; +} + +/** + * ttm_bo_reserve_slowpath: + * @bo: A pointer to a struct ttm_buffer_object. + * @interruptible: Sleep interruptible if waiting. + * @sequence: Set (@bo)->sequence to this value after lock + * + * This is called after ttm_bo_reserve returns -EAGAIN and we backed off + * from all our other reservations. Because there are no other reservations + * held by us, this function cannot deadlock any more. + */ +static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo, + bool interruptible, + struct ww_acquire_ctx *ticket) +{ + if (interruptible) { + int ret = dma_resv_lock_slow_interruptible(bo->base.resv, + ticket); + if (ret == -EINTR) + ret = -ERESTARTSYS; + return ret; + } + dma_resv_lock_slow(bo->base.resv, ticket); + return 0; +} + +void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo); + +static inline void +ttm_bo_move_to_lru_tail_unlocked(struct ttm_buffer_object *bo) +{ + spin_lock(&bo->bdev->lru_lock); + ttm_bo_move_to_lru_tail(bo); + spin_unlock(&bo->bdev->lru_lock); +} + +static inline void ttm_bo_assign_mem(struct ttm_buffer_object *bo, + struct ttm_resource *new_mem) +{ + WARN_ON(bo->resource); + bo->resource = new_mem; +} + +/** + * ttm_bo_move_null = assign memory for a buffer object. + * @bo: The bo to assign the memory to + * @new_mem: The memory to be assigned. + * + * Assign the memory from new_mem to the memory of the buffer object bo. + */ +static inline void ttm_bo_move_null(struct ttm_buffer_object *bo, + struct ttm_resource *new_mem) +{ + ttm_resource_free(bo, &bo->resource); + ttm_bo_assign_mem(bo, new_mem); +} + +/** + * ttm_bo_unreserve + * + * @bo: A pointer to a struct ttm_buffer_object. + * + * Unreserve a previous reservation of @bo. + */ +static inline void ttm_bo_unreserve(struct ttm_buffer_object *bo) +{ + ttm_bo_move_to_lru_tail_unlocked(bo); + dma_resv_unlock(bo->base.resv); +} + +/** + * ttm_kmap_obj_virtual + * + * @map: A struct ttm_bo_kmap_obj returned from ttm_bo_kmap. + * @is_iomem: Pointer to an integer that on return indicates 1 if the + * virtual map is io memory, 0 if normal memory. + * + * Returns the virtual address of a buffer object area mapped by ttm_bo_kmap. + * If *is_iomem is 1 on return, the virtual address points to an io memory area, + * that should strictly be accessed by the iowriteXX() and similar functions. + */ +static inline void *ttm_kmap_obj_virtual(struct ttm_bo_kmap_obj *map, + bool *is_iomem) +{ + *is_iomem = !!(map->bo_kmap_type & TTM_BO_MAP_IOMEM_MASK); + return map->virtual; +} + +int ttm_bo_wait(struct ttm_buffer_object *bo, bool interruptible, bool no_wait); +int ttm_bo_wait_ctx(struct ttm_buffer_object *bo, + struct ttm_operation_ctx *ctx); +int ttm_bo_validate(struct ttm_buffer_object *bo, + struct ttm_placement *placement, + struct ttm_operation_ctx *ctx); +void ttm_bo_put(struct ttm_buffer_object *bo); +void ttm_bo_set_bulk_move(struct ttm_buffer_object *bo, + struct ttm_lru_bulk_move *bulk); +int ttm_bo_lock_delayed_workqueue(struct ttm_device *bdev); +void ttm_bo_unlock_delayed_workqueue(struct ttm_device *bdev, int resched); +bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, + const struct ttm_place *place); +int ttm_bo_init_reserved(struct ttm_device *bdev, struct ttm_buffer_object *bo, + enum ttm_bo_type type, struct ttm_placement *placement, + uint32_t alignment, struct ttm_operation_ctx *ctx, + struct sg_table *sg, struct dma_resv *resv, + void (*destroy)(struct ttm_buffer_object *)); +int ttm_bo_init_validate(struct ttm_device *bdev, struct ttm_buffer_object *bo, + enum ttm_bo_type type, struct ttm_placement *placement, + uint32_t alignment, bool interruptible, + struct sg_table *sg, struct dma_resv *resv, + void (*destroy)(struct ttm_buffer_object *)); +int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page, + unsigned long num_pages, struct ttm_bo_kmap_obj *map); +void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map); +int ttm_bo_vmap(struct ttm_buffer_object *bo, struct iosys_map *map); +void ttm_bo_vunmap(struct ttm_buffer_object *bo, struct iosys_map *map); +int ttm_bo_mmap_obj(struct vm_area_struct *vma, struct ttm_buffer_object *bo); +int ttm_bo_swapout(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx, + gfp_t gfp_flags); +void ttm_bo_pin(struct ttm_buffer_object *bo); +void ttm_bo_unpin(struct ttm_buffer_object *bo); +int ttm_mem_evict_first(struct ttm_device *bdev, + struct ttm_resource_manager *man, + const struct ttm_place *place, + struct ttm_operation_ctx *ctx, + struct ww_acquire_ctx *ticket); +vm_fault_t ttm_bo_vm_reserve(struct ttm_buffer_object *bo, + struct vm_fault *vmf); +vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, + pgprot_t prot, + pgoff_t num_prefault); +vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf); +void ttm_bo_vm_open(struct vm_area_struct *vma); +void ttm_bo_vm_close(struct vm_area_struct *vma); +int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr, + void *buf, int len, int write); +vm_fault_t ttm_bo_vm_dummy_page(struct vm_fault *vmf, pgprot_t prot); + +int ttm_bo_mem_space(struct ttm_buffer_object *bo, + struct ttm_placement *placement, + struct ttm_resource **mem, + struct ttm_operation_ctx *ctx); + +void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo); +/* + * ttm_bo_util.c + */ +int ttm_mem_io_reserve(struct ttm_device *bdev, + struct ttm_resource *mem); +void ttm_mem_io_free(struct ttm_device *bdev, + struct ttm_resource *mem); +void ttm_move_memcpy(bool clear, u32 num_pages, + struct ttm_kmap_iter *dst_iter, + struct ttm_kmap_iter *src_iter); +int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, + struct ttm_operation_ctx *ctx, + struct ttm_resource *new_mem); +int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, + struct dma_fence *fence, bool evict, + bool pipeline, + struct ttm_resource *new_mem); +void ttm_bo_move_sync_cleanup(struct ttm_buffer_object *bo, + struct ttm_resource *new_mem); +int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo); +pgprot_t ttm_io_prot(struct ttm_buffer_object *bo, struct ttm_resource *res, + pgprot_t tmp); +void ttm_bo_tt_destroy(struct ttm_buffer_object *bo); + +#endif diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h deleted file mode 100644 index 69e62bbb01e3..000000000000 --- a/include/drm/ttm/ttm_bo_api.h +++ /dev/null @@ -1,447 +0,0 @@ -/************************************************************************** - * - * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ - -#ifndef _TTM_BO_API_H_ -#define _TTM_BO_API_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ttm_resource.h" - -struct ttm_global; - -struct ttm_device; - -struct iosys_map; - -struct drm_mm_node; - -struct ttm_placement; - -struct ttm_place; - -/** - * enum ttm_bo_type - * - * @ttm_bo_type_device: These are 'normal' buffers that can - * be mmapped by user space. Each of these bos occupy a slot in the - * device address space, that can be used for normal vm operations. - * - * @ttm_bo_type_kernel: These buffers are like ttm_bo_type_device buffers, - * but they cannot be accessed from user-space. For kernel-only use. - * - * @ttm_bo_type_sg: Buffer made from dmabuf sg table shared with another - * driver. - */ - -enum ttm_bo_type { - ttm_bo_type_device, - ttm_bo_type_kernel, - ttm_bo_type_sg -}; - -struct ttm_tt; - -/** - * struct ttm_buffer_object - * - * @base: drm_gem_object superclass data. - * @bdev: Pointer to the buffer object device structure. - * @type: The bo type. - * @page_alignment: Page alignment. - * @destroy: Destruction function. If NULL, kfree is used. - * @num_pages: Actual number of pages. - * @kref: Reference count of this buffer object. When this refcount reaches - * zero, the object is destroyed or put on the delayed delete list. - * @mem: structure describing current placement. - * @ttm: TTM structure holding system pages. - * @evicted: Whether the object was evicted without user-space knowing. - * @deleted: True if the object is only a zombie and already deleted. - * @swap: List head for swap LRU list. - * @offset: The current GPU offset, which can have different meanings - * depending on the memory type. For SYSTEM type memory, it should be 0. - * @cur_placement: Hint of current placement. - * - * Base class for TTM buffer object, that deals with data placement and CPU - * mappings. GPU mappings are really up to the driver, but for simpler GPUs - * the driver can usually use the placement offset @offset directly as the - * GPU virtual address. For drivers implementing multiple - * GPU memory manager contexts, the driver should manage the address space - * in these contexts separately and use these objects to get the correct - * placement and caching for these GPU maps. This makes it possible to use - * these objects for even quite elaborate memory management schemes. - * The destroy member, the API visibility of this object makes it possible - * to derive driver specific types. - */ - -struct ttm_buffer_object { - struct drm_gem_object base; - - /** - * Members constant at init. - */ - - struct ttm_device *bdev; - enum ttm_bo_type type; - uint32_t page_alignment; - void (*destroy) (struct ttm_buffer_object *); - - /** - * Members not needing protection. - */ - struct kref kref; - - /** - * Members protected by the bo::resv::reserved lock. - */ - - struct ttm_resource *resource; - struct ttm_tt *ttm; - bool deleted; - struct ttm_lru_bulk_move *bulk_move; - unsigned priority; - unsigned pin_count; - - /** - * @delayed_delete: Work item used when we can't delete the BO - * immediately - */ - struct work_struct delayed_delete; - - /** - * Special members that are protected by the reserve lock - * and the bo::lock when written to. Can be read with - * either of these locks held. - */ - - struct sg_table *sg; -}; - -/** - * struct ttm_bo_kmap_obj - * - * @virtual: The current kernel virtual address. - * @page: The page when kmap'ing a single page. - * @bo_kmap_type: Type of bo_kmap. - * - * Object describing a kernel mapping. Since a TTM bo may be located - * in various memory types with various caching policies, the - * mapping can either be an ioremap, a vmap, a kmap or part of a - * premapped region. - */ - -#define TTM_BO_MAP_IOMEM_MASK 0x80 -struct ttm_bo_kmap_obj { - void *virtual; - struct page *page; - enum { - ttm_bo_map_iomap = 1 | TTM_BO_MAP_IOMEM_MASK, - ttm_bo_map_vmap = 2, - ttm_bo_map_kmap = 3, - ttm_bo_map_premapped = 4 | TTM_BO_MAP_IOMEM_MASK, - } bo_kmap_type; - struct ttm_buffer_object *bo; -}; - -/** - * struct ttm_operation_ctx - * - * @interruptible: Sleep interruptible if sleeping. - * @no_wait_gpu: Return immediately if the GPU is busy. - * @gfp_retry_mayfail: Set the __GFP_RETRY_MAYFAIL when allocation pages. - * @allow_res_evict: Allow eviction of reserved BOs. Can be used when multiple - * BOs share the same reservation object. - * @force_alloc: Don't check the memory account during suspend or CPU page - * faults. Should only be used by TTM internally. - * @resv: Reservation object to allow reserved evictions with. - * - * Context for TTM operations like changing buffer placement or general memory - * allocation. - */ -struct ttm_operation_ctx { - bool interruptible; - bool no_wait_gpu; - bool gfp_retry_mayfail; - bool allow_res_evict; - bool force_alloc; - struct dma_resv *resv; - uint64_t bytes_moved; -}; - -/** - * ttm_bo_get - reference a struct ttm_buffer_object - * - * @bo: The buffer object. - */ -static inline void ttm_bo_get(struct ttm_buffer_object *bo) -{ - kref_get(&bo->kref); -} - -/** - * ttm_bo_get_unless_zero - reference a struct ttm_buffer_object unless - * its refcount has already reached zero. - * @bo: The buffer object. - * - * Used to reference a TTM buffer object in lookups where the object is removed - * from the lookup structure during the destructor and for RCU lookups. - * - * Returns: @bo if the referencing was successful, NULL otherwise. - */ -static inline __must_check struct ttm_buffer_object * -ttm_bo_get_unless_zero(struct ttm_buffer_object *bo) -{ - if (!kref_get_unless_zero(&bo->kref)) - return NULL; - return bo; -} - -/** - * ttm_bo_wait - wait for buffer idle. - * - * @bo: The buffer object. - * @interruptible: Use interruptible wait. - * @no_wait: Return immediately if buffer is busy. - * - * This function must be called with the bo::mutex held, and makes - * sure any previous rendering to the buffer is completed. - * Note: It might be necessary to block validations before the - * wait by reserving the buffer. - * Returns -EBUSY if no_wait is true and the buffer is busy. - * Returns -ERESTARTSYS if interrupted by a signal. - */ -int ttm_bo_wait(struct ttm_buffer_object *bo, bool interruptible, bool no_wait); - -static inline int ttm_bo_wait_ctx(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx) -{ - return ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu); -} - -/** - * ttm_bo_validate - * - * @bo: The buffer object. - * @placement: Proposed placement for the buffer object. - * @ctx: validation parameters. - * - * Changes placement and caching policy of the buffer object - * according proposed placement. - * Returns - * -EINVAL on invalid proposed placement. - * -ENOMEM on out-of-memory condition. - * -EBUSY if no_wait is true and buffer busy. - * -ERESTARTSYS if interrupted by a signal. - */ -int ttm_bo_validate(struct ttm_buffer_object *bo, - struct ttm_placement *placement, - struct ttm_operation_ctx *ctx); - -/** - * ttm_bo_put - * - * @bo: The buffer object. - * - * Unreference a buffer object. - */ -void ttm_bo_put(struct ttm_buffer_object *bo); - -void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo); -void ttm_bo_set_bulk_move(struct ttm_buffer_object *bo, - struct ttm_lru_bulk_move *bulk); - -/** - * ttm_bo_eviction_valuable - * - * @bo: The buffer object to evict - * @place: the placement we need to make room for - * - * Check if it is valuable to evict the BO to make room for the given placement. - */ -bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, - const struct ttm_place *place); - -int ttm_bo_init_reserved(struct ttm_device *bdev, struct ttm_buffer_object *bo, - enum ttm_bo_type type, struct ttm_placement *placement, - uint32_t alignment, struct ttm_operation_ctx *ctx, - struct sg_table *sg, struct dma_resv *resv, - void (*destroy) (struct ttm_buffer_object *)); -int ttm_bo_init_validate(struct ttm_device *bdev, struct ttm_buffer_object *bo, - enum ttm_bo_type type, struct ttm_placement *placement, - uint32_t alignment, bool interruptible, - struct sg_table *sg, struct dma_resv *resv, - void (*destroy) (struct ttm_buffer_object *)); - -/** - * ttm_kmap_obj_virtual - * - * @map: A struct ttm_bo_kmap_obj returned from ttm_bo_kmap. - * @is_iomem: Pointer to an integer that on return indicates 1 if the - * virtual map is io memory, 0 if normal memory. - * - * Returns the virtual address of a buffer object area mapped by ttm_bo_kmap. - * If *is_iomem is 1 on return, the virtual address points to an io memory area, - * that should strictly be accessed by the iowriteXX() and similar functions. - */ -static inline void *ttm_kmap_obj_virtual(struct ttm_bo_kmap_obj *map, - bool *is_iomem) -{ - *is_iomem = !!(map->bo_kmap_type & TTM_BO_MAP_IOMEM_MASK); - return map->virtual; -} - -/** - * ttm_bo_kmap - * - * @bo: The buffer object. - * @start_page: The first page to map. - * @num_pages: Number of pages to map. - * @map: pointer to a struct ttm_bo_kmap_obj representing the map. - * - * Sets up a kernel virtual mapping, using ioremap, vmap or kmap to the - * data in the buffer object. The ttm_kmap_obj_virtual function can then be - * used to obtain a virtual address to the data. - * - * Returns - * -ENOMEM: Out of memory. - * -EINVAL: Invalid range. - */ -int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page, - unsigned long num_pages, struct ttm_bo_kmap_obj *map); - -/** - * ttm_bo_kunmap - * - * @map: Object describing the map to unmap. - * - * Unmaps a kernel map set up by ttm_bo_kmap. - */ -void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map); - -/** - * ttm_bo_vmap - * - * @bo: The buffer object. - * @map: pointer to a struct iosys_map representing the map. - * - * Sets up a kernel virtual mapping, using ioremap or vmap to the - * data in the buffer object. The parameter @map returns the virtual - * address as struct iosys_map. Unmap the buffer with ttm_bo_vunmap(). - * - * Returns - * -ENOMEM: Out of memory. - * -EINVAL: Invalid range. - */ -int ttm_bo_vmap(struct ttm_buffer_object *bo, struct iosys_map *map); - -/** - * ttm_bo_vunmap - * - * @bo: The buffer object. - * @map: Object describing the map to unmap. - * - * Unmaps a kernel map set up by ttm_bo_vmap(). - */ -void ttm_bo_vunmap(struct ttm_buffer_object *bo, struct iosys_map *map); - -/** - * ttm_bo_mmap_obj - mmap memory backed by a ttm buffer object. - * - * @vma: vma as input from the fbdev mmap method. - * @bo: The bo backing the address space. - * - * Maps a buffer object. - */ -int ttm_bo_mmap_obj(struct vm_area_struct *vma, struct ttm_buffer_object *bo); - -/** - * ttm_bo_io - * - * @bdev: Pointer to the struct ttm_device. - * @filp: Pointer to the struct file attempting to read / write. - * @wbuf: User-space pointer to address of buffer to write. NULL on read. - * @rbuf: User-space pointer to address of buffer to read into. - * Null on write. - * @count: Number of bytes to read / write. - * @f_pos: Pointer to current file position. - * @write: 1 for read, 0 for write. - * - * This function implements read / write into ttm buffer objects, and is - * intended to - * be called from the fops::read and fops::write method. - * Returns: - * See man (2) write, man(2) read. In particular, - * the function may return -ERESTARTSYS if - * interrupted by a signal. - */ -ssize_t ttm_bo_io(struct ttm_device *bdev, struct file *filp, - const char __user *wbuf, char __user *rbuf, - size_t count, loff_t *f_pos, bool write); - -int ttm_bo_swapout(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx, - gfp_t gfp_flags); - -void ttm_bo_pin(struct ttm_buffer_object *bo); -void ttm_bo_unpin(struct ttm_buffer_object *bo); - -int ttm_mem_evict_first(struct ttm_device *bdev, - struct ttm_resource_manager *man, - const struct ttm_place *place, - struct ttm_operation_ctx *ctx, - struct ww_acquire_ctx *ticket); - -/* Default number of pre-faulted pages in the TTM fault handler */ -#define TTM_BO_VM_NUM_PREFAULT 16 - -vm_fault_t ttm_bo_vm_reserve(struct ttm_buffer_object *bo, - struct vm_fault *vmf); - -vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, - pgprot_t prot, - pgoff_t num_prefault); - -vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf); - -void ttm_bo_vm_open(struct vm_area_struct *vma); - -void ttm_bo_vm_close(struct vm_area_struct *vma); - -int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr, - void *buf, int len, int write); -vm_fault_t ttm_bo_vm_dummy_page(struct vm_fault *vmf, pgprot_t prot); - -#endif diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h deleted file mode 100644 index 1afa891f488a..000000000000 --- a/include/drm/ttm/ttm_bo_driver.h +++ /dev/null @@ -1,303 +0,0 @@ -/************************************************************************** - * - * Copyright (c) 2006-2009 Vmware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ -#ifndef _TTM_BO_DRIVER_H_ -#define _TTM_BO_DRIVER_H_ - -#include -#include -#include -#include -#include -#include - -#include - -#include "ttm_bo_api.h" -#include "ttm_kmap_iter.h" -#include "ttm_placement.h" -#include "ttm_tt.h" -#include "ttm_pool.h" - -/* - * ttm_bo.c - */ - -/** - * ttm_bo_mem_space - * - * @bo: Pointer to a struct ttm_buffer_object. the data of which - * we want to allocate space for. - * @proposed_placement: Proposed new placement for the buffer object. - * @mem: A struct ttm_resource. - * @interruptible: Sleep interruptible when sliping. - * @no_wait_gpu: Return immediately if the GPU is busy. - * - * Allocate memory space for the buffer object pointed to by @bo, using - * the placement flags in @mem, potentially evicting other idle buffer objects. - * This function may sleep while waiting for space to become available. - * Returns: - * -EBUSY: No space available (only if no_wait == 1). - * -ENOMEM: Could not allocate memory for the buffer object, either due to - * fragmentation or concurrent allocators. - * -ERESTARTSYS: An interruptible sleep was interrupted by a signal. - */ -int ttm_bo_mem_space(struct ttm_buffer_object *bo, - struct ttm_placement *placement, - struct ttm_resource **mem, - struct ttm_operation_ctx *ctx); - -/** - * ttm_bo_unmap_virtual - * - * @bo: tear down the virtual mappings for this BO - */ -void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo); - -/** - * ttm_bo_reserve: - * - * @bo: A pointer to a struct ttm_buffer_object. - * @interruptible: Sleep interruptible if waiting. - * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY. - * @ticket: ticket used to acquire the ww_mutex. - * - * Locks a buffer object for validation. (Or prevents other processes from - * locking it for validation), while taking a number of measures to prevent - * deadlocks. - * - * Returns: - * -EDEADLK: The reservation may cause a deadlock. - * Release all buffer reservations, wait for @bo to become unreserved and - * try again. - * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by - * a signal. Release all buffer reservations and return to user-space. - * -EBUSY: The function needed to sleep, but @no_wait was true - * -EALREADY: Bo already reserved using @ticket. This error code will only - * be returned if @use_ticket is set to true. - */ -static inline int ttm_bo_reserve(struct ttm_buffer_object *bo, - bool interruptible, bool no_wait, - struct ww_acquire_ctx *ticket) -{ - int ret; - - if (no_wait) { - bool success; - if (WARN_ON(ticket)) - return -EBUSY; - - success = dma_resv_trylock(bo->base.resv); - return success ? 0 : -EBUSY; - } - - if (interruptible) - ret = dma_resv_lock_interruptible(bo->base.resv, ticket); - else - ret = dma_resv_lock(bo->base.resv, ticket); - if (ret == -EINTR) - return -ERESTARTSYS; - return ret; -} - -/** - * ttm_bo_reserve_slowpath: - * @bo: A pointer to a struct ttm_buffer_object. - * @interruptible: Sleep interruptible if waiting. - * @sequence: Set (@bo)->sequence to this value after lock - * - * This is called after ttm_bo_reserve returns -EAGAIN and we backed off - * from all our other reservations. Because there are no other reservations - * held by us, this function cannot deadlock any more. - */ -static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo, - bool interruptible, - struct ww_acquire_ctx *ticket) -{ - if (interruptible) { - int ret = dma_resv_lock_slow_interruptible(bo->base.resv, - ticket); - if (ret == -EINTR) - ret = -ERESTARTSYS; - return ret; - } - dma_resv_lock_slow(bo->base.resv, ticket); - return 0; -} - -static inline void -ttm_bo_move_to_lru_tail_unlocked(struct ttm_buffer_object *bo) -{ - spin_lock(&bo->bdev->lru_lock); - ttm_bo_move_to_lru_tail(bo); - spin_unlock(&bo->bdev->lru_lock); -} - -static inline void ttm_bo_assign_mem(struct ttm_buffer_object *bo, - struct ttm_resource *new_mem) -{ - WARN_ON(bo->resource); - bo->resource = new_mem; -} - -/** - * ttm_bo_move_null = assign memory for a buffer object. - * @bo: The bo to assign the memory to - * @new_mem: The memory to be assigned. - * - * Assign the memory from new_mem to the memory of the buffer object bo. - */ -static inline void ttm_bo_move_null(struct ttm_buffer_object *bo, - struct ttm_resource *new_mem) -{ - ttm_resource_free(bo, &bo->resource); - ttm_bo_assign_mem(bo, new_mem); -} - -/** - * ttm_bo_unreserve - * - * @bo: A pointer to a struct ttm_buffer_object. - * - * Unreserve a previous reservation of @bo. - */ -static inline void ttm_bo_unreserve(struct ttm_buffer_object *bo) -{ - ttm_bo_move_to_lru_tail_unlocked(bo); - dma_resv_unlock(bo->base.resv); -} - -/* - * ttm_bo_util.c - */ -int ttm_mem_io_reserve(struct ttm_device *bdev, - struct ttm_resource *mem); -void ttm_mem_io_free(struct ttm_device *bdev, - struct ttm_resource *mem); - -/** - * ttm_bo_move_memcpy - * - * @bo: A pointer to a struct ttm_buffer_object. - * @interruptible: Sleep interruptible if waiting. - * @no_wait_gpu: Return immediately if the GPU is busy. - * @new_mem: struct ttm_resource indicating where to move. - * - * Fallback move function for a mappable buffer object in mappable memory. - * The function will, if successful, - * free any old aperture space, and set (@new_mem)->mm_node to NULL, - * and update the (@bo)->mem placement flags. If unsuccessful, the old - * data remains untouched, and it's up to the caller to free the - * memory space indicated by @new_mem. - * Returns: - * !0: Failure. - */ - -int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, - struct ttm_operation_ctx *ctx, - struct ttm_resource *new_mem); - -/** - * ttm_bo_move_accel_cleanup. - * - * @bo: A pointer to a struct ttm_buffer_object. - * @fence: A fence object that signals when moving is complete. - * @evict: This is an evict move. Don't return until the buffer is idle. - * @pipeline: evictions are to be pipelined. - * @new_mem: struct ttm_resource indicating where to move. - * - * Accelerated move function to be called when an accelerated move - * has been scheduled. The function will create a new temporary buffer object - * representing the old placement, and put the sync object on both buffer - * objects. After that the newly created buffer object is unref'd to be - * destroyed when the move is complete. This will help pipeline - * buffer moves. - */ -int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, - struct dma_fence *fence, bool evict, - bool pipeline, - struct ttm_resource *new_mem); - -/** - * ttm_bo_move_sync_cleanup. - * - * @bo: A pointer to a struct ttm_buffer_object. - * @new_mem: struct ttm_resource indicating where to move. - * - * Special case of ttm_bo_move_accel_cleanup where the bo is guaranteed - * by the caller to be idle. Typically used after memcpy buffer moves. - */ -void ttm_bo_move_sync_cleanup(struct ttm_buffer_object *bo, - struct ttm_resource *new_mem); - -/** - * ttm_bo_pipeline_gutting. - * - * @bo: A pointer to a struct ttm_buffer_object. - * - * Pipelined gutting a BO of its backing store. - */ -int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo); - -/** - * ttm_io_prot - * - * bo: ttm buffer object - * res: ttm resource object - * @tmp: Page protection flag for a normal, cached mapping. - * - * Utility function that returns the pgprot_t that should be used for - * setting up a PTE with the caching model indicated by @c_state. - */ -pgprot_t ttm_io_prot(struct ttm_buffer_object *bo, struct ttm_resource *res, - pgprot_t tmp); - -/** - * ttm_bo_tt_bind - * - * Bind the object tt to a memory resource. - */ -int ttm_bo_tt_bind(struct ttm_buffer_object *bo, struct ttm_resource *mem); - -/** - * ttm_bo_tt_destroy. - */ -void ttm_bo_tt_destroy(struct ttm_buffer_object *bo); - -void ttm_move_memcpy(bool clear, - u32 num_pages, - struct ttm_kmap_iter *dst_iter, - struct ttm_kmap_iter *src_iter); - -struct ttm_kmap_iter * -ttm_kmap_iter_iomap_init(struct ttm_kmap_iter_iomap *iter_io, - struct io_mapping *iomap, - struct sg_table *st, - resource_size_t start); -#endif diff --git a/include/drm/ttm/ttm_execbuf_util.h b/include/drm/ttm/ttm_execbuf_util.h index a99d7fdf2964..03aca29d3ce4 100644 --- a/include/drm/ttm/ttm_execbuf_util.h +++ b/include/drm/ttm/ttm_execbuf_util.h @@ -33,7 +33,9 @@ #include -#include "ttm_bo_api.h" +struct ww_acquire_ctx; +struct dma_fence; +struct ttm_buffer_object; /** * struct ttm_validate_buffer -- cgit From 196c92263f5525a644e8e6a0c9df5cc2da9e2b16 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Tue, 29 Nov 2022 19:19:42 +0000 Subject: drm/i915/gt: Remove #ifdef guards for PM related functions Instead of defining two versions of intel_sysfs_rc6_init(), one for each value of CONFIG_PM, add a check on !IS_ENABLED(CONFIG_PM) early in the function. This will allow the compiler to automatically drop the dead code when CONFIG_PM is disabled, without having to use #ifdef guards. This has the advantage of always compiling these functions in, independently of any Kconfig option. Thanks to that, bugs and other regressions are subsequently easier to catch. Signed-off-by: Paul Cercueil Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20221129191942.138244-13-paul@crapouillou.net --- drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c index cf71305ad586..09b9365ededd 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c @@ -164,7 +164,6 @@ sysfs_gt_attribute_r_func(struct kobject *kobj, struct attribute *attr, NULL); \ INTEL_GT_ATTR_RO(_name) -#ifdef CONFIG_PM static u32 get_residency(struct intel_gt *gt, enum intel_rc6_res_type id) { intel_wakeref_t wakeref; @@ -300,7 +299,7 @@ static void intel_sysfs_rc6_init(struct intel_gt *gt, struct kobject *kobj) { int ret; - if (!HAS_RC6(gt->i915)) + if (!IS_ENABLED(CONFIG_PM) || !HAS_RC6(gt->i915)) return; ret = __intel_gt_sysfs_create_group(kobj, rc6_attr_group); @@ -329,11 +328,6 @@ static void intel_sysfs_rc6_init(struct intel_gt *gt, struct kobject *kobj) gt->info.id, ERR_PTR(ret)); } } -#else -static void intel_sysfs_rc6_init(struct intel_gt *gt, struct kobject *kobj) -{ -} -#endif /* CONFIG_PM */ static u32 __act_freq_mhz_show(struct intel_gt *gt) { -- cgit From 58377de46eee1e0066c93f659c91a809432d024c Mon Sep 17 00:00:00 2001 From: Christian König Date: Thu, 24 Nov 2022 13:30:18 +0100 Subject: drm/i915: stop using ttm_bo_wait MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TTM is just wrapping core DMA functionality here, remove the mid-layer. No functional change. Signed-off-by: Christian König Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20221125102137.1801-7-christian.koenig@amd.com --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 5247d88b3c13..d409a77449a3 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -599,13 +599,16 @@ i915_ttm_resource_get_st(struct drm_i915_gem_object *obj, static int i915_ttm_truncate(struct drm_i915_gem_object *obj) { struct ttm_buffer_object *bo = i915_gem_to_ttm(obj); - int err; + long err; WARN_ON_ONCE(obj->mm.madv == I915_MADV_WILLNEED); - err = ttm_bo_wait(bo, true, false); - if (err) + err = dma_resv_wait_timeout(bo->base.resv, DMA_RESV_USAGE_BOOKKEEP, + true, 15 * HZ); + if (err < 0) return err; + if (err == 0) + return -EBUSY; err = i915_ttm_move_notify(bo); if (err) -- cgit