diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-02 07:59:23 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-02 07:59:23 -0700 |
commit | 320b164abb32db876866a4ff8c2cb710524ac6ea (patch) | |
tree | 1f79119cde6e24c9f1d01fb1e51252bca7c4cdd5 /drivers/gpu/drm/ttm/ttm_bo.c | |
parent | 0adb32858b0bddf4ada5f364a84ed60b196dbcda (diff) | |
parent | 694f54f680f7fd8e9561928fbfc537d9afbc3d79 (diff) | |
download | linux-320b164abb32db876866a4ff8c2cb710524ac6ea.tar.gz linux-320b164abb32db876866a4ff8c2cb710524ac6ea.tar.bz2 linux-320b164abb32db876866a4ff8c2cb710524ac6ea.zip |
Merge tag 'drm-for-v4.17' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie:
"Cannonlake and Vega12 support are probably the two major things. This
pull lacks nouveau, Ben had some unforseen leave and a few other
blockers so we'll see how things look or maybe leave it for this merge
window.
core:
- Device links to handle sound/gpu pm dependency
- Color encoding/range properties
- Plane clipping into plane check helper
- Backlight helpers
- DP TP4 + HBR3 helper support
amdgpu:
- Vega12 support
- Enable DC by default on all supported GPUs
- Powerplay restructuring and cleanup
- DC bandwidth calc updates
- DC backlight on pre-DCE11
- TTM backing store dropping support
- SR-IOV fixes
- Adding "wattman" like functionality
- DC crc support
- Improved DC dual-link handling
amdkfd:
- GPUVM support for dGPU
- KFD events for dGPU
- Enable PCIe atomics for dGPUs
- HSA process eviction support
- Live-lock fixes for process eviction
- VM page table allocation fix for large-bar systems
panel:
- Raydium RM68200
- AUO G104SN02 V2
- KEO TX31D200VM0BAA
- ARM Versatile panels
i915:
- Cannonlake support enabled
- AUX-F port support added
- Icelake base enabling until internal milestone of forcewake support
- Query uAPI interface (used for GPU topology information currently)
- Compressed framebuffer support for sprites
- kmem cache shrinking when GPU is idle
- Avoid boosting GPU when waited item is being processed already
- Avoid retraining LSPCON link unnecessarily
- Decrease request signaling latency
- Deprecation of I915_SET_COLORKEY_NONE
- Kerneldoc and compiler warning cleanup for upcoming CI enforcements
- Full range ycbcr toggling
- HDCP support
i915/gvt:
- Big refactor for shadow ppgtt
- KBL context save/restore via LRI cmd (Weinan)
- Properly unmap dma for guest page (Changbin)
vmwgfx:
- Lots of various improvements
etnaviv:
- Use the drm gpu scheduler
- prep work for GC7000L support
vc4:
- fix alpha blending
- Expose perf counters to userspace
pl111:
- Bandwidth checking/limiting
- Versatile panel support
sun4i:
- A83T HDMI support
- A80 support
- YUV plane support
- H3/H5 HDMI support
omapdrm:
- HPD support for DVI connector
- remove lots of static variables
msm:
- DSI updates from 10nm / SDM845
- fix for race condition with a3xx/a4xx fence completion irq
- some refactoring/prep work for eventual a6xx support (ie. when we
have a userspace)
- a5xx debugfs enhancements
- some mdp5 fixes/cleanups to prepare for eventually merging
writeback
- support (ie. when we have a userspace)
tegra:
- mmap() fixes for fbdev devices
- Overlay plane for hw cursor fix
- dma-buf cache maintenance support
mali-dp:
- YUV->RGB conversion support
rockchip:
- rk3399/chromebook fixes and improvements
rcar-du:
- LVDS support move to drm bridge
- DT bindings for R8A77995
- Driver/DT support for R8A77970
tilcdc:
- DRM panel support"
* tag 'drm-for-v4.17' of git://people.freedesktop.org/~airlied/linux: (1646 commits)
drm/i915: Fix hibernation with ACPI S0 target state
drm/i915/execlists: Use a locked clear_bit() for synchronisation with interrupt
drm/i915: Specify which engines to reset following semaphore/event lockups
drm/i915/dp: Write to SET_POWER dpcd to enable MST hub.
drm/amdkfd: Use ordered workqueue to restore processes
drm/amdgpu: Fix acquiring VM on large-BAR systems
drm/amd/pp: clean header file hwmgr.h
drm/amd/pp: use mlck_table.count for array loop index limit
drm: Fix uabi regression by allowing garbage mode->type from userspace
drm/amdgpu: Add an ATPX quirk for hybrid laptop
drm/amdgpu: fix spelling mistake: "asssert" -> "assert"
drm/amd/pp: Add new asic support in pp_psm.c
drm/amd/pp: Clean up powerplay code on Vega12
drm/amd/pp: Add smu irq handlers for legacy asics
drm/amd/pp: Fix set wrong temperature range on smu7
drm/amdgpu: Don't change preferred domian when fallback GTT v5
drm/vmwgfx: Bump version patchlevel and date
drm/vmwgfx: use monotonic event timestamps
drm/vmwgfx: Unpin the screen object backup buffer when not used
drm/vmwgfx: Stricter count of legacy surface device resources
...
Diffstat (limited to 'drivers/gpu/drm/ttm/ttm_bo.c')
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_bo.c | 121 |
1 files changed, 43 insertions, 78 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 2fef09a56d16..98e06f8bf23b 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -49,6 +49,12 @@ static struct attribute ttm_bo_count = { .mode = S_IRUGO }; +/* default destructor */ +static void ttm_bo_default_destroy(struct ttm_buffer_object *bo) +{ + kfree(bo); +} + static inline int ttm_mem_type_from_place(const struct ttm_place *place, uint32_t *mem_type) { @@ -143,15 +149,11 @@ static void ttm_bo_release_list(struct kref *list_kref) BUG_ON(!list_empty(&bo->lru)); BUG_ON(!list_empty(&bo->ddestroy)); ttm_tt_destroy(bo->ttm); - atomic_dec(&bo->glob->bo_count); + atomic_dec(&bo->bdev->glob->bo_count); dma_fence_put(bo->moving); reservation_object_fini(&bo->ttm_resv); mutex_destroy(&bo->wu_mutex); - if (bo->destroy) - bo->destroy(bo); - else { - kfree(bo); - } + bo->destroy(bo); ttm_mem_global_free(bdev->glob->mem_glob, acc_size); } @@ -163,7 +165,6 @@ void ttm_bo_add_to_lru(struct ttm_buffer_object *bo) reservation_object_assert_held(bo->resv); if (!(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) { - BUG_ON(!list_empty(&bo->lru)); man = &bdev->man[bo->mem.mem_type]; @@ -173,7 +174,7 @@ void ttm_bo_add_to_lru(struct ttm_buffer_object *bo) if (bo->ttm && !(bo->ttm->page_flags & (TTM_PAGE_FLAG_SG | TTM_PAGE_FLAG_SWAPPED))) { list_add_tail(&bo->swap, - &bo->glob->swap_lru[bo->priority]); + &bdev->glob->swap_lru[bo->priority]); kref_get(&bo->list_kref); } } @@ -204,9 +205,11 @@ void ttm_bo_del_from_lru(struct ttm_buffer_object *bo) void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo) { - spin_lock(&bo->glob->lru_lock); + struct ttm_bo_global *glob = bo->bdev->glob; + + spin_lock(&glob->lru_lock); ttm_bo_del_from_lru(bo); - spin_unlock(&bo->glob->lru_lock); + spin_unlock(&glob->lru_lock); } EXPORT_SYMBOL(ttm_bo_del_sub_from_lru); @@ -219,51 +222,6 @@ void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo) } EXPORT_SYMBOL(ttm_bo_move_to_lru_tail); -/* - * Call bo->mutex locked. - */ -static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc) -{ - struct ttm_bo_device *bdev = bo->bdev; - struct ttm_bo_global *glob = bo->glob; - int ret = 0; - uint32_t page_flags = 0; - - reservation_object_assert_held(bo->resv); - bo->ttm = NULL; - - if (bdev->need_dma32) - page_flags |= TTM_PAGE_FLAG_DMA32; - - switch (bo->type) { - case ttm_bo_type_device: - if (zero_alloc) - page_flags |= TTM_PAGE_FLAG_ZERO_ALLOC; - case ttm_bo_type_kernel: - bo->ttm = bdev->driver->ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT, - page_flags, glob->dummy_read_page); - if (unlikely(bo->ttm == NULL)) - ret = -ENOMEM; - break; - case ttm_bo_type_sg: - bo->ttm = bdev->driver->ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT, - page_flags | TTM_PAGE_FLAG_SG, - glob->dummy_read_page); - if (unlikely(bo->ttm == NULL)) { - ret = -ENOMEM; - break; - } - bo->ttm->sg = bo->sg; - break; - default: - pr_err("Illegal buffer object type\n"); - ret = -EINVAL; - break; - } - - return ret; -} - static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, struct ttm_mem_reg *mem, bool evict, struct ttm_operation_ctx *ctx) @@ -291,7 +249,7 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) { if (bo->ttm == NULL) { bool zero = !(old_man->flags & TTM_MEMTYPE_FLAG_FIXED); - ret = ttm_bo_add_ttm(bo, zero); + ret = ttm_tt_create(bo, zero); if (ret) goto out_err; } @@ -425,7 +383,7 @@ static void ttm_bo_flush_all_fences(struct ttm_buffer_object *bo) static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) { struct ttm_bo_device *bdev = bo->bdev; - struct ttm_bo_global *glob = bo->glob; + struct ttm_bo_global *glob = bdev->glob; int ret; ret = ttm_bo_individualize_resv(bo); @@ -496,7 +454,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool interruptible, bool no_wait_gpu, bool unlock_resv) { - struct ttm_bo_global *glob = bo->glob; + struct ttm_bo_global *glob = bo->bdev->glob; struct reservation_object *resv; int ret; @@ -611,10 +569,9 @@ static void ttm_bo_delayed_workqueue(struct work_struct *work) struct ttm_bo_device *bdev = container_of(work, struct ttm_bo_device, wq.work); - if (!ttm_bo_delayed_delete(bdev, false)) { + if (!ttm_bo_delayed_delete(bdev, false)) schedule_delayed_work(&bdev->wq, ((HZ / 100) < 1) ? 1 : HZ / 100); - } } static void ttm_bo_release(struct kref *kref) @@ -665,14 +622,23 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, reservation_object_assert_held(bo->resv); + placement.num_placement = 0; + placement.num_busy_placement = 0; + bdev->driver->evict_flags(bo, &placement); + + if (!placement.num_placement && !placement.num_busy_placement) { + ret = ttm_bo_pipeline_gutting(bo); + if (ret) + return ret; + + return ttm_tt_create(bo, false); + } + evict_mem = bo->mem; evict_mem.mm_node = NULL; evict_mem.bus.io_reserved_vm = false; evict_mem.bus.io_reserved_count = 0; - placement.num_placement = 0; - placement.num_busy_placement = 0; - bdev->driver->evict_flags(bo, &placement); ret = ttm_bo_mem_space(bo, &placement, &evict_mem, ctx); if (ret) { if (ret != -ERESTARTSYS) { @@ -727,7 +693,8 @@ static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo, *locked = false; if (bo->resv == ctx->resv) { reservation_object_assert_held(bo->resv); - if (ctx->allow_reserved_eviction || !list_empty(&bo->ddestroy)) + if (ctx->flags & TTM_OPT_FLAG_ALLOW_RES_EVICT + || !list_empty(&bo->ddestroy)) ret = true; } else { *locked = reservation_object_trylock(bo->resv); @@ -1130,7 +1097,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, * We might need to add a TTM. */ if (bo->mem.mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) { - ret = ttm_bo_add_ttm(bo, true); + ret = ttm_tt_create(bo, true); if (ret) return ret; } @@ -1145,7 +1112,6 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, struct ttm_placement *placement, uint32_t page_alignment, struct ttm_operation_ctx *ctx, - struct file *persistent_swap_storage, size_t acc_size, struct sg_table *sg, struct reservation_object *resv, @@ -1176,7 +1142,7 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, ttm_mem_global_free(mem_glob, acc_size); return -EINVAL; } - bo->destroy = destroy; + bo->destroy = destroy ? destroy : ttm_bo_default_destroy; kref_init(&bo->kref); kref_init(&bo->list_kref); @@ -1187,7 +1153,6 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, INIT_LIST_HEAD(&bo->io_reserve_lru); mutex_init(&bo->wu_mutex); bo->bdev = bdev; - bo->glob = bdev->glob; bo->type = type; bo->num_pages = num_pages; bo->mem.size = num_pages << PAGE_SHIFT; @@ -1199,7 +1164,6 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, bo->mem.bus.io_reserved_count = 0; bo->moving = NULL; bo->mem.placement = (TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED); - bo->persistent_swap_storage = persistent_swap_storage; bo->acc_size = acc_size; bo->sg = sg; if (resv) { @@ -1209,7 +1173,7 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, bo->resv = &bo->ttm_resv; } reservation_object_init(&bo->ttm_resv); - atomic_inc(&bo->glob->bo_count); + atomic_inc(&bo->bdev->glob->bo_count); drm_vma_node_reset(&bo->vma_node); bo->priority = 0; @@ -1242,9 +1206,9 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, } if (resv && !(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) { - spin_lock(&bo->glob->lru_lock); + spin_lock(&bdev->glob->lru_lock); ttm_bo_add_to_lru(bo); - spin_unlock(&bo->glob->lru_lock); + spin_unlock(&bdev->glob->lru_lock); } return ret; @@ -1258,7 +1222,6 @@ int ttm_bo_init(struct ttm_bo_device *bdev, struct ttm_placement *placement, uint32_t page_alignment, bool interruptible, - struct file *persistent_swap_storage, size_t acc_size, struct sg_table *sg, struct reservation_object *resv, @@ -1268,8 +1231,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev, int ret; ret = ttm_bo_init_reserved(bdev, bo, size, type, placement, - page_alignment, &ctx, - persistent_swap_storage, acc_size, + page_alignment, &ctx, acc_size, sg, resv, destroy); if (ret) return ret; @@ -1315,7 +1277,6 @@ int ttm_bo_create(struct ttm_bo_device *bdev, struct ttm_placement *placement, uint32_t page_alignment, bool interruptible, - struct file *persistent_swap_storage, struct ttm_buffer_object **p_bo) { struct ttm_buffer_object *bo; @@ -1328,7 +1289,7 @@ int ttm_bo_create(struct ttm_bo_device *bdev, acc_size = ttm_bo_acc_size(bdev, size, sizeof(struct ttm_buffer_object)); ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment, - interruptible, persistent_swap_storage, acc_size, + interruptible, acc_size, NULL, NULL, NULL); if (likely(ret == 0)) *p_bo = bo; @@ -1340,7 +1301,11 @@ EXPORT_SYMBOL(ttm_bo_create); static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev, unsigned mem_type) { - struct ttm_operation_ctx ctx = { false, false }; + struct ttm_operation_ctx ctx = { + .interruptible = false, + .no_wait_gpu = false, + .flags = TTM_OPT_FLAG_FORCE_ALLOC + }; struct ttm_mem_type_manager *man = &bdev->man[mem_type]; struct ttm_bo_global *glob = bdev->glob; struct dma_fence *fence; |