msm: adsprpc: vote for CPU to stay awake during RPC call
Vote with PM for CPU to stay awake while processing RPC call and to relax when waiting for response from remote subsystem. Print error if the maximum remote session concurrency is hit. Change-Id: Iabf43fbc53f8799e4d446335f1c0cae80d27491f Acked-by: Thyagarajan Venkatanarayanan <venkatan@qti.qualcomm.com> Signed-off-by: Tharun Kumar Merugu <mtharu@codeaurora.org> Signed-off-by: Mohammed Nayeem Ur Rahman <mohara@codeaurora.org> Signed-off-by: UtsavBalar1231 <utsavbalar1231@gmail.com>
This commit is contained in:
committed by
UtsavBalar1231
parent
567ff07630
commit
223369bb8e
@@ -225,6 +225,7 @@ struct smq_invoke_ctx {
|
||||
struct fastrpc_buf *lbuf;
|
||||
size_t used;
|
||||
struct fastrpc_file *fl;
|
||||
uint32_t handle;
|
||||
uint32_t sc;
|
||||
struct overlap *overs;
|
||||
struct overlap **overps;
|
||||
@@ -310,6 +311,8 @@ struct fastrpc_apps {
|
||||
spinlock_t ctxlock;
|
||||
struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX];
|
||||
bool legacy_remote_heap;
|
||||
struct wakeup_source *wake_source;
|
||||
unsigned int wake_count;
|
||||
};
|
||||
|
||||
struct fastrpc_mmap {
|
||||
@@ -391,6 +394,8 @@ struct fastrpc_file {
|
||||
/* Identifies the device (MINOR_NUM_DEV / MINOR_NUM_SECURE_DEV) */
|
||||
int dev_minor;
|
||||
char *debug_buf;
|
||||
/* Flag to enable PM wake/relax voting for every remote invoke */
|
||||
int wake_enable;
|
||||
};
|
||||
|
||||
static struct fastrpc_apps gfa;
|
||||
@@ -1228,6 +1233,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
|
||||
goto bail;
|
||||
}
|
||||
ctx->crc = (uint32_t *)invokefd->crc;
|
||||
ctx->handle = invoke->handle;
|
||||
ctx->sc = invoke->sc;
|
||||
if (bufs) {
|
||||
VERIFY(err, 0 == context_build_overlap(ctx));
|
||||
@@ -1907,7 +1913,36 @@ static void fastrpc_init(struct fastrpc_apps *me)
|
||||
me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL;
|
||||
}
|
||||
|
||||
static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl);
|
||||
static inline void fastrpc_pm_awake(int fl_wake_enable, int *wake_enable)
|
||||
{
|
||||
struct fastrpc_apps *me = &gfa;
|
||||
|
||||
if (!fl_wake_enable)
|
||||
return;
|
||||
|
||||
spin_lock(&me->hlock);
|
||||
if (!me->wake_count)
|
||||
__pm_stay_awake(me->wake_source);
|
||||
me->wake_count++;
|
||||
spin_unlock(&me->hlock);
|
||||
*wake_enable = 1;
|
||||
}
|
||||
|
||||
static inline void fastrpc_pm_relax(int *wake_enable)
|
||||
{
|
||||
struct fastrpc_apps *me = &gfa;
|
||||
|
||||
if (!(*wake_enable))
|
||||
return;
|
||||
|
||||
spin_lock(&me->hlock);
|
||||
if (me->wake_count)
|
||||
me->wake_count--;
|
||||
if (!me->wake_count)
|
||||
__pm_relax(me->wake_source);
|
||||
spin_unlock(&me->hlock);
|
||||
*wake_enable = 0;
|
||||
}
|
||||
|
||||
static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
|
||||
uint32_t kernel,
|
||||
@@ -1916,6 +1951,7 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
|
||||
struct smq_invoke_ctx *ctx = NULL;
|
||||
struct fastrpc_ioctl_invoke *invoke = &inv->inv;
|
||||
int err = 0, cid = -1, interrupted = 0;
|
||||
int wake_enable = 0;
|
||||
struct timespec invoket = {0};
|
||||
int64_t *perf_counter = NULL;
|
||||
|
||||
@@ -1932,6 +1968,7 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
|
||||
}
|
||||
perf_counter = getperfcounter(fl, PERF_COUNT);
|
||||
|
||||
fastrpc_pm_awake(fl->wake_enable, &wake_enable);
|
||||
if (fl->profile)
|
||||
getnstimeofday(&invoket);
|
||||
|
||||
@@ -1982,14 +2019,15 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
|
||||
if (err)
|
||||
goto bail;
|
||||
wait:
|
||||
fastrpc_pm_relax(&wake_enable);
|
||||
if (kernel)
|
||||
wait_for_completion(&ctx->work);
|
||||
else {
|
||||
else
|
||||
interrupted = wait_for_completion_interruptible(&ctx->work);
|
||||
VERIFY(err, 0 == (err = interrupted));
|
||||
if (err)
|
||||
goto bail;
|
||||
}
|
||||
fastrpc_pm_awake(fl->wake_enable, &wake_enable);
|
||||
VERIFY(err, 0 == (err = interrupted));
|
||||
if (err)
|
||||
goto bail;
|
||||
|
||||
PERF(fl->profile, GET_COUNTER(perf_counter, PERF_INVARGS),
|
||||
if (!fl->sctx->smmu.coherent)
|
||||
@@ -2027,6 +2065,7 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
|
||||
*count = *count+1;
|
||||
}
|
||||
}
|
||||
fastrpc_pm_relax(&wake_enable);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -2808,9 +2847,12 @@ static int fastrpc_session_alloc_locked(struct fastrpc_channel_ctx *chan,
|
||||
break;
|
||||
}
|
||||
}
|
||||
VERIFY(err, idx < chan->sesscount);
|
||||
if (err)
|
||||
if (idx >= chan->sesscount) {
|
||||
err = -EUSERS;
|
||||
pr_err("adsprpc: ERROR %d: %s: max concurrent sessions limit (%d) already reached on %s\n",
|
||||
err, __func__, chan->sesscount, chan->subsys);
|
||||
goto bail;
|
||||
}
|
||||
chan->session[idx].smmu.faults = 0;
|
||||
} else {
|
||||
VERIFY(err, me->dev != NULL);
|
||||
@@ -3265,7 +3307,7 @@ static int fastrpc_channel_open(struct fastrpc_file *fl)
|
||||
|
||||
VERIFY(err, fl && fl->sctx && fl->cid >= 0 && fl->cid < NUM_CHANNELS);
|
||||
if (err) {
|
||||
pr_err("adsprpc: ERROR: %s: user application %s domain is not set\n",
|
||||
pr_err("adsprpc: ERROR: %s: kernel session not initialized yet for %s\n",
|
||||
__func__, current->comm);
|
||||
err = -EBADR;
|
||||
return err;
|
||||
@@ -3423,8 +3465,8 @@ static int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info)
|
||||
fl->cid = cid;
|
||||
fl->ssrcount = fl->apps->channel[cid].ssrcount;
|
||||
mutex_lock(&fl->apps->channel[cid].smd_mutex);
|
||||
VERIFY(err, !fastrpc_session_alloc_locked(
|
||||
&fl->apps->channel[cid], 0, &fl->sctx));
|
||||
err = fastrpc_session_alloc_locked(&fl->apps->channel[cid],
|
||||
0, &fl->sctx);
|
||||
mutex_unlock(&fl->apps->channel[cid].smd_mutex);
|
||||
if (err)
|
||||
goto bail;
|
||||
@@ -3467,8 +3509,11 @@ static int fastrpc_internal_control(struct fastrpc_file *fl,
|
||||
case FASTRPC_CONTROL_KALLOC:
|
||||
cp->kalloc.kalloc_support = 1;
|
||||
break;
|
||||
case FASTRPC_CONTROL_WAKELOCK:
|
||||
fl->wake_enable = cp->wp.enable;
|
||||
break;
|
||||
default:
|
||||
err = -ENOTTY;
|
||||
err = -EBADRQC;
|
||||
break;
|
||||
}
|
||||
bail:
|
||||
@@ -4385,11 +4430,19 @@ static int __init fastrpc_device_init(void)
|
||||
|
||||
err = register_rpmsg_driver(&fastrpc_rpmsg_client);
|
||||
if (err) {
|
||||
pr_err("adsprpc: register_rpmsg_driver: failed with err %d\n",
|
||||
err);
|
||||
pr_err("adsprpc: %s: register_rpmsg_driver failed with err %d\n",
|
||||
__func__, err);
|
||||
goto device_create_bail;
|
||||
}
|
||||
me->rpmsg_register = 1;
|
||||
|
||||
me->wake_source = wakeup_source_register(NULL, "adsprpc");
|
||||
VERIFY(err, !IS_ERR_OR_NULL(me->wake_source));
|
||||
if (err) {
|
||||
pr_err("adsprpc: Error: %s: wakeup_source_register failed with err %d\n",
|
||||
__func__, PTR_ERR(me->wake_source));
|
||||
goto device_create_bail;
|
||||
}
|
||||
return 0;
|
||||
device_create_bail:
|
||||
for (i = 0; i < NUM_CHANNELS; i++) {
|
||||
@@ -4438,6 +4491,8 @@ static void __exit fastrpc_device_exit(void)
|
||||
unregister_chrdev_region(me->dev_no, NUM_CHANNELS);
|
||||
if (me->rpmsg_register == 1)
|
||||
unregister_rpmsg_driver(&fastrpc_rpmsg_client);
|
||||
if (me->wake_source)
|
||||
wakeup_source_unregister(me->wake_source);
|
||||
debugfs_remove_recursive(debugfs_root);
|
||||
}
|
||||
|
||||
|
||||
@@ -241,22 +241,32 @@ struct fastrpc_ioctl_perf { /* kernel performance data */
|
||||
uintptr_t keys;
|
||||
};
|
||||
|
||||
#define FASTRPC_CONTROL_LATENCY (1)
|
||||
enum fastrpc_control_type {
|
||||
FASTRPC_CONTROL_LATENCY = 1,
|
||||
FASTRPC_CONTROL_SMMU = 2,
|
||||
FASTRPC_CONTROL_KALLOC = 3,
|
||||
FASTRPC_CONTROL_WAKELOCK = 4,
|
||||
};
|
||||
|
||||
struct fastrpc_ctrl_latency {
|
||||
uint32_t enable; /* latency control enable */
|
||||
uint32_t level; /* level of control */
|
||||
};
|
||||
|
||||
#define FASTRPC_CONTROL_KALLOC (3)
|
||||
struct fastrpc_ctrl_kalloc {
|
||||
uint32_t kalloc_support; /* Remote memory allocation from kernel */
|
||||
};
|
||||
/* FASTRPC_CONTROL value 2 is reserved in user space */
|
||||
|
||||
struct fastrpc_ctrl_wakelock {
|
||||
uint32_t enable; /* wakelock control enable */
|
||||
};
|
||||
|
||||
struct fastrpc_ioctl_control {
|
||||
uint32_t req;
|
||||
union {
|
||||
struct fastrpc_ctrl_latency lp;
|
||||
struct fastrpc_ctrl_kalloc kalloc;
|
||||
struct fastrpc_ctrl_wakelock wp;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user