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

Commit ddbef40a authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

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

parents cae2be6e 65e208cf
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;