Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ebea1dd authored by Jeya R's avatar Jeya R Committed by Gerrit - the friendly Code Review server
Browse files

msm: adsprpc: Enable ram dumps collection



Enabled ram dump collection for
cDSP that is used for debug the
cDSP crashes due to UserPD.

Change-Id: I22b276ea5c19dc13d55ab8f36c807e14488fc4ed
Acked-by: default avatarKrishnaiah Tadakamalla <ktadakam@qti.qualcomm.com>
Signed-off-by: default avatarJeya R <jeyr@codeaurora.org>
parent e4d3a647
Loading
Loading
Loading
Loading
+73 −20
Original line number Diff line number Diff line
@@ -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 =
				ramdump_segments_rh.address =
				match->phys;
					ramdump_segments_rh->v_address =
				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);
				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);
					kfree(ramdump_segments_rh);
				}
			}
			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",