msm: adsprpc: store glink transaction history in global buffer

Store the history of recently sent and received glink messages in
a rolling buffer, maintained per channel.

Change-Id: I4547de2190f59ad36dba5d1bdbb83d7d6fa656b9
Acked-by: Thyagarajan Venkatanarayanan <venkatan@qti.qualcomm.com>
Signed-off-by: Himateja Reddy <hmreddy@codeaurora.org>
This commit is contained in:
Himateja Reddy 2020-08-13 23:19:55 -07:00
commit 44bde2c4a1

View file

@ -189,6 +189,9 @@
/* Max no. of persistent headers pre-allocated per process */
#define MAX_PERSISTENT_HEADERS (25)
/* Length of glink transaction history to store */
#define GLINK_MSG_HISTORY_LEN (128)
/* Fastrpc remote process attributes */
enum fastrpc_proc_attr {
FASTRPC_MODE_UNSIGNED_MODULE = (1 << 3),
@ -313,6 +316,29 @@ struct fastrpc_buf {
struct fastrpc_ctx_lst;
struct fastrpc_tx_msg {
struct smq_msg msg; /* Msg sent to remote subsystem */
int rpmsg_send_err; /* rpmsg error */
int64_t ns; /* Timestamp (in ns) of msg */
};
struct fastrpc_rx_msg {
struct smq_invoke_rspv2 rsp; /* Response from remote subsystem */
int64_t ns; /* Timestamp (in ns) of response */
};
struct fastrpc_rpmsg_log {
unsigned int tx_index; /* Current index of 'tx_msgs' array */
unsigned int rx_index; /* Current index of 'rx_msgs' array */
/* Rolling history of messages sent to remote subsystem */
struct fastrpc_tx_msg tx_msgs[GLINK_MSG_HISTORY_LEN];
/* Rolling history of responses from remote subsystem */
struct fastrpc_rx_msg rx_msgs[GLINK_MSG_HISTORY_LEN];
spinlock_t lock;
};
struct overlap {
uintptr_t start;
uintptr_t end;
@ -434,6 +460,7 @@ struct fastrpc_channel_ctx {
bool cpuinfo_status;
struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX];
spinlock_t ctxlock;
struct fastrpc_rpmsg_log gmsg_log;
};
struct fastrpc_apps {
@ -658,6 +685,21 @@ static inline int64_t getnstimediff(struct timespec64 *start)
return ns;
}
/**
* get_timestamp_in_ns - Gets time of day in nanoseconds
*
* Returns: Timestamp in nanoseconds
*/
static inline int64_t get_timestamp_in_ns(void)
{
int64_t ns = 0;
struct timespec64 ts;
ktime_get_real_ts64(&ts);
ns = timespec64_to_ns(&ts);
return ns;
}
static inline int64_t *getperfcounter(struct fastrpc_file *fl, int key)
{
int err = 0;
@ -741,6 +783,79 @@ static inline int poll_on_early_response(struct smq_invoke_ctx *ctx)
return err;
}
/**
* fastrpc_update_txmsg_buf - Update history of sent glink messages
* @chan : Channel context
* @msg : Pointer to RPC message to remote subsystem
* @rpmsg_send_err : Error from rpmsg
* @ns : Timestamp (in ns) of sent message
*
* Returns none
*/
static inline void fastrpc_update_txmsg_buf(struct fastrpc_channel_ctx *chan,
struct smq_msg *msg, int rpmsg_send_err, int64_t ns)
{
unsigned long flags = 0;
unsigned int tx_index = 0;
struct fastrpc_tx_msg *tx_msg = NULL;
spin_lock_irqsave(&chan->gmsg_log.lock, flags);
tx_index = chan->gmsg_log.tx_index;
tx_msg = &chan->gmsg_log.tx_msgs[tx_index];
memcpy(&tx_msg->msg, msg, sizeof(struct smq_msg));
tx_msg->rpmsg_send_err = rpmsg_send_err;
tx_msg->ns = ns;
tx_index++;
chan->gmsg_log.tx_index =
(tx_index > (GLINK_MSG_HISTORY_LEN - 1)) ? 0 : tx_index;
spin_unlock_irqrestore(&chan->gmsg_log.lock, flags);
}
/**
* fastrpc_update_rxmsg_buf - Update history of received glink responses
* @chan : Channel context
* @ctx : Context of received response from DSP
* @retval : Return value for RPC call
* @rsp_flags : Response type
* @early_wake_time : Poll time for early wakeup
* @ver : Version of response
* @ns : Timestamp (in ns) of response
*
* Returns none
*/
static inline void fastrpc_update_rxmsg_buf(struct fastrpc_channel_ctx *chan,
uint64_t ctx, int retval, uint32_t rsp_flags,
uint32_t early_wake_time, uint32_t ver, int64_t ns)
{
unsigned long flags = 0;
unsigned int rx_index = 0;
struct fastrpc_rx_msg *rx_msg = NULL;
struct smq_invoke_rspv2 *rsp = NULL;
spin_lock_irqsave(&chan->gmsg_log.lock, flags);
rx_index = chan->gmsg_log.rx_index;
rx_msg = &chan->gmsg_log.rx_msgs[rx_index];
rsp = &rx_msg->rsp;
rsp->ctx = ctx;
rsp->retval = retval;
rsp->flags = rsp_flags;
rsp->early_wake_time = early_wake_time;
rsp->version = ver;
rx_msg->ns = ns;
rx_index++;
chan->gmsg_log.rx_index =
(rx_index > (GLINK_MSG_HISTORY_LEN - 1)) ? 0 : rx_index;
spin_unlock_irqrestore(&chan->gmsg_log.lock, flags);
}
static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache)
{
struct fastrpc_file *fl = buf == NULL ? NULL : buf->fl;
@ -2553,6 +2668,8 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx,
struct fastrpc_file *fl = ctx->fl;
struct fastrpc_channel_ctx *channel_ctx = NULL;
int err = 0, cid = -1;
uint32_t sc = ctx->sc;
int64_t ns = 0;
cid = fl->cid;
VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
@ -2571,7 +2688,7 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx,
msg->pid = 0;
msg->invoke.header.ctx = ctx->ctxid | fl->pd;
msg->invoke.header.handle = handle;
msg->invoke.header.sc = ctx->sc;
msg->invoke.header.sc = sc;
msg->invoke.page.addr = ctx->buf ? ctx->buf->phys : 0;
msg->invoke.page.size = buf_page_size(ctx->used);
@ -2590,11 +2707,15 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx,
goto bail;
}
err = rpmsg_send(channel_ctx->rpdev->ept, (void *)msg, sizeof(*msg));
trace_fastrpc_rpmsg_send(fl->cid, (uint64_t)ctx, msg->invoke.header.ctx,
handle, msg->invoke.header.sc, msg->invoke.page.addr,
msg->invoke.page.size);
mutex_unlock(&channel_ctx->rpmsg_mutex);
trace_fastrpc_rpmsg_send(fl->cid, (uint64_t)ctx, msg->invoke.header.ctx,
handle, sc, msg->invoke.page.addr, msg->invoke.page.size);
ns = get_timestamp_in_ns();
fastrpc_update_txmsg_buf(channel_ctx, msg, err, ns);
bail:
if (err)
ADSPRPC_ERR("failed with err %d, dom %d (hndl 0x%x, sc 0x%x)\n",
err, cid, handle, sc);
return err;
}
@ -2616,6 +2737,7 @@ static void fastrpc_init(struct fastrpc_apps *me)
mutex_init(&me->channel[i].smd_mutex);
mutex_init(&me->channel[i].rpmsg_mutex);
spin_lock_init(&me->channel[i].ctxlock);
spin_lock_init(&me->channel[i].gmsg_log.lock);
}
/* Set CDSP channel to non secure */
me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL;
@ -4595,10 +4717,11 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
struct smq_invoke_rspv2 *rspv2 = NULL;
struct smq_invoke_ctx *ctx = NULL;
struct fastrpc_apps *me = &gfa;
uint32_t index, rsp_flags = 0, early_wake_time = 0;
uint32_t index, rsp_flags = 0, early_wake_time = 0, ver = 0;
int err = 0, cid = -1, ignore_rpmsg_err = 0;
struct fastrpc_channel_ctx *chan = NULL;
unsigned long irq_flags = 0;
int64_t ns = 0;
cid = get_cid_from_rpdev(rpdev);
VERIFY(err, (cid >= ADSP_DOMAIN_ID && cid <= NUM_CHANNELS));
@ -4618,9 +4741,13 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
if (rspv2) {
early_wake_time = rspv2->early_wake_time;
rsp_flags = rspv2->flags;
ver = rspv2->version;
}
trace_fastrpc_rpmsg_response(cid, rsp->ctx,
rsp->retval, rsp_flags, early_wake_time);
ns = get_timestamp_in_ns();
fastrpc_update_rxmsg_buf(chan, rsp->ctx, rsp->retval,
rsp_flags, early_wake_time, ver, ns);
index = (uint32_t)GET_TABLE_IDX_FROM_CTXID(rsp->ctx);
VERIFY(err, index < FASTRPC_CTX_MAX);