2018-03-30 03:17:34

by Leo Yan

[permalink] [raw]
Subject: [PATCH v4 0/6] Coresight: Support panic kdump

This patch set is to explore Coresight tracing data for postmortem
debugging. When kernel panic happens, the Coresight panic kdump can
help to save on-chip tracing data and tracer metadata into DRAM, later
relies on kdump and crash/perf tools to recovery tracing data for
"offline" analysis.

The documentation is important to understand the purpose of Coresight
panic kdump, the implementation of framework and usage. Patches 0001
and patch 0002 are used for creating new sub directory for placing
Coresight docs and add a new doc for Coresight panic kdump.

Patch 0003 introduces the simple panic kdump framework which provides
helper functions can be used by Coresight devices, and it registers
panic notifier for dump tracing data.

Patches 0004/0005 support panic kdump for ETB; Patch 0006 supports the
kdump for ETMv4.

This patch set has been reworked by following suggestions at Linaro
HKG18 connect (mainly suggestions from Mathieu, thanks a lot!), and
it's rebased on acme git tree [1] with last commit 109d59b900e7 ('perf
vendor events s390: Add JSON files for IBM z14').

Due Coresight kdump data structure has been changed significantly, the
corresponding crash extension program also has been updated for this
reason [2]; furthermore the crash extension program is updated to
dynamically generate kernel buildid according to vmlinux elf info [3],
this is a fixing for the old code which uses hard-coded buildid value.

This patch set has been verified on 96boards Hikey620 with Coresight
enabling by the sysFS interface. Also the updated crash extension
program has been verified to cowork with Coresight panic kdump and it
successfully extracts tracing data from the vmcore and finally can be
decoded by perf tool.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git
[2] https://git.linaro.org/people/leo.yan/crash.git/tree/extensions/csdump.c
[3] https://git.linaro.org/people/leo.yan/crash.git/tree/extensions/csdump_buildid.c

Changes from v3:
* Following Mathieu suggestion, reworked the panic kdump framework,
used kdump array to maintain source and sink device handlers;
* According to Mathieu suggestion, optimized panic notifier to
firstly dump panic CPU tracing data and then dump other CPUs tracing
data;
* Refined doc to reflect these implementation changes;
* Changed ETMv4 driver to add source device handler at probe phase;
* Refactored crash extension program to reflect kernel changes.

Changes from v2:
* Add the two patches for documentation.
* Following Mathieu suggestion, reworked the panic kdump framework,
removed the useless flag "PRE_PANIC".
* According to comment, changed to add and delete kdump node operations
in sink enable/disable functions;
* According to Mathieu suggestion, handle kdump node
addition/deletion/updating separately for sysFS interface and perf
method.

Changes from v1:
* Add support to dump ETMv4 meta data.
* Wrote 'crash' extension csdump.so so rely on it to generate 'perf'
format compatible file.
* Refactored panic dump driver to support pre & post panic dump.

Changes from RFC:
* Follow Mathieu's suggestion, use general framework to support dump
functionality.
* Changed to use perf to analyse trace data.

Leo Yan (6):
doc: Add Coresight documentation directory
doc: Add documentation for Coresight panic kdump
coresight: Support panic kdump functionality
coresight: tmc: Hook callback for panic kdump
coresight: Set and clear sink device handler for kdump node
coresight: etm4x: Support panic kdump

Documentation/trace/coresight-cpu-debug.txt | 187 ----------
Documentation/trace/coresight.txt | 383 ---------------------
.../trace/coresight/coresight-cpu-debug.txt | 187 ++++++++++
.../trace/coresight/coresight-panic-kdump.txt | 130 +++++++
Documentation/trace/coresight/coresight.txt | 383 +++++++++++++++++++++
MAINTAINERS | 5 +-
drivers/hwtracing/coresight/Kconfig | 9 +
drivers/hwtracing/coresight/Makefile | 1 +
drivers/hwtracing/coresight/coresight-etm-perf.c | 5 +
drivers/hwtracing/coresight/coresight-etm4x.c | 27 ++
drivers/hwtracing/coresight/coresight-etm4x.h | 15 +
.../hwtracing/coresight/coresight-panic-kdump.c | 199 +++++++++++
drivers/hwtracing/coresight/coresight-priv.h | 12 +
drivers/hwtracing/coresight/coresight-tmc-etf.c | 30 ++
drivers/hwtracing/coresight/coresight.c | 16 +-
include/linux/coresight.h | 4 +
16 files changed, 1019 insertions(+), 574 deletions(-)
delete mode 100644 Documentation/trace/coresight-cpu-debug.txt
delete mode 100644 Documentation/trace/coresight.txt
create mode 100644 Documentation/trace/coresight/coresight-cpu-debug.txt
create mode 100644 Documentation/trace/coresight/coresight-panic-kdump.txt
create mode 100644 Documentation/trace/coresight/coresight.txt
create mode 100644 drivers/hwtracing/coresight/coresight-panic-kdump.c

--
2.7.4



2018-03-30 03:17:41

by Leo Yan

[permalink] [raw]
Subject: [PATCH v4 3/6] coresight: Support panic kdump functionality

After kernel panic happens, Coresight tracing data has much useful info
which can be used for analysis. For example, the trace info from ETB
RAM can be used to check the CPU execution flows before the crash. So
we can save the tracing data from sink devices, and rely on kdump to
save DDR content and uses "crash" tool to extract Coresight dumping
from the vmcore file.

This patch is to add a simple framework to support panic dump
functionality; it registers panic notifier, and provide the helper
functions coresight_kdump_source()/coresight_kdump_sink() so Coresight
source and sink devices can be recorded into Coresight kdump node for
kernel panic kdump.

When kernel panic happens, the notifier iterates dump array and invoke
callback function to dump tracing data. Later the tracing data can be
used to reverse execution flow before the kernel panic.

Signed-off-by: Leo Yan <[email protected]>
---
drivers/hwtracing/coresight/Kconfig | 9 +
drivers/hwtracing/coresight/Makefile | 1 +
.../hwtracing/coresight/coresight-panic-kdump.c | 199 +++++++++++++++++++++
drivers/hwtracing/coresight/coresight-priv.h | 12 ++
include/linux/coresight.h | 4 +
5 files changed, 225 insertions(+)
create mode 100644 drivers/hwtracing/coresight/coresight-panic-kdump.c

diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
index ef9cb3c..3089abf 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -103,4 +103,13 @@ config CORESIGHT_CPU_DEBUG
properly, please refer Documentation/trace/coresight-cpu-debug.txt
for detailed description and the example for usage.

