All of lore.kernel.org
 help / color / mirror / Atom feed
From: Leo Yan <leo.yan@linaro.org>
To: Mathieu Poirier <mathieu.poirier@linaro.org>,
	Will Deacon <will.deacon@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	Mike Leach <mike.leach@linaro.org>,
	Chunyan Zhang <zhang.chunyan@linaro.org>
Cc: Leo Yan <leo.yan@linaro.org>
Subject: [PATCH v1 1/4] coresight: support panic dump functionality
Date: Sat,  3 Jun 2017 22:42:53 +0800	[thread overview]
Message-ID: <1496500976-18362-2-git-send-email-leo.yan@linaro.org> (raw)
In-Reply-To: <1496500976-18362-1-git-send-email-leo.yan@linaro.org>

After kernel panic happens, coresight has many useful info can be used
for analysis. For example, the trace info from ETB RAM can be used to
check the CPU execution flows before crash. So we can save the tracing
data from sink devices, and rely on kdump to extract them from vmcore
file.

This patch is to add a simple framework to support panic dump
functionality; it registers panic notifier, and provide the general APIs
{coresight_add_panic_cb|coresight_del_panic_cb} as helper functions so
any coresight device can add itself into dump list or delete as needed;
usually these two functions can be used when a session is started or
when it ends. When kernel panic happened, the panic notifier iterates
dump list and calls every node for the device callback function to dump
device specific info. Generally all the panic dump specific stuff are
related to the sinks devices, so this initial version code it only
supports sink devices.

Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
 drivers/hwtracing/coresight/Kconfig                |  10 ++
 drivers/hwtracing/coresight/Makefile               |   1 +
 drivers/hwtracing/coresight/coresight-panic-dump.c | 130 +++++++++++++++++++++
 drivers/hwtracing/coresight/coresight-priv.h       |  10 ++
 include/linux/coresight.h                          |   2 +
 5 files changed, 153 insertions(+)
 create mode 100644 drivers/hwtracing/coresight/coresight-panic-dump.c

diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
index 8d55d6d..8890023 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -103,4 +103,14 @@ config CORESIGHT_CPU_DEBUG
 	  properly, please refer Documentation/trace/coresight-cpu-debug.txt
 	  for detailed description and the example for usage.
 
+config CORESIGHT_PANIC_DUMP
+	bool "CoreSight Panic Dump driver"
+	depends on ARM || ARM64
+	depends on CORESIGHT_LINKS_AND_SINKS
+	help
+	  This driver provides panic dump functionality for coresight
+	  devices; when kernel panic happens, we can use callback functions
+	  to save trace data to memory. Finally can rely on kdump to extract
+	  out these trace data from kernel dump file.
+
 endif
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index 433d590..0ac3216 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o \
 obj-$(CONFIG_CORESIGHT_QCOM_REPLICATOR) += coresight-replicator-qcom.o
 obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
 obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
