Merge "msm: adsprpc: Enable ram dumps collection"

This commit is contained in:
qctecmdr 2021-04-19 01:39:22 -07:00 • committed by Gerrit - the friendly Code Review server
commit ec4154969e

View file

@ -264,6 +264,9 @@ enum fastrpc_msg_type {
#define IS_ASYNC_FASTRPC_AVAILABLE (1)
/* User PD Dump Name Max length */
#define RAMDUMP_NAME_MAX_LENGTH 20
static int fastrpc_pdr_notifier_cb(struct notifier_block *nb,
unsigned long code,
void *data);
@ -332,6 +335,7 @@ struct fastrpc_file;
struct fastrpc_buf {
struct hlist_node hn;
struct hlist_node hn_rem;
struct hlist_node hn_init;
struct fastrpc_file *fl;
void *virt;
uint64_t phys;
@ -511,6 +515,7 @@ struct fastrpc_channel_ctx {
struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX];
spinlock_t ctxlock;
struct fastrpc_rpmsg_log gmsg_log;
struct hlist_head initmems;
};
struct fastrpc_apps {
@ -888,6 +893,23 @@ static inline void reset_unique_index(int index)
mutex_unlock(&gfa.mut_uid);
}
/**
* fastrpc_elf_ramdump - Dump given ram dump entry
* @rh_dump_dev : Device handle for given channel
* @ramdump_entry : Dump region entry
*
* Returns int
*/
static int fastrpc_elf_ramdump(void *rh_dump_dev, struct ramdump_segment *ramdump_seg)
{
int err = 0;
err = do_elf_ramdump(
rh_dump_dev,
ramdump_seg, 1);
return err;
}
/**
* fastrpc_minidump_add_region - Add mini dump region
@ -2219,6 +2241,42 @@ static void fastrpc_notify_users_staticpd_pdr(struct fastrpc_file *me)
spin_unlock(&me->hlock);
}
static void fastrpc_ramdump_collection(int cid)
{
struct fastrpc_file *fl = NULL;
struct hlist_node *n = NULL;
struct fastrpc_apps *me = &gfa;
struct fastrpc_channel_ctx *chan = &me->channel[cid];
struct ramdump_segment ramdump_entry;
struct fastrpc_buf *buf = NULL;
int ret;
char ramdump_name[RAMDUMP_NAME_MAX_LENGTH];
spin_lock(&me->hlock);
hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
if (fl->cid == cid && fl->init_mem)
hlist_add_head(&fl->init_mem->hn_init, &chan->initmems);
}
spin_unlock(&me->hlock);
if (chan->rh_dump_dev) {
hlist_for_each_entry_safe(buf, n, &chan->initmems, hn_init) {
ramdump_entry.address = buf->phys;
ramdump_entry.v_address = (void __iomem *)buf->virt;
ramdump_entry.size = buf->size;
if (buf->fl) {
scnprintf(ramdump_name, ARRAY_SIZE(ramdump_name),
"%s_%x_", gcinfo[cid].subsys, buf->fl->tgid);
ramdump_entry.name = ramdump_name;
}
ret = fastrpc_elf_ramdump(chan->rh_dump_dev, &ramdump_entry);
if (ret < 0)
pr_err("adsprpc: %s: unable to dump PD memory (err %d)\n",
__func__, ret);
hlist_del_init(&buf->hn_init);
}
}
}
static void fastrpc_notify_drivers(struct fastrpc_apps *me, int cid)
{
@ -2891,6 +2949,7 @@ static void fastrpc_init(struct fastrpc_apps *me)
mutex_init(&me->channel[i].rpmsg_mutex);
spin_lock_init(&me->channel[i].ctxlock);
spin_lock_init(&me->channel[i].gmsg_log.lock);
INIT_HLIST_HEAD(&me->channel[i].initmems);
}
/* Set CDSP channel to non secure */
me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL;
@ -4436,7 +4495,7 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl)
struct hlist_node *n = NULL;
int err = 0, ret = 0;
struct fastrpc_apps *me = &gfa;
struct ramdump_segment *ramdump_segments_rh = NULL;
struct ramdump_segment ramdump_segments_rh;
VERIFY(err, fl->cid == RH_CID);
if (err) {
@ -4459,22 +4518,15 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl)
if (err)
goto bail;
if (me->ramdump_handle && me->enable_ramdump) {
ramdump_segments_rh = kcalloc(1,
sizeof(struct ramdump_segment), GFP_KERNEL);
if (ramdump_segments_rh) {
ramdump_segments_rh->address =
match->phys;
ramdump_segments_rh->v_address =
(void __iomem *)match->va;
ramdump_segments_rh->size = match->size;
ret = do_elf_ramdump(
me->ramdump_handle,
ramdump_segments_rh, 1);
if (ret < 0)
pr_err("adsprpc: %s: unable to dump heap (err %d)\n",
__func__, ret);
kfree(ramdump_segments_rh);
}
ramdump_segments_rh.address =
match->phys;
ramdump_segments_rh.v_address =
(void __iomem *)match->va;
ramdump_segments_rh.size = match->size;
ret = fastrpc_elf_ramdump(me->ramdump_handle, &ramdump_segments_rh);
if (ret < 0)
pr_err("adsprpc: %s: unable to dump heap (err %d)\n",
__func__, ret);
}
fastrpc_mmap_free(match, 0);
}
@ -4925,7 +4977,6 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
{
int err = 0;
int cid = -1;
struct fastrpc_apps *me = &gfa;
VERIFY(err, !IS_ERR_OR_NULL(rpdev));
if (err) {
@ -4942,7 +4993,6 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
mutex_lock(&gcinfo[cid].rpmsg_mutex);
gcinfo[cid].rpdev = NULL;
mutex_unlock(&gcinfo[cid].rpmsg_mutex);
fastrpc_notify_drivers(me, cid);
ADSPRPC_INFO("closed rpmsg channel of %s\n",
gcinfo[cid].subsys);
bail:
@ -6112,6 +6162,8 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb,
if (me->ramdump_handle)
me->channel[RH_CID].ramdumpenabled = 1;
}
if (cid == CDSP_DOMAIN_ID)
fastrpc_ramdump_collection(cid);
pr_info("adsprpc: %s: received RAMDUMP notification for %s\n",
__func__, gcinfo[cid].subsys);
} else if (code == SUBSYS_BEFORE_POWERUP) {
@ -6122,6 +6174,7 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb,
me->channel[RH_CID].ramdumpenabled = 0;
}
}
fastrpc_notify_drivers(me, cid);
} else if (code == SUBSYS_AFTER_POWERUP) {
pr_info("adsprpc: %s: %s subsystem is up\n",
__func__, gcinfo[cid].subsys);
@ -6719,7 +6772,7 @@ static int __init fastrpc_device_init(void)
pr_info("adsprpc: %s: SSR notifier registered for %s\n",
__func__, gcinfo[i].subsys);
}
me->channel[CDSP_DOMAIN_ID].rh_dump_dev = create_ramdump_device("cdsp_minidump", NULL);
err = register_rpmsg_driver(&fastrpc_rpmsg_client);
if (err) {
pr_err("Error: adsprpc: %s: register_rpmsg_driver failed with err %d\n",