msm: kgsl: Add a work item for processing expired timestamps
Add a work item to be triggered following a RB complete interrupt
signifying that a timestamp has been processed and retired on
the GPU. To kick things off, this work item is the the new home
for flushing expired memory objects allowing us to get rid of
kgsl_memqueue_drain and its various offspring.
Change-Id: Ic0dedbad853291ae5d05247241f449a7b523e318
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index 8a7ab35..064b05e 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1520,6 +1520,7 @@
if (status & (CP_INT_CNTL__IB1_INT_MASK | CP_INT_CNTL__RB_INT_MASK)) {
KGSL_CMD_WARN(rb->device, "ringbuffer ib1/rb interrupt\n");
+ queue_work(device->work_queue, &device->ts_expired_ws);
wake_up_interruptible_all(&device->wait_queue);
atomic_notifier_call_chain(&(device->ts_notifier_list),
device->id,
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index e146ab8..165bbbf 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -180,35 +180,28 @@
list_add_tail(&entry->list, &device->memqueue);
}
-static void kgsl_memqueue_drain(struct kgsl_device *device)
+static void kgsl_timestamp_expired(struct work_struct *work)
{
+ struct kgsl_device *device = container_of(work, struct kgsl_device,
+ ts_expired_ws);
struct kgsl_mem_entry *entry, *entry_tmp;
uint32_t ts_processed;
- BUG_ON(!mutex_is_locked(&device->mutex));
+ mutex_lock(&device->mutex);
/* get current EOP timestamp */
ts_processed = device->ftbl->readtimestamp(device,
KGSL_TIMESTAMP_RETIRED);
+ /* Flush the freememontimestamp queue */
list_for_each_entry_safe(entry, entry_tmp, &device->memqueue, list) {
- KGSL_MEM_INFO(device,
- "ts_processed %d ts_free %d gpuaddr %x)\n",
- ts_processed, entry->free_timestamp,
- entry->memdesc.gpuaddr);
if (!timestamp_cmp(ts_processed, entry->free_timestamp))
break;
list_del(&entry->list);
kgsl_mem_entry_put(entry);
}
-}
-static void kgsl_memqueue_drain_unlocked(struct kgsl_device *device)
-{
- mutex_lock(&device->mutex);
- kgsl_check_suspended(device);
- kgsl_memqueue_drain(device);
mutex_unlock(&device->mutex);
}
@@ -771,8 +764,6 @@
param->timestamp,
param->timeout);
- kgsl_memqueue_drain(dev_priv->device);
-
/* Fire off any pending suspend operations that are in flight */
INIT_COMPLETION(dev_priv->device->suspend_gate);
@@ -950,7 +941,6 @@
if (entry) {
kgsl_memqueue_freememontimestamp(dev_priv->device, entry,
param->timestamp, param->type);
- kgsl_memqueue_drain(dev_priv->device);
} else {
KGSL_DRV_ERR(dev_priv->device,
"invalid gpuaddr %08x\n", param->gpuaddr);
@@ -1062,9 +1052,6 @@
if (!kgsl_mmu_enabled())
return -ENODEV;
- /* Make sure all pending freed memory is collected */
- kgsl_memqueue_drain_unlocked(dev_priv->device);
-
if (!param->hostptr) {
KGSL_CORE_ERR("invalid hostptr %x\n", param->hostptr);
result = -EINVAL;
@@ -1383,8 +1370,6 @@
if (entry == NULL)
return -ENOMEM;
- kgsl_memqueue_drain_unlocked(dev_priv->device);
-
if (_IOC_SIZE(cmd) == sizeof(struct kgsl_sharedmem_from_pmem))
memtype = KGSL_USER_MEM_TYPE_PMEM;
else
@@ -1524,9 +1509,6 @@
if (entry == NULL)
return -ENOMEM;
- /* Make sure all pending freed memory is collected */
- kgsl_memqueue_drain_unlocked(dev_priv->device);
-
result = kgsl_allocate_user(&entry->memdesc, private->pagetable,
param->size, param->flags);
@@ -1914,6 +1896,7 @@
goto err_devlist;
INIT_WORK(&device->idle_check_ws, kgsl_idle_check);
+ INIT_WORK(&device->ts_expired_ws, kgsl_timestamp_expired);
INIT_LIST_HEAD(&device->memqueue);
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 10e345a..2f369ed 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -165,6 +165,7 @@
struct kgsl_pwrscale pwrscale;
struct kobject pwrscale_kobj;
struct pm_qos_request_list pm_qos_req_dma;
+ struct work_struct ts_expired_ws;
};
struct kgsl_context {
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index a81eeaa..61a3edb 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -234,6 +234,7 @@
count &= 255;
z180_dev->timestamp += count;
+ queue_work(device->work_queue, &device->ts_expired_ws);
wake_up_interruptible(&device->wait_queue);
atomic_notifier_call_chain(