diff options
Diffstat (limited to 'drivers/gpu/msm/kgsl.c')
-rw-r--r-- | drivers/gpu/msm/kgsl.c | 58 |
1 files changed, 28 insertions, 30 deletions
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index b2def8dea954..afb489f10172 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -255,13 +255,6 @@ static void _deferred_put(struct work_struct *work) kgsl_mem_entry_put(entry); } -static inline void -kgsl_mem_entry_put_deferred(struct kgsl_mem_entry *entry) -{ - if (entry) - queue_work(kgsl_driver.mem_workqueue, &entry->work); -} - static inline struct kgsl_mem_entry * kgsl_mem_entry_create(void) { @@ -272,7 +265,6 @@ kgsl_mem_entry_create(void) /* put this ref in the caller functions after init */ kref_get(&entry->refcount); - INIT_WORK(&entry->work, _deferred_put); } return entry; } @@ -1869,7 +1861,7 @@ long kgsl_ioctl_sharedmem_free(struct kgsl_device_private *dev_priv, return -EINVAL; ret = gpumem_free_entry(entry); - kgsl_mem_entry_put_deferred(entry); + kgsl_mem_entry_put(entry); return ret; } @@ -1887,7 +1879,7 @@ long kgsl_ioctl_gpumem_free_id(struct kgsl_device_private *dev_priv, return -EINVAL; ret = gpumem_free_entry(entry); - kgsl_mem_entry_put_deferred(entry); + kgsl_mem_entry_put(entry); return ret; } @@ -1924,7 +1916,8 @@ static void gpuobj_free_fence_func(void *priv) { struct kgsl_mem_entry *entry = priv; - kgsl_mem_entry_put_deferred(entry); + INIT_WORK(&entry->work, _deferred_put); + queue_work(kgsl_driver.mem_workqueue, &entry->work); } static long gpuobj_free_on_fence(struct kgsl_device_private *dev_priv, @@ -1988,7 +1981,7 @@ long kgsl_ioctl_gpuobj_free(struct kgsl_device_private *dev_priv, else ret = -EINVAL; - kgsl_mem_entry_put_deferred(entry); + kgsl_mem_entry_put(entry); return ret; } @@ -2217,21 +2210,23 @@ static int kgsl_setup_dmabuf_useraddr(struct kgsl_device *device, if (fd != 0) dmabuf = dma_buf_get(fd - 1); } - up_read(¤t->mm->mmap_sem); - if (IS_ERR_OR_NULL(dmabuf)) + if (IS_ERR_OR_NULL(dmabuf)) { + up_read(¤t->mm->mmap_sem); return dmabuf ? PTR_ERR(dmabuf) : -ENODEV; + } ret = kgsl_setup_dma_buf(device, pagetable, entry, dmabuf); if (ret) { dma_buf_put(dmabuf); + up_read(¤t->mm->mmap_sem); return ret; } /* Setup the user addr/cache mode for cache operations */ entry->memdesc.useraddr = hostptr; _setup_cache_mode(entry, vma); - + up_read(¤t->mm->mmap_sem); return 0; } #else @@ -3363,13 +3358,7 @@ long kgsl_ioctl_sparse_phys_free(struct kgsl_device_private *dev_priv, if (entry == NULL) return -EINVAL; - if (!kgsl_mem_entry_set_pend(entry)) { - kgsl_mem_entry_put(entry); - return -EBUSY; - } - if (entry->memdesc.cur_bindings != 0) { - kgsl_mem_entry_unset_pend(entry); kgsl_mem_entry_put(entry); return -EINVAL; } @@ -3378,7 +3367,7 @@ long kgsl_ioctl_sparse_phys_free(struct kgsl_device_private *dev_priv, /* One put for find_id(), one put for the kgsl_mem_entry_create() */ kgsl_mem_entry_put(entry); - kgsl_mem_entry_put_deferred(entry); + kgsl_mem_entry_put(entry); return 0; } @@ -3438,13 +3427,7 @@ long kgsl_ioctl_sparse_virt_free(struct kgsl_device_private *dev_priv, if (entry == NULL) return -EINVAL; - if (!kgsl_mem_entry_set_pend(entry)) { - kgsl_mem_entry_put(entry); - return -EBUSY; - } - if (entry->bind_tree.rb_node != NULL) { - kgsl_mem_entry_unset_pend(entry); kgsl_mem_entry_put(entry); return -EINVAL; } @@ -3453,7 +3436,7 @@ long kgsl_ioctl_sparse_virt_free(struct kgsl_device_private *dev_priv, /* One put for find_id(), one put for the kgsl_mem_entry_create() */ kgsl_mem_entry_put(entry); - kgsl_mem_entry_put_deferred(entry); + kgsl_mem_entry_put(entry); return 0; } @@ -4719,6 +4702,7 @@ int kgsl_device_platform_probe(struct kgsl_device *device) device->id, device->reg_phys, device->reg_len); rwlock_init(&device->context_lock); + spin_lock_init(&device->submit_lock); setup_timer(&device->idle_timer, kgsl_timer, (unsigned long) device); @@ -4863,6 +4847,8 @@ static void kgsl_core_exit(void) static int __init kgsl_core_init(void) { int result = 0; + struct sched_param param = { .sched_priority = 2 }; + /* alloc major and minor device numbers */ result = alloc_chrdev_region(&kgsl_driver.major, 0, KGSL_DEVICE_MAX, "kgsl"); @@ -4926,7 +4912,19 @@ static int __init kgsl_core_init(void) WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS, 0); kgsl_driver.mem_workqueue = alloc_workqueue("kgsl-mementry", - WQ_MEM_RECLAIM, 0); + WQ_UNBOUND | WQ_MEM_RECLAIM, 0); + + init_kthread_worker(&kgsl_driver.worker); + + kgsl_driver.worker_thread = kthread_run(kthread_worker_fn, + &kgsl_driver.worker, "kgsl_worker_thread"); + + if (IS_ERR(kgsl_driver.worker_thread)) { + pr_err("unable to start kgsl thread\n"); + goto err; + } + + sched_setscheduler(kgsl_driver.worker_thread, SCHED_FIFO, ¶m); kgsl_events_init(); |