diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 36d218ff2b21..413614ac4b53 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -483,7 +483,7 @@ struct fastrpc_file { /* To indicate attempt has been made to allocate memory for debug_buf */ int debug_buf_alloced_attempted; /* Flag to indicate dynamic process creation status*/ - bool in_process_create; + enum fastrpc_process_create_state dsp_process_state; struct completion shutdown; }; @@ -2538,7 +2538,7 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl, int locked); static int fastrpc_init_process(struct fastrpc_file *fl, struct fastrpc_ioctl_init_attrs *uproc) { - int err = 0, rh_hyp_done = 0; + int err = 0, rh_hyp_done = 0, locked = 0; struct fastrpc_apps *me = &gfa; struct fastrpc_ioctl_invoke_crc ioctl; struct fastrpc_ioctl_init *init = &uproc->init; @@ -2552,6 +2552,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl, int unsigned_request = proc_attrs && init_flags; int cid = fl->cid; struct fastrpc_channel_ctx *chan = &me->channel[cid]; + struct fastrpc_buf *init_mem; if (chan->unsigned_support && fl->dev_minor == MINOR_NUM_DEV) { @@ -2617,13 +2618,13 @@ static int fastrpc_init_process(struct fastrpc_file *fl, } inbuf; spin_lock(&fl->hlock); - if (fl->in_process_create) { + if (fl->dsp_process_state) { err = -EALREADY; pr_err("Already in create init process\n"); spin_unlock(&fl->hlock); return err; } - fl->in_process_create = true; + fl->dsp_process_state = PROCESS_CREATE_IS_INPROGRESS; spin_unlock(&fl->hlock); inbuf.pgid = fl->tgid; inbuf.namelen = strlen(current->comm) + 1; @@ -2832,20 +2833,27 @@ bail: fastrpc_mmap_free(mem, 0); mutex_unlock(&fl->map_mutex); } - if (err) { - if (!IS_ERR_OR_NULL(fl->init_mem)) { - fastrpc_buf_free(fl->init_mem, 0); - fl->init_mem = NULL; - } - } if (file) { mutex_lock(&fl->map_mutex); fastrpc_mmap_free(file, 0); mutex_unlock(&fl->map_mutex); } - if (init->flags == FASTRPC_INIT_CREATE) { - spin_lock(&fl->hlock); - fl->in_process_create = false; + spin_lock(&fl->hlock); + locked = 1; + if (err) { + fl->dsp_process_state = PROCESS_CREATE_DEFAULT; + if (!IS_ERR_OR_NULL(fl->init_mem)) { + init_mem = fl->init_mem; + fl->init_mem = NULL; + locked = 0; + spin_unlock(&fl->hlock); + fastrpc_buf_free(init_mem, 0); + } + } else { + fl->dsp_process_state = PROCESS_CREATE_SUCCESS; + } + if (locked) { + locked = 0; spin_unlock(&fl->hlock); } return err; @@ -3811,7 +3819,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl) } spin_lock(&fl->hlock); fl->file_close = 1; - fl->in_process_create = false; + fl->dsp_process_state = PROCESS_CREATE_DEFAULT; spin_unlock(&fl->hlock); if (!IS_ERR_OR_NULL(fl->init_mem)) fastrpc_buf_free(fl->init_mem, 0); @@ -4213,7 +4221,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fl->cid = -1; fl->dev_minor = dev_minor; fl->init_mem = NULL; - fl->in_process_create = false; + fl->dsp_process_state = PROCESS_CREATE_DEFAULT; memset(&fl->perf, 0, sizeof(fl->perf)); fl->qos_request = 0; fl->dsp_proc_init = 0; diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h index 7785b8446cd6..d726a0e1664d 100644 --- a/drivers/char/adsprpc_shared.h +++ b/drivers/char/adsprpc_shared.h @@ -319,6 +319,15 @@ struct smq_invoke_rsp { int retval; /* invoke return value */ }; +enum fastrpc_process_create_state { + /* Process is not created */ + PROCESS_CREATE_DEFAULT = 0, + /* Process creation is in progress */ + PROCESS_CREATE_IS_INPROGRESS = 1, + /* Process creation is successful */ + PROCESS_CREATE_SUCCESS = 2, +}; + enum fastrpc_response_flags { NORMAL_RESPONSE = 0, EARLY_RESPONSE = 1,