+config CORESIGHT_PANIC_KDUMP
+ bool "CoreSight Panic Kdump driver"
+ depends on ARM || ARM64
+ help
+ This driver provides panic kdump functionality for CoreSight devices.
+ When kernel panic happen Coresight device supplied callback function
+ is to dump trace data to memory. From then on, kdump can be used to
+ extract the trace data from kernel dump file.
+
endif
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index 61db9dd..946fe19 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o \
obj-$(CONFIG_CORESIGHT_DYNAMIC_REPLICATOR) += coresight-dynamic-replicator.o
obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
+obj-$(CONFIG_CORESIGHT_PANIC_KDUMP) += coresight-panic-kdump.o
diff --git a/drivers/hwtracing/coresight/coresight-panic-kdump.c b/drivers/hwtracing/coresight/coresight-panic-kdump.c
new file mode 100644
index 0000000..f4589e9
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-panic-kdump.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017~2018 Linaro Limited.
+#include <linux/coresight.h>
+#include <linux/coresight-pmu.h>
+#include <linux/cpumask.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/perf_event.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "coresight-priv.h"
+
+/**
+ * struct coresight_kdump_node - Node information for dump
+ * @source_csdev: Handler for source coresight device
+ * @sink_csdev: Handler for sink coresight device
+ */
+struct coresight_kdump_node {
+ struct coresight_device *source_csdev;
+ struct coresight_device *sink_csdev;
+};
+
+static DEFINE_SPINLOCK(coresight_kdump_lock);
+static struct coresight_kdump_node *coresight_kdump_nodes;
+static struct notifier_block coresight_kdump_nb;
+
+/**
+ * coresight_kdump_source - Set source dump info for specific CPU
+ * @cpu: CPU ID
+ * @csdev: Source device structure handler
+ * @data: Pointer for source device metadata buffer
+ * @data_sz: Size of source device metadata buffer
+ *
+ * This function is a helper function which is used to set/clear source device
+ * handler and metadata when the tracer is enabled; and it can be used to clear
+ * source device related info when the tracer is disabled.
+ *
+ * Returns: 0 on success, negative errno otherwise.
+ */
+int coresight_kdump_source(int cpu, struct coresight_device *csdev,
+ char *data, unsigned int data_sz)
+{
+ struct coresight_kdump_node *node;
+ unsigned long flags;
+
+ if (!coresight_kdump_nodes)
+ return -EPROBE_DEFER;
+
+ spin_lock_irqsave(&coresight_kdump_lock, flags);
+
+ node = &coresight_kdump_nodes[cpu];
+ node->source_csdev = csdev;
+
+ csdev->kdump_buf = data;
+ csdev->kdump_buf_sz = data_sz;
+
+ spin_unlock_irqrestore(&coresight_kdump_lock, flags);
+ return 0;
+}
+
+/**
+ * coresight_kdump_sink - Set sink device handler for specific CPU
+ * @cpu: CPU ID
+ * @csdev: Sink device structure handler
+ *
+ * This function is a helper function which is used to set sink device handler
+ * when the Coresight path has been enabled for specific CPU; and it can be used
+ * to clear sink device handler when the path is disabled.
+ *
+ * Returns: 0 on success, negative errno otherwise.
+ */
+int coresight_kdump_sink(int cpu, struct coresight_device *csdev)
+{
+ struct coresight_kdump_node *node;
+ unsigned long flags;
+
+ if (!coresight_kdump_nodes)
+ return -EPROBE_DEFER;
+
+ spin_lock_irqsave(&coresight_kdump_lock, flags);
+
+ node = &coresight_kdump_nodes[cpu];
+ node->sink_csdev = csdev;
+
+ spin_unlock_irqrestore(&coresight_kdump_lock, flags);
+ return 0;
+}
+
+/**
+ * coresight_kdump_sink_cb - Invoke sink callback for specific CPU
+ * @cpu: CPU ID
+ *
+ * This function is to invoke sink device corresponding callback. It needs
+ * to check two cases: one case is the CPU has not been enabled for Coresight
+ * path so there totally has no trace data for the CPU, another case is the
+ * CPU shares the same sink device with other CPUs but the tracing data has
+ * been dumped by previous CPUs; it skips dump for these two cases.
+ */
+static void coresight_kdump_sink_cb(int cpu)
+{
+ struct coresight_kdump_node *node;
+ struct coresight_device *csdev;
+ unsigned long flags;
+
+ spin_lock_irqsave(&coresight_kdump_lock, flags);
+
+ node = &coresight_kdump_nodes[cpu];
+ csdev = node->sink_csdev;
+
+ /* Path has not been enabled */
+ if (!csdev)
+ goto skip_dump;
+
+ /* Have been dumped by previous CPU */
+ if (csdev->kdump_buf)
+ goto skip_dump;
+
+ /* Invoke panic callback */
+ csdev = coresight_kdump_nodes[cpu].sink_csdev;
+ if (csdev && sink_ops(csdev)->panic_cb)
+ sink_ops(csdev)->panic_cb(csdev);
+
+skip_dump:
+ spin_unlock_irqrestore(&coresight_kdump_lock, flags);
+}
+
+/**
+ * coresight_kdump_notify - Invoke panic dump callbacks
+ * @nb: Pointer to notifier block
+ * @event: Notification reason
+ * @_unused: Pointer to notification data object, unused
+ *
+ * This function is called when panic happens to invoke dump callbacks, it takes
+ * panic CPU tracing data with high priority to firstly invoke panic CPU sink
+ * callback function, then the notifier iterates callback functions one by one
+ * for other CPUs. If one sink device is shared among CPUs, the sink panic
+ * callback is invoked for the first traversed CPU node and other sequential
+ * CPUs are skipped.
+ *
+ * Returns: 0 on success.
+ */
+static int coresight_kdump_notify(struct notifier_block *nb,
+ unsigned long event, void *_unused)
+{
+ int cpu, first;
+
+ /* Give panic CPU trace data with high priority */
+ first = atomic_read(&panic_cpu);
+ coresight_kdump_sink_cb(first);
+
+ /* Dump rest CPUs trace data */
+ for (cpu = 0; cpu < num_possible_cpus(); cpu++) {
+ if (cpu == first)
+ continue;
+
+ coresight_kdump_sink_cb(cpu);
+ }
+
+ return 0;
+}
+
+/**
+ * coresight_kdump_init - Coresight kdump module initialization
+ *
+ * This function allcoates dump array and register panic norifier.
+ *
+ * Returns: 0 on success, negative errno otherwise.
+ */
+static int __init coresight_kdump_init(void)
+{
+ int ret;
+
+ coresight_kdump_nodes = kmalloc_array(num_possible_cpus(),
+ sizeof(*coresight_kdump_nodes),
+ GFP_KERNEL);
+ if (!coresight_kdump_nodes) {
+ pr_err("%s: kmalloc failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ memset(coresight_kdump_nodes, 0,
+ num_possible_cpus() * sizeof(*coresight_kdump_nodes));
+
+ coresight_kdump_nb.notifier_call = coresight_kdump_notify;
+ ret = atomic_notifier_chain_register(&panic_notifier_list,
+ &coresight_kdump_nb);
+ if (ret) {
+ pr_err("%s: unable to register notifier: %d\n",
+ __func__, ret);
+ kfree(coresight_kdump_nodes);
+ return ret;
+ }
+
+ return 0;
+}
+postcore_initcall(coresight_kdump_init);
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index f1d0e21d..76d27d6 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -151,4 +151,16 @@ 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_KDUMP
+extern int coresight_kdump_source(int cpu, struct coresight_device *csdev,
+ char *data, unsigned int data_sz);
+extern int coresight_kdump_sink(int cpu, struct coresight_device *csdev);
+#else
+static inline int coresight_kdump_source(int cpu,
+ struct coresight_device *csdev,
+ char *data, unsigned int data_sz) { return 0; }
+static inline void coresight_kdump_sink(int cpu,
+ struct coresight_device *csdev) { return 0; }
+#endif
+
#endif
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index d950dad..89aad8d 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -171,6 +171,8 @@ struct coresight_device {
bool orphan;
bool enable; /* true only if configured as part of a path */
bool activated; /* true only if a sink is part of a path */
+ char *kdump_buf;
+ unsigned int kdump_buf_sz;
};

#define to_coresight_device(d) container_of(d, struct coresight_device, dev)
@@ -189,6 +191,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: hook function for panic notifier.
*/
struct coresight_ops_sink {
int (*enable)(struct coresight_device *csdev, u32 mode);
@@ -205,6 +208,7 @@ struct coresight_ops_sink {
void (*update_buffer)(struct coresight_device *csdev,
struct perf_output_handle *handle,
void *sink_config);
+ void (*panic_cb)(void *data);
};

/**
--
2.7.4


2018-03-30 03:17:44

by Leo Yan

[permalink] [raw]
Subject: [PATCH v4 5/6] coresight: Set and clear sink device handler for kdump node

If Coresight path is enabled for specific CPU, the sink device handler
need to be set to kdump node; on the other hand we also need to clear
sink device handler when path is disabled.

This patch sets sink devices handler for kdump node for two separate
Coresight enabling modes: CS_MODE_SYSFS and CS_MODE_PERF; and clear the
handler when Coresight is disabled.

Signed-off-by: Leo Yan <[email protected]>
---
drivers/hwtracing/coresight/coresight-etm-perf.c | 5 +++++
drivers/hwtracing/coresight/coresight.c | 16 ++++++++++++++--
2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 8a0ad77..f8b159c 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -139,6 +139,8 @@ static void free_event_data(struct work_struct *work)
for_each_cpu(cpu, mask) {
if (!(IS_ERR_OR_NULL(event_data->path[cpu])))
coresight_release_path(event_data->path[cpu]);
+
+ coresight_kdump_sink(cpu, NULL);
}

kfree(event_data->path);
@@ -238,6 +240,9 @@ static void *etm_setup_aux(int event_cpu, void **pages,
event_data->path[cpu] = coresight_build_path(csdev, sink);
if (IS_ERR(event_data->path[cpu]))
goto err;
+
+ if (coresight_kdump_sink(cpu, sink))
+ goto err;
}

if (!sink_ops(sink)->alloc_buffer)
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index 389c4ba..483a1f7 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -272,6 +272,7 @@ static int coresight_enable_source(struct coresight_device *csdev, u32 mode)
static bool coresight_disable_source(struct coresight_device *csdev)
{
if (atomic_dec_return(csdev->refcnt) == 0) {
+
if (source_ops(csdev)->disable)
source_ops(csdev)->disable(csdev, NULL);
csdev->enable = false;
@@ -612,6 +613,13 @@ int coresight_enable(struct coresight_device *csdev)
if (ret)
goto err_source;

+ cpu = source_ops(csdev)->cpu_id(csdev);
+
+ /* Set sink device handler into kdump node */
+ ret = coresight_kdump_sink(cpu, sink);
+ if (ret)
+ goto err_kdump;
+
switch (subtype) {
case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
/*
@@ -621,7 +629,6 @@ int coresight_enable(struct coresight_device *csdev)
* be a single session per tracer (when working from sysFS)
* a per-cpu variable will do just fine.
*/
- cpu = source_ops(csdev)->cpu_id(csdev);
per_cpu(tracer_path, cpu) = path;
break;
case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
@@ -636,6 +643,9 @@ int coresight_enable(struct coresight_device *csdev)
mutex_unlock(&coresight_mutex);
return ret;

+err_kdump:
+ coresight_disable_source(csdev);
+
err_source:
coresight_disable_path(path);

@@ -659,9 +669,10 @@ void coresight_disable(struct coresight_device *csdev)
if (!csdev->enable || !coresight_disable_source(csdev))
goto out;

+ cpu = source_ops(csdev)->cpu_id(csdev);
+
switch (csdev->subtype.source_subtype) {
case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
- cpu = source_ops(csdev)->cpu_id(csdev);
path = per_cpu(tracer_path, cpu);
per_cpu(tracer_path, cpu) = NULL;
break;
@@ -674,6 +685,7 @@ void coresight_disable(struct coresight_device *csdev)
break;
}

+ coresight_kdump_sink(cpu, NULL);
coresight_disable_path(path);
coresight_release_path(path);

--
2.7.4


2018-03-30 03:17:43

by Leo Yan

[permalink] [raw]
Subject: [PATCH v4 1/6] doc: Add Coresight documentation directory

For easy management and friendly adding more Coresight documentation,
this commit creates a new directory: Documentation/trace/coresight.

This commit also moves Coresight related docs into the new directory
and updates MAINTAINERS file to reflect docs movement.

Signed-off-by: Leo Yan <[email protected]>
---
Documentation/trace/coresight-cpu-debug.txt | 187 ----------
Documentation/trace/coresight.txt | 383 ---------------------
.../trace/coresight/coresight-cpu-debug.txt | 187 ++++++++++
Documentation/trace/coresight/coresight.txt | 383 +++++++++++++++++++++
MAINTAINERS | 4 +-
5 files changed, 572 insertions(+), 572 deletions(-)
delete mode 100644 Documentation/trace/coresight-cpu-debug.txt
delete mode 100644 Documentation/trace/coresight.txt
create mode 100644 Documentation/trace/coresight/coresight-cpu-debug.txt
create mode 100644 Documentation/trace/coresight/coresight.txt

diff --git a/Documentation/trace/coresight-cpu-debug.txt b/Documentation/trace/coresight-cpu-debug.txt
deleted file mode 100644
index 2b9b51c..0000000
--- a/Documentation/trace/coresight-cpu-debug.txt
+++ /dev/null
@@ -1,187 +0,0 @@
- Coresight CPU Debug Module
- ==========================
-
- Author: Leo Yan <[email protected]>
- Date: April 5th, 2017
-
-Introduction
-------------
-
-Coresight CPU debug module is defined in ARMv8-a architecture reference manual
-(ARM DDI 0487A.k) Chapter 'Part H: External debug', the CPU can integrate
-debug module and it is mainly used for two modes: self-hosted debug and
-external debug. Usually the external debug mode is well known as the external
-debugger connects with SoC from JTAG port; on the other hand the program can
-explore debugging method which rely on self-hosted debug mode, this document
-is to focus on this part.
-
-The debug module provides sample-based profiling extension, which can be used
-to sample CPU program counter, secure state and exception level, etc; usually
-every CPU has one dedicated debug module to be connected. Based on self-hosted
-debug mechanism, Linux kernel can access these related registers from mmio
-region when the kernel panic happens. The callback notifier for kernel panic
-will dump related registers for every CPU; finally this is good for assistant
-analysis for panic.
-
-
-Implementation
---------------
-
-- During driver registration, it uses EDDEVID and EDDEVID1 - two device ID
- registers to decide if sample-based profiling is implemented or not. On some
- platforms this hardware feature is fully or partially implemented; and if
- this feature is not supported then registration will fail.
-
-- At the time this documentation was written, the debug driver mainly relies on
- information gathered by the kernel panic callback notifier from three
- sampling registers: EDPCSR, EDVIDSR and EDCIDSR: from EDPCSR we can get
- program counter; EDVIDSR has information for secure state, exception level,
- bit width, etc; EDCIDSR is context ID value which contains the sampled value
- of CONTEXTIDR_EL1.
-
-- The driver supports a CPU running in either AArch64 or AArch32 mode. The
- registers naming convention is a bit different between them, AArch64 uses
- 'ED' for register prefix (ARM DDI 0487A.k, chapter H9.1) and AArch32 uses
- 'DBG' as prefix (ARM DDI 0487A.k, chapter G5.1). The driver is unified to
- use AArch64 naming convention.
-
-- ARMv8-a (ARM DDI 0487A.k) and ARMv7-a (ARM DDI 0406C.b) have different
- register bits definition. So the driver consolidates two difference:
-
- If PCSROffset=0b0000, on ARMv8-a the feature of EDPCSR is not implemented;
- but ARMv7-a defines "PCSR samples are offset by a value that depends on the
- instruction set state". For ARMv7-a, the driver checks furthermore if CPU
- runs with ARM or thumb instruction set and calibrate PCSR value, the
- detailed description for offset is in ARMv7-a ARM (ARM DDI 0406C.b) chapter
- C11.11.34 "DBGPCSR, Program Counter Sampling Register".
-
- If PCSROffset=0b0010, ARMv8-a defines "EDPCSR implemented, and samples have
- no offset applied and do not sample the instruction set state in AArch32
- state". So on ARMv8 if EDDEVID1.PCSROffset is 0b0010 and the CPU operates
- in AArch32 state, EDPCSR is not sampled; when the CPU operates in AArch64
- state EDPCSR is sampled and no offset are applied.
-
-
-Clock and power domain
-----------------------
-
-Before accessing debug registers, we should ensure the clock and power domain
-have been enabled properly. In ARMv8-a ARM (ARM DDI 0487A.k) chapter 'H9.1
-Debug registers', the debug registers are spread into two domains: the debug
-domain and the CPU domain.
-
- +---------------+
- | |
- | |
- +----------+--+ |
- dbg_clock -->| |**| |<-- cpu_clock
- | Debug |**| CPU |
- dbg_power_domain -->| |**| |<-- cpu_power_domain
- +----------+--+ |
- | |
- | |
- +---------------+
-
-For debug domain, the user uses DT binding "clocks" and "power-domains" to
-specify the corresponding clock source and power supply for the debug logic.
-The driver calls the pm_runtime_{put|get} operations as needed to handle the
-debug power domain.
-
-For CPU domain, the different SoC designs have different power management
-schemes and finally this heavily impacts external debug module. So we can
-divide into below cases:
-
-- On systems with a sane power controller which can behave correctly with
- respect to CPU power domain, the CPU power domain can be controlled by
- register EDPRCR in driver. The driver firstly writes bit EDPRCR.COREPURQ
- to power up the CPU, and then writes bit EDPRCR.CORENPDRQ for emulation
- of CPU power down. As result, this can ensure the CPU power domain is
- powered on properly during the period when access debug related registers;
-
-- Some designs will power down an entire cluster if all CPUs on the cluster
- are powered down - including the parts of the debug registers that should
- remain powered in the debug power domain. The bits in EDPRCR are not
- respected in these cases, so these designs do not support debug over
- power down in the way that the CoreSight / Debug designers anticipated.
- This means that even checking EDPRSR has the potential to cause a bus hang
- if the target register is unpowered.
-
- In this case, accessing to the debug registers while they are not powered
- is a recipe for disaster; so we need preventing CPU low power states at boot
- time or when user enable module at the run time. Please see chapter
- "How to use the module" for detailed usage info for this.
-
-
-Device Tree Bindings
---------------------
-
-See Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt for details.
-
-
-How to use the module
----------------------
-
-If you want to enable debugging functionality at boot time, you can add
-"coresight_cpu_debug.enable=1" to the kernel command line parameter.
-
-The driver also can work as module, so can enable the debugging when insmod
-module:
-# insmod coresight_cpu_debug.ko debug=1
-
-When boot time or insmod module you have not enabled the debugging, the driver
-uses the debugfs file system to provide a knob to dynamically enable or disable
-debugging:
-
-To enable it, write a '1' into /sys/kernel/debug/coresight_cpu_debug/enable:
-# echo 1 > /sys/kernel/debug/coresight_cpu_debug/enable
-
-To disable it, write a '0' into /sys/kernel/debug/coresight_cpu_debug/enable:
-# echo 0 > /sys/kernel/debug/coresight_cpu_debug/enable
-
-As explained in chapter "Clock and power domain", if you are working on one
-platform which has idle states to power off debug logic and the power
-controller cannot work well for the request from EDPRCR, then you should
-firstly constraint CPU idle states before enable CPU debugging feature; so can
-ensure the accessing to debug logic.
-
-If you want to limit idle states at boot time, you can use "nohlt" or
-"cpuidle.off=1" in the kernel command line.
-
-At the runtime you can disable idle states with below methods:
-
-It is possible to disable CPU idle states by way of the PM QoS
-subsystem, more specifically by using the "/dev/cpu_dma_latency"
-interface (see Documentation/power/pm_qos_interface.txt for more
-details). As specified in the PM QoS documentation the requested
-parameter will stay in effect until the file descriptor is released.
-For example:
-
-# exec 3<> /dev/cpu_dma_latency; echo 0 >&3
-...
-Do some work...
-...
-# exec 3<>-
-
-The same can also be done from an application program.
-
-Disable specific CPU's specific idle state from cpuidle sysfs (see
-Documentation/cpuidle/sysfs.txt):
-# echo 1 > /sys/devices/system/cpu/cpu$cpu/cpuidle/state$state/disable
-
-
-Output format
--------------
-
-Here is an example of the debugging output format:
-
-ARM external debug module:
-coresight-cpu-debug 850000.debug: CPU[0]:
-coresight-cpu-debug 850000.debug: EDPRSR: 00000001 (Power:On DLK:Unlock)
-coresight-cpu-debug 850000.debug: EDPCSR: [<ffff00000808e9bc>] handle_IPI+0x174/0x1d8
-coresight-cpu-debug 850000.debug: EDCIDSR: 00000000
-coresight-cpu-debug 850000.debug: EDVIDSR: 90000000 (State:Non-secure Mode:EL1/0 Width:64bits VMID:0)
-coresight-cpu-debug 852000.debug: CPU[1]:
-coresight-cpu-debug 852000.debug: EDPRSR: 00000001 (Power:On DLK:Unlock)
-coresight-cpu-debug 852000.debug: EDPCSR: [<ffff0000087fab34>] debug_notifier_call+0x23c/0x358
-coresight-cpu-debug 852000.debug: EDCIDSR: 00000000
-coresight-cpu-debug 852000.debug: EDVIDSR: 90000000 (State:Non-secure Mode:EL1/0 Width:64bits VMID:0)
diff --git a/Documentation/trace/coresight.txt b/Documentation/trace/coresight.txt
deleted file mode 100644
index 6f0120c..0000000
--- a/Documentation/trace/coresight.txt
+++ /dev/null
@@ -1,383 +0,0 @@
- Coresight - HW Assisted Tracing on ARM
- ======================================
-
- Author: Mathieu Poirier <[email protected]>
- Date: September 11th, 2014
-
-Introduction
-------------
-
-Coresight is an umbrella of technologies allowing for the debugging of ARM
-based SoC. It includes solutions for JTAG and HW assisted tracing. This
-document is concerned with the latter.
-
-HW assisted tracing is becoming increasingly useful when dealing with systems
-that have many SoCs and other components like GPU and DMA engines. ARM has
-developed a HW assisted tracing solution by means of different components, each
-being added to a design at synthesis time to cater to specific tracing needs.
-Components are generally categorised as source, link and sinks and are
-(usually) discovered using the AMBA bus.
-
-"Sources" generate a compressed stream representing the processor instruction
-path based on tracing scenarios as configured by users. From there the stream
-flows through the coresight system (via ATB bus) using links that are connecting
-the emanating source to a sink(s). Sinks serve as endpoints to the coresight
-implementation, either storing the compressed stream in a memory buffer or
-creating an interface to the outside world where data can be transferred to a
-host without fear of filling up the onboard coresight memory buffer.
-
-At typical coresight system would look like this:
-
- *****************************************************************
- **************************** AMBA AXI ****************************===||
- ***************************************************************** ||
- ^ ^ | ||
- | | * **
- 0000000 ::::: 0000000 ::::: ::::: @@@@@@@ ||||||||||||
- 0 CPU 0<-->: C : 0 CPU 0<-->: C : : C : @ STM @ || System ||
- |->0000000 : T : |->0000000 : T : : T :<--->@@@@@ || Memory ||
- | #######<-->: I : | #######<-->: I : : I : @@@<-| ||||||||||||
- | # ETM # ::::: | # PTM # ::::: ::::: @ |
- | ##### ^ ^ | ##### ^ ! ^ ! . | |||||||||
- | |->### | ! | |->### | ! | ! . | || DAP ||
- | | # | ! | | # | ! | ! . | |||||||||
- | | . | ! | | . | ! | ! . | | |
- | | . | ! | | . | ! | ! . | | *
- | | . | ! | | . | ! | ! . | | SWD/
- | | . | ! | | . | ! | ! . | | JTAG
- *****************************************************************<-|
- *************************** AMBA Debug APB ************************
- *****************************************************************
- | . ! . ! ! . |
- | . * . * * . |
- *****************************************************************
- ******************** Cross Trigger Matrix (CTM) *******************
- *****************************************************************
- | . ^ . . |
- | * ! * * |
- *****************************************************************
- ****************** AMBA Advanced Trace Bus (ATB) ******************
- *****************************************************************
- | ! =============== |
- | * ===== F =====<---------|
- | ::::::::: ==== U ====
- |-->:: CTI ::<!! === N ===
- | ::::::::: ! == N ==
- | ^ * == E ==
- | ! &&&&&&&&& IIIIIII == L ==
- |------>&& ETB &&<......II I =======
- | ! &&&&&&&&& II I .
- | ! I I .
- | ! I REP I<..........
- | ! I I
- | !!>&&&&&&&&& II I *Source: ARM ltd.
- |------>& TPIU &<......II I DAP = Debug Access Port
- &&&&&&&&& IIIIIII ETM = Embedded Trace Macrocell
- ; PTM = Program Trace Macrocell
- ; CTI = Cross Trigger Interface
- * ETB = Embedded Trace Buffer
- To trace port TPIU= Trace Port Interface Unit
- SWD = Serial Wire Debug
-
-While on target configuration of the components is done via the APB bus,
-all trace data are carried out-of-band on the ATB bus. The CTM provides
-a way to aggregate and distribute signals between CoreSight components.
-
-The coresight framework provides a central point to represent, configure and
-manage coresight devices on a platform. This first implementation centers on
-the basic tracing functionality, enabling components such ETM/PTM, funnel,
-replicator, TMC, TPIU and ETB. Future work will enable more
-intricate IP blocks such as STM and CTI.
-
-
-Acronyms and Classification
----------------------------
-
-Acronyms:
-
-PTM: Program Trace Macrocell
-ETM: Embedded Trace Macrocell
-STM: System trace Macrocell
-ETB: Embedded Trace Buffer
-ITM: Instrumentation Trace Macrocell
-TPIU: Trace Port Interface Unit
-TMC-ETR: Trace Memory Controller, configured as Embedded Trace Router
-TMC-ETF: Trace Memory Controller, configured as Embedded Trace FIFO
-CTI: Cross Trigger Interface
-
-Classification:
-
-Source:
- ETMv3.x ETMv4, PTMv1.0, PTMv1.1, STM, STM500, ITM
-Link:
- Funnel, replicator (intelligent or not), TMC-ETR
-Sinks:
- ETBv1.0, ETB1.1, TPIU, TMC-ETF
-Misc:
- CTI
-
-
-Device Tree Bindings
-----------------------
-
-See Documentation/devicetree/bindings/arm/coresight.txt for details.
-
-As of this writing drivers for ITM, STMs and CTIs are not provided but are
-expected to be added as the solution matures.
-
-
-Framework and implementation
-----------------------------
-
-The coresight framework provides a central point to represent, configure and
-manage coresight devices on a platform. Any coresight compliant device can
-register with the framework for as long as they use the right APIs:
-
-struct coresight_device *coresight_register(struct coresight_desc *desc);
-void coresight_unregister(struct coresight_device *csdev);
-
-The registering function is taking a "struct coresight_device *csdev" and
-register the device with the core framework. The unregister function takes
-a reference to a "struct coresight_device", obtained at registration time.
-
-If everything goes well during the registration process the new devices will
-show up under /sys/bus/coresight/devices, as showns here for a TC2 platform:
-
-root:~# ls /sys/bus/coresight/devices/
-replicator 20030000.tpiu 2201c000.ptm 2203c000.etm 2203e000.etm
-20010000.etb 20040000.funnel 2201d000.ptm 2203d000.etm
-root:~#
-
-The functions take a "struct coresight_device", which looks like this:
-
-struct coresight_desc {
- enum coresight_dev_type type;
- struct coresight_dev_subtype subtype;
- const struct coresight_ops *ops;
- struct coresight_platform_data *pdata;
- struct device *dev;
- const struct attribute_group **groups;
-};
-
-
-The "coresight_dev_type" identifies what the device is, i.e, source link or
-sink while the "coresight_dev_subtype" will characterise that type further.
-
-The "struct coresight_ops" is mandatory and will tell the framework how to
-perform base operations related to the components, each component having
-a different set of requirement. For that "struct coresight_ops_sink",
-"struct coresight_ops_link" and "struct coresight_ops_source" have been
-provided.
-
-The next field, "struct coresight_platform_data *pdata" is acquired by calling
-"of_get_coresight_platform_data()", as part of the driver's _probe routine and
-"struct device *dev" gets the device reference embedded in the "amba_device":
-
-static int etm_probe(struct amba_device *adev, const struct amba_id *id)
-{
- ...
- ...
- drvdata->dev = &adev->dev;
- ...
-}
-
-Specific class of device (source, link, or sink) have generic operations
-that can be performed on them (see "struct coresight_ops"). The
-"**groups" is a list of sysfs entries pertaining to operations
-specific to that component only. "Implementation defined" customisations are
-expected to be accessed and controlled using those entries.
-
-Last but not least, "struct module *owner" is expected to be set to reflect
-the information carried in "THIS_MODULE".
-
-How to use the tracer modules
------------------------------
-
-Before trace collection can start, a coresight sink needs to be identify.
-There is no limit on the amount of sinks (nor sources) that can be enabled at
-any given moment. As a generic operation, all device pertaining to the sink
-class will have an "active" entry in sysfs:
-
-root:/sys/bus/coresight/devices# ls
-replicator 20030000.tpiu 2201c000.ptm 2203c000.etm 2203e000.etm
-20010000.etb 20040000.funnel 2201d000.ptm 2203d000.etm
-root:/sys/bus/coresight/devices# ls 20010000.etb
-enable_sink status trigger_cntr
-root:/sys/bus/coresight/devices# echo 1 > 20010000.etb/enable_sink
-root:/sys/bus/coresight/devices# cat 20010000.etb/enable_sink
-1
-root:/sys/bus/coresight/devices#
-
-At boot time the current etm3x driver will configure the first address
-comparator with "_stext" and "_etext", essentially tracing any instruction
-that falls within that range. As such "enabling" a source will immediately
-trigger a trace capture:
-
-root:/sys/bus/coresight/devices# echo 1 > 2201c000.ptm/enable_source
-root:/sys/bus/coresight/devices# cat 2201c000.ptm/enable_source
-1
-root:/sys/bus/coresight/devices# cat 20010000.etb/status
-Depth: 0x2000
-Status: 0x1
-RAM read ptr: 0x0
-RAM wrt ptr: 0x19d3 <----- The write pointer is moving
-Trigger cnt: 0x0
-Control: 0x1
-Flush status: 0x0
-Flush ctrl: 0x2001
-root:/sys/bus/coresight/devices#
-
-Trace collection is stopped the same way:
-
-root:/sys/bus/coresight/devices# echo 0 > 2201c000.ptm/enable_source
-root:/sys/bus/coresight/devices#
-
-The content of the ETB buffer can be harvested directly from /dev:
-
-root:/sys/bus/coresight/devices# dd if=/dev/20010000.etb \
-of=~/cstrace.bin
-
-64+0 records in
-64+0 records out
-32768 bytes (33 kB) copied, 0.00125258 s, 26.2 MB/s
-root:/sys/bus/coresight/devices#
-
-The file cstrace.bin can be decompressed using "ptm2human", DS-5 or Trace32.
-
-Following is a DS-5 output of an experimental loop that increments a variable up
-to a certain value. The example is simple and yet provides a glimpse of the
-wealth of possibilities that coresight provides.
-
-Info Tracing enabled
-Instruction 106378866 0x8026B53C E52DE004 false PUSH {lr}
-Instruction 0 0x8026B540 E24DD00C false SUB sp,sp,#0xc
-Instruction 0 0x8026B544 E3A03000 false MOV r3,#0
-Instruction 0 0x8026B548 E58D3004 false STR r3,[sp,#4]
-Instruction 0 0x8026B54C E59D3004 false LDR r3,[sp,#4]
-Instruction 0 0x8026B550 E3530004 false CMP r3,#4
-Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1
-Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4]
-Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c
-Timestamp Timestamp: 17106715833
-Instruction 319 0x8026B54C E59D3004 false LDR r3,[sp,#4]
-Instruction 0 0x8026B550 E3530004 false CMP r3,#4
-Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1
-Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4]
-Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c
-Instruction 9 0x8026B54C E59D3004 false LDR r3,[sp,#4]
-Instruction 0 0x8026B550 E3530004 false CMP r3,#4
-Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1
-Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4]
-Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c
-Instruction 7 0x8026B54C E59D3004 false LDR r3,[sp,#4]
-Instruction 0 0x8026B550 E3530004 false CMP r3,#4
-Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1
-Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4]
-Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c
-Instruction 7 0x8026B54C E59D3004 false LDR r3,[sp,#4]
-Instruction 0 0x8026B550 E3530004 false CMP r3,#4
-Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1
-Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4]
-Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c
-Instruction 10 0x8026B54C E59D3004 false LDR r3,[sp,#4]
-Instruction 0 0x8026B550 E3530004 false CMP r3,#4
-Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1
-Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4]
-Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c
-Instruction 6 0x8026B560 EE1D3F30 false MRC p15,#0x0,r3,c13,c0,#1
-Instruction 0 0x8026B564 E1A0100D false MOV r1,sp
-Instruction 0 0x8026B568 E3C12D7F false BIC r2,r1,#0x1fc0
-Instruction 0 0x8026B56C E3C2203F false BIC r2,r2,#0x3f
-Instruction 0 0x8026B570 E59D1004 false LDR r1,[sp,#4]
-Instruction 0 0x8026B574 E59F0010 false LDR r0,[pc,#16] ; [0x8026B58C] = 0x80550368
-Instruction 0 0x8026B578 E592200C false LDR r2,[r2,#0xc]
-Instruction 0 0x8026B57C E59221D0 false LDR r2,[r2,#0x1d0]
-Instruction 0 0x8026B580 EB07A4CF true BL {pc}+0x1e9344 ; 0x804548c4
-Info Tracing enabled
-Instruction 13570831 0x8026B584 E28DD00C false ADD sp,sp,#0xc
-Instruction 0 0x8026B588 E8BD8000 true LDM sp!,{pc}
-Timestamp Timestamp: 17107041535
-
-How to use the STM module
--------------------------
-
-Using the System Trace Macrocell module is the same as the tracers - the only
-difference is that clients are driving the trace capture rather
-than the program flow through the code.
-
-As with any other CoreSight component, specifics about the STM tracer can be
-found in sysfs with more information on each entry being found in [1]:
-
-root@genericarmv8:~# ls /sys/bus/coresight/devices/20100000.stm
-enable_source hwevent_select port_enable subsystem uevent
-hwevent_enable mgmt port_select traceid
-root@genericarmv8:~#
-
-Like any other source a sink needs to be identified and the STM enabled before
-being used:
-
-root@genericarmv8:~# echo 1 > /sys/bus/coresight/devices/20010000.etf/enable_sink
-root@genericarmv8:~# echo 1 > /sys/bus/coresight/devices/20100000.stm/enable_source
-
-From there user space applications can request and use channels using the devfs
-interface provided for that purpose by the generic STM API:
-
-root@genericarmv8:~# ls -l /dev/20100000.stm
-crw------- 1 root root 10, 61 Jan 3 18:11 /dev/20100000.stm
-root@genericarmv8:~#
-
-Details on how to use the generic STM API can be found here [2].
-
-[1]. Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
-[2]. Documentation/trace/stm.txt
-
-
-Using perf tools
-----------------
-
-perf can be used to record and analyze trace of programs.
-
-Execution can be recorded using 'perf record' with the cs_etm event,
-specifying the name of the sink to record to, e.g:
-
- perf record -e cs_etm/@20070000.etr/u --per-thread
-
-The 'perf report' and 'perf script' commands can be used to analyze execution,
-synthesizing instruction and branch events from the instruction trace.
-'perf inject' can be used to replace the trace data with the synthesized events.
-The --itrace option controls the type and frequency of synthesized events
-(see perf documentation).
-
-Note that only 64-bit programs are currently supported - further work is
-required to support instruction decode of 32-bit Arm programs.
-
-
-Generating coverage files for Feedback Directed Optimization: AutoFDO
----------------------------------------------------------------------
-
-'perf inject' accepts the --itrace option in which case tracing data is
-removed and replaced with the synthesized events. e.g.
-
- perf inject --itrace --strip -i perf.data -o perf.data.new
-
-Below is an example of using ARM ETM for autoFDO. It requires autofdo
-(https://github.com/google/autofdo) and gcc version 5. The bubble
-sort example is from the AutoFDO tutorial (https://gcc.gnu.org/wiki/AutoFDO/Tutorial).
-
- $ gcc-5 -O3 sort.c -o sort
- $ taskset -c 2 ./sort
- Bubble sorting array of 30000 elements
- 5910 ms
-
- $ perf record -e cs_etm/@20070000.etr/u --per-thread taskset -c 2 ./sort
- Bubble sorting array of 30000 elements
- 12543 ms
- [ perf record: Woken up 35 times to write data ]
- [ perf record: Captured and wrote 69.640 MB perf.data ]
-
- $ perf inject -i perf.data -o inj.data --itrace=il64 --strip
- $ create_gcov --binary=./sort --profile=inj.data --gcov=sort.gcov -gcov_version=1
- $ gcc-5 -O3 -fauto-profile=sort.gcov sort.c -o sort_autofdo
- $ taskset -c 2 ./sort_autofdo
- Bubble sorting array of 30000 elements
- 5806 ms
diff --git a/Documentation/trace/coresight/coresight-cpu-debug.txt b/Documentation/trace/coresight/coresight-cpu-debug.txt
new file mode 100644
index 0000000..2b9b51c
--- /dev/null
+++ b/Documentation/trace/coresight/coresight-cpu-debug.txt
@@ -0,0 +1,187 @@
+ Coresight CPU Debug Module
+ ==========================
+
+ Author: Leo Yan <[email protected]>
+ Date: April 5th, 2017
+
+Introduction
+------------
+
+Coresight CPU debug module is defined in ARMv8-a architecture reference manual
+(ARM DDI 0487A.k) Chapter 'Part H: External debug', the CPU can integrate
+debug module and it is mainly used for two modes: self-hosted debug and
+external debug. Usually the external debug mode is well known as the external
+debugger connects with SoC from JTAG port; on the other hand the program can
+explore debugging method which rely on self-hosted debug mode, this document
+is to focus on this part.
+
+The debug module provides sample-based profiling extension, which can be used
+to sample CPU program counter, secure state and exception level, etc; usually
+every CPU has one dedicated debug module to be connected. Based on self-hosted
+debug mechanism, Linux kernel can access these related registers from mmio
+region when the kernel panic happens. The callback notifier for kernel panic
+will dump related registers for every CPU; finally this is good for assistant
+analysis for panic.
+
+
+Implementation
+--------------
+
+- During driver registration, it uses EDDEVID and EDDEVID1 - two device ID
+ registers to decide if sample-based profiling is implemented or not. On some
+ platforms this hardware feature is fully or partially implemented; and if
+ this feature is not supported then registration will fail.
+
+- At the time this documentation was written, the debug driver mainly relies on
+ information gathered by the kernel panic callback notifier from three
+ sampling registers: EDPCSR, EDVIDSR and EDCIDSR: from EDPCSR we can get
+ program counter; EDVIDSR has information for secure state, exception level,
+ bit width, etc; EDCIDSR is context ID value which contains the sampled value
+ of CONTEXTIDR_EL1.
+
+- The driver supports a CPU running in either AArch64 or AArch32 mode. The
+ registers naming convention is a bit different between them, AArch64 uses
+ 'ED' for register prefix (ARM DDI 0487A.k, chapter H9.1) and AArch32 uses
+ 'DBG' as prefix (ARM DDI 0487A.k, chapter G5.1). The driver is unified to
+ use AArch64 naming convention.
+
+- ARMv8-a (ARM DDI 0487A.k) and ARMv7-a (ARM DDI 0406C.b) have different
+ register bits definition. So the driver consolidates two difference:
+
+ If PCSROffset=0b0000, on ARMv8-a the feature of EDPCSR is not implemented;
+ but ARMv7-a defines "PCSR samples are offset by a value that depends on the
+ instruction set state". For ARMv7-a, the driver checks furthermore if CPU
+ runs with ARM or thumb instruction set and calibrate PCSR value, the
+ detailed description for offset is in ARMv7-a ARM (ARM DDI 0406C.b) chapter
+ C11.11.34 "DBGPCSR, Program Counter Sampling Register".
+
+ If PCSROffset=0b0010, ARMv8-a defines "EDPCSR implemented, and samples have
+ no offset applied and do not sample the instruction set state in AArch32
+ state". So on ARMv8 if EDDEVID1.PCSROffset is 0b0010 and the CPU operates
+ in AArch32 state, EDPCSR is not sampled; when the CPU operates in AArch64
+ state EDPCSR is sampled and no offset are applied.
+
+
+Clock and power domain
+----------------------
+
+Before accessing debug registers, we should ensure the clock and power domain
+have been enabled properly. In ARMv8-a ARM (ARM DDI 0487A.k) chapter 'H9.1
+Debug registers', the debug registers are spread into two domains: the debug
+domain and the CPU domain.
+
+ +---------------+
+ | |
+ | |
+ +----------+--+ |
+ dbg_clock -->| |**| |<-- cpu_clock
+ | Debug |**| CPU |
+ dbg_power_domain -->| |**| |<-- cpu_power_domain
+ +----------+--+ |
+ | |
+ | |
+ +---------------+
+
+For debug domain, the user uses DT binding "clocks" and "power-domains" to
+specify the corresponding clock source and power supply for the debug logic.
+The driver calls the pm_runtime_{put|get} operations as needed to handle the
+debug power domain.
+
+For CPU domain, the different SoC designs have different power management
+schemes and finally this heavily impacts external debug module. So we can
+divide into below cases:
+
+- On systems with a sane power controller which can behave correctly with
+ respect to CPU power domain, the CPU power domain can be controlled by
+ register EDPRCR in driver. The driver firstly writes bit EDPRCR.COREPURQ
+ to power up the CPU, and then writes bit EDPRCR.CORENPDRQ for emulation
+ of CPU power down. As result, this can ensure the CPU power domain is
+ powered on properly during the period when access debug related registers;
+
+- Some designs will power down an entire cluster if all CPUs on the cluster
+ are powered down - including the parts of the debug registers that should
+ remain powered in the debug power domain. The bits in EDPRCR are not
+ respected in these cases, so these designs do not support debug over
+ power down in the way that the CoreSight / Debug designers anticipated.
+ This means that even checking EDPRSR has the potential to cause a bus hang
+ if the target register is unpowered.
+
+ In this case, accessing to the debug registers while they are not powered
+ is a recipe for disaster; so we need preventing CPU low power states at boot
+ time or when user enable module at the run time. Please see chapter
+ "How to use the module" for detailed usage info for this.
+
+
+Device Tree Bindings
+--------------------
+
+See Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt for details.
+
+
+How to use the module
+---------------------
+
+If you want to enable debugging functionality at boot time, you can add
+"coresight_cpu_debug.enable=1" to the kernel command line parameter.
+
+The driver also can work as module, so can enable the debugging when insmod
+module:
+# insmod coresight_cpu_debug.ko debug=1
+
+When boot time or insmod module you have not enabled the debugging, the driver
+uses the debugfs file system to provide a knob to dynamically enable or disable
+debugging:
+
+To enable it, write a '1' into /sys/kernel/debug/coresight_cpu_debug/enable:
+# echo 1 > /sys/kernel/debug/coresight_cpu_debug/enable
+
+To disable it, write a '0' into /sys/kernel/debug/coresight_cpu_debug/enable:
+# echo 0 > /sys/kernel/debug/coresight_cpu_debug/enable
+
+As explained in chapter "Clock and power domain", if you are working on one
+platform which has idle states to power off debug logic and the power
+controller cannot work well for the request from EDPRCR, then you should
+firstly constraint CPU idle states before enable CPU debugging feature; so can
+ensure the accessing to debug logic.
+
+If you want to limit idle states at boot time, you can use "nohlt" or
+"cpuidle.off=1" in the kernel command line.
+
+At the runtime you can disable idle states with below methods:
+
+It is possible to disable CPU idle states by way of the PM QoS
+subsystem, more specifically by using the "/dev/cpu_dma_latency"
+interface (see Documentation/power/pm_qos_interface.txt for more
+details). As specified in the PM QoS documentation the requested
+parameter will stay in effect until the file descriptor is released.
+For example:
+
+# exec 3<> /dev/cpu_dma_latency; echo 0 >&3
+...
+Do some work...
+...
+# exec 3<>-
+
+The same can also be done from an application program.
+
+Disable specific CPU's specific idle state from cpuidle sysfs (see
+Documentation/cpuidle/sysfs.txt):
+# echo 1 > /sys/devices/system/cpu/cpu$cpu/cpuidle/state$state/disable
+
+
+Output format
+-------------
+
+Here is an example of the debugging output format:
+
+ARM external debug module:
+coresight-cpu-debug 850000.debug: CPU[0]:
+coresight-cpu-debug 850000.debug: EDPRSR: 00000001 (Power:On DLK:Unlock)
+coresight-cpu-debug 850000.debug: EDPCSR: [<ffff00000808e9bc>] handle_IPI+0x174/0x1d8
+coresight-cpu-debug 850000.debug: EDCIDSR: 00000000
+coresight-cpu-debug 850000.debug: EDVIDSR: 90000000 (State:Non-secure Mode:EL1/0 Width:64bits VMID:0)
+coresight-cpu-debug 852000.debug: CPU[1]:
+coresight-cpu-debug 852000.debug: EDPRSR: 00000001 (Power:On DLK:Unlock)
+coresight-cpu-debug 852000.debug: EDPCSR: [<ffff0000087fab34>] debug_notifier_call+0x23c/0x358
+coresight-cpu-debug 852000.debug: EDCIDSR: 00000000
+coresight-cpu-debug 852000.debug: EDVIDSR: 90000000 (State:Non-secure Mode:EL1/0 Width:64bits VMID:0)
diff --git a/Documentation/trace/coresight/coresight.txt b/Documentation/trace/coresight/coresight.txt
new file mode 100644
index 0000000..6f0120c
--- /dev/null
+++ b/Documentation/trace/coresight/coresight.txt
@@ -0,0 +1,383 @@
+ Coresight - HW Assisted Tracing on ARM
+ ======================================
+
+ Author: Mathieu Poirier <[email protected]>
+ Date: September 11th, 2014
+
+Introduction
+------------
+
+Coresight is an umbrella of technologies allowing for the debugging of ARM
+based SoC. It includes solutions for JTAG and HW assisted tracing. This
+document is concerned with the latter.
+
+HW assisted tracing is becoming increasingly useful when dealing with systems
+that have many SoCs and other components like GPU and DMA engines. ARM has
+developed a HW assisted tracing solution by means of different components, each
+being added to a design at synthesis time to cater to specific tracing needs.
+Components are generally categorised as source, link and sinks and are
+(usually) discovered using the AMBA bus.
+
+"Sources" generate a compressed stream representing the processor instruction
+path based on tracing scenarios as configured by users. From there the stream
+flows through the coresight system (via ATB bus) using links that are connecting
+the emanating source to a sink(s). Sinks serve as endpoints to the coresight
+implementation, either storing the compressed stream in a memory buffer or
+creating an interface to the outside world where data can be transferred to a
+host without fear of filling up the onboard coresight memory buffer.
+
+At typical coresight system would look like this:
+
+ *****************************************************************
+ **************************** AMBA AXI ****************************===||
+ ***************************************************************** ||
+ ^ ^ | ||
+ | | * **
+ 0000000 ::::: 0000000 ::::: ::::: @@@@@@@ ||||||||||||
+ 0 CPU 0<-->: C : 0 CPU 0<-->: C : : C : @ STM @ || System ||
+ |->0000000 : T : |->0000000 : T : : T :<--->@@@@@ || Memory ||
+ | #######<-->: I : | #######<-->: I : : I : @@@<-| ||||||||||||
+ | # ETM # ::::: | # PTM # ::::: ::::: @ |
+ | ##### ^ ^ | ##### ^ ! ^ ! . | |||||||||
+ | |->### | ! | |->### | ! | ! . | || DAP ||
+ | | # | ! | | # | ! | ! . | |||||||||
+ | | . | ! | | . | ! | ! . | | |
+ | | . | ! | | . | ! | ! . | | *
+ | | . | ! | | . | ! | ! . | | SWD/
+ | | . | ! | | . | ! | ! . | | JTAG
+ *****************************************************************<-|
+ *************************** AMBA Debug APB ************************
+ *****************************************************************
+ | . ! . ! ! . |
+ | . * . * * . |
+ *****************************************************************
+ ******************** Cross Trigger Matrix (CTM) *******************
+ *****************************************************************
+ | . ^ . . |
+ | * ! * * |
+ *****************************************************************
+ ****************** AMBA Advanced Trace Bus (ATB) ******************
+ *****************************************************************
+ | ! =============== |
+ | * ===== F =====<---------|
+ | ::::::::: ==== U ====
+ |-->:: CTI ::<!! === N ===
+ | ::::::::: ! == N ==
+ | ^ * == E ==
+ | ! &&&&&&&&& IIIIIII == L ==
+ |------>&& ETB &&<......II I =======
+ | ! &&&&&&&&& II I .
+ | ! I I .
+ | ! I REP I<..........
+ | ! I I
+ | !!>&&&&&&&&& II I *Source: ARM ltd.
+ |------>& TPIU &<......II I DAP = Debug Access Port
+ &&&&&&&&& IIIIIII ETM = Embedded Trace Macrocell
+ ; PTM = Program Trace Macrocell
+ ; CTI = Cross Trigger Interface
+ * ETB = Embedded Trace Buffer
+ To trace port TPIU= Trace Port Interface Unit
+ SWD = Serial Wire Debug
+
+While on target configuration of the components is done via the APB bus,
+all trace data are carried out-of-band on the ATB bus. The CTM provides
+a way to aggregate and distribute signals between CoreSight components.
+
+The coresight framework provides a central point to represent, configure and
+manage coresight devices on a platform. This first implementation centers on
+the basic tracing functionality, enabling components such ETM/PTM, funnel,
+replicator, TMC, TPIU and ETB. Future work will enable more
+intricate IP blocks such as STM and CTI.
+
+
+Acronyms and Classification
+---------------------------
+
+Acronyms:
+
+PTM: Program Trace Macrocell
+ETM: Embedded Trace Macrocell
+STM: System trace Macrocell
+ETB: Embedded Trace Buffer
+ITM: Instrumentation Trace Macrocell
+TPIU: Trace Port Interface Unit
+TMC-ETR: Trace Memory Controller, configured as Embedded Trace Router
+TMC-ETF: Trace Memory Controller, configured as Embedded Trace FIFO
+CTI: Cross Trigger Interface
+
+Classification:
+
+Source:
+ ETMv3.x ETMv4, PTMv1.0, PTMv1.1, STM, STM500, ITM
+Link:
+ Funnel, replicator (intelligent or not), TMC-ETR
+Sinks:
+ ETBv1.0, ETB1.1, TPIU, TMC-ETF
+Misc:
+ CTI
+
+
+Device Tree Bindings
+----------------------
+
+See Documentation/devicetree/bindings/arm/coresight.txt for details.
+
+As of this writing drivers for ITM, STMs and CTIs are not provided but are
+expected to be added as the solution matures.
+
+
+Framework and implementation
+----------------------------
+
+The coresight framework provides a central point to represent, configure and
+manage coresight devices on a platform. Any coresight compliant device can
+register with the framework for as long as they use the right APIs:
+
+struct coresight_device *coresight_register(struct coresight_desc *desc);
+void coresight_unregister(struct coresight_device *csdev);
+
+The registering function is taking a "struct coresight_device *csdev" and
+register the device with the core framework. The unregister function takes
+a reference to a "struct coresight_device", obtained at registration time.
+
+If everything goes well during the registration process the new devices will
+show up under /sys/bus/coresight/devices, as showns here for a TC2 platform:
+
+root:~# ls /sys/bus/coresight/devices/
+replicator 20030000.tpiu 2201c000.ptm 2203c000.etm 2203e000.etm
+20010000.etb 20040000.funnel 2201d000.ptm 2203d000.etm
+root:~#
+
+The functions take a "struct coresight_device", which looks like this:
+
+struct coresight_desc {
+ enum coresight_dev_type type;
+ struct coresight_dev_subtype subtype;
+ const struct coresight_ops *ops;
+ struct coresight_platform_data *pdata;
+ struct device *dev;
+ const struct attribute_group **groups;
+};
+
+
+The "coresight_dev_type" identifies what the device is, i.e, source link or
+sink while the "coresight_dev_subtype" will characterise that type further.
+
+The "struct coresight_ops" is mandatory and will tell the framework how to
+perform base operations related to the components, each component having
+a different set of requirement. For that "struct coresight_ops_sink",
+"struct coresight_ops_link" and "struct coresight_ops_source" have been
+provided.
+
+The next field, "struct coresight_platform_data *pdata" is acquired by calling
+"of_get_coresight_platform_data()", as part of the driver's _probe routine and
+"struct device *dev" gets the device reference embedded in the "amba_device":
+
+static int etm_probe(struct amba_device *adev, const struct amba_id *id)
+{
+ ...
+ ...
+ drvdata->dev = &adev->dev;
+ ...
+}
+
+Specific class of device (source, link, or sink) have generic operations
+that can be performed on them (see "struct coresight_ops"). The
+"**groups" is a list of sysfs entries pertaining to operations
+specific to that component only. "Implementation defined" customisations are
+expected to be accessed and controlled using those entries.
+
+Last but not least, "struct module *owner" is expected to be set to reflect
+the information carried in "THIS_MODULE".
+
+How to use the tracer modules
+-----------------------------
+
+Before trace collection can start, a coresight sink needs to be identify.
+There is no limit on the amount of sinks (nor sources) that can be enabled at
+any given moment. As a generic operation, all device pertaining to the sink
+class will have an "active" entry in sysfs:
+
+root:/sys/bus/coresight/devices# ls
+replicator 20030000.tpiu 2201c000.ptm 2203c000.etm 2203e000.etm
+20010000.etb 20040000.funnel 2201d000.ptm 2203d000.etm
+root:/sys/bus/coresight/devices# ls 20010000.etb
+enable_sink status trigger_cntr
+root:/sys/bus/coresight/devices# echo 1 > 20010000.etb/enable_sink
+root:/sys/bus/coresight/devices# cat 20010000.etb/enable_sink
+1
+root:/sys/bus/coresight/devices#
+
+At boot time the current etm3x driver will configure the first address
+comparator with "_stext" and "_etext", essentially tracing any instruction
+that falls within that range. As such "enabling" a source will immediately
+trigger a trace capture:
+
+root:/sys/bus/coresight/devices# echo 1 > 2201c000.ptm/enable_source
+root:/sys/bus/coresight/devices# cat 2201c000.ptm/enable_source
+1
+root:/sys/bus/coresight/devices# cat 20010000.etb/status
+Depth: 0x2000
+Status: 0x1
+RAM read ptr: 0x0
+RAM wrt ptr: 0x19d3 <----- The write pointer is moving
+Trigger cnt: 0x0
+Control: 0x1
+Flush status: 0x0
+Flush ctrl: 0x2001
+root:/sys/bus/coresight/devices#
+
+Trace collection is stopped the same way:
+
+root:/sys/bus/coresight/devices# echo 0 > 2201c000.ptm/enable_source
+root:/sys/bus/coresight/devices#
+
+The content of the ETB buffer can be harvested directly from /dev:
+
+root:/sys/bus/coresight/devices# dd if=/dev/20010000.etb \
+of=~/cstrace.bin
+
+64+0 records in
+64+0 records out
+32768 bytes (33 kB) copied, 0.00125258 s, 26.2 MB/s
+root:/sys/bus/coresight/devices#
+
+The file cstrace.bin can be decompressed using "ptm2human", DS-5 or Trace32.
+
+Following is a DS-5 output of an experimental loop that increments a variable up
+to a certain value. The example is simple and yet provides a glimpse of the
+wealth of possibilities that coresight provides.
+
+Info Tracing enabled
+Instruction 106378866 0x8026B53C E52DE004 false PUSH {lr}
+Instruction 0 0x8026B540 E24DD00C false SUB sp,sp,#0xc
+Instruction 0 0x8026B544 E3A03000 false MOV r3,#0
+Instruction 0 0x8026B548 E58D3004 false STR r3,[sp,#4]
+Instruction 0 0x8026B54C E59D3004 false LDR r3,[sp,#4]
+Instruction 0 0x8026B550 E3530004 false CMP r3,#4
+Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1
+Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4]
+Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c
+Timestamp Timestamp: 17106715833
+Instruction 319 0x8026B54C E59D3004 false LDR r3,[sp,#4]
+Instruction 0 0x8026B550 E3530004 false CMP r3,#4
+Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1
+Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4]
+Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c
+Instruction 9 0x8026B54C E59D3004 false LDR r3,[sp,#4]
+Instruction 0 0x8026B550 E3530004 false CMP r3,#4
+Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1
+Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4]
+Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c
+Instruction 7 0x8026B54C E59D3004 false LDR r3,[sp,#4]
+Instruction 0 0x8026B550 E3530004 false CMP r3,#4
+Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1
+Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4]
+Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c
+Instruction 7 0x8026B54C E59D3004 false LDR r3,[sp,#4]
+Instruction 0 0x8026B550 E3530004 false CMP r3,#4
+Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1
+Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4]
+Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c
+Instruction 10 0x8026B54C E59D3004 false LDR r3,[sp,#4]
+Instruction 0 0x8026B550 E3530004 false CMP r3,#4
+Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1
+Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4]
+Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c
+Instruction 6 0x8026B560 EE1D3F30 false MRC p15,#0x0,r3,c13,c0,#1
+Instruction 0 0x8026B564 E1A0100D false MOV r1,sp
+Instruction 0 0x8026B568 E3C12D7F false BIC r2,r1,#0x1fc0
+Instruction 0 0x8026B56C E3C2203F false BIC r2,r2,#0x3f
+Instruction 0 0x8026B570 E59D1004 false LDR r1,[sp,#4]
+Instruction 0 0x8026B574 E59F0010 false LDR r0,[pc,#16] ; [0x8026B58C] = 0x80550368
+Instruction 0 0x8026B578 E592200C false LDR r2,[r2,#0xc]
+Instruction 0 0x8026B57C E59221D0 false LDR r2,[r2,#0x1d0]
+Instruction 0 0x8026B580 EB07A4CF true BL {pc}+0x1e9344 ; 0x804548c4
+Info Tracing enabled
+Instruction 13570831 0x8026B584 E28DD00C false ADD sp,sp,#0xc
+Instruction 0 0x8026B588 E8BD8000 true LDM sp!,{pc}
+Timestamp Timestamp: 17107041535
+
+How to use the STM module
+-------------------------
+
+Using the System Trace Macrocell module is the same as the tracers - the only
+difference is that clients are driving the trace capture rather
+than the program flow through the code.
+
+As with any other CoreSight component, specifics about the STM tracer can be
+found in sysfs with more information on each entry being found in [1]:
+
+root@genericarmv8:~# ls /sys/bus/coresight/devices/20100000.stm
+enable_source hwevent_select port_enable subsystem uevent
+hwevent_enable mgmt port_select traceid
+root@genericarmv8:~#
+
+Like any other source a sink needs to be identified and the STM enabled before
+being used:
+
+root@genericarmv8:~# echo 1 > /sys/bus/coresight/devices/20010000.etf/enable_sink
+root@genericarmv8:~# echo 1 > /sys/bus/coresight/devices/20100000.stm/enable_source
+
+From there user space applications can request and use channels using the devfs
+interface provided for that purpose by the generic STM API:
+
+root@genericarmv8:~# ls -l /dev/20100000.stm
+crw------- 1 root root 10, 61 Jan 3 18:11 /dev/20100000.stm
+root@genericarmv8:~#
+
+Details on how to use the generic STM API can be found here [2].
+
+[1]. Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
+[2]. Documentation/trace/stm.txt
+
+
+Using perf tools
+----------------
+
+perf can be used to record and analyze trace of programs.
+
+Execution can be recorded using 'perf record' with the cs_etm event,
+specifying the name of the sink to record to, e.g:
+
+ perf record -e cs_etm/@20070000.etr/u --per-thread
+
+The 'perf report' and 'perf script' commands can be used to analyze execution,
+synthesizing instruction and branch events from the instruction trace.
+'perf inject' can be used to replace the trace data with the synthesized events.
+The --itrace option controls the type and frequency of synthesized events
+(see perf documentation).
+
+Note that only 64-bit programs are currently supported - further work is
+required to support instruction decode of 32-bit Arm programs.
+
+
+Generating coverage files for Feedback Directed Optimization: AutoFDO
+---------------------------------------------------------------------
+
+'perf inject' accepts the --itrace option in which case tracing data is
+removed and replaced with the synthesized events. e.g.
+
+ perf inject --itrace --strip -i perf.data -o perf.data.new
+
+Below is an example of using ARM ETM for autoFDO. It requires autofdo
+(https://github.com/google/autofdo) and gcc version 5. The bubble
+sort example is from the AutoFDO tutorial (https://gcc.gnu.org/wiki/AutoFDO/Tutorial).
+
+ $ gcc-5 -O3 sort.c -o sort
+ $ taskset -c 2 ./sort
+ Bubble sorting array of 30000 elements
+ 5910 ms
+
+ $ perf record -e cs_etm/@20070000.etr/u --per-thread taskset -c 2 ./sort
+ Bubble sorting array of 30000 elements
+ 12543 ms
+ [ perf record: Woken up 35 times to write data ]
+ [ perf record: Captured and wrote 69.640 MB perf.data ]
+
+ $ perf inject -i perf.data -o inj.data --itrace=il64 --strip
+ $ create_gcov --binary=./sort --profile=inj.data --gcov=sort.gcov -gcov_version=1
+ $ gcc-5 -O3 -fauto-profile=sort.gcov sort.c -o sort_autofdo
+ $ taskset -c 2 ./sort_autofdo
+ Bubble sorting array of 30000 elements
+ 5806 ms
diff --git a/MAINTAINERS b/MAINTAINERS
index 205c8fc..7ee1fdc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1331,8 +1331,8 @@ M: Mathieu Poirier <[email protected]>
L: [email protected] (moderated for non-subscribers)
S: Maintained
F: drivers/hwtracing/coresight/*
-F: Documentation/trace/coresight.txt
-F: Documentation/trace/coresight-cpu-debug.txt
+F: Documentation/trace/coresight/coresight.txt
+F: Documentation/trace/coresight/coresight-cpu-debug.txt
F: Documentation/devicetree/bindings/arm/coresight.txt
F: Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt
F: Documentation/ABI/testing/sysfs-bus-coresight-devices-*
--
2.7.4


2018-03-30 03:17:47

by Leo Yan

[permalink] [raw]
Subject: [PATCH v4 6/6] coresight: etm4x: Support panic kdump

ETMv4 hardware information and configuration needs to be saved as
metadata; the metadata format should be compatible with 'perf' tool and
finally is used by tracing data decoder. ETMv4 works as tracer per CPU,
we cannot wait for gathering ETM info after CPU panic has happened in
case there have CPU is locked up and can't response inter-processor
interrupt for execution dump operations; so it's more reliable to gather
tracer metadata when all of the CPUs are alive.

This patch saves ETMv4 metadata but with the different method for
different registers. Since values in TRCIDR{0, 1, 2, 8} and
TRCAUTHSTATUS are read-only and won't change afterward, thus those
registers values are filled into metadata structure when tracers are
instantiated. The configuration and control registers TRCCONFIGR and
TRCTRACEIDR are dynamically configured, their values are recorded during
tracer enabling phase.

To avoid unnecessary overload introduced by set/clear operations for
updating kdump node, we only set ETMv4 metadata info for the
corresponding kdump node at initialization and won't be cleared anymore.

Suggested-by: Mathieu Poirier <[email protected]>
Signed-off-by: Leo Yan <[email protected]>
---
drivers/hwtracing/coresight/coresight-etm4x.c | 27 +++++++++++++++++++++++++++
drivers/hwtracing/coresight/coresight-etm4x.h | 15 +++++++++++++++
2 files changed, 42 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index cf364a5..88b1e19 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -288,6 +288,8 @@ static int etm4_enable(struct coresight_device *csdev,
int ret;
u32 val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct etmv4_config *config = &drvdata->config;
+ struct etmv4_metadata *metadata = &drvdata->metadata;

val = local_cmpxchg(&drvdata->mode, CS_MODE_DISABLED, mode);

@@ -306,6 +308,10 @@ static int etm4_enable(struct coresight_device *csdev,
ret = -EINVAL;
}

+ /* Update tracer meta data after tracer configuration */
+ metadata->trcconfigr = config->cfg;
+ metadata->trctraceidr = drvdata->trcid;
+
/* The tracer didn't start */
if (ret)
local_set(&drvdata->mode, CS_MODE_DISABLED);
@@ -438,6 +444,7 @@ static void etm4_init_arch_data(void *info)
u32 etmidr4;
u32 etmidr5;
struct etmv4_drvdata *drvdata = info;
+ struct etmv4_metadata *metadata = &drvdata->metadata;

/* Make sure all registers are accessible */
etm4_os_unlock(drvdata);
@@ -590,6 +597,16 @@ static void etm4_init_arch_data(void *info)
drvdata->nrseqstate = BMVAL(etmidr5, 25, 27);
/* NUMCNTR, bits[30:28] number of counters available for tracing */
drvdata->nr_cntr = BMVAL(etmidr5, 28, 30);
+
+ /* Update metadata */
+ metadata->magic = ETM4_METADATA_MAGIC;
+ metadata->cpu = drvdata->cpu;
+ metadata->trcidr0 = readl_relaxed(drvdata->base + TRCIDR0);
+ metadata->trcidr1 = readl_relaxed(drvdata->base + TRCIDR1);
+ metadata->trcidr2 = readl_relaxed(drvdata->base + TRCIDR2);
+ metadata->trcidr8 = readl_relaxed(drvdata->base + TRCIDR8);
+ metadata->trcauthstatus = readl_relaxed(drvdata->base + TRCAUTHSTATUS);
+
CS_LOCK(drvdata->base);
}

@@ -957,6 +974,7 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
struct device *dev = &adev->dev;
struct coresight_platform_data *pdata = NULL;
struct etmv4_drvdata *drvdata;
+ struct etmv4_metadata *metadata;
struct resource *res = &adev->res;
struct coresight_desc desc = { 0 };
struct device_node *np = adev->dev.of_node;
@@ -1027,6 +1045,15 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
goto err_arch_supported;
}

+ /* Set source device handler and metadata into kdump node */
+ metadata = &drvdata->metadata;
+ ret = coresight_kdump_source(drvdata->cpu, drvdata->csdev,
+ (char *)metadata, sizeof(*metadata));
+ if (ret) {
+ coresight_unregister(drvdata->csdev);
+ goto err_arch_supported;
+ }
+
ret = etm_perf_symlink(drvdata->csdev, true);
if (ret) {
coresight_unregister(drvdata->csdev);
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index b3b5ea7..08dc8b7 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -198,6 +198,20 @@
#define ETM_EXLEVEL_NS_HYP BIT(14)
#define ETM_EXLEVEL_NS_NA BIT(15)

+#define ETM4_METADATA_MAGIC 0x4040404040404040ULL
+
+struct etmv4_metadata {
+ u64 magic;
+ u64 cpu;
+ u64 trcconfigr;
+ u64 trctraceidr;
+ u64 trcidr0;
+ u64 trcidr1;
+ u64 trcidr2;
+ u64 trcidr8;
+ u64 trcauthstatus;
+};
+
/**
* struct etmv4_config - configuration information related to an ETMv4
* @mode: Controls various modes supported by this ETM.
@@ -393,6 +407,7 @@ struct etmv4_drvdata {
bool atbtrig;
bool lpoverride;
struct etmv4_config config;
+ struct etmv4_metadata metadata;
};

/* Address comparator access types */
--
2.7.4


2018-03-30 03:19:03

by Leo Yan

[permalink] [raw]
Subject: [PATCH v4 4/6] coresight: tmc: Hook callback for panic kdump

Since Coresight panic kdump functionality has been ready, this patch is
to hook panic callback function for ETB/ETF driver. The driver data
structure has allocated a buffer when the session started, so simply
save tracing data into this buffer when panic happens and update buffer
related info for kdump.

Signed-off-by: Leo Yan <[email protected]>
---
drivers/hwtracing/coresight/coresight-tmc-etf.c | 30 +++++++++++++++++++++++++
1 file changed, 30 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index e2513b7..d20d546 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -504,6 +504,35 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev,
CS_LOCK(drvdata->base);
}

+static void tmc_panic_cb(void *data)
+{
+ struct coresight_device *csdev = (struct coresight_device *)data;
+ struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ unsigned long flags;
+
+ if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETB &&
+ drvdata->config_type != TMC_CONFIG_TYPE_ETF))
+ return;
+
+ if (drvdata->mode == CS_MODE_DISABLED)
+ return;
+
+ spin_lock_irqsave(&drvdata->spinlock, flags);
+
+ CS_UNLOCK(drvdata->base);
+
+ tmc_flush_and_stop(drvdata);
+ tmc_etb_dump_hw(drvdata);
+
+ CS_LOCK(drvdata->base);
+
+ /* Update buffer info for panic dump */
+ csdev->kdump_buf = drvdata->buf;
+ csdev->kdump_buf_sz = drvdata->len;
+
+ spin_unlock_irqrestore(&drvdata->spinlock, flags);
+}
+
static const struct coresight_ops_sink tmc_etf_sink_ops = {
.enable = tmc_enable_etf_sink,
.disable = tmc_disable_etf_sink,
@@ -512,6 +541,7 @@ static const struct coresight_ops_sink tmc_etf_sink_ops = {
.set_buffer = tmc_set_etf_buffer,
.reset_buffer = tmc_reset_etf_buffer,
.update_buffer = tmc_update_etf_buffer,
+ .panic_cb = tmc_panic_cb,
};

static const struct coresight_ops_link tmc_etf_link_ops = {
--
2.7.4


2018-03-30 03:20:34

by Leo Yan

[permalink] [raw]
Subject: [PATCH v4 2/6] doc: Add documentation for Coresight panic kdump

Add detailed documentation for Coresight panic kdump, which contains
the idea for why need Coresight panic kdump and introduce the
implementation of Coresight panic kdump framework; the last section is
to explain what's usage.

Credits to Mathieu Poirier for many suggestions since the first version
patch reviewing. The suggestions include using an array to manage dump
related info, this makes code scalable for more CPUs; the Coresight
kdump driver and integration kdump flow with other Coresight devices
also have many ideas from Mathieu.

Suggested-by: Mathieu Poirier <[email protected]>
Signed-off-by: Leo Yan <[email protected]>
---
.../trace/coresight/coresight-panic-kdump.txt | 130 +++++++++++++++++++++
MAINTAINERS | 1 +
2 files changed, 131 insertions(+)
create mode 100644 Documentation/trace/coresight/coresight-panic-kdump.txt

diff --git a/Documentation/trace/coresight/coresight-panic-kdump.txt b/Documentation/trace/coresight/coresight-panic-kdump.txt
new file mode 100644
index 0000000..c02e520
--- /dev/null
+++ b/Documentation/trace/coresight/coresight-panic-kdump.txt
@@ -0,0 +1,130 @@
+ Coresight Panic Kdump
+ =====================
+
+ Author: Leo Yan <[email protected]>
+ Date: March 29th, 2018
+
+Introduction
+------------
+
+Coresight has different sinks for trace data, the trace data is quite useful
+for postmortem debugging. Embedded Trace Buffer (ETB) is one type sink which
+provides on-chip storage of trace data, usually uses SRAM as the buffer with
+several KBs size; if the SoC designs to support 'Local ETF' (ARM DDI 0461B,
+chapter 1.2.7), every CPU has one local ETB buffer so the per CPU trace data
+can avoid being overwritten by each other. Trace Memory Controller (TMC) is
+another kind sink designed as a successor to the CoreSight ETB to capture trace
+into DRAM.
+
+After Linux kernel panic has occurred, the trace data keeps the last execution
+flow before issues happen. We could consider the trace data is quite useful for
+postmortem debugging, especially when we can save trace data into DRAM and rely on
+kdump to preserve them into vmcore file; at the end, we can retrieve trace data
+from vmcore file and "offline" to analyze the execution flow.
+
+
+Implementation
+--------------
+
+Coresight panic kdump is a simple framework to support Coresight dump
+functionality when panic happens, it maintains an array for the dump, every array
+item is dedicated to one specific CPU by using CPU number as an index. For
+'offline' recovery and analysis Coresight tracing data, except should to recovery
+tracing data for sinks, we also need to know CPU tracer configurations; for this
+purpose, the array item is a structure which combines source and sink device
+handlers, the device handler points to Coresight device structure which contains
+dump info: dump buffer base address and buffer size. Below diagram is to
+present data structures relationship:
+
+ array: coresight_kdump_nodes
+ +------+------+----------------------+
+ | CPU0 | CPU1 | ... |
+ +------+------+----------------------+
+ |
+ V
+ coresight_kdump_node coresight_device
+ +-------------------+ +-------------------+
+ | source_csdev | ----------> | kdump_buf |
+ +-------------------+ / +-------------------+
+ | sink_csdev | ----' | kdump_buf_sz |
+ +-------------------+ +-------------------+
+
+Every CPU has its own tracer, we need save tracer registers for tracer ID and
+configuration related information as metadata, the metadata is used by tracing
+decoder. But the tracer has the different configuration at the different phase,
+below diagram explains tracer configurations for different time points: at the
+system boot phase, the tracer is disabled so its registers have not been set;
+after tracer has been enabled or when panic happens, tracer registers have been
+configured, but we need to consider if there has CPU is locked up at panic phase
+then this dead CPU has no chance to handle inter-processor interrupt for panic
+dump; thus we choose tracer enabling phase to save tracer metadata. Coresight
+panic kdump provides API coresight_kdump_source() as helper function for
+recording tracer metadata.
+
+ Boot Enabling Panic
+
+ Timeline: ------->|----------->|----------->|----------->
+
+ Tracer: Disabled Configured Configured
+ Sink: Disabled Enabled Enabled with tracing data
+ | |
+ | `--> Tracing data dump
+ |
+ `--> Tracer metadata dump
+
+After enabling Coresight sink device, function coresight_kdump_sink() is used to
+set sink device handler for related CPU; sink device handler points to Coresight
+device structure, furthermore we can retrieve its ops structure and panic
+callback 'panic_cb' in the ops structure. Coresight panic notifier takes panic CPU
+tracing data with high priority to firstly invoke panic CPU sink callback function,
+then the notifier iterates dump array and invoke callback functions one by one
+for other CPUs. If one sink device is shared among CPUs, the sink panic
+callback is invoked for the first traversed CPU node and other sequential CPUs
+are skipped.
+
+
+Usage
+-----
+
+Build Linux kernel with enabling 'CONFIG_CORESIGHT_PANIC_KDUMP' configuration.
+
+After system booting up, we need firstly prepare dump-capture kernel, this can
+refer doc [1] chapter 'Load the Dump-capture Kernel' for detailed steps. Then
+we need enable the Coresight tracer, this can use either perf framework method
+or sysFS interface, please refer doc [2] chapter 'How to use the tracer modules'
+for detailed steps.
+
+When kernel panic happens, the panic kdump records trace data and launches
+dump-capture kernel, we can utilize the dump-capture kernel to save kernel dump
+file, this can refer doc [1] chapter 'Write Out the Dump File'.
+
+After get kernel dump file, we can use 'crash' tool + csdump.so extension to
+extract trace data and generate 'perf.data' file:
+
+ ./crash vmcore vmlinux
+ crash> extend csdump.so
+ crash> csdump output_dir
+
+ We can see in the 'output_dir' there will generate out three files:
+ output_dir/
+ ├── cstrace.bin -> trace raw data
+ ├── metadata.bin -> meta data
+ └── perf.data -> 'perf' format compatible file
+
+Finally use 'perf' tool for offline analysis:
+
+ ./perf script -v -F cpu,event,ip,sym,symoff -i perf.data -k vmlinux --kallsyms /proc/kallsyms
+ [001] instructions: ffff000008559ad0 pl011_console_write+0x90
+ [001] instructions: ffff000008559230 pl011_read+0x0
+ [001] instructions: ffff00000855924c pl011_read+0x1c
+ [001] instructions: ffff000008559ae0 pl011_console_write+0xa0
+ [001] instructions: ffff000008559ad0 pl011_console_write+0x90
+ [001] instructions: ffff000008559230 pl011_read+0x0
+ [001] instructions: ffff00000855924c pl011_read+0x1c
+ [001] instructions: ffff000008559ae0 pl011_console_write+0xa0
+ [001] instructions: ffff000008559ad0 pl011_console_write+0x90
+ [001] instructions: ffff000008559230 pl011_read+0x0
+ [001] instructions: ffff00000855924c pl011_read+0x1c
+
+[1] Documentation/kdump/kdump.txt
+[2] Documentation/trace/coresight/coresight.txt
diff --git a/MAINTAINERS b/MAINTAINERS
index 7ee1fdc..cc1243b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1333,6 +1333,7 @@ S: Maintained
F: drivers/hwtracing/coresight/*
F: Documentation/trace/coresight/coresight.txt
F: Documentation/trace/coresight/coresight-cpu-debug.txt
+F: Documentation/trace/coresight/coresight-panic-kdump.txt
F: Documentation/devicetree/bindings/arm/coresight.txt
F: Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt
F: Documentation/ABI/testing/sysfs-bus-coresight-devices-*
--
2.7.4


2018-04-02 16:42:38

by Mathieu Poirier

[permalink] [raw]
Subject: Re: [PATCH v4 0/6] Coresight: Support panic kdump

Hi Leo,

Please see below (and in upcoming patches) my comments related to your latest
work.

Thanks,
Mathieu

On Fri, Mar 30, 2018 at 11:15:18AM +0800, Leo Yan wrote:
> This patch set is to explore Coresight tracing data for postmortem
> debugging. When kernel panic happens, the Coresight panic kdump can
> help to save on-chip tracing data and tracer metadata into DRAM, later
> relies on kdump and crash/perf tools to recovery tracing data for
> "offline" analysis.
>
> The documentation is important to understand the purpose of Coresight
> panic kdump, the implementation of framework and usage. Patches 0001
> and patch 0002 are used for creating new sub directory for placing
> Coresight docs and add a new doc for Coresight panic kdump.
>
> Patch 0003 introduces the simple panic kdump framework which provides
> helper functions can be used by Coresight devices, and it registers
> panic notifier for dump tracing data.
>
> Patches 0004/0005 support panic kdump for ETB; Patch 0006 supports the
> kdump for ETMv4.
>
> This patch set has been reworked by following suggestions at Linaro
> HKG18 connect (mainly suggestions from Mathieu, thanks a lot!), and
> it's rebased on acme git tree [1] with last commit 109d59b900e7 ('perf
> vendor events s390: Add JSON files for IBM z14').
>
> Due Coresight kdump data structure has been changed significantly, the
> corresponding crash extension program also has been updated for this
> reason [2]; furthermore the crash extension program is updated to
> dynamically generate kernel buildid according to vmlinux elf info [3],
> this is a fixing for the old code which uses hard-coded buildid value.
>
> This patch set has been verified on 96boards Hikey620 with Coresight
> enabling by the sysFS interface. Also the updated crash extension
> program has been verified to cowork with Coresight panic kdump and it
> successfully extracts tracing data from the vmcore and finally can be
> decoded by perf tool.
>
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git
> [2] https://git.linaro.org/people/leo.yan/crash.git/tree/extensions/csdump.c
> [3] https://git.linaro.org/people/leo.yan/crash.git/tree/extensions/csdump_buildid.c
>
> Changes from v3:
> * Following Mathieu suggestion, reworked the panic kdump framework,
> used kdump array to maintain source and sink device handlers;
> * According to Mathieu suggestion, optimized panic notifier to
> firstly dump panic CPU tracing data and then dump other CPUs tracing
> data;
> * Refined doc to reflect these implementation changes;
> * Changed ETMv4 driver to add source device handler at probe phase;
> * Refactored crash extension program to reflect kernel changes.
>
> Changes from v2:
> * Add the two patches for documentation.
> * Following Mathieu suggestion, reworked the panic kdump framework,
> removed the useless flag "PRE_PANIC".
> * According to comment, changed to add and delete kdump node operations
> in sink enable/disable functions;
> * According to Mathieu suggestion, handle kdump node
> addition/deletion/updating separately for sysFS interface and perf
> method.
>
> Changes from v1:
> * Add support to dump ETMv4 meta data.
> * Wrote 'crash' extension csdump.so so rely on it to generate 'perf'
> format compatible file.
> * Refactored panic dump driver to support pre & post panic dump.
>
> Changes from RFC:
> * Follow Mathieu's suggestion, use general framework to support dump
> functionality.
> * Changed to use perf to analyse trace data.
>
> Leo Yan (6):
> doc: Add Coresight documentation directory
> doc: Add documentation for Coresight panic kdump
> coresight: Support panic kdump functionality
> coresight: tmc: Hook callback for panic kdump
> coresight: Set and clear sink device handler for kdump node
> coresight: etm4x: Support panic kdump
>
> Documentation/trace/coresight-cpu-debug.txt | 187 ----------
> Documentation/trace/coresight.txt | 383 ---------------------
> .../trace/coresight/coresight-cpu-debug.txt | 187 ++++++++++
> .../trace/coresight/coresight-panic-kdump.txt | 130 +++++++
> Documentation/trace/coresight/coresight.txt | 383 +++++++++++++++++++++

Please use the -M option with git format-patch in order to prevent the metrics
associated with the renaming of files to be tallied.

> MAINTAINERS | 5 +-
> drivers/hwtracing/coresight/Kconfig | 9 +
> drivers/hwtracing/coresight/Makefile | 1 +
> drivers/hwtracing/coresight/coresight-etm-perf.c | 5 +
> drivers/hwtracing/coresight/coresight-etm4x.c | 27 ++
> drivers/hwtracing/coresight/coresight-etm4x.h | 15 +
> .../hwtracing/coresight/coresight-panic-kdump.c | 199 +++++++++++
> drivers/hwtracing/coresight/coresight-priv.h | 12 +
> drivers/hwtracing/coresight/coresight-tmc-etf.c | 30 ++
> drivers/hwtracing/coresight/coresight.c | 16 +-
> include/linux/coresight.h | 4 +
> 16 files changed, 1019 insertions(+), 574 deletions(-)
> delete mode 100644 Documentation/trace/coresight-cpu-debug.txt
> delete mode 100644 Documentation/trace/coresight.txt
> create mode 100644 Documentation/trace/coresight/coresight-cpu-debug.txt
> create mode 100644 Documentation/trace/coresight/coresight-panic-kdump.txt
> create mode 100644 Documentation/trace/coresight/coresight.txt
> create mode 100644 drivers/hwtracing/coresight/coresight-panic-kdump.c
>
> --
> 2.7.4
>

2018-04-02 17:28:01

by Mathieu Poirier

[permalink] [raw]
Subject: Re: [PATCH v4 2/6] doc: Add documentation for Coresight panic kdump

On Fri, Mar 30, 2018 at 11:15:20AM +0800, Leo Yan wrote:
> Add detailed documentation for Coresight panic kdump, which contains
> the idea for why need Coresight panic kdump and introduce the
> implementation of Coresight panic kdump framework; the last section is
> to explain what's usage.
>
> Credits to Mathieu Poirier for many suggestions since the first version
> patch reviewing. The suggestions include using an array to manage dump
> related info, this makes code scalable for more CPUs; the Coresight
> kdump driver and integration kdump flow with other Coresight devices
> also have many ideas from Mathieu.

Please remove the above paragraph.

>
> Suggested-by: Mathieu Poirier <[email protected]>

And the above line too.

> Signed-off-by: Leo Yan <[email protected]>
> ---
> .../trace/coresight/coresight-panic-kdump.txt | 130 +++++++++++++++++++++
> MAINTAINERS | 1 +
> 2 files changed, 131 insertions(+)
> create mode 100644 Documentation/trace/coresight/coresight-panic-kdump.txt
>
> diff --git a/Documentation/trace/coresight/coresight-panic-kdump.txt b/Documentation/trace/coresight/coresight-panic-kdump.txt
> new file mode 100644
> index 0000000..c02e520
> --- /dev/null
> +++ b/Documentation/trace/coresight/coresight-panic-kdump.txt
> @@ -0,0 +1,130 @@
> + Coresight Panic Kdump
> + =====================
> +
> + Author: Leo Yan <[email protected]>
> + Date: March 29th, 2018
> +
> +Introduction
> +------------
> +
> +Coresight has different sinks for trace data, the trace data is quite useful
> +for postmortem debugging. Embedded Trace Buffer (ETB) is one type sink which
> +provides on-chip storage of trace data, usually uses SRAM as the buffer with
> +several KBs size; if the SoC designs to support 'Local ETF' (ARM DDI 0461B,
> +chapter 1.2.7), every CPU has one local ETB buffer so the per CPU trace data
> +can avoid being overwritten by each other. Trace Memory Controller (TMC) is
> +another kind sink designed as a successor to the CoreSight ETB to capture trace
> +into DRAM.

I don't think details about the sinks themselves is worth adding here. In my
opinion we can simply stick with the abstract notion of a sink and achieve the
same result.

> +
> +After Linux kernel panic has occurred, the trace data keeps the last execution
> +flow before issues happen. We could consider the trace data is quite useful for
> +postmortem debugging, especially when we can save trace data into DRAM and rely on

Even in documentation files please keep line wrapped to 80 characters (note that
checkpatch won't complain). Console text from the command line (as added below)
is exempt from this rule.

> +kdump to preserve them into vmcore file; at the end, we can retrieve trace data
> +from vmcore file and "offline" to analyze the execution flow.
> +
> +
> +Implementation
> +--------------
> +
> +Coresight panic kdump is a simple framework to support Coresight dump
> +functionality when panic happens, it maintains an array for the dump, every array
> +item is dedicated to one specific CPU by using CPU number as an index. For
> +'offline' recovery and analysis Coresight tracing data, except should to recovery

This paragraph as a whole is hard to read and the usage of the word 'except'
above doesn't not work in this context. Please consider reviewing and/or get in
touch with me if you want to work on it together.

> +tracing data for sinks, we also need to know CPU tracer configurations; for this
> +purpose, the array item is a structure which combines source and sink device
> +handlers, the device handler points to Coresight device structure which contains
> +dump info: dump buffer base address and buffer size. Below diagram is to
> +present data structures relationship:
> +
> + array: coresight_kdump_nodes
> + +------+------+----------------------+
> + | CPU0 | CPU1 | ... |
> + +------+------+----------------------+
> + |
> + V
> + coresight_kdump_node coresight_device
> + +-------------------+ +-------------------+
> + | source_csdev | ----------> | kdump_buf |
> + +-------------------+ / +-------------------+
> + | sink_csdev | ----' | kdump_buf_sz |
> + +-------------------+ +-------------------+
> +
> +Every CPU has its own tracer, we need save tracer registers for tracer ID and
> +configuration related information as metadata, the metadata is used by tracing
> +decoder. But the tracer has the different configuration at the different phase,
> +below diagram explains tracer configurations for different time points: at the
> +system boot phase, the tracer is disabled so its registers have not been set;
> +after tracer has been enabled or when panic happens, tracer registers have been
> +configured, but we need to consider if there has CPU is locked up at panic phase
> +then this dead CPU has no chance to handle inter-processor interrupt for panic
> +dump; thus we choose tracer enabling phase to save tracer metadata. Coresight
> +panic kdump provides API coresight_kdump_source() as helper function for
> +recording tracer metadata.
> +
> + Boot Enabling Panic
> +
> + Timeline: ------->|----------->|----------->|----------->
> +
> + Tracer: Disabled Configured Configured
> + Sink: Disabled Enabled Enabled with tracing data
> + | |
> + | `--> Tracing data dump
> + |
> + `--> Tracer metadata dump
> +
> +After enabling Coresight sink device, function coresight_kdump_sink() is used to
> +set sink device handler for related CPU; sink device handler points to Coresight
> +device structure, furthermore we can retrieve its ops structure and panic
> +callback 'panic_cb' in the ops structure. Coresight panic notifier takes panic CPU
> +tracing data with high priority to firstly invoke panic CPU sink callback function,
> +then the notifier iterates dump array and invoke callback functions one by one
> +for other CPUs.

Same comment as above - this last sentence needs reviewing. While doing so
please avoid using "high priority" as it can confuse a reader in thinking that
scheduling classes are involved, which isn't the case.

> If one sink device is shared among CPUs, the sink panic
> +callback is invoked for the first traversed CPU node and other sequential CPUs
> +are skipped.
> +
> +
> +Usage
> +-----
> +
> +Build Linux kernel with enabling 'CONFIG_CORESIGHT_PANIC_KDUMP' configuration.
> +
> +After system booting up, we need firstly prepare dump-capture kernel, this can
> +refer doc [1] chapter 'Load the Dump-capture Kernel' for detailed steps. Then
> +we need enable the Coresight tracer, this can use either perf framework method
> +or sysFS interface, please refer doc [2] chapter 'How to use the tracer modules'
> +for detailed steps.
> +
> +When kernel panic happens, the panic kdump records trace data and launches
> +dump-capture kernel, we can utilize the dump-capture kernel to save kernel dump
> +file, this can refer doc [1] chapter 'Write Out the Dump File'.
> +
> +After get kernel dump file, we can use 'crash' tool + csdump.so extension to
> +extract trace data and generate 'perf.data' file:
> +
> + ./crash vmcore vmlinux
> + crash> extend csdump.so
> + crash> csdump output_dir
> +
> + We can see in the 'output_dir' there will generate out three files:
> + output_dir/
> + ├── cstrace.bin -> trace raw data
> + ├── metadata.bin -> meta data
> + └── perf.data -> 'perf' format compatible file

Humm... Saying that perf.data is a "perf format compatible file" is not
accurate as it can't be processed by "perf report". This is because it doesn't
containt the PERF_RECORD_AUX event notifications and the mechanic for indexing
CS trace data lumps in the perf.data file.

This will likely lead to confusion and calls from many angry users. As such I
suggest to:

1) Rename perf.data cskdump.data (unless you have a better name).
2) Add a comment to makes it clear that only "perf script" can be used with
cskdump.data

On my side I will review the crash extensions you referred to in the cover
letter. I may have more comments once I've done so.

> +
> +Finally use 'perf' tool for offline analysis:
> +
> + ./perf script -v -F cpu,event,ip,sym,symoff -i perf.data -k vmlinux --kallsyms /proc/kallsyms
> + [001] instructions: ffff000008559ad0 pl011_console_write+0x90
> + [001] instructions: ffff000008559230 pl011_read+0x0
> + [001] instructions: ffff00000855924c pl011_read+0x1c
> + [001] instructions: ffff000008559ae0 pl011_console_write+0xa0
> + [001] instructions: ffff000008559ad0 pl011_console_write+0x90
> + [001] instructions: ffff000008559230 pl011_read+0x0
> + [001] instructions: ffff00000855924c pl011_read+0x1c
> + [001] instructions: ffff000008559ae0 pl011_console_write+0xa0
> + [001] instructions: ffff000008559ad0 pl011_console_write+0x90
> + [001] instructions: ffff000008559230 pl011_read+0x0
> + [001] instructions: ffff00000855924c pl011_read+0x1c
> +
> +[1] Documentation/kdump/kdump.txt
> +[2] Documentation/trace/coresight/coresight.txt
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 7ee1fdc..cc1243b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1333,6 +1333,7 @@ S: Maintained
> F: drivers/hwtracing/coresight/*
> F: Documentation/trace/coresight/coresight.txt
> F: Documentation/trace/coresight/coresight-cpu-debug.txt
> +F: Documentation/trace/coresight/coresight-panic-kdump.txt
> F: Documentation/devicetree/bindings/arm/coresight.txt
> F: Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt
> F: Documentation/ABI/testing/sysfs-bus-coresight-devices-*
> --
> 2.7.4
>

2018-04-02 20:24:29

by Mathieu Poirier

[permalink] [raw]
Subject: Re: [PATCH v4 3/6] coresight: Support panic kdump functionality

On Fri, Mar 30, 2018 at 11:15:21AM +0800, Leo Yan wrote:
> After kernel panic happens, Coresight tracing data has much useful info
> which can be used for analysis. For example, the trace info from ETB
> RAM can be used to check the CPU execution flows before the crash. So
> we can save the tracing data from sink devices, and rely on kdump to
> save DDR content and uses "crash" tool to extract Coresight dumping
> from the vmcore file.
>
> This patch is to add a simple framework to support panic dump
> functionality; it registers panic notifier, and provide the helper
> functions coresight_kdump_source()/coresight_kdump_sink() so Coresight
> source and sink devices can be recorded into Coresight kdump node for
> kernel panic kdump.
>
> When kernel panic happens, the notifier iterates dump array and invoke
> callback function to dump tracing data. Later the tracing data can be
> used to reverse execution flow before the kernel panic.
>
> Signed-off-by: Leo Yan <[email protected]>
> ---
> drivers/hwtracing/coresight/Kconfig | 9 +
> drivers/hwtracing/coresight/Makefile | 1 +
> .../hwtracing/coresight/coresight-panic-kdump.c | 199 +++++++++++++++++++++
> drivers/hwtracing/coresight/coresight-priv.h | 12 ++
> include/linux/coresight.h | 4 +
> 5 files changed, 225 insertions(+)
> create mode 100644 drivers/hwtracing/coresight/coresight-panic-kdump.c
>
> diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
> index ef9cb3c..3089abf 100644
> --- a/drivers/hwtracing/coresight/Kconfig
> +++ b/drivers/hwtracing/coresight/Kconfig
> @@ -103,4 +103,13 @@ config CORESIGHT_CPU_DEBUG
> properly, please refer Documentation/trace/coresight-cpu-debug.txt
> for detailed description and the example for usage.
>
> +config CORESIGHT_PANIC_KDUMP
> + bool "CoreSight Panic Kdump driver"
> + depends on ARM || ARM64
> + help
> + This driver provides panic kdump functionality for CoreSight devices.
> + When kernel panic happen Coresight device supplied callback function

s/Coresight/CoreSight

> + is to dump trace data to memory. From then on, kdump can be used to
> + extract the trace data from kernel dump file.
> +
> endif
> diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
> index 61db9dd..946fe19 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -18,3 +18,4 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o \
> obj-$(CONFIG_CORESIGHT_DYNAMIC_REPLICATOR) += coresight-dynamic-replicator.o
> obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
> obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
> +obj-$(CONFIG_CORESIGHT_PANIC_KDUMP) += coresight-panic-kdump.o
> diff --git a/drivers/hwtracing/coresight/coresight-panic-kdump.c b/drivers/hwtracing/coresight/coresight-panic-kdump.c
> new file mode 100644
> index 0000000..f4589e9
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-panic-kdump.c
> @@ -0,0 +1,199 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2017~2018 Linaro Limited.

I don't remember if I commented on this before but the above line (not the SPDX)
should be enclosed with C style comments (/* */) rather than C++ (//).

I would also add a new line between the copyright statement and the header file
listing.

> +#include <linux/coresight.h>
> +#include <linux/coresight-pmu.h>
> +#include <linux/cpumask.h>
> +#include <linux/device.h>
> +#include <linux/init.h>
> +#include <linux/list.h>
> +#include <linux/mm.h>
> +#include <linux/perf_event.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
> +
> +#include "coresight-priv.h"
> +
> +/**
> + * struct coresight_kdump_node - Node information for dump
> + * @source_csdev: Handler for source coresight device
> + * @sink_csdev: Handler for sink coresight device
> + */
> +struct coresight_kdump_node {
> + struct coresight_device *source_csdev;
> + struct coresight_device *sink_csdev;
> +};
> +
> +static DEFINE_SPINLOCK(coresight_kdump_lock);
> +static struct coresight_kdump_node *coresight_kdump_nodes;
> +static struct notifier_block coresight_kdump_nb;
> +
> +/**
> + * coresight_kdump_source - Set source dump info for specific CPU
> + * @cpu: CPU ID
> + * @csdev: Source device structure handler
> + * @data: Pointer for source device metadata buffer
> + * @data_sz: Size of source device metadata buffer
> + *
> + * This function is a helper function which is used to set/clear source device
> + * handler and metadata when the tracer is enabled; and it can be used to clear
> + * source device related info when the tracer is disabled.
> + *
> + * Returns: 0 on success, negative errno otherwise.
> + */
> +int coresight_kdump_source(int cpu, struct coresight_device *csdev,
> + char *data, unsigned int data_sz)
> +{
> + struct coresight_kdump_node *node;
> + unsigned long flags;
> +
> + if (!coresight_kdump_nodes)
> + return -EPROBE_DEFER;

Before grabbing the lock you also need to make sure
@cpu is < num_possible_cpus().

> +
> + spin_lock_irqsave(&coresight_kdump_lock, flags);
> +
> + node = &coresight_kdump_nodes[cpu];
> + node->source_csdev = csdev;
> +
> + csdev->kdump_buf = data;
> + csdev->kdump_buf_sz = data_sz;
> +
> + spin_unlock_irqrestore(&coresight_kdump_lock, flags);
> + return 0;
> +}
> +
> +/**
> + * coresight_kdump_sink - Set sink device handler for specific CPU
> + * @cpu: CPU ID
> + * @csdev: Sink device structure handler
> + *
> + * This function is a helper function which is used to set sink device handler
> + * when the Coresight path has been enabled for specific CPU; and it can be used
> + * to clear sink device handler when the path is disabled.
> + *
> + * Returns: 0 on success, negative errno otherwise.
> + */
> +int coresight_kdump_sink(int cpu, struct coresight_device *csdev)
> +{
> + struct coresight_kdump_node *node;
> + unsigned long flags;
> +
> + if (!coresight_kdump_nodes)
> + return -EPROBE_DEFER;

Same comment as above.

> +
> + spin_lock_irqsave(&coresight_kdump_lock, flags);
> +
> + node = &coresight_kdump_nodes[cpu];
> + node->sink_csdev = csdev;

csdev->kdump_buf = NULL;
csdev->kdump_buf_sz = 0;

> +
> + spin_unlock_irqrestore(&coresight_kdump_lock, flags);
> + return 0;
> +}
> +
> +/**
> + * coresight_kdump_sink_cb - Invoke sink callback for specific CPU
> + * @cpu: CPU ID
> + *
> + * This function is to invoke sink device corresponding callback. It needs
> + * to check two cases: one case is the CPU has not been enabled for Coresight
> + * path so there totally has no trace data for the CPU, another case is the
> + * CPU shares the same sink device with other CPUs but the tracing data has
> + * been dumped by previous CPUs; it skips dump for these two cases.
> + */
> +static void coresight_kdump_sink_cb(int cpu)
> +{
> + struct coresight_kdump_node *node;
> + struct coresight_device *csdev;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&coresight_kdump_lock, flags);
> +
> + node = &coresight_kdump_nodes[cpu];
> + csdev = node->sink_csdev;
> +
> + /* Path has not been enabled */
> + if (!csdev)
> + goto skip_dump;
> +
> + /* Have been dumped by previous CPU */
> + if (csdev->kdump_buf)

I would use csdev->kdump_buf_sz instead of csdev->kdump_buf. The reason is that
the sink may not always use an internal SRAM buffer. For instance the ETR uses
system RAM, either as a contiguous buffer or a scatter-gather list. When the
panic callback for an ETR is implemented the code in the core (i.e this file)
need not change as kdump_buf_sz is independent of the way data is conveyed.

> + goto skip_dump;
> +
> + /* Invoke panic callback */
> + csdev = coresight_kdump_nodes[cpu].sink_csdev;
> + if (csdev && sink_ops(csdev)->panic_cb)
> + sink_ops(csdev)->panic_cb(csdev);
> +
> +skip_dump:
> + spin_unlock_irqrestore(&coresight_kdump_lock, flags);
> +}
> +
> +/**
> + * coresight_kdump_notify - Invoke panic dump callbacks
> + * @nb: Pointer to notifier block
> + * @event: Notification reason
> + * @_unused: Pointer to notification data object, unused
> + *
> + * This function is called when panic happens to invoke dump callbacks, it takes
> + * panic CPU tracing data with high priority to firstly invoke panic CPU sink
> + * callback function, then the notifier iterates callback functions one by one
> + * for other CPUs. If one sink device is shared among CPUs, the sink panic
> + * callback is invoked for the first traversed CPU node and other sequential
> + * CPUs are skipped.
> + *
> + * Returns: 0 on success.
> + */
> +static int coresight_kdump_notify(struct notifier_block *nb,
> + unsigned long event, void *_unused)
> +{
> + int cpu, first;
> +
> + /* Give panic CPU trace data with high priority */

I would replace the above comment with "Start with the panic'ed CPU".


> + first = atomic_read(&panic_cpu);
> + coresight_kdump_sink_cb(first);
> +
> + /* Dump rest CPUs trace data */
> + for (cpu = 0; cpu < num_possible_cpus(); cpu++) {
> + if (cpu == first)
> + continue;
> +
> + coresight_kdump_sink_cb(cpu);
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * coresight_kdump_init - Coresight kdump module initialization
> + *
> + * This function allcoates dump array and register panic norifier.
> + *
> + * Returns: 0 on success, negative errno otherwise.
> + */
> +static int __init coresight_kdump_init(void)
> +{
> + int ret;
> +
> + coresight_kdump_nodes = kmalloc_array(num_possible_cpus(),
> + sizeof(*coresight_kdump_nodes),
> + GFP_KERNEL);
> + if (!coresight_kdump_nodes) {
> + pr_err("%s: kmalloc failed\n", __func__);
> + return -ENOMEM;
> + }
> +
> + memset(coresight_kdump_nodes, 0,
> + num_possible_cpus() * sizeof(*coresight_kdump_nodes));

If you use kcalloc() above you don't need to explicitly zero out the memory.

> +
> + coresight_kdump_nb.notifier_call = coresight_kdump_notify;
> + ret = atomic_notifier_chain_register(&panic_notifier_list,
> + &coresight_kdump_nb);
> + if (ret) {
> + pr_err("%s: unable to register notifier: %d\n",
> + __func__, ret);
> + kfree(coresight_kdump_nodes);
> + return ret;
> + }
> +
> + return 0;
> +}
> +postcore_initcall(coresight_kdump_init);
> diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
> index f1d0e21d..76d27d6 100644
> --- a/drivers/hwtracing/coresight/coresight-priv.h
> +++ b/drivers/hwtracing/coresight/coresight-priv.h
> @@ -151,4 +151,16 @@ 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_KDUMP
> +extern int coresight_kdump_source(int cpu, struct coresight_device *csdev,
> + char *data, unsigned int data_sz);
> +extern int coresight_kdump_sink(int cpu, struct coresight_device *csdev);
> +#else
> +static inline int coresight_kdump_source(int cpu,
> + struct coresight_device *csdev,
> + char *data, unsigned int data_sz) { return 0; }
> +static inline void coresight_kdump_sink(int cpu,
> + struct coresight_device *csdev) { return 0; }

To me the above is harder to read - I suggest:

static inline int
coresight_kdump_source(int cpu,
struct coresight_device *csdev,
char *data, unsigned int data_sz) { return 0; }
static inline void
coresight_kdump_sink(int cpu,
struct coresight_device *csdev) { return 0; }

> +#endif
> +
> #endif
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index d950dad..89aad8d 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -171,6 +171,8 @@ struct coresight_device {
> bool orphan;
> bool enable; /* true only if configured as part of a path */
> bool activated; /* true only if a sink is part of a path */
> + char *kdump_buf;
> + unsigned int kdump_buf_sz;

Please add structure documentation, the same way all the other fields in this
structure is.

> };
>
> #define to_coresight_device(d) container_of(d, struct coresight_device, dev)
> @@ -189,6 +191,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: hook function for panic notifier.
> */
> struct coresight_ops_sink {
> int (*enable)(struct coresight_device *csdev, u32 mode);
> @@ -205,6 +208,7 @@ struct coresight_ops_sink {
> void (*update_buffer)(struct coresight_device *csdev,
> struct perf_output_handle *handle,
> void *sink_config);
> + void (*panic_cb)(void *data);
> };
>
> /**
> --
> 2.7.4
>

2018-04-02 20:38:31

by Mathieu Poirier

[permalink] [raw]
Subject: Re: [PATCH v4 4/6] coresight: tmc: Hook callback for panic kdump

On Fri, Mar 30, 2018 at 11:15:22AM +0800, Leo Yan wrote:
> Since Coresight panic kdump functionality has been ready, this patch is
> to hook panic callback function for ETB/ETF driver. The driver data
> structure has allocated a buffer when the session started, so simply
> save tracing data into this buffer when panic happens and update buffer
> related info for kdump.
>
> Signed-off-by: Leo Yan <[email protected]>
> ---
> drivers/hwtracing/coresight/coresight-tmc-etf.c | 30 +++++++++++++++++++++++++
> 1 file changed, 30 insertions(+)
>
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
> index e2513b7..d20d546 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
> @@ -504,6 +504,35 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev,
> CS_LOCK(drvdata->base);
> }
>
> +static void tmc_panic_cb(void *data)

I would call the function tmc_kdump_panic_cb()... That way there is absolutely
no confusion as to what it does.

> +{
> + struct coresight_device *csdev = (struct coresight_device *)data;
> + struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> + unsigned long flags;
> +
> + if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETB &&
> + drvdata->config_type != TMC_CONFIG_TYPE_ETF))
> + return;
> +
> + if (drvdata->mode == CS_MODE_DISABLED)
> + return;

This is racy - between the check and acquiring the spinlock someone may beat you
to it.

> +
> + spin_lock_irqsave(&drvdata->spinlock, flags);

if (drvdata->mode == CS_MODE_DISABLED)
goto out;

drvdata->mode = CS_MODE_DISABLED

> +
> + CS_UNLOCK(drvdata->base);
> +
> + tmc_flush_and_stop(drvdata);
> + tmc_etb_dump_hw(drvdata);
> +
> + CS_LOCK(drvdata->base);
> +
> + /* Update buffer info for panic dump */
> + csdev->kdump_buf = drvdata->buf;
> + csdev->kdump_buf_sz = drvdata->len;

out:
> +
> + spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +}
> +
> static const struct coresight_ops_sink tmc_etf_sink_ops = {
> .enable = tmc_enable_etf_sink,
> .disable = tmc_disable_etf_sink,
> @@ -512,6 +541,7 @@ static const struct coresight_ops_sink tmc_etf_sink_ops = {
> .set_buffer = tmc_set_etf_buffer,
> .reset_buffer = tmc_reset_etf_buffer,
> .update_buffer = tmc_update_etf_buffer,
> + .panic_cb = tmc_panic_cb,
> };
>
> static const struct coresight_ops_link tmc_etf_link_ops = {
> --
> 2.7.4
>

2018-04-02 21:36:05

by Mathieu Poirier

[permalink] [raw]
Subject: Re: [PATCH v4 5/6] coresight: Set and clear sink device handler for kdump node

On Fri, Mar 30, 2018 at 11:15:23AM +0800, Leo Yan wrote:
> If Coresight path is enabled for specific CPU, the sink device handler
> need to be set to kdump node; on the other hand we also need to clear
> sink device handler when path is disabled.
>
> This patch sets sink devices handler for kdump node for two separate
> Coresight enabling modes: CS_MODE_SYSFS and CS_MODE_PERF; and clear the
> handler when Coresight is disabled.
>
> Signed-off-by: Leo Yan <[email protected]>
> ---
> drivers/hwtracing/coresight/coresight-etm-perf.c | 5 +++++
> drivers/hwtracing/coresight/coresight.c | 16 ++++++++++++++--
> 2 files changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
> index 8a0ad77..f8b159c 100644
> --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
> +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
> @@ -139,6 +139,8 @@ static void free_event_data(struct work_struct *work)
> for_each_cpu(cpu, mask) {
> if (!(IS_ERR_OR_NULL(event_data->path[cpu])))
> coresight_release_path(event_data->path[cpu]);
> +
> + coresight_kdump_sink(cpu, NULL);
> }
>
> kfree(event_data->path);
> @@ -238,6 +240,9 @@ static void *etm_setup_aux(int event_cpu, void **pages,
> event_data->path[cpu] = coresight_build_path(csdev, sink);
> if (IS_ERR(event_data->path[cpu]))
> goto err;
> +
> + if (coresight_kdump_sink(cpu, sink))
> + goto err;

I remember telling you to use free_event_data() and etm_setup_aux(). _Maybe_ it
made sense in the previous patchset but in this one it won't work. We need to
reflect the current trace context, as such use etm_event_start() and
etm_event_stop().

In etm_event_start() call coresight_kdump_sink(cpu, sink) just before
source_ops(csdev)->enable(). Similarly call coresight_kdump_sink(cpu, NULL)
right after source_ops(csdev)->disable() in etm_event_stop().

Find me on IRC if you want more information on this.

> }
>
> if (!sink_ops(sink)->alloc_buffer)
> diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
> index 389c4ba..483a1f7 100644
> --- a/drivers/hwtracing/coresight/coresight.c
> +++ b/drivers/hwtracing/coresight/coresight.c
> @@ -272,6 +272,7 @@ static int coresight_enable_source(struct coresight_device *csdev, u32 mode)
> static bool coresight_disable_source(struct coresight_device *csdev)
> {
> if (atomic_dec_return(csdev->refcnt) == 0) {
> +

This newline shouldn't be part of this set.

> if (source_ops(csdev)->disable)
> source_ops(csdev)->disable(csdev, NULL);
> csdev->enable = false;
> @@ -612,6 +613,13 @@ int coresight_enable(struct coresight_device *csdev)
> if (ret)
> goto err_source;
>
> + cpu = source_ops(csdev)->cpu_id(csdev);
> +
> + /* Set sink device handler into kdump node */
> + ret = coresight_kdump_sink(cpu, sink);
> + if (ret)
> + goto err_kdump;
> +

Call coresight_kdump_sink() just before coresight_enable_source(). That way if
there is a dump just after coresight_enable_source() is called we get the chance
of getting some traces in the dump file.

> switch (subtype) {
> case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
> /*
> @@ -621,7 +629,6 @@ int coresight_enable(struct coresight_device *csdev)
> * be a single session per tracer (when working from sysFS)
> * a per-cpu variable will do just fine.
> */
> - cpu = source_ops(csdev)->cpu_id(csdev);
> per_cpu(tracer_path, cpu) = path;
> break;
> case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
> @@ -636,6 +643,9 @@ int coresight_enable(struct coresight_device *csdev)
> mutex_unlock(&coresight_mutex);
> return ret;
>
> +err_kdump:
> + coresight_disable_source(csdev);
> +
> err_source:
> coresight_disable_path(path);
>
> @@ -659,9 +669,10 @@ void coresight_disable(struct coresight_device *csdev)
> if (!csdev->enable || !coresight_disable_source(csdev))
> goto out;
>
> + cpu = source_ops(csdev)->cpu_id(csdev);
> +
> switch (csdev->subtype.source_subtype) {
> case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
> - cpu = source_ops(csdev)->cpu_id(csdev);
> path = per_cpu(tracer_path, cpu);
> per_cpu(tracer_path, cpu) = NULL;
> break;
> @@ -674,6 +685,7 @@ void coresight_disable(struct coresight_device *csdev)
> break;
> }
>
> + coresight_kdump_sink(cpu, NULL);
> coresight_disable_path(path);
> coresight_release_path(path);
>
> --
> 2.7.4
>

2018-04-02 21:59:07

by Mathieu Poirier

[permalink] [raw]
Subject: Re: [PATCH v4 6/6] coresight: etm4x: Support panic kdump

On Fri, Mar 30, 2018 at 11:15:24AM +0800, Leo Yan wrote:
> ETMv4 hardware information and configuration needs to be saved as
> metadata; the metadata format should be compatible with 'perf' tool and
> finally is used by tracing data decoder. ETMv4 works as tracer per CPU,
> we cannot wait for gathering ETM info after CPU panic has happened in
> case there have CPU is locked up and can't response inter-processor
> interrupt for execution dump operations; so it's more reliable to gather
> tracer metadata when all of the CPUs are alive.
>
> This patch saves ETMv4 metadata but with the different method for
> different registers. Since values in TRCIDR{0, 1, 2, 8} and
> TRCAUTHSTATUS are read-only and won't change afterward, thus those
> registers values are filled into metadata structure when tracers are
> instantiated. The configuration and control registers TRCCONFIGR and
> TRCTRACEIDR are dynamically configured, their values are recorded during
> tracer enabling phase.
>
> To avoid unnecessary overload introduced by set/clear operations for
> updating kdump node, we only set ETMv4 metadata info for the
> corresponding kdump node at initialization and won't be cleared anymore.
>
> Suggested-by: Mathieu Poirier <[email protected]>
> Signed-off-by: Leo Yan <[email protected]>
> ---
> drivers/hwtracing/coresight/coresight-etm4x.c | 27 +++++++++++++++++++++++++++
> drivers/hwtracing/coresight/coresight-etm4x.h | 15 +++++++++++++++
> 2 files changed, 42 insertions(+)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
> index cf364a5..88b1e19 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
> @@ -288,6 +288,8 @@ static int etm4_enable(struct coresight_device *csdev,
> int ret;
> u32 val;
> struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> + struct etmv4_config *config = &drvdata->config;
> + struct etmv4_metadata *metadata = &drvdata->metadata;
>
> val = local_cmpxchg(&drvdata->mode, CS_MODE_DISABLED, mode);
>
> @@ -306,6 +308,10 @@ static int etm4_enable(struct coresight_device *csdev,
> ret = -EINVAL;
> }
>
> + /* Update tracer meta data after tracer configuration */
> + metadata->trcconfigr = config->cfg;
> + metadata->trctraceidr = drvdata->trcid;
> +
> /* The tracer didn't start */
> if (ret)
> local_set(&drvdata->mode, CS_MODE_DISABLED);
> @@ -438,6 +444,7 @@ static void etm4_init_arch_data(void *info)
> u32 etmidr4;
> u32 etmidr5;
> struct etmv4_drvdata *drvdata = info;
> + struct etmv4_metadata *metadata = &drvdata->metadata;
>
> /* Make sure all registers are accessible */
> etm4_os_unlock(drvdata);
> @@ -590,6 +597,16 @@ static void etm4_init_arch_data(void *info)
> drvdata->nrseqstate = BMVAL(etmidr5, 25, 27);
> /* NUMCNTR, bits[30:28] number of counters available for tracing */
> drvdata->nr_cntr = BMVAL(etmidr5, 28, 30);
> +
> + /* Update metadata */
> + metadata->magic = ETM4_METADATA_MAGIC;
> + metadata->cpu = drvdata->cpu;
> + metadata->trcidr0 = readl_relaxed(drvdata->base + TRCIDR0);
> + metadata->trcidr1 = readl_relaxed(drvdata->base + TRCIDR1);
> + metadata->trcidr2 = readl_relaxed(drvdata->base + TRCIDR2);
> + metadata->trcidr8 = readl_relaxed(drvdata->base + TRCIDR8);
> + metadata->trcauthstatus = readl_relaxed(drvdata->base + TRCAUTHSTATUS);
> +
> CS_LOCK(drvdata->base);
> }
>
> @@ -957,6 +974,7 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
> struct device *dev = &adev->dev;
> struct coresight_platform_data *pdata = NULL;
> struct etmv4_drvdata *drvdata;
> + struct etmv4_metadata *metadata;
> struct resource *res = &adev->res;
> struct coresight_desc desc = { 0 };
> struct device_node *np = adev->dev.of_node;
> @@ -1027,6 +1045,15 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
> goto err_arch_supported;
> }
>
> + /* Set source device handler and metadata into kdump node */
> + metadata = &drvdata->metadata;
> + ret = coresight_kdump_source(drvdata->cpu, drvdata->csdev,
> + (char *)metadata, sizeof(*metadata));
> + if (ret) {
> + coresight_unregister(drvdata->csdev);
> + goto err_arch_supported;
> + }
> +
> ret = etm_perf_symlink(drvdata->csdev, true);
> if (ret) {
> coresight_unregister(drvdata->csdev);
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
> index b3b5ea7..08dc8b7 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> @@ -198,6 +198,20 @@
> #define ETM_EXLEVEL_NS_HYP BIT(14)
> #define ETM_EXLEVEL_NS_NA BIT(15)
>
> +#define ETM4_METADATA_MAGIC 0x4040404040404040ULL

Please dd a comment that this needs to be kept in sync with
__perf_cs_etmv4_magic in tools/perf/util/cs-etm.h.

> +
> +struct etmv4_metadata {
> + u64 magic;
> + u64 cpu;
> + u64 trcconfigr;
> + u64 trctraceidr;
> + u64 trcidr0;
> + u64 trcidr1;
> + u64 trcidr2;
> + u64 trcidr8;
> + u64 trcauthstatus;
> +};
> +
> /**
> * struct etmv4_config - configuration information related to an ETMv4
> * @mode: Controls various modes supported by this ETM.
> @@ -393,6 +407,7 @@ struct etmv4_drvdata {
> bool atbtrig;
> bool lpoverride;
> struct etmv4_config config;
> + struct etmv4_metadata metadata;

Structure documentation please.

> };
>
> /* Address comparator access types */
> --
> 2.7.4
>