remoteproc: qcom: support collection of mini and full dumps in SSR

Add a field for rproc client to enable collection of both minidump and
fulldump in coredump collection in recovery during SSR. Collect both
the dumps only if debug config is enabled, the flag for collecting
both dumps is set for the client and the collection of both dumps
is enabled by sysfs node by the user.

Change-Id: I6792da1c739bced7bee74b33ffa91d12792c758b
Signed-off-by: Naman Jain <quic_namajain@quicinc.com>
This commit is contained in:
Naman Jain 2022-11-15 17:52:22 +05:30 committed by Gerrit - the friendly Code Review server
parent 9654c24068
commit 715100c478
3 changed files with 43 additions and 6 deletions

View File

@ -102,6 +102,8 @@ static struct kobject *sysfs_kobject;
bool qcom_device_shutdown_in_progress;
EXPORT_SYMBOL(qcom_device_shutdown_in_progress);
static bool qcom_collect_both_coredumps;
static LIST_HEAD(qcom_ssr_subsystem_list);
static DEFINE_MUTEX(qcom_ssr_subsys_lock);
@ -124,6 +126,23 @@ static ssize_t qcom_rproc_shutdown_request_store(struct kobject *kobj, struct ko
static struct kobj_attribute shutdown_requested_attr = __ATTR(shutdown_in_progress, 0220, NULL,
qcom_rproc_shutdown_request_store);
static ssize_t qcom_collect_both_coredumps_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count)
{
bool val;
int ret;
ret = kstrtobool(buf, &val);
if (ret)
return ret;
qcom_collect_both_coredumps = val;
pr_info("qcom rproc: Collect both coredumps: %s\n", val ? "true" : "false");
return count;
}
static struct kobj_attribute both_coredumps_attr = __ATTR(collect_both_coredumps, 0644, NULL,
qcom_collect_both_coredumps_store);
static void qcom_minidump_cleanup(struct rproc *rproc)
{
struct rproc_dump_segment *entry, *tmp;
@ -280,8 +299,8 @@ static void qcom_rproc_minidump(struct rproc *rproc, struct device *md_dev)
dev_coredumpv(md_dev, data, data_size, GFP_KERNEL);
}
void qcom_minidump(struct rproc *rproc, struct device *md_dev,
unsigned int minidump_id, rproc_dumpfn_t dumpfn)
void qcom_minidump(struct rproc *rproc, struct device *md_dev, unsigned int minidump_id,
rproc_dumpfn_t dumpfn, bool both_dumps)
{
int ret;
struct minidump_subsystem *subsystem;
@ -309,6 +328,11 @@ void qcom_minidump(struct rproc *rproc, struct device *md_dev,
return rproc_coredump(rproc);
}
if (both_dumps && IS_ENABLED(CONFIG_QCOM_RPROC_BOTH_DUMPS) &&
qcom_collect_both_coredumps)
rproc_coredump(rproc);
if (le32_to_cpu(subsystem->encryption_status) != MD_SS_ENCR_DONE) {
dev_err(&rproc->dev, "Minidump not ready, skipping\n");
return;
@ -813,10 +837,16 @@ static int __init qcom_common_init(void)
goto remove_kobject;
}
ret = sysfs_create_file(sysfs_kobject, &both_coredumps_attr.attr);
if (ret) {
pr_err("qcom rproc: failed to create both_coredumps sysfs file\n");
goto remove_shutdown_sysfs;
}
ret = register_trace_android_vh_rproc_recovery(qcom_check_ssr_status, NULL);
if (ret) {
pr_err("qcom rproc: failed to register trace hooks\n");
goto remove_sysfs;
goto remove_coredump_sysfs;
}
ret = register_trace_android_vh_rproc_recovery_set(rproc_recovery_notifier, NULL);
@ -829,7 +859,9 @@ static int __init qcom_common_init(void)
unregister_rproc_recovery_vh:
unregister_trace_android_vh_rproc_recovery(qcom_check_ssr_status, NULL);
remove_sysfs:
remove_coredump_sysfs:
sysfs_remove_file(sysfs_kobject, &both_coredumps_attr.attr);
remove_shutdown_sysfs:
sysfs_remove_file(sysfs_kobject, &shutdown_requested_attr.attr);
remove_kobject:
kobject_put(sysfs_kobject);
@ -841,6 +873,7 @@ module_init(qcom_common_init);
static void __exit qcom_common_exit(void)
{
unregister_trace_android_vh_rproc_recovery_set(rproc_recovery_notifier, NULL);
sysfs_remove_file(sysfs_kobject, &both_coredumps_attr.attr);
sysfs_remove_file(sysfs_kobject, &shutdown_requested_attr.attr);
kobject_put(sysfs_kobject);
unregister_trace_android_vh_rproc_recovery(qcom_check_ssr_status, NULL);

View File

@ -62,7 +62,7 @@ typedef void (*rproc_dumpfn_t)(struct rproc *rproc, struct rproc_dump_segment *s
void *dest, size_t offset, size_t size);
void qcom_minidump(struct rproc *rproc, struct device *md_dev,
unsigned int minidump_id, rproc_dumpfn_t dumpfn);
unsigned int minidump_id, rproc_dumpfn_t dumpfn, bool both_dumps);
void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink,
const char *ssr_name);

View File

@ -61,6 +61,7 @@ struct adsp_data {
int dtb_pas_id;
bool free_after_auth_reset;
unsigned int minidump_id;
bool both_dumps;
bool uses_elf64;
bool has_aggre2_clk;
bool auto_boot;
@ -106,6 +107,7 @@ struct qcom_adsp {
struct qcom_mdt_metadata *mdata;
struct qcom_mdt_metadata dtb_mdata;
unsigned int minidump_id;
bool both_dumps;
bool retry_shutdown;
struct icc_path *bus_client;
int crash_reason_smem;
@ -170,7 +172,8 @@ static void adsp_minidump(struct rproc *rproc)
if (rproc->dump_conf == RPROC_COREDUMP_DISABLED)
goto exit;
qcom_minidump(rproc, adsp->minidump_dev, adsp->minidump_id, adsp_segment_dump);
qcom_minidump(rproc, adsp->minidump_dev, adsp->minidump_id, adsp_segment_dump,
adsp->both_dumps);
exit:
trace_rproc_qcom_event(dev_name(adsp->dev), "adsp_minidump", "exit");
@ -1056,6 +1059,7 @@ static int adsp_probe(struct platform_device *pdev)
adsp->decrypt_shutdown = desc->decrypt_shutdown;
adsp->qmp_name = desc->qmp_name;
adsp->dma_phys_below_32b = desc->dma_phys_below_32b;
adsp->both_dumps = desc->both_dumps;
if (desc->free_after_auth_reset) {
adsp->mdata = devm_kzalloc(adsp->dev, sizeof(struct qcom_mdt_metadata), GFP_KERNEL);