Scheduling issues were occurring with the GPU event worker after
b7be807 (msm: kgsl: Unbind the kgsl-event workqueue) was merged.
In certain conditions, it seems that the kgsl-event workqueue
was conflicting with the KGSL worker and slowing it down.
It turns out that everywhere we schedule the event worker
and the dispatcher worker at the same time. Since the worker
is singlethread, the event worker and the dispatcher run
synchronously anyway, so it makes sense to run the event processor
from within the dispatcher and save the extra schedule.
CRs-Fixed:
1043509
Change-Id: Ic0dedbad67eb04d41afb6add4477f146dfff9784
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
- kgsl_schedule_work(&device->event_work);
adreno_dispatcher_schedule(device);
}
mutex_unlock(&device->mutex);
/* Reschedule just to make sure everything retires */
- kgsl_schedule_work(&device->event_work);
adreno_dispatcher_schedule(device);
}
}
a5xx_preemption_trigger(adreno_dev);
-
- kgsl_schedule_work(&device->event_work);
adreno_dispatcher_schedule(device);
}
break;
}
+ kgsl_process_event_groups(device);
+
/*
* dispatcher_do_fault() returns 0 if no faults occurred. If that is the
* case, then clean up preemption and try to schedule more work
*/
if (dispatcher_do_fault(adreno_dev) == 0) {
+
/* Clean up after preemption */
if (gpudev->preemption_schedule)
gpudev->preemption_schedule(adreno_dev);
- /* Re-kick the event engine to catch stragglers */
- if (dispatcher->inflight == 0 && count != 0)
- kgsl_schedule_work(&device->event_work);
-
/* Run the scheduler for to dispatch new commands */
_adreno_dispatcher_issuecmds(adreno_dev);
}
PM_QOS_DEFAULT_VALUE);
}
-
- device->events_wq = create_singlethread_workqueue("kgsl-events");
+ device->events_wq = alloc_workqueue("kgsl-events",
+ WQ_UNBOUND | WQ_MEM_RECLAIM, 0);
/* Initalize the snapshot engine */
kgsl_device_snapshot_init(device);
int mem_log;
int pwr_log;
struct kgsl_pwrscale pwrscale;
- struct work_struct event_work;
int reset_counter; /* Track how many GPU core resets have occured */
int cff_dump_enable;
.cmdbatch_gate = COMPLETION_INITIALIZER((_dev).cmdbatch_gate),\
.idle_check_ws = __WORK_INITIALIZER((_dev).idle_check_ws,\
kgsl_idle_check),\
- .event_work = __WORK_INITIALIZER((_dev).event_work,\
- kgsl_process_events),\
.context_idr = IDR_INIT((_dev).context_idr),\
.wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).wait_queue),\
.active_cnt_wq = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).active_cnt_wq),\
struct kgsl_event_group *group);
void kgsl_flush_event_group(struct kgsl_device *device,
struct kgsl_event_group *group);
-void kgsl_process_events(struct work_struct *work);
+void kgsl_process_event_groups(struct kgsl_device *device);
void kgsl_context_destroy(struct kref *kref);
static DEFINE_RWLOCK(group_lock);
static LIST_HEAD(group_list);
-/**
- * kgsl_process_events() - Work queue for processing new timestamp events
- * @work: Pointer to a work_struct
- */
-void kgsl_process_events(struct work_struct *work)
+void kgsl_process_event_groups(struct kgsl_device *device)
{
struct kgsl_event_group *group;
- struct kgsl_device *device = container_of(work, struct kgsl_device,
- event_work);
read_lock(&group_lock);
list_for_each_entry(group, &group_list, group)
_process_event_group(device, group, false);
read_unlock(&group_lock);
}
-EXPORT_SYMBOL(kgsl_process_events);
+EXPORT_SYMBOL(kgsl_process_event_groups);
/**
* kgsl_del_event_group() - Remove a GPU event group