From 715100c478a1726f2f7e2da11254bb26748046cc Mon Sep 17 00:00:00 2001 From: Naman Jain Date: Tue, 15 Nov 2022 17:52:22 +0530 Subject: [PATCH] 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 --- drivers/remoteproc/qcom_common.c | 41 +++++++++++++++++++++++++++--- drivers/remoteproc/qcom_common.h | 2 +- drivers/remoteproc/qcom_q6v5_pas.c | 6 ++++- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c index 2bb72c8337d0..120de038fb4f 100644 --- a/drivers/remoteproc/qcom_common.c +++ b/drivers/remoteproc/qcom_common.c @@ -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); diff --git a/drivers/remoteproc/qcom_common.h b/drivers/remoteproc/qcom_common.h index 13368967c3ab..2c760c984671 100644 --- a/drivers/remoteproc/qcom_common.h +++ b/drivers/remoteproc/qcom_common.h @@ -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); diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 15f9a05b8d3a..c9e4df5e6d4f 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -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);