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

Commit 69595f9a authored by Tarun Karra's avatar Tarun Karra
Browse files

msm: kgsl: Prevent device start after it is already started



Check if device is already started in high priority workqueue thread,
this check prevents calling device start after it is already started,
thereby avoiding unpredictable behavior.

Change-Id: Iffcd065f8c02746d168c8e5779d10d4b0e2404a9
Signed-off-by: default avatarTarun Karra <tkarra@codeaurora.org>
parent 012fce15
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -1861,6 +1861,8 @@ static int _adreno_start(struct adreno_device *adreno_dev)

	device->reset_counter++;

	set_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv);

	return 0;

error_rb_stop:
@@ -1898,7 +1900,25 @@ static void adreno_start_work(struct work_struct *work)
	set_user_nice(current, _wake_nice);

	mutex_lock(&device->mutex);
	/*
	 *  If adreno start is already called, no need to call it again
	 *  it can lead to unpredictable behavior if we try to start
	 *  the device that is already started.
	 *  Below is the sequence of events that can go bad without the check
	 *  1) thread 1 calls adreno_start to be scheduled on high priority wq
	 *  2) thread 2 calls adreno_start with normal priority
	 *  3) thread 1 after checking the device to be in slumber state gives
	 *     up mutex to be scheduled on high priority wq
	 *  4) thread 2 after checking the device to be in slumber state gets
	 *     the mutex and finishes adreno_start before thread 1 is scheduled
	 *     on high priority wq.
	 *  5) thread 1 gets scheduled on high priority wq and executes
	 *     adreno_start again. This leads to unpredictable behavior.
	 */
	if (!test_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv))
		_status = _adreno_start(adreno_dev);
	else
		_status = 0;
	mutex_unlock(&device->mutex);
}

@@ -1962,6 +1982,8 @@ static int adreno_stop(struct kgsl_device *device)

	kgsl_cffdump_close(device);

	clear_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv);

	return 0;
}

+1 −0
Original line number Diff line number Diff line
@@ -206,6 +206,7 @@ enum adreno_device_flags {
	ADRENO_DEVICE_INITIALIZED = 2,
	ADRENO_DEVICE_CORESIGHT = 3,
	ADRENO_DEVICE_HANG_INTR = 4,
	ADRENO_DEVICE_STARTED = 5,
};

#define PERFCOUNTER_FLAG_NONE 0x0