mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 15:11:48 -04:00
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: Deepak Kumar <dkumar@codeaurora.org>
This commit is contained in:
parent
c76c741a86
commit
65e208cf89
1 changed files with 32 additions and 5 deletions
|
|
@ -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 @@ done:
|
|||
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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue