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

Commit 65e208cf authored by Deepak Kumar's avatar Deepak Kumar
Browse files

msm: kgsl: Retry process private open in a special failure case



Currently, process private open/kgsl_open fails in case same pid
previous process private refcount is zero but destroy didn't
complete yet. In this failure case, as we are sure that destroy
is triggered and just pending to finish, retry process private
open again after some delay to ensure process private open is
successful.

Change-Id: I7cd8a2b7d64d9472121ffa8633d0621923f5ec89
Signed-off-by: default avatarDeepak Kumar <dkumar@codeaurora.org>
parent c76c741a
Loading
Loading
Loading
Loading
+32 −5
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
#include <uapi/linux/sched/types.h>
#include <linux/ctype.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/dma-buf.h>
#include <linux/fdtable.h>
#include <linux/io.h>
@@ -933,9 +934,15 @@ static struct kgsl_process_private *kgsl_process_private_new(
	/* Search in the process list */
	list_for_each_entry(private, &kgsl_driver.process_list, list) {
		if (private->pid == cur_pid) {
			if (!kgsl_process_private_get(private)) {
				private = ERR_PTR(-EINVAL);
			}
			if (!kgsl_process_private_get(private))
				/*
				 * This will happen only if refcount is zero
				 * i.e. destroy is triggered but didn't complete
				 * yet. Return -EEXIST to indicate caller that
				 * destroy is pending to allow caller to take
				 * appropriate action.
				 */
				private = ERR_PTR(-EEXIST);
			/*
			 * We need to hold only one reference to the PID for
			 * each process struct to avoid overflowing the
@@ -1043,8 +1050,7 @@ static void kgsl_process_private_close(struct kgsl_device_private *dev_priv,
	kgsl_process_private_put(private);
}


static struct kgsl_process_private *kgsl_process_private_open(
static struct kgsl_process_private *_process_private_open(
		struct kgsl_device *device)
{
	struct kgsl_process_private *private;
@@ -1062,6 +1068,27 @@ static struct kgsl_process_private *kgsl_process_private_open(
	return private;
}

static struct kgsl_process_private *kgsl_process_private_open(
		struct kgsl_device *device)
{
	struct kgsl_process_private *private;
	int i;

	private = _process_private_open(device);

	/*
	 * If we get error and error is -EEXIST that means previous process
	 * private destroy is triggered but didn't complete. Retry creating
	 * process private after sometime to allow previous destroy to complete.
	 */
	for (i = 0; (PTR_ERR_OR_ZERO(private) == -EEXIST) && (i < 5); i++) {
		usleep_range(10, 100);
		private = _process_private_open(device);
	}

	return private;
}

int kgsl_gpu_frame_count(pid_t pid, u64 *frame_count)
{
	struct kgsl_process_private *p;