diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/0783-Revert-drm-amdgpu-revert-fix-exclusive-mode-game-tex.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.14.71/0783-Revert-drm-amdgpu-revert-fix-exclusive-mode-game-tex.patch | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/0783-Revert-drm-amdgpu-revert-fix-exclusive-mode-game-tex.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/0783-Revert-drm-amdgpu-revert-fix-exclusive-mode-game-tex.patch new file mode 100644 index 00000000..3dcf1e5b --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/0783-Revert-drm-amdgpu-revert-fix-exclusive-mode-game-tex.patch @@ -0,0 +1,423 @@ +From ada9566114097cebd9471fdee421e7e3f2931041 Mon Sep 17 00:00:00 2001 +From: "Hongbo.He" <Hongbo.He@amd.com> +Date: Tue, 6 Dec 2016 16:23:39 +0800 +Subject: [PATCH 0783/4131] Revert "drm/amdgpu: "revert fix exclusive mode game + texture blank(v2)"" + +This reverts commit 3bf3029fd2416d63d5439fde2412e76ac77d081f. + +Change-Id: I10ce2f9a2d3716d3b0e0eced8e7c9a6b32411ba8 + + Conflicts: + drivers/gpu/drm/amd/amdgpu/amdgpu.h + drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +--- + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 5 + + drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 8 ++ + drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 7 ++ + drivers/gpu/drm/amd/amdgpu/amdgpu_sem.c | 192 ++++++++++++++++++++++---------- + drivers/gpu/drm/amd/amdgpu/amdgpu_sem.h | 10 +- + 5 files changed, 164 insertions(+), 58 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index 6cf1620..9db84c8 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -59,6 +59,7 @@ + #include "amdgpu_sync.h" + #include "amdgpu_ring.h" + #include "amdgpu_vm.h" ++#include "amdgpu_sem.h" + #include "amd_powerplay.h" + #include "amdgpu_dpm.h" + #include "amdgpu_acp.h" +@@ -757,6 +758,8 @@ struct amdgpu_fpriv { + struct mutex bo_list_lock; + struct idr bo_list_handles; + struct amdgpu_ctx_mgr ctx_mgr; ++ spinlock_t sem_handles_lock; ++ struct idr sem_handles; + u32 vram_lost_counter; + }; + +@@ -1327,6 +1330,8 @@ int amdgpu_sem_ioctl(struct drm_device *dev, void *data, + int amdgpu_sem_add_cs(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, + struct amdgpu_sync *sync); + ++void amdgpu_sem_destroy(struct amdgpu_fpriv *fpriv, u32 handle); ++ + int amdgpu_gem_dgma_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp); + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +index cd84bd0..b502338 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +@@ -131,6 +131,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, + unsigned i; + int r = 0; + bool need_pipe_sync = false; ++ unsigned extra_nop = 0; + + if (num_ibs == 0) + return -EINVAL; +@@ -157,6 +158,11 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, + alloc_size = ring->funcs->emit_frame_size + num_ibs * + ring->funcs->emit_ib_size; + ++ if (job && !job->vm_needs_flush && ring->funcs->type == AMDGPU_RING_TYPE_GFX) { ++ extra_nop = 128; ++ alloc_size += extra_nop; ++ } ++ + r = amdgpu_ring_alloc(ring, alloc_size); + if (r) { + dev_err(adev->dev, "scheduling IB failed (%d).\n", r); +@@ -174,6 +180,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, + ring->funcs->insert_start(ring); + + if (job) { ++ amdgpu_ring_insert_nop(ring, extra_nop); /* prevent CE go too fast than DE */ ++ + r = amdgpu_vm_flush(ring, job, need_pipe_sync); + if (r) { + amdgpu_ring_undo(ring); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +index a5507b5..2e32262 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +@@ -877,6 +877,8 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) + + mutex_init(&fpriv->bo_list_lock); + idr_init(&fpriv->bo_list_handles); ++ spin_lock_init(&fpriv->sem_handles_lock); ++ idr_init(&fpriv->sem_handles); + + amdgpu_ctx_mgr_init(&fpriv->ctx_mgr); + +@@ -904,6 +906,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev, + struct amdgpu_device *adev = dev->dev_private; + struct amdgpu_fpriv *fpriv = file_priv->driver_priv; + struct amdgpu_bo_list *list; ++ struct amdgpu_sem *sem; + int handle; + + if (!fpriv) +@@ -936,6 +939,10 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev, + idr_destroy(&fpriv->bo_list_handles); + mutex_destroy(&fpriv->bo_list_lock); + ++ idr_for_each_entry(&fpriv->sem_handles, sem, handle) ++ amdgpu_sem_destroy(fpriv, handle); ++ idr_destroy(&fpriv->sem_handles); ++ + kfree(fpriv); + file_priv->driver_priv = NULL; + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.c +index 9fae1ef..d26b23f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.c +@@ -40,31 +40,17 @@ static int amdgpu_sem_cring_add(struct amdgpu_fpriv *fpriv, + struct drm_amdgpu_sem_in *in, + struct amdgpu_sem *sem); + +-static const struct file_operations amdgpu_sem_fops; +- +-static struct amdgpu_sem *amdgpu_sem_alloc(struct dma_fence *fence) ++static void amdgpu_sem_core_free(struct kref *kref) + { +- struct amdgpu_sem *sem; +- +- sem = kzalloc(sizeof(struct amdgpu_sem), GFP_KERNEL); +- if (!sem) +- return NULL; ++ struct amdgpu_sem_core *core = container_of( ++ kref, struct amdgpu_sem_core, kref); + +- sem->file = anon_inode_getfile("sem_file", +- &amdgpu_sem_fops, +- sem, 0); +- if (IS_ERR(sem->file)) +- goto err; ++ if (core->file) ++ fput(core->file); + +- kref_init(&sem->kref); +- INIT_LIST_HEAD(&sem->list); +- /* fence should be get before passing here */ +- sem->fence = fence; +- +- return sem; +-err: +- kfree(sem); +- return NULL; ++ dma_fence_put(core->fence); ++ mutex_destroy(&core->lock); ++ kfree(core); + } + + static void amdgpu_sem_free(struct kref *kref) +@@ -72,15 +58,28 @@ static void amdgpu_sem_free(struct kref *kref) + struct amdgpu_sem *sem = container_of( + kref, struct amdgpu_sem, kref); + +- dma_fence_put(sem->fence); ++ list_del(&sem->list); ++ kref_put(&sem->base->kref, amdgpu_sem_core_free); + kfree(sem); + } + ++static inline void amdgpu_sem_get(struct amdgpu_sem *sem) ++{ ++ if (sem) ++ kref_get(&sem->kref); ++} ++ ++static inline void amdgpu_sem_put(struct amdgpu_sem *sem) ++{ ++ if (sem) ++ kref_put(&sem->kref, amdgpu_sem_free); ++} ++ + static int amdgpu_sem_release(struct inode *inode, struct file *file) + { + struct amdgpu_sem *sem = file->private_data; + +- kref_put(&sem->kref, amdgpu_sem_free); ++ amdgpu_sem_put(sem); + return 0; + } + +@@ -102,49 +101,128 @@ static const struct file_operations amdgpu_sem_fops = { + .compat_ioctl = amdgpu_sem_file_ioctl, + }; + +-static int amdgpu_sem_create(void) ++ ++static inline struct amdgpu_sem *amdgpu_sem_lookup(struct amdgpu_fpriv *fpriv, u32 handle) + { +- return get_unused_fd_flags(O_CLOEXEC); ++ struct amdgpu_sem *sem; ++ ++ spin_lock(&fpriv->sem_handles_lock); ++ ++ /* Check if we currently have a reference on the object */ ++ sem = idr_find(&fpriv->sem_handles, handle); ++ amdgpu_sem_get(sem); ++ ++ spin_unlock(&fpriv->sem_handles_lock); ++ ++ return sem; + } + +-static int amdgpu_sem_signal(int fd, struct dma_fence *fence) ++static struct amdgpu_sem_core *amdgpu_sem_core_alloc(void) ++{ ++ struct amdgpu_sem_core *core; ++ ++ core = kzalloc(sizeof(*core), GFP_KERNEL); ++ if (!core) ++ return NULL; ++ ++ kref_init(&core->kref); ++ mutex_init(&core->lock); ++ return core; ++} ++ ++static struct amdgpu_sem *amdgpu_sem_alloc(void) + { + struct amdgpu_sem *sem; + +- sem = amdgpu_sem_alloc(fence); ++ sem = kzalloc(sizeof(*sem), GFP_KERNEL); + if (!sem) ++ return NULL; ++ ++ kref_init(&sem->kref); ++ INIT_LIST_HEAD(&sem->list); ++ ++ return sem; ++} ++ ++static int amdgpu_sem_create(struct amdgpu_fpriv *fpriv, u32 *handle) ++{ ++ struct amdgpu_sem *sem; ++ struct amdgpu_sem_core *core; ++ int ret; ++ ++ sem = amdgpu_sem_alloc(); ++ core = amdgpu_sem_core_alloc(); ++ if (!sem || !core) { ++ kfree(sem); ++ kfree(core); + return -ENOMEM; +- fd_install(fd, sem->file); ++ } ++ ++ sem->base = core; ++ ++ idr_preload(GFP_KERNEL); ++ spin_lock(&fpriv->sem_handles_lock); ++ ++ ret = idr_alloc(&fpriv->sem_handles, sem, 1, 0, GFP_NOWAIT); ++ ++ spin_unlock(&fpriv->sem_handles_lock); ++ idr_preload_end(); ++ ++ if (ret < 0) ++ return ret; ++ ++ *handle = ret; ++ return 0; ++} ++ ++static int amdgpu_sem_signal(struct amdgpu_fpriv *fpriv, ++ u32 handle, struct dma_fence *fence) ++{ ++ struct amdgpu_sem *sem; ++ struct amdgpu_sem_core *core; ++ ++ sem = amdgpu_sem_lookup(fpriv, handle); ++ if (!sem) ++ return -EINVAL; ++ ++ core = sem->base; ++ mutex_lock(&core->lock); ++ dma_fence_put(core->fence); ++ core->fence = dma_fence_get(fence); ++ mutex_unlock(&core->lock); + ++ amdgpu_sem_put(sem); + return 0; + } + +-static int amdgpu_sem_wait(int fd, struct amdgpu_fpriv *fpriv, ++static int amdgpu_sem_wait(struct amdgpu_fpriv *fpriv, + struct drm_amdgpu_sem_in *in) + { +- struct file *file = fget(fd); + struct amdgpu_sem *sem; +- int r; ++ int ret; + +- if (!file) ++ sem = amdgpu_sem_lookup(fpriv, in->handle); ++ if (!sem) + return -EINVAL; + +- sem = file->private_data; +- if (!sem) { +- r = -EINVAL; +- goto err; +- } +- r = amdgpu_sem_cring_add(fpriv, in, sem); +-err: +- fput(file); +- return r; ++ ret = amdgpu_sem_cring_add(fpriv, in, sem); ++ amdgpu_sem_put(sem); ++ ++ return ret; + } + +-static void amdgpu_sem_destroy(void) ++void amdgpu_sem_destroy(struct amdgpu_fpriv *fpriv, u32 handle) + { +- /* userspace should close fd when they try to destroy sem, +- * closing fd will free semaphore object. +- */ ++ struct amdgpu_sem *sem = amdgpu_sem_lookup(fpriv, handle); ++ if (!sem) ++ return; ++ ++ spin_lock(&fpriv->sem_handles_lock); ++ idr_remove(&fpriv->sem_handles, handle); ++ spin_unlock(&fpriv->sem_handles_lock); ++ ++ kref_put(&sem->kref, amdgpu_sem_free); ++ kref_put(&sem->kref, amdgpu_sem_free); + } + + static struct dma_fence *amdgpu_sem_get_fence(struct amdgpu_fpriv *fpriv, +@@ -219,12 +297,14 @@ int amdgpu_sem_add_cs(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, + mutex_lock(&ctx->rings[ring->idx].sem_lock); + list_for_each_entry_safe(sem, tmp, &ctx->rings[ring->idx].sem_list, + list) { +- r = amdgpu_sync_fence(ctx->adev, sync, sem->fence); +- dma_fence_put(sem->fence); ++ r = amdgpu_sync_fence(ctx->adev, sync, sem->base->fence); + if (r) + goto err; +- list_del(&sem->list); +- kfree(sem); ++ mutex_lock(&sem->base->lock); ++ dma_fence_put(sem->base->fence); ++ sem->base->fence = NULL; ++ mutex_unlock(&sem->base->lock); ++ list_del_init(&sem->list); + } + err: + mutex_unlock(&ctx->rings[ring->idx].sem_lock); +@@ -238,14 +318,13 @@ int amdgpu_sem_ioctl(struct drm_device *dev, void *data, + struct amdgpu_fpriv *fpriv = filp->driver_priv; + struct dma_fence *fence; + int r = 0; +- int fd = args->in.fd; + + switch (args->in.op) { + case AMDGPU_SEM_OP_CREATE_SEM: +- args->out.fd = amdgpu_sem_create(); ++ r = amdgpu_sem_create(fpriv, &args->out.handle); + break; + case AMDGPU_SEM_OP_WAIT_SEM: +- r = amdgpu_sem_wait(fd, fpriv, &args->in); ++ r = amdgpu_sem_wait(fpriv, &args->in); + break; + case AMDGPU_SEM_OP_SIGNAL_SEM: + fence = amdgpu_sem_get_fence(fpriv, &args->in); +@@ -253,14 +332,15 @@ int amdgpu_sem_ioctl(struct drm_device *dev, void *data, + r = PTR_ERR(fence); + return r; + } +- r = amdgpu_sem_signal(fd, fence); ++ r = amdgpu_sem_signal(fpriv, args->in.handle, fence); + dma_fence_put(fence); + break; + case AMDGPU_SEM_OP_DESTROY_SEM: +- amdgpu_sem_destroy(); ++ amdgpu_sem_destroy(fpriv, args->in.handle); + break; + default: +- return -EINVAL; ++ r = -EINVAL; ++ break; + } + + return r; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.h +index 10ec58e..40854ff 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sem.h +@@ -34,10 +34,16 @@ + #include <linux/spinlock.h> + #include <linux/dma-fence.h> + +-struct amdgpu_sem { ++struct amdgpu_sem_core { + struct file *file; + struct kref kref; +- struct dam_fence *fence; ++ struct dma_fence *fence; ++ struct mutex lock; ++}; ++ ++struct amdgpu_sem { ++ struct amdgpu_sem_core *base; ++ struct kref kref; + struct list_head list; + }; + +-- +2.7.4 + |