All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mukesh Ojha <quic_mojha@quicinc.com>
To: <corbet@lwn.net>, <andersson@kernel.org>,
	<konrad.dybcio@linaro.org>, <robh+dt@kernel.org>,
	<krzysztof.kozlowski+dt@linaro.org>, <conor+dt@kernel.org>,
	<keescook@chromium.org>, <tony.luck@intel.com>,
	<gpiccoli@igalia.com>, <mathieu.poirier@linaro.org>,
	<vigneshr@ti.com>, <nm@ti.com>, <matthias.bgg@gmail.com>,
	<kgene@kernel.org>, <alim.akhtar@samsung.com>,
	<bmasney@redhat.com>
Cc: <linux-doc@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<linux-arm-msm@vger.kernel.org>,
	<linux-hardening@vger.kernel.org>,
	<linux-remoteproc@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-mediatek@lists.infradead.org>,
	<linux-samsung-soc@vger.kernel.org>, <kernel@quicinc.com>,
	<quic_mojha@quicinc.com>
Subject: [PATCH v8 09/10] pstore/ram: Add ramoops information notifier support
Date: Wed, 31 Jan 2024 16:38:36 +0530	[thread overview]
Message-ID: <20240131110837.14218-10-quic_mojha@quicinc.com> (raw)
In-Reply-To: <20240131110837.14218-1-quic_mojha@quicinc.com>

Client like minidump is interested in knowing ramoops
individual zone addresses and their size so that it
could register them with its table.

Let's introduce a info notifier in ramoops which
gets called when ramoops driver probes successfully
and it passes the ramoops region information to the
passed callback by the client and If the call for
ramoops ready register comes after ramoops probe
than call the callback directly.

Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
---
 fs/pstore/ram.c            | 114 +++++++++++++++++++++++++++++++++++++
 include/linux/pstore_ram.h |  15 +++++
 2 files changed, 129 insertions(+)

diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 1faf0835700b..bd94c11e43ff 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -22,6 +22,8 @@
 #include <linux/of_address.h>
 #include <linux/memblock.h>
 #include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
 
 #include "internal.h"
 #include "ram_internal.h"
@@ -101,6 +103,19 @@ struct ramoops_context {
 	unsigned int ftrace_read_cnt;
 	unsigned int pmsg_read_cnt;
 	struct pstore_info pstore;
+	struct blocking_notifier_head ramoops_notifiers;
+	bool ramoops_ready;
+	/*
+	 * Lock to serialize access to ramoops_ready and to not
+	 * miss any ongoing notifier registration while ramoops
+	 * probe is in progress.
+	 */
+	struct mutex lock;
+};
+
+struct ramoops_backend {
+	struct	notifier_block nb;
+	int	(*fn)(const char *name, int id, void *vaddr, phys_addr_t paddr, size_t size);
 };
 
 static struct platform_device *dummy;
@@ -501,6 +516,8 @@ static struct ramoops_context oops_cxt = {
 		.write_user	= ramoops_pstore_write_user,
 		.erase	= ramoops_pstore_erase,
 	},
+	.ramoops_notifiers = BLOCKING_NOTIFIER_INIT(oops_cxt.ramoops_notifiers),
+	.lock   = __MUTEX_INITIALIZER(oops_cxt.lock),
 };
 
 static void ramoops_free_przs(struct ramoops_context *cxt)
@@ -666,6 +683,98 @@ static int ramoops_init_prz(const char *name,
 	return 0;
 }
 
+static int __ramoops_info_notifier(struct ramoops_context *cxt, int (*fn)(const char *,
+				   int, void *, phys_addr_t, size_t))
+{
+	struct persistent_ram_zone *prz;
+	int ret;
+	int i;
+
+	for (i = 0; i < cxt->max_dump_cnt; i++) {
+		prz = cxt->dprzs[i];
+		ret = fn("dmesg", i, prz->vaddr, prz->paddr, prz->size);
+		if (ret < 0)
+			goto err;
+	}
+
+	if (cxt->console_size) {
+		prz = cxt->cprz;
+		ret = fn("console", 0, prz->vaddr, prz->paddr, prz->size);
+		if (ret < 0)
+			goto err;
+	}
+
+	for (i = 0; i < cxt->max_ftrace_cnt; i++) {
+		prz = cxt->fprzs[i];
+		ret = fn("ftrace", i, prz->vaddr, prz->paddr, prz->size);
+		if (ret < 0)
+			goto err;
+	}
+
+	if (cxt->pmsg_size) {
+		prz = cxt->mprz;
+		ret = fn("pmsg", 0, prz->vaddr, prz->paddr, prz->size);
+		if (ret < 0)
+			goto err;
+	}
+
+err:
+	return ret;
+}
+
+static int ramoops_info_notifier(struct notifier_block *nb, unsigned long event,
+				 void *data)
+{
+	struct ramoops_backend *b_info = container_of(nb, struct ramoops_backend, nb);
+	struct ramoops_context *cxt = data;
+
+	return __ramoops_info_notifier(cxt, b_info->fn);
+}
+
+void *register_ramoops_info_notifier(int (*fn)(const char *, int,
+				     void *, phys_addr_t, size_t))
+{
+	struct ramoops_context *cxt = &oops_cxt;
+	struct ramoops_backend *b_info;
+
+	mutex_lock(&cxt->lock);
+	/*
+	 * There is no need to register callback if ramoops probe
+	 * is already done instead, call the callback directly
+	 */
+	if (cxt->ramoops_ready) {
+		mutex_unlock(&cxt->lock);
+		__ramoops_info_notifier(cxt, fn);
+		return NULL;
+	}
+
+	b_info = kzalloc(sizeof(*b_info), GFP_KERNEL);
+	if (!b_info) {
+		b_info = ERR_PTR(-ENOMEM);
+		goto out;
+	}
+
+	b_info->fn = fn;
+	b_info->nb.notifier_call = ramoops_info_notifier;
+	blocking_notifier_chain_register(&cxt->ramoops_notifiers, &b_info->nb);
+
+out:
+	mutex_unlock(&cxt->lock);
+	return b_info;
+}
+EXPORT_SYMBOL_GPL(register_ramoops_info_notifier);
+
+void unregister_ramoops_info_notifier(void *b_info)
+{
+	struct ramoops_context *cxt = &oops_cxt;
+	struct ramoops_backend *tmp = b_info;
+
+	mutex_lock(&cxt->lock);
+	blocking_notifier_chain_unregister(&cxt->ramoops_notifiers, &tmp->nb);
+	mutex_unlock(&cxt->lock);
+}
+EXPORT_SYMBOL_GPL(unregister_ramoops_info_notifier);
+
 /* Read a u32 from a dt property and make sure it's safe for an int. */
 static int ramoops_parse_dt_u32(struct platform_device *pdev,
 				const char *propname,
@@ -915,6 +1024,11 @@ static int ramoops_probe(struct platform_device *pdev)
 	ramoops_pmsg_size = pdata->pmsg_size;
 	ramoops_ftrace_size = pdata->ftrace_size;
 
+	mutex_lock(&cxt->lock);
+	cxt->ramoops_ready = true;
+	mutex_unlock(&cxt->lock);
+	blocking_notifier_call_chain(&cxt->ramoops_notifiers, 0, cxt);
+
 	pr_info("using 0x%lx@0x%llx, ecc: %d\n",
 		cxt->size, (unsigned long long)cxt->phys_addr,
 		cxt->ecc_info.ecc_size);
diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h
index 1efff7a38333..7e27cfc09243 100644
--- a/include/linux/pstore_ram.h
+++ b/include/linux/pstore_ram.h
@@ -39,6 +39,21 @@ struct ramoops_platform_data {
 	struct persistent_ram_ecc_info ecc_info;
 };
 
+#if IS_ENABLED(CONFIG_PSTORE_RAM)
+void *register_ramoops_info_notifier(int (*fn)(const char *name, int id,
+				     void *vaddr, phys_addr_t paddr,
+				     size_t size));
+void unregister_ramoops_info_notifier(void *nb_cookie);
+#else
+static inline void *register_ramoops_info_notifier(int (*fn)(const char *name, int id,
+						   void *vaddr, phys_addr_t paddr,
+						   size_t size))
+{
+	return NULL;
+}
+static inline void unregister_ramoops_info_notifier(void *nb_cookie) { }
+#endif
+
 #ifdef CONFIG_PSTORE_DYNAMIC_RAMOOPS
 void __init setup_dynamic_ramoops(void);
 #else
-- 
2.43.0.254.ga26002b62827


WARNING: multiple messages have this Message-ID (diff)
From: Mukesh Ojha <quic_mojha@quicinc.com>
To: <corbet@lwn.net>, <andersson@kernel.org>,
	<konrad.dybcio@linaro.org>, <robh+dt@kernel.org>,
	<krzysztof.kozlowski+dt@linaro.org>, <conor+dt@kernel.org>,
	<keescook@chromium.org>, <tony.luck@intel.com>,
	<gpiccoli@igalia.com>, <mathieu.poirier@linaro.org>,
	<vigneshr@ti.com>, <nm@ti.com>, <matthias.bgg@gmail.com>,
	<kgene@kernel.org>, <alim.akhtar@samsung.com>,
	<bmasney@redhat.com>
Cc: <linux-doc@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<linux-arm-msm@vger.kernel.org>,
	<linux-hardening@vger.kernel.org>,
	<linux-remoteproc@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-mediatek@lists.infradead.org>,
	<linux-samsung-soc@vger.kernel.org>, <kernel@quicinc.com>,
	<quic_mojha@quicinc.com>
Subject: [PATCH v8 09/10] pstore/ram: Add ramoops information notifier support
Date: Wed, 31 Jan 2024 16:38:36 +0530	[thread overview]
Message-ID: <20240131110837.14218-10-quic_mojha@quicinc.com> (raw)
In-Reply-To: <20240131110837.14218-1-quic_mojha@quicinc.com>

Client like minidump is interested in knowing ramoops
individual zone addresses and their size so that it
could register them with its table.

Let's introduce a info notifier in ramoops which
gets called when ramoops driver probes successfully
and it passes the ramoops region information to the
passed callback by the client and If the call for
ramoops ready register comes after ramoops probe
than call the callback directly.

Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
---
 fs/pstore/ram.c            | 114 +++++++++++++++++++++++++++++++++++++
 include/linux/pstore_ram.h |  15 +++++
 2 files changed, 129 insertions(+)

diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 1faf0835700b..bd94c11e43ff 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -22,6 +22,8 @@
 #include <linux/of_address.h>
 #include <linux/memblock.h>
 #include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
 
 #include "internal.h"
 #include "ram_internal.h"
@@ -101,6 +103,19 @@ struct ramoops_context {
 	unsigned int ftrace_read_cnt;
 	unsigned int pmsg_read_cnt;
 	struct pstore_info pstore;
+	struct blocking_notifier_head ramoops_notifiers;
+	bool ramoops_ready;
+	/*
+	 * Lock to serialize access to ramoops_ready and to not
+	 * miss any ongoing notifier registration while ramoops
+	 * probe is in progress.
+	 */
+	struct mutex lock;
+};
+
+struct ramoops_backend {
+	struct	notifier_block nb;
+	int	(*fn)(const char *name, int id, void *vaddr, phys_addr_t paddr, size_t size);
 };
 
 static struct platform_device *dummy;
@@ -501,6 +516,8 @@ static struct ramoops_context oops_cxt = {
 		.write_user	= ramoops_pstore_write_user,
 		.erase	= ramoops_pstore_erase,
 	},
+	.ramoops_notifiers = BLOCKING_NOTIFIER_INIT(oops_cxt.ramoops_notifiers),
+	.lock   = __MUTEX_INITIALIZER(oops_cxt.lock),
 };
 
 static void ramoops_free_przs(struct ramoops_context *cxt)
@@ -666,6 +683,98 @@ static int ramoops_init_prz(const char *name,
 	return 0;
 }
 
+static int __ramoops_info_notifier(struct ramoops_context *cxt, int (*fn)(const char *,
+				   int, void *, phys_addr_t, size_t))
+{
+	struct persistent_ram_zone *prz;
+	int ret;
+	int i;
+
+	for (i = 0; i < cxt->max_dump_cnt; i++) {
+		prz = cxt->dprzs[i];
+		ret = fn("dmesg", i, prz->vaddr, prz->paddr, prz->size);
+		if (ret < 0)
+			goto err;
+	}
+
+	if (cxt->console_size) {
+		prz = cxt->cprz;
+		ret = fn("console", 0, prz->vaddr, prz->paddr, prz->size);
+		if (ret < 0)
+			goto err;
+	}
+
+	for (i = 0; i < cxt->max_ftrace_cnt; i++) {
+		prz = cxt->fprzs[i];
+		ret = fn("ftrace", i, prz->vaddr, prz->paddr, prz->size);
+		if (ret < 0)
+			goto err;
+	}
+
+	if (cxt->pmsg_size) {
+		prz = cxt->mprz;
+		ret = fn("pmsg", 0, prz->vaddr, prz->paddr, prz->size);
+		if (ret < 0)
+			goto err;
+	}
+
+err:
+	return ret;
+}
+
+static int ramoops_info_notifier(struct notifier_block *nb, unsigned long event,
+				 void *data)
+{
+	struct ramoops_backend *b_info = container_of(nb, struct ramoops_backend, nb);
+	struct ramoops_context *cxt = data;
+
+	return __ramoops_info_notifier(cxt, b_info->fn);
+}
+
+void *register_ramoops_info_notifier(int (*fn)(const char *, int,
+				     void *, phys_addr_t, size_t))
+{
+	struct ramoops_context *cxt = &oops_cxt;
+	struct ramoops_backend *b_info;
+
+	mutex_lock(&cxt->lock);
+	/*
+	 * There is no need to register callback if ramoops probe
+	 * is already done instead, call the callback directly
+	 */
+	if (cxt->ramoops_ready) {
+		mutex_unlock(&cxt->lock);
+		__ramoops_info_notifier(cxt, fn);
+		return NULL;
+	}
+
+	b_info = kzalloc(sizeof(*b_info), GFP_KERNEL);
+	if (!b_info) {
+		b_info = ERR_PTR(-ENOMEM);
+		goto out;
+	}
+
+	b_info->fn = fn;
+	b_info->nb.notifier_call = ramoops_info_notifier;
+	blocking_notifier_chain_register(&cxt->ramoops_notifiers, &b_info->nb);
+
+out:
+	mutex_unlock(&cxt->lock);
+	return b_info;
+}
+EXPORT_SYMBOL_GPL(register_ramoops_info_notifier);
+
+void unregister_ramoops_info_notifier(void *b_info)
+{
+	struct ramoops_context *cxt = &oops_cxt;
+	struct ramoops_backend *tmp = b_info;
+
+	mutex_lock(&cxt->lock);
+	blocking_notifier_chain_unregister(&cxt->ramoops_notifiers, &tmp->nb);
+	mutex_unlock(&cxt->lock);
+}
+EXPORT_SYMBOL_GPL(unregister_ramoops_info_notifier);
+
 /* Read a u32 from a dt property and make sure it's safe for an int. */
 static int ramoops_parse_dt_u32(struct platform_device *pdev,
 				const char *propname,
@@ -915,6 +1024,11 @@ static int ramoops_probe(struct platform_device *pdev)
 	ramoops_pmsg_size = pdata->pmsg_size;
 	ramoops_ftrace_size = pdata->ftrace_size;
 
+	mutex_lock(&cxt->lock);
+	cxt->ramoops_ready = true;
+	mutex_unlock(&cxt->lock);
+	blocking_notifier_call_chain(&cxt->ramoops_notifiers, 0, cxt);
+
 	pr_info("using 0x%lx@0x%llx, ecc: %d\n",
 		cxt->size, (unsigned long long)cxt->phys_addr,
 		cxt->ecc_info.ecc_size);
diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h
index 1efff7a38333..7e27cfc09243 100644
--- a/include/linux/pstore_ram.h
+++ b/include/linux/pstore_ram.h
@@ -39,6 +39,21 @@ struct ramoops_platform_data {
 	struct persistent_ram_ecc_info ecc_info;
 };
 
+#if IS_ENABLED(CONFIG_PSTORE_RAM)
+void *register_ramoops_info_notifier(int (*fn)(const char *name, int id,
+				     void *vaddr, phys_addr_t paddr,
+				     size_t size));
+void unregister_ramoops_info_notifier(void *nb_cookie);
+#else
+static inline void *register_ramoops_info_notifier(int (*fn)(const char *name, int id,
+						   void *vaddr, phys_addr_t paddr,
+						   size_t size))
+{
+	return NULL;
+}
+static inline void unregister_ramoops_info_notifier(void *nb_cookie) { }
+#endif
+
 #ifdef CONFIG_PSTORE_DYNAMIC_RAMOOPS
 void __init setup_dynamic_ramoops(void);
 #else
-- 
2.43.0.254.ga26002b62827


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2024-01-31 11:10 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-31 11:08 [PATCH v8 00/10] Add Qualcomm APSS Minidump driver related support Mukesh Ojha
2024-01-31 11:08 ` Mukesh Ojha
2024-01-31 11:08 ` [PATCH v8 01/10] docs: qcom: Add qualcomm minidump guide Mukesh Ojha
2024-01-31 11:08   ` Mukesh Ojha
2024-01-31 11:08 ` [PATCH v8 02/10] soc: qcom: Add qcom_rproc_minidump module Mukesh Ojha
2024-01-31 11:08   ` Mukesh Ojha
2024-01-31 11:08 ` [PATCH v8 03/10] remoteproc: qcom_q6v5_pas: Use qcom_rproc_minidump() Mukesh Ojha
2024-01-31 11:08   ` Mukesh Ojha
2024-01-31 11:08 ` [PATCH v8 04/10] remoteproc: qcom: Remove minidump related data from qcom_common.c Mukesh Ojha
2024-01-31 11:08   ` Mukesh Ojha
2024-01-31 11:08 ` [PATCH v8 05/10] init: export linux_banner data variable Mukesh Ojha
2024-01-31 11:08   ` Mukesh Ojha
2024-01-31 11:08 ` [PATCH v8 06/10] soc: qcom: Add Qualcomm APSS minidump kernel driver Mukesh Ojha
2024-01-31 11:08   ` Mukesh Ojha
2024-01-31 11:08 ` [PATCH v8 07/10] MAINTAINERS: Add entry for minidump related files Mukesh Ojha
2024-01-31 11:08   ` Mukesh Ojha
2024-01-31 11:08 ` [PATCH v8 08/10] pstore/ram: Add dynamic ramoops region support through commandline Mukesh Ojha
2024-01-31 11:08   ` Mukesh Ojha
2024-02-12 13:34   ` Mukesh Ojha
2024-02-12 13:34     ` Mukesh Ojha
2024-01-31 11:08 ` Mukesh Ojha [this message]
2024-01-31 11:08   ` [PATCH v8 09/10] pstore/ram: Add ramoops information notifier support Mukesh Ojha
2024-01-31 11:08 ` [PATCH v8 10/10] soc: qcom: register ramoops region with APSS minidump Mukesh Ojha
2024-01-31 11:08   ` Mukesh Ojha
2024-03-04 16:45 ` [PATCH v8 00/10] Add Qualcomm APSS Minidump driver related support Mukesh Ojha
2024-03-04 16:45   ` Mukesh Ojha
  -- strict thread matches above, loose matches on Subject: below --
2024-01-31 10:57 Mukesh Ojha
2024-01-31 10:57 ` [PATCH v8 09/10] pstore/ram: Add ramoops information notifier support Mukesh Ojha

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240131110837.14218-10-quic_mojha@quicinc.com \
    --to=quic_mojha@quicinc.com \
    --cc=alim.akhtar@samsung.com \
    --cc=andersson@kernel.org \
    --cc=bmasney@redhat.com \
    --cc=conor+dt@kernel.org \
    --cc=corbet@lwn.net \
    --cc=gpiccoli@igalia.com \
    --cc=keescook@chromium.org \
    --cc=kernel@quicinc.com \
    --cc=kgene@kernel.org \
    --cc=konrad.dybcio@linaro.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-remoteproc@vger.kernel.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=mathieu.poirier@linaro.org \
    --cc=matthias.bgg@gmail.com \
    --cc=nm@ti.com \
    --cc=robh+dt@kernel.org \
    --cc=tony.luck@intel.com \
    --cc=vigneshr@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.