+obj-$(CONFIG_CORESIGHT_PANIC_DUMP) += coresight-panic-dump.o
diff --git a/drivers/hwtracing/coresight/coresight-panic-dump.c b/drivers/hwtracing/coresight/coresight-panic-dump.c
new file mode 100644
index 0000000..23869ff
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-panic-dump.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright(C) 2017 Linaro Limited. All rights reserved.
+ * Author: Leo Yan <leo.yan@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/coresight.h>
+#include <linux/coresight-pmu.h>
+#include <linux/cpumask.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/perf_event.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+static DEFINE_MUTEX(coresight_panic_lock);
+static struct list_head coresight_panic_list;
+static struct notifier_block coresight_panic_nb;
+
+struct coresight_panic_node {
+	char *name;
+	struct coresight_device *csdev;
+	struct list_head list;
+};
+
+static int coresight_panic_notify(struct notifier_block *nb,
+				  unsigned long mode, void *_unused)
+{
+	int ret = 0, err;
+	struct coresight_panic_node *node;
+	struct coresight_device *csdev;
+	u32 type;
+
+	mutex_lock(&coresight_panic_lock);
+
+	list_for_each_entry(node, &coresight_panic_list, list) {
+		csdev = node->csdev;
+		type = csdev->type;
+
+		dev_info(&csdev->dev, "invoke panic dump...\n");
+
+		switch (type) {
+		case CORESIGHT_DEV_TYPE_SINK:
+		case CORESIGHT_DEV_TYPE_LINKSINK:
+			err = sink_ops(csdev)->panic_cb(csdev);
+			if (err)
+				ret = err;
+			break;
+		default:
+			dev_err(&csdev->dev,
+				"Unsupported type for panic dump\n");
+			break;
+		}
+	}
+
+	mutex_unlock(&coresight_panic_lock);
+	return ret;
+}
+
+int coresight_add_panic_cb(struct coresight_device *csdev)
+{
+	struct coresight_panic_node *node;
+
+	node = kzalloc(sizeof(struct coresight_panic_node), GFP_KERNEL);
+	if (!node)
+		return -ENOMEM;
+
+	node->name = kstrndup(dev_name(&csdev->dev), 16, GFP_KERNEL);
+	if (!node->name) {
+		kfree(node);
+		return -ENOMEM;
+	}
+	node->csdev = csdev;
+
+	mutex_lock(&coresight_panic_lock);
+	list_add_tail(&node->list, &coresight_panic_list);
+	mutex_unlock(&coresight_panic_lock);
+
+	return 0;
+}
+
+void coresight_del_panic_cb(struct coresight_device *csdev)
+{
+	struct coresight_panic_node *node;
+
+	mutex_lock(&coresight_panic_lock);
+
+	list_for_each_entry(node, &coresight_panic_list, list) {
+		if (node->csdev == csdev) {
+			list_del(&node->list);
+			kfree(node->name);
+			kfree(node);
+			mutex_unlock(&coresight_panic_lock);
+			return;
+		}
+	}
+
+	dev_err(&csdev->dev, "Failed to find panic node.\n");
+	mutex_unlock(&coresight_panic_lock);
+}
+
+static int __init coresight_panic_init(void)
+{
+	int ret;
+
+	INIT_LIST_HEAD(&coresight_panic_list);
+
+	coresight_panic_nb.notifier_call = coresight_panic_notify;
+	ret = atomic_notifier_chain_register(&panic_notifier_list,
+					     &coresight_panic_nb);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+subsys_initcall(coresight_panic_init);
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 5f662d8..e6ed3e9 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -122,4 +122,14 @@ static inline int etm_readl_cp14(u32 off, unsigned int *val) { return 0; }
 static inline int etm_writel_cp14(u32 off, u32 val) { return 0; }
 #endif
 
+#ifdef CONFIG_CORESIGHT_PANIC_DUMP
+extern int coresight_add_panic_cb(struct coresight_device *csdev);
+extern void coresight_del_panic_cb(struct coresight_device *csdev);
+#else
+static inline int coresight_add_panic_cb(struct coresight_device *csdev)
+{ return 0; }
+static inline void coresight_del_panic_cb(struct coresight_device *csdev)
+{ return; }
+#endif
+
 #endif
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index d950dad..31fcaeb 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -189,6 +189,7 @@ struct coresight_device {
  * @set_buffer:		initialises buffer mechanic before a trace session.
  * @reset_buffer:	finalises buffer mechanic after a trace session.
  * @update_buffer:	update buffer pointers after a trace session.
+ * @panic_cb:		hooks callback function for panic notifier.
  */
 struct coresight_ops_sink {
 	int (*enable)(struct coresight_device *csdev, u32 mode);
@@ -205,6 +206,7 @@ struct coresight_ops_sink {
 	void (*update_buffer)(struct coresight_device *csdev,
 			      struct perf_output_handle *handle,
 			      void *sink_config);
+	int (*panic_cb)(struct coresight_device *csdev);
 };
 
 /**
-- 
2.7.4

WARNING: multiple messages have this Message-ID (diff)
From: leo.yan@linaro.org (Leo Yan)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v1 1/4] coresight: support panic dump functionality
Date: Sat,  3 Jun 2017 22:42:53 +0800	[thread overview]
Message-ID: <1496500976-18362-2-git-send-email-leo.yan@linaro.org> (raw)
In-Reply-To: <1496500976-18362-1-git-send-email-leo.yan@linaro.org>

After kernel panic happens, coresight has many useful info can be used
for analysis. For example, the trace info from ETB RAM can be used to
check the CPU execution flows before crash. So we can save the tracing
data from sink devices, and rely on kdump to extract them from vmcore
file.

This patch is to add a simple framework to support panic dump
functionality; it registers panic notifier, and provide the general APIs
{coresight_add_panic_cb|coresight_del_panic_cb} as helper functions so
any coresight device can add itself into dump list or delete as needed;
usually these two functions can be used when a session is started or
when it ends. When kernel panic happened, the panic notifier iterates
dump list and calls every node for the device callback function to dump
device specific info. Generally all the panic dump specific stuff are
related to the sinks devices, so this initial version code it only
supports sink devices.

Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
 drivers/hwtracing/coresight/Kconfig                |  10 ++
 drivers/hwtracing/coresight/Makefile               |   1 +
 drivers/hwtracing/coresight/coresight-panic-dump.c | 130 +++++++++++++++++++++
 drivers/hwtracing/coresight/coresight-priv.h       |  10 ++
 include/linux/coresight.h                          |   2 +
 5 files changed, 153 insertions(+)
 create mode 100644 drivers/hwtracing/coresight/coresight-panic-dump.c

diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
index 8d55d6d..8890023 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -103,4 +103,14 @@ config CORESIGHT_CPU_DEBUG
 	  properly, please refer Documentation/trace/coresight-cpu-debug.txt
 	  for detailed description and the example for usage.
 
+config CORESIGHT_PANIC_DUMP
+	bool "CoreSight Panic Dump driver"
+	depends on ARM || ARM64
+	depends on CORESIGHT_LINKS_AND_SINKS
+	help
+	  This driver provides panic dump functionality for coresight
+	  devices; when kernel panic happens, we can use callback functions
+	  to save trace data to memory. Finally can rely on kdump to extract
+	  out these trace data from kernel dump file.
+
 endif
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index 433d590..0ac3216 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o \
 obj-$(CONFIG_CORESIGHT_QCOM_REPLICATOR) += coresight-replicator-qcom.o
 obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
 obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
+obj-$(CONFIG_CORESIGHT_PANIC_DUMP) += coresight-panic-dump.o
diff --git a/drivers/hwtracing/coresight/coresight-panic-dump.c b/drivers/hwtracing/coresight/coresight-panic-dump.c
new file mode 100644
index 0000000..23869ff
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-panic-dump.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright(C) 2017 Linaro Limited. All rights reserved.
+ * Author: Leo Yan <leo.yan@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/coresight.h>
+#include <linux/coresight-pmu.h>
+#include <linux/cpumask.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/perf_event.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+static DEFINE_MUTEX(coresight_panic_lock);
+static struct list_head coresight_panic_list;
+static struct notifier_block coresight_panic_nb;
+
+struct coresight_panic_node {
+	char *name;
+	struct coresight_device *csdev;
+	struct list_head list;
+};
+
+static int coresight_panic_notify(struct notifier_block *nb,
+				  unsigned long mode, void *_unused)
+{
+	int ret = 0, err;
+	struct coresight_panic_node *node;
+	struct coresight_device *csdev;
+	u32 type;
+
+	mutex_lock(&coresight_panic_lock);
+
+	list_for_each_entry(node, &coresight_panic_list, list) {
+		csdev = node->csdev;
+		type = csdev->type;
+
+		dev_info(&csdev->dev, "invoke panic dump...\n");
+
+		switch (type) {
+		case CORESIGHT_DEV_TYPE_SINK:
+		case CORESIGHT_DEV_TYPE_LINKSINK:
+			err = sink_ops(csdev)->panic_cb(csdev);
+			if (err)
+				ret = err;
+			break;
+		default:
+			dev_err(&csdev->dev,
+				"Unsupported type for panic dump\n");
+			break;
+		}
+	}
+
+	mutex_unlock(&coresight_panic_lock);
+	return ret;
+}
+
+int coresight_add_panic_cb(struct coresight_device *csdev)
+{
+	struct coresight_panic_node *node;
+
+	node = kzalloc(sizeof(struct coresight_panic_node), GFP_KERNEL);
+	if (!node)
+		return -ENOMEM;
+
+	node->name = kstrndup(dev_name(&csdev->dev), 16, GFP_KERNEL);
+	if (!node->name) {
+		kfree(node);
+		return -ENOMEM;
+	}
+	node->csdev = csdev;
+
+	mutex_lock(&coresight_panic_lock);
+	list_add_tail(&node->list, &coresight_panic_list);
+	mutex_unlock(&coresight_panic_lock);
+
+	return 0;
+}
+
+void coresight_del_panic_cb(struct coresight_device *csdev)
+{
+	struct coresight_panic_node *node;
+
+	mutex_lock(&coresight_panic_lock);
+
+	list_for_each_entry(node, &coresight_panic_list, list) {
+		if (node->csdev == csdev) {
+			list_del(&node->list);
+			kfree(node->name);
+			kfree(node);
+			mutex_unlock(&coresight_panic_lock);
+			return;
+		}
+	}
+
+	dev_err(&csdev->dev, "Failed to find panic node.\n");
+	mutex_unlock(&coresight_panic_lock);
+}
+
+static int __init coresight_panic_init(void)
+{
+	int ret;
+
+	INIT_LIST_HEAD(&coresight_panic_list);
+
+	coresight_panic_nb.notifier_call = coresight_panic_notify;
+	ret = atomic_notifier_chain_register(&panic_notifier_list,
+					     &coresight_panic_nb);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+subsys_initcall(coresight_panic_init);
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 5f662d8..e6ed3e9 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -122,4 +122,14 @@ static inline int etm_readl_cp14(u32 off, unsigned int *val) { return 0; }
 static inline int etm_writel_cp14(u32 off, u32 val) { return 0; }
 #endif
 
+#ifdef CONFIG_CORESIGHT_PANIC_DUMP
+extern int coresight_add_panic_cb(struct coresight_device *csdev);
+extern void coresight_del_panic_cb(struct coresight_device *csdev);
+#else
+static inline int coresight_add_panic_cb(struct coresight_device *csdev)
+{ return 0; }
+static inline void coresight_del_panic_cb(struct coresight_device *csdev)
+{ return; }
+#endif
+
 #endif
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index d950dad..31fcaeb 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -189,6 +189,7 @@ struct coresight_device {
  * @set_buffer:		initialises buffer mechanic before a trace session.
  * @reset_buffer:	finalises buffer mechanic after a trace session.
  * @update_buffer:	update buffer pointers after a trace session.
+ * @panic_cb:		hooks callback function for panic notifier.
  */
 struct coresight_ops_sink {
 	int (*enable)(struct coresight_device *csdev, u32 mode);
@@ -205,6 +206,7 @@ struct coresight_ops_sink {
 	void (*update_buffer)(struct coresight_device *csdev,
 			      struct perf_output_handle *handle,
 			      void *sink_config);
+	int (*panic_cb)(struct coresight_device *csdev);
 };
 
 /**
-- 
2.7.4

  reply	other threads:[~2017-06-03 14:43 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-03 14:42 [PATCH v1 0/4] coresight: support panic dump functionality Leo Yan
2017-06-03 14:42 ` Leo Yan
2017-06-03 14:42 ` Leo Yan [this message]
2017-06-03 14:42   ` [PATCH v1 1/4] " Leo Yan
2017-06-08 18:13   ` Mathieu Poirier
2017-06-08 18:13     ` Mathieu Poirier
2017-06-03 14:42 ` [PATCH v1 2/4] coresight: add and remove panic callback for sink Leo Yan
2017-06-03 14:42   ` Leo Yan
2017-06-05  9:24   ` Suzuki K Poulose
2017-06-05  9:24     ` Suzuki K Poulose
2017-06-05 10:10     ` Leo Yan
2017-06-05 10:10       ` Leo Yan
2017-06-03 14:42 ` [PATCH v1 3/4] coresight: tmc: hook panic callback for ETB/ETF Leo Yan
2017-06-03 14:42   ` Leo Yan
2017-06-03 14:42 ` [PATCH v1 4/4] coresight: etb10: hook panic callback Leo Yan
2017-06-03 14:42   ` Leo Yan
2017-06-05  8:57 ` [PATCH v1 0/4] coresight: support panic dump functionality Suzuki K Poulose
2017-06-05  8:57   ` Suzuki K Poulose
2017-06-05  9:27   ` Leo Yan
2017-06-05  9:27     ` Leo Yan
2017-06-08 18:16   ` Mathieu Poirier
2017-06-08 18:16     ` Mathieu Poirier
2017-06-08 18:23 ` Mathieu Poirier
2017-06-08 18:23   ` Mathieu Poirier

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=1496500976-18362-2-git-send-email-leo.yan@linaro.org \
    --to=leo.yan@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mathieu.poirier@linaro.org \
    --cc=mike.leach@linaro.org \
    --cc=suzuki.poulose@arm.com \
    --cc=will.deacon@arm.com \
    --cc=zhang.chunyan@linaro.org \
    /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.