-/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
kmem_cache_free(events_cache, event);
}
+/* return true if the group needs to be processed */
+static bool _do_process_group(unsigned int processed, unsigned int cur)
+{
+ if (processed == cur)
+ return false;
+
+ /*
+ * This ensures that the timestamp didn't slip back accidently, maybe
+ * due to a memory barrier issue. This is highly unlikely but we've
+ * been burned here in the past.
+ */
+ if ((cur < processed) && ((processed - cur) < KGSL_TIMESTAMP_WINDOW))
+ return false;
+
+ return true;
+}
+
static void _process_event_group(struct kgsl_device *device,
struct kgsl_event_group *group, bool flush)
{
group->readtimestamp(device, group->priv, KGSL_TIMESTAMP_RETIRED,
×tamp);
- /*
- * If no timestamps have been retired since the last time we were here
- * then we can avoid going through this loop
- */
- if (!flush && timestamp_cmp(timestamp, group->processed) <= 0)
+ if (!flush && _do_process_group(group->processed, timestamp) == false)
goto out;
list_for_each_entry_safe(event, tmp, &group->events, node) {