Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 92d5ded7 authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Relax timestamp comparisons for processing events



When processing an event group we check the previously processed
timestamp to avoid going through the loop if we don't need to.
We use timestamp_cmp() to check the timestamp. In situations
where the retired timestamp has advanced by more than 0x80000000
since the last time we checked the timestamp, timestamp_cmp()
will return -1 as it thinks that the new timestamp is older than
the processed timestamp. This can happen with certain tests and
scheduling hiccups.

The event processor can be much less restrictive - all we really
care about is that the retired timestamp didn't slip backwards by
accident (highly unlikely). So just check that the last proccessed
timestamp is not equal to the retired timestamp and if the
retired timestamp has already rolled, that the delta is outside
of the 0x8000000 window.

Change-Id: Ic0dedbad641bfa3fd6cbc1c91a37fb0e37f72bae
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent ee76770e
Loading
Loading
Loading
Loading
+19 −6
Original line number Diff line number Diff line
/* 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
@@ -56,6 +56,23 @@ static void _kgsl_event_worker(struct work_struct *work)
	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)
{
@@ -80,11 +97,7 @@ static void _process_event_group(struct kgsl_device *device,
	group->readtimestamp(device, group->priv, KGSL_TIMESTAMP_RETIRED,
		&timestamp);

	/*
	 * 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) {