linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/6] Coresight: support panic kdump
@ 2017-12-21  8:20 Leo Yan
  2017-12-21  8:20 ` [PATCH v3 1/6] doc: Add Coresight documentation directory Leo Yan
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Leo Yan @ 2017-12-21  8:20 UTC (permalink / raw)
  To: Jonathan Corbet, Mathieu Poirier, Greg Kroah-Hartman,
	Will Deacon, linux-doc, linux-kernel, linux-arm-kernel,
	coresight
  Cc: Leo Yan

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

The documentation is important to understand the purpose of Coresight
panic kdump, the implementation and usage. Patches 0001/0002 are used
to relocate and add related documenation.

Patch 0003 introduces the simple panic kdump framework which can be
easily used by Coresight devices.

Patches 0004/0005 support panic kdump for ETB; Patch 0006 supports
the dump for ETMv4. As Mathieu suggested, patch 0006 distinguish two
different tracer enabling mode: sysFS interface and perf mode.

This patch set have been verified on 96boards Hikey with tracer
enabling by sysFS interface.

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: Add and delete sink callback for panic kdump list
  coresight: etm4x: Support panic kdump

 Documentation/trace/coresight-cpu-debug.txt        | 187 ------------
 Documentation/trace/coresight.txt                  | 332 ---------------------
 .../trace/coresight/coresight-cpu-debug.txt        | 187 ++++++++++++
 .../trace/coresight/coresight-panic-kdump.txt      |  91 ++++++
 Documentation/trace/coresight/coresight.txt        | 332 +++++++++++++++++++++
 MAINTAINERS                                        |   5 +-
 drivers/hwtracing/coresight/Kconfig                |   9 +
 drivers/hwtracing/coresight/Makefile               |   1 +
 drivers/hwtracing/coresight/coresight-etm-perf.c   |  12 +-
 drivers/hwtracing/coresight/coresight-etm4x.c      |  23 ++
 drivers/hwtracing/coresight/coresight-etm4x.h      |  15 +
 .../hwtracing/coresight/coresight-panic-kdump.c    | 154 ++++++++++
 drivers/hwtracing/coresight/coresight-priv.h       |  13 +
 drivers/hwtracing/coresight/coresight-tmc-etf.c    |  29 ++
 drivers/hwtracing/coresight/coresight.c            |  12 +
 include/linux/coresight.h                          |   7 +
 16 files changed, 887 insertions(+), 522 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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v3 1/6] doc: Add Coresight documentation directory
  2017-12-21  8:20 [PATCH v3 0/6] Coresight: support panic kdump Leo Yan
@ 2017-12-21  8:20 ` Leo Yan
  2017-12-21  8:20 ` [PATCH v3 2/6] doc: Add documentation for Coresight panic kdump Leo Yan
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Leo Yan @ 2017-12-21  8:20 UTC (permalink / raw)
  To: Jonathan Corbet, Mathieu Poirier, Greg Kroah-Hartman,
	Will Deacon, linux-doc, linux-kernel, linux-arm-kernel,
	coresight
  Cc: Leo Yan

For easily management and friendly adding more Coresight related
documentations, this commit creates one dedicated directory:
Documentation/trace/coresight.  It moves Coresight related docs into
this new directory and updates MAINTAINERS file to reflect docs
movement.

Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
 Documentation/trace/coresight-cpu-debug.txt        | 187 ------------
 Documentation/trace/coresight.txt                  | 332 ---------------------
 .../trace/coresight/coresight-cpu-debug.txt        | 187 ++++++++++++
 Documentation/trace/coresight/coresight.txt        | 332 +++++++++++++++++++++
 MAINTAINERS                                        |   4 +-
 5 files changed, 521 insertions(+), 521 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 <leo.yan@linaro.org>
-   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 a33c88c..0000000
--- a/Documentation/trace/coresight.txt
+++ /dev/null
@@ -1,332 +0,0 @@
-		Coresight - HW Assisted Tracing on ARM
-		======================================
-
-   Author:   Mathieu Poirier <mathieu.poirier@linaro.org>
-   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
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 <leo.yan@linaro.org>
+   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..a33c88c
--- /dev/null
+++ b/Documentation/trace/coresight/coresight.txt
@@ -0,0 +1,332 @@
+		Coresight - HW Assisted Tracing on ARM
+		======================================
+
+   Author:   Mathieu Poirier <mathieu.poirier@linaro.org>
+   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
diff --git a/MAINTAINERS b/MAINTAINERS
index 4641719..d7a6fc7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1307,8 +1307,8 @@ M:	Mathieu Poirier <mathieu.poirier@linaro.org>
 L:	linux-arm-kernel@lists.infradead.org (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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 2/6] doc: Add documentation for Coresight panic kdump
  2017-12-21  8:20 [PATCH v3 0/6] Coresight: support panic kdump Leo Yan
  2017-12-21  8:20 ` [PATCH v3 1/6] doc: Add Coresight documentation directory Leo Yan
@ 2017-12-21  8:20 ` Leo Yan
  2017-12-21  8:20 ` [PATCH v3 3/6] coresight: Support panic kdump functionality Leo Yan
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Leo Yan @ 2017-12-21  8:20 UTC (permalink / raw)
  To: Jonathan Corbet, Mathieu Poirier, Greg Kroah-Hartman,
	Will Deacon, linux-doc, linux-kernel, linux-arm-kernel,
	coresight
  Cc: Leo Yan

Add detailed documentation for Coresight panic kdump, which contains
the idea for why need this and introduce the framework implementation
and usage.

Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
 .../trace/coresight/coresight-panic-kdump.txt      | 91 ++++++++++++++++++++++
 MAINTAINERS                                        |  1 +
 2 files changed, 92 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..6bf9cac
--- /dev/null
+++ b/Documentation/trace/coresight/coresight-panic-kdump.txt
@@ -0,0 +1,91 @@
+		Coresight Panic Kdump
+		=====================
+
+   Author:   Leo Yan <leo.yan@linaro.org>
+   Date:     Dec 21th, 2017
+
+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 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 to be overwritted by other CPUs.  Trace Memory Controller (TMC) is
+another kind sink designed as a successor to the CoreSight ETB to capture trace
+into DRAM.
+
+After Linux kernel trigger panic, 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 record trace data into DRAM and rely
+on kdump to save 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 dump functionality,
+it maintains dump list with every node recording the dump buffer base address
+and buffer size.  Coresight panic kdump provides the general APIs
+{coresight_kdump_add|coresight_kdump_del} as helper functions so any coresight
+device can add itself into dump list or delete as needed.
+
+Generally coresight device set its 'panic_cb' in the ops structure, the panic
+notifier iterates dump list and invokes callback function to dump device specific
+info.
+
+For easily used by offline analysis, we also record tracer metadata so can
+retrieve tracer IDs and configuration, in this case the node records CPU number so
+can create connection between the metadata and specific CPU.  The tracer
+driver uses helper function coresight_kdump_update() to update the dump
+buffer base address and buffer size; so the tracer can save metadata at runtime
+and these info can be prepared well pre panic happening.
+
+
+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 d7a6fc7..26276e0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1309,6 +1309,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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 3/6] coresight: Support panic kdump functionality
  2017-12-21  8:20 [PATCH v3 0/6] Coresight: support panic kdump Leo Yan
  2017-12-21  8:20 ` [PATCH v3 1/6] doc: Add Coresight documentation directory Leo Yan
  2017-12-21  8:20 ` [PATCH v3 2/6] doc: Add documentation for Coresight panic kdump Leo Yan
@ 2017-12-21  8:20 ` Leo Yan
  2018-01-09 18:41   ` Mathieu Poirier
  2017-12-21  8:20 ` [PATCH v3 4/6] coresight: tmc: Hook callback for panic kdump Leo Yan
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Leo Yan @ 2017-12-21  8:20 UTC (permalink / raw)
  To: Jonathan Corbet, Mathieu Poirier, Greg Kroah-Hartman,
	Will Deacon, linux-doc, linux-kernel, linux-arm-kernel,
	coresight
  Cc: Leo Yan

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

This patch is to add a simple framework to support panic dump
functionality; it registers panic notifier, and provide the general APIs
{coresight_kdump_add|coresight_kdump_del} as helper functions so any
coresight device can add itself into dump list or delete as needed.

This driver provides helper function coresight_kdump_update() to update
the dump buffer base address and buffer size.  This function can be used
by coresight driver, e.g. it can be used to save ETM meta data info at
runtime and these info can be prepared pre panic happening.

When kernel panic happens, the notifier iterates dump list and calls
callback function to dump device specific info.  The panic dump is
mainly used to dump trace data so we can get to know the execution flow
before the panic happens.

Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
 drivers/hwtracing/coresight/Kconfig                |   9 ++
 drivers/hwtracing/coresight/Makefile               |   1 +
 .../hwtracing/coresight/coresight-panic-kdump.c    | 154 +++++++++++++++++++++
 drivers/hwtracing/coresight/coresight-priv.h       |  13 ++
 include/linux/coresight.h                          |   7 +
 5 files changed, 184 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..4812529 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 a kernel panic happen a device supplied callback function
+	  is used to save trace data to memory. From there we rely on kdump 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..c21d20b
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-panic-kdump.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 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"
+
+typedef void (*coresight_cb_t)(void *data);
+
+/**
+ * struct coresight_kdump_node - Node information for dump
+ * @cpu:	The cpu this node is affined to.
+ * @csdev:	Handler for coresight device.
+ * @buf:	Pointer for dump buffer.
+ * @buf_size:	Length of dump buffer.
+ * @list:	Hook to the list.
+ */
+struct coresight_kdump_node {
+	int cpu;
+	struct coresight_device *csdev;
+	char *buf;
+	unsigned int buf_size;
+	struct list_head list;
+};
+
+static DEFINE_SPINLOCK(coresight_kdump_lock);
+static LIST_HEAD(coresight_kdump_list);
+static struct notifier_block coresight_kdump_nb;
+
+int coresight_kdump_update(struct coresight_device *csdev, char *buf,
+			   unsigned int buf_size)
+{
+	struct coresight_kdump_node *node = csdev->dump_node;
+
+	if (!node) {
+		dev_err(&csdev->dev, "Failed to update dump node.\n");
+		return -EINVAL;
+	}
+
+	node->buf = buf;
+	node->buf_size = buf_size;
+	return 0;
+}
+
+int coresight_kdump_add(struct coresight_device *csdev, int cpu)
+{
+	struct coresight_kdump_node *node;
+	unsigned long flags;
+
+	node = kzalloc(sizeof(*node), GFP_KERNEL);
+	if (!node)
+		return -ENOMEM;
+
+	csdev->dump_node = (void *)node;
+	node->cpu = cpu;
+	node->csdev = csdev;
+
+	spin_lock_irqsave(&coresight_kdump_lock, flags);
+	list_add_tail(&node->list, &coresight_kdump_list);
+	spin_unlock_irqrestore(&coresight_kdump_lock, flags);
+	return 0;
+}
+
+void coresight_kdump_del(struct coresight_device *csdev)
+{
+	struct coresight_kdump_node *node, *next;
+	unsigned long flags;
+
+	spin_lock_irqsave(&coresight_kdump_lock, flags);
+	list_for_each_entry_safe(node, next, &coresight_kdump_list, list) {
+		if (node->csdev == csdev) {
+			list_del(&node->list);
+			kfree(node);
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&coresight_kdump_lock, flags);
+}
+
+static coresight_cb_t
+coresight_kdump_get_cb(struct coresight_device *csdev)
+{
+	coresight_cb_t cb = NULL;
+
+	switch (csdev->type) {
+	case CORESIGHT_DEV_TYPE_SINK:
+	case CORESIGHT_DEV_TYPE_LINKSINK:
+		cb = sink_ops(csdev)->panic_cb;
+		break;
+	case CORESIGHT_DEV_TYPE_SOURCE:
+		cb = source_ops(csdev)->panic_cb;
+		break;
+	case CORESIGHT_DEV_TYPE_LINK:
+		cb = link_ops(csdev)->panic_cb;
+		break;
+	default:
+		dev_info(&csdev->dev, "Unsupport panic dump\n");
+		break;
+	}
+
+	return cb;
+}
+
+/**
+ * coresight_kdump_notify - Invoke panic dump callbacks, this is
+ * the main function to fulfill the panic dump.  It distinguishs
+ * to two types: one is pre panic dump which the callback function
+ * handler is NULL and coresight drivers can use function
+ * coresight_kdump_update() to directly update dump buffer base
+ * address and buffer size, for this case this function does nothing
+ * and directly bail out; another case is for post panic dump so
+ * invoke callback on alive CPU.
+ *
+ * Returns: 0 on success.
+ */
+static int coresight_kdump_notify(struct notifier_block *nb,
+				  unsigned long mode, void *_unused)
+{
+	struct coresight_kdump_node *node;
+	struct coresight_device *csdev;
+	coresight_cb_t cb;
+	unsigned long flags;
+
+	spin_lock_irqsave(&coresight_kdump_lock, flags);
+
+	list_for_each_entry(node, &coresight_kdump_list, list) {
+		csdev = node->csdev;
+		cb = coresight_kdump_get_cb(csdev);
+		if (cb)
+			cb(csdev);
+	}
+
+	spin_unlock_irqrestore(&coresight_kdump_lock, flags);
+	return 0;
+}
+
+static int __init coresight_kdump_init(void)
+{
+	int ret;
+
+	coresight_kdump_nb.notifier_call = coresight_kdump_notify;
+	ret = atomic_notifier_chain_register(&panic_notifier_list,
+					     &coresight_kdump_nb);
+	return ret;
+}
+late_initcall(coresight_kdump_init);
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index f1d0e21d..937750e 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -151,4 +151,17 @@ 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_add(struct coresight_device *csdev, int cpu);
+extern void coresight_kdump_del(struct coresight_device *csdev);
+extern int coresight_kdump_update(struct coresight_device *csdev,
+				  char *buf, unsigned int buf_size);
+#else
+static inline int
+coresight_kdump_add(struct coresight_device *csdev, int cpu) { return 0; }
+static inline void coresight_kdump_del(struct coresight_device *csdev) {}
+static inline int coresight_kdump_update(struct coresight_device *csdev,
+	char *buf, unsigned int buf_size) { return 0; }
+#endif
+
 #endif
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index d950dad..43e40fa 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -171,6 +171,7 @@ 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 */
+	void *dump_node;
 };
 
 #define to_coresight_device(d) container_of(d, struct coresight_device, dev)
@@ -189,6 +190,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 +207,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);
 };
 
 /**
@@ -212,10 +215,12 @@ struct coresight_ops_sink {
  * Operations available for links.
  * @enable:	enables flow between iport and oport.
  * @disable:	disables flow between iport and oport.
+ * @panic_cb:	hook function for panic notifier.
  */
 struct coresight_ops_link {
 	int (*enable)(struct coresight_device *csdev, int iport, int oport);
 	void (*disable)(struct coresight_device *csdev, int iport, int oport);
+	void (*panic_cb)(void *data);
 };
 
 /**
@@ -227,6 +232,7 @@ struct coresight_ops_link {
  *		to the HW.
  * @enable:	enables tracing for a source.
  * @disable:	disables tracing for a source.
+ * @panic_cb:	hook function for panic notifier.
  */
 struct coresight_ops_source {
 	int (*cpu_id)(struct coresight_device *csdev);
@@ -235,6 +241,7 @@ struct coresight_ops_source {
 		      struct perf_event *event,  u32 mode);
 	void (*disable)(struct coresight_device *csdev,
 			struct perf_event *event);
+	void (*panic_cb)(void *data);
 };
 
 struct coresight_ops {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 4/6] coresight: tmc: Hook callback for panic kdump
  2017-12-21  8:20 [PATCH v3 0/6] Coresight: support panic kdump Leo Yan
                   ` (2 preceding siblings ...)
  2017-12-21  8:20 ` [PATCH v3 3/6] coresight: Support panic kdump functionality Leo Yan
@ 2017-12-21  8:20 ` Leo Yan
  2017-12-21  8:20 ` [PATCH v3 5/6] coresight: Add and delete sink callback for panic kdump list Leo Yan
  2017-12-21  8:20 ` [PATCH v3 6/6] coresight: etm4x: Support panic kdump Leo Yan
  5 siblings, 0 replies; 13+ messages in thread
From: Leo Yan @ 2017-12-21  8:20 UTC (permalink / raw)
  To: Jonathan Corbet, Mathieu Poirier, Greg Kroah-Hartman,
	Will Deacon, linux-doc, linux-kernel, linux-arm-kernel,
	coresight
  Cc: Leo Yan

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

Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
 drivers/hwtracing/coresight/coresight-tmc-etf.c | 29 +++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index e2513b7..f823464 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -504,6 +504,34 @@ 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 */
+	coresight_kdump_update(csdev, drvdata->buf, 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 +540,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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 5/6] coresight: Add and delete sink callback for panic kdump list
  2017-12-21  8:20 [PATCH v3 0/6] Coresight: support panic kdump Leo Yan
                   ` (3 preceding siblings ...)
  2017-12-21  8:20 ` [PATCH v3 4/6] coresight: tmc: Hook callback for panic kdump Leo Yan
@ 2017-12-21  8:20 ` Leo Yan
  2017-12-21  8:20 ` [PATCH v3 6/6] coresight: etm4x: Support panic kdump Leo Yan
  5 siblings, 0 replies; 13+ messages in thread
From: Leo Yan @ 2017-12-21  8:20 UTC (permalink / raw)
  To: Jonathan Corbet, Mathieu Poirier, Greg Kroah-Hartman,
	Will Deacon, linux-doc, linux-kernel, linux-arm-kernel,
	coresight
  Cc: Leo Yan

If the sink device has panic kdump callback, this means the sink device
wants to save tracing data for panic happening.

This commit adds node into panic kdump list when the sink device is
enabled, and delete node when the sink device is disabled.

Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
 drivers/hwtracing/coresight/coresight.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index 389c4ba..56798b1 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -146,6 +146,14 @@ static int coresight_enable_sink(struct coresight_device *csdev, u32 mode)
 			if (ret)
 				return ret;
 		}
+
+		/* Add into panic kdump list */
+		if (sink_ops(csdev)->panic_cb) {
+			ret = coresight_kdump_add(csdev, 0);
+			if (ret)
+				return ret;
+		}
+
 		csdev->enable = true;
 	}
 
@@ -157,6 +165,10 @@ static int coresight_enable_sink(struct coresight_device *csdev, u32 mode)
 static void coresight_disable_sink(struct coresight_device *csdev)
 {
 	if (atomic_dec_return(csdev->refcnt) == 0) {
+		/* Delete from panic kdump list */
+		if (sink_ops(csdev)->panic_cb)
+			coresight_kdump_del(csdev);
+
 		if (sink_ops(csdev)->disable) {
 			sink_ops(csdev)->disable(csdev);
 			csdev->enable = false;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 6/6] coresight: etm4x: Support panic kdump
  2017-12-21  8:20 [PATCH v3 0/6] Coresight: support panic kdump Leo Yan
                   ` (4 preceding siblings ...)
  2017-12-21  8:20 ` [PATCH v3 5/6] coresight: Add and delete sink callback for panic kdump list Leo Yan
@ 2017-12-21  8:20 ` Leo Yan
  2018-01-09 20:21   ` Mathieu Poirier
  5 siblings, 1 reply; 13+ messages in thread
From: Leo Yan @ 2017-12-21  8:20 UTC (permalink / raw)
  To: Jonathan Corbet, Mathieu Poirier, Greg Kroah-Hartman,
	Will Deacon, linux-doc, linux-kernel, linux-arm-kernel,
	coresight
  Cc: Leo Yan

ETMv4 hardware information and configuration needs to be saved as
metadata; these metadata should be compatible with tool 'perf' and
can be used for tracing data analysis.  ETMv4 usually works as tracer
per CPU, we cannot wait to gather ETM info after the CPU has been panic
and cannot execute dump operations for itself; so should gather
metadata when the corresponding CPU is alive.

Since values in TRCIDR{0, 1, 2, 8} and TRCAUTHSTATUS are read-only and
won't change at the runtime.  Those registers value are filled when
tracers are instantiated.

The configuration and control registers TRCCONFIGR and TRCTRACEIDR are
dynamically configured, we record their value when enabling coresight
path.  When operating from sysFS tracer these two registers are recorded
in etm4_enable_sysfs() and add kdump node into list, and remove the
kdump node in etm4_disable_sysfs().  When operating from perf,
etm_setup_aux() adds all tracers to the dump list and etm4_enable_perf()
is used to record configuration registers and update dump buffer info,
this can avoid unnecessary list addition and deletion operations.
Removal of the tracers from the dump list is done in function
free_event_data().

Suggested-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
 drivers/hwtracing/coresight/coresight-etm-perf.c | 12 +++++++++++-
 drivers/hwtracing/coresight/coresight-etm4x.c    | 23 +++++++++++++++++++++++
 drivers/hwtracing/coresight/coresight-etm4x.h    | 15 +++++++++++++++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 8a0ad77..fec779b 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -137,6 +137,12 @@ static void free_event_data(struct work_struct *work)
 	}
 
 	for_each_cpu(cpu, mask) {
+		struct coresight_device *csdev;
+
+		csdev = per_cpu(csdev_src, cpu);
+		if (csdev)
+			coresight_kdump_del(csdev);
+
 		if (!(IS_ERR_OR_NULL(event_data->path[cpu])))
 			coresight_release_path(event_data->path[cpu]);
 	}
@@ -195,7 +201,7 @@ static void etm_free_aux(void *data)
 static void *etm_setup_aux(int event_cpu, void **pages,
 			   int nr_pages, bool overwrite)
 {
-	int cpu;
+	int cpu, ret;
 	cpumask_t *mask;
 	struct coresight_device *sink;
 	struct etm_event_data *event_data = NULL;
@@ -238,6 +244,10 @@ 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;
+
+		ret = coresight_kdump_add(csdev, cpu);
+		if (ret)
+			goto err;
 	}
 
 	if (!sink_ops(sink)->alloc_buffer)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index cf364a5..cbde398 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -258,10 +258,19 @@ static int etm4_enable_perf(struct coresight_device *csdev,
 static int etm4_enable_sysfs(struct coresight_device *csdev)
 {
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	struct etmv4_config *config = &drvdata->config;
+	struct etmv4_metadata *metadata = &drvdata->metadata;
 	int ret;
 
 	spin_lock(&drvdata->spinlock);
 
+	/* Update meta data and add into kdump list */
+	metadata->trcconfigr = config->cfg;
+	metadata->trctraceidr = drvdata->trcid;
+
+	coresight_kdump_add(csdev, drvdata->cpu);
+	coresight_kdump_update(csdev, (char *)metadata, sizeof(*metadata));
+
 	/*
 	 * Executing etm4_enable_hw on the cpu whose ETM is being enabled
 	 * ensures that register writes occur when cpu is powered.
@@ -384,6 +393,9 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
 	 */
 	smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1);
 
+	/* Delete from kdump list */
+	coresight_kdump_del(csdev);
+
 	spin_unlock(&drvdata->spinlock);
 	cpus_read_unlock();
 
@@ -438,6 +450,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 +603,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);
 }
 
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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 3/6] coresight: Support panic kdump functionality
  2017-12-21  8:20 ` [PATCH v3 3/6] coresight: Support panic kdump functionality Leo Yan
@ 2018-01-09 18:41   ` Mathieu Poirier
  2018-01-10  5:19     ` Leo Yan
  0 siblings, 1 reply; 13+ messages in thread
From: Mathieu Poirier @ 2018-01-09 18:41 UTC (permalink / raw)
  To: Leo Yan
  Cc: Jonathan Corbet, Greg Kroah-Hartman, Will Deacon, linux-doc,
	linux-kernel, linux-arm-kernel, coresight

On Thu, Dec 21, 2017 at 04:20:12PM +0800, Leo Yan wrote:
> After kernel panic happens, coresight has many useful info can be used
> for analysis.  For example, the trace info from ETB RAM can be used to
> check the CPU execution flows before crash.  So we can save the tracing
> data from sink devices, and rely on kdump to save DDR content and uses
> "crash" tool to extract coresight dumping from vmcore file.
> 
> This patch is to add a simple framework to support panic dump
> functionality; it registers panic notifier, and provide the general APIs
> {coresight_kdump_add|coresight_kdump_del} as helper functions so any
> coresight device can add itself into dump list or delete as needed.
> 
> This driver provides helper function coresight_kdump_update() to update
> the dump buffer base address and buffer size.  This function can be used
> by coresight driver, e.g. it can be used to save ETM meta data info at
> runtime and these info can be prepared pre panic happening.
> 
> When kernel panic happens, the notifier iterates dump list and calls
> callback function to dump device specific info.  The panic dump is
> mainly used to dump trace data so we can get to know the execution flow
> before the panic happens.
> 
> Signed-off-by: Leo Yan <leo.yan@linaro.org>
> ---
>  drivers/hwtracing/coresight/Kconfig                |   9 ++
>  drivers/hwtracing/coresight/Makefile               |   1 +
>  .../hwtracing/coresight/coresight-panic-kdump.c    | 154 +++++++++++++++++++++
>  drivers/hwtracing/coresight/coresight-priv.h       |  13 ++
>  include/linux/coresight.h                          |   7 +
>  5 files changed, 184 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..4812529 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

At this time only ETMv4 supports the feature, so it is only ARM64.

> +	help
> +	  This driver provides panic kdump functionality for CoreSight
> +	  devices.  When a kernel panic happen a device supplied callback function
> +	  is used to save trace data to memory. From there we rely on kdump 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..c21d20b
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-panic-kdump.c
> @@ -0,0 +1,154 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2017 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"
> +
> +typedef void (*coresight_cb_t)(void *data);
> +
> +/**
> + * struct coresight_kdump_node - Node information for dump
> + * @cpu:	The cpu this node is affined to.
> + * @csdev:	Handler for coresight device.
> + * @buf:	Pointer for dump buffer.
> + * @buf_size:	Length of dump buffer.
> + * @list:	Hook to the list.
> + */
> +struct coresight_kdump_node {
> +	int cpu;
> +	struct coresight_device *csdev;
> +	char *buf;
> +	unsigned int buf_size;
> +	struct list_head list;
> +};
> +
> +static DEFINE_SPINLOCK(coresight_kdump_lock);
> +static LIST_HEAD(coresight_kdump_list);
> +static struct notifier_block coresight_kdump_nb;
> +
> +int coresight_kdump_update(struct coresight_device *csdev, char *buf,
> +			   unsigned int buf_size)
> +{
> +	struct coresight_kdump_node *node = csdev->dump_node;
> +
> +	if (!node) {
> +		dev_err(&csdev->dev, "Failed to update dump node.\n");
> +		return -EINVAL;
> +	}
> +
> +	node->buf = buf;
> +	node->buf_size = buf_size;
> +	return 0;
> +}
> +
> +int coresight_kdump_add(struct coresight_device *csdev, int cpu)
> +{
> +	struct coresight_kdump_node *node;
> +	unsigned long flags;
> +
> +	node = kzalloc(sizeof(*node), GFP_KERNEL);
> +	if (!node)
> +		return -ENOMEM;
> +
> +	csdev->dump_node = (void *)node;
> +	node->cpu = cpu;
> +	node->csdev = csdev;
> +
> +	spin_lock_irqsave(&coresight_kdump_lock, flags);
> +	list_add_tail(&node->list, &coresight_kdump_list);
> +	spin_unlock_irqrestore(&coresight_kdump_lock, flags);
> +	return 0;
> +}
> +
> +void coresight_kdump_del(struct coresight_device *csdev)
> +{
> +	struct coresight_kdump_node *node, *next;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&coresight_kdump_lock, flags);
> +	list_for_each_entry_safe(node, next, &coresight_kdump_list, list) {
> +		if (node->csdev == csdev) {
> +			list_del(&node->list);
> +			kfree(node);
> +			break;
> +		}
> +	}
> +	spin_unlock_irqrestore(&coresight_kdump_lock, flags);
> +}
> +
> +static coresight_cb_t
> +coresight_kdump_get_cb(struct coresight_device *csdev)
> +{
> +	coresight_cb_t cb = NULL;
> +
> +	switch (csdev->type) {
> +	case CORESIGHT_DEV_TYPE_SINK:
> +	case CORESIGHT_DEV_TYPE_LINKSINK:
> +		cb = sink_ops(csdev)->panic_cb;
> +		break;
> +	case CORESIGHT_DEV_TYPE_SOURCE:
> +		cb = source_ops(csdev)->panic_cb;
> +		break;
> +	case CORESIGHT_DEV_TYPE_LINK:
> +		cb = link_ops(csdev)->panic_cb;
> +		break;

I don't see why we need a callback for link devices - didn't I raised
that question before?


And I've been thinking further about this.  The way we call the panic callbacks
won't work.  When a panic is triggered there might be trace data in the CS network
that hasn't made it to the sink yet and calling the panic callbacks for sinks
will lead to a loss of data.

That is why, when accessing from both sysFS and perf, the current implementation
takes great care to stop the tracers first and then deal with the sink.  To fix
this I suggest to call the panic callbacks only for sources.  What happens there
will depend on what interface is used (sysFS or perf) - look at what is
currently done to get a better understanding.


> +	default:
> +		dev_info(&csdev->dev, "Unsupport panic dump\n");

I would not bother with the dev_info()...

> +		break;
> +	}
> +
> +	return cb;
> +}
> +
> +/**
> + * coresight_kdump_notify - Invoke panic dump callbacks, this is
> + * the main function to fulfill the panic dump.  It distinguishs
> + * to two types: one is pre panic dump which the callback function
> + * handler is NULL and coresight drivers can use function
> + * coresight_kdump_update() to directly update dump buffer base
> + * address and buffer size, for this case this function does nothing
> + * and directly bail out; another case is for post panic dump so
> + * invoke callback on alive CPU.

Now that pre and post processing are gone the description above doesn't match
what the function is doing.

> + *
> + * Returns: 0 on success.
> + */
> +static int coresight_kdump_notify(struct notifier_block *nb,
> +				  unsigned long mode, void *_unused)
> +{
> +	struct coresight_kdump_node *node;
> +	struct coresight_device *csdev;
> +	coresight_cb_t cb;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&coresight_kdump_lock, flags);
> +
> +	list_for_each_entry(node, &coresight_kdump_list, list) {
> +		csdev = node->csdev;
> +		cb = coresight_kdump_get_cb(csdev);
> +		if (cb)
> +			cb(csdev);
> +	}
> +
> +	spin_unlock_irqrestore(&coresight_kdump_lock, flags);
> +	return 0;
> +}
> +
> +static int __init coresight_kdump_init(void)
> +{
> +	int ret;
> +
> +	coresight_kdump_nb.notifier_call = coresight_kdump_notify;
> +	ret = atomic_notifier_chain_register(&panic_notifier_list,
> +					     &coresight_kdump_nb);
> +	return ret;
> +}
> +late_initcall(coresight_kdump_init);
> diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
> index f1d0e21d..937750e 100644
> --- a/drivers/hwtracing/coresight/coresight-priv.h
> +++ b/drivers/hwtracing/coresight/coresight-priv.h
> @@ -151,4 +151,17 @@ 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_add(struct coresight_device *csdev, int cpu);
> +extern void coresight_kdump_del(struct coresight_device *csdev);
> +extern int coresight_kdump_update(struct coresight_device *csdev,
> +				  char *buf, unsigned int buf_size);
> +#else
> +static inline int
> +coresight_kdump_add(struct coresight_device *csdev, int cpu) { return 0; }
> +static inline void coresight_kdump_del(struct coresight_device *csdev) {}
> +static inline int coresight_kdump_update(struct coresight_device *csdev,
> +	char *buf, unsigned int buf_size) { return 0; }

static inline int
coresight_kdump_update(struct coresight_device *csdev, char *buf,
                       unsigned int buf_size) { return 0; }


> +#endif
> +
>  #endif
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index d950dad..43e40fa 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -171,6 +171,7 @@ 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 */
> +	void *dump_node;

Please add a description for this entry.

>  };
>  
>  #define to_coresight_device(d) container_of(d, struct coresight_device, dev)
> @@ -189,6 +190,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 +207,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);
>  };
>  
>  /**
> @@ -212,10 +215,12 @@ struct coresight_ops_sink {
>   * Operations available for links.
>   * @enable:	enables flow between iport and oport.
>   * @disable:	disables flow between iport and oport.
> + * @panic_cb:	hook function for panic notifier.
>   */
>  struct coresight_ops_link {
>  	int (*enable)(struct coresight_device *csdev, int iport, int oport);
>  	void (*disable)(struct coresight_device *csdev, int iport, int oport);
> +	void (*panic_cb)(void *data);
>  };
>  
>  /**
> @@ -227,6 +232,7 @@ struct coresight_ops_link {
>   *		to the HW.
>   * @enable:	enables tracing for a source.
>   * @disable:	disables tracing for a source.
> + * @panic_cb:	hook function for panic notifier.
>   */
>  struct coresight_ops_source {
>  	int (*cpu_id)(struct coresight_device *csdev);
> @@ -235,6 +241,7 @@ struct coresight_ops_source {
>  		      struct perf_event *event,  u32 mode);
>  	void (*disable)(struct coresight_device *csdev,
>  			struct perf_event *event);
> +	void (*panic_cb)(void *data);
>  };
>  
>  struct coresight_ops {
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 6/6] coresight: etm4x: Support panic kdump
  2017-12-21  8:20 ` [PATCH v3 6/6] coresight: etm4x: Support panic kdump Leo Yan
@ 2018-01-09 20:21   ` Mathieu Poirier
  2018-01-10  5:33     ` Leo Yan
  0 siblings, 1 reply; 13+ messages in thread
From: Mathieu Poirier @ 2018-01-09 20:21 UTC (permalink / raw)
  To: Leo Yan
  Cc: Jonathan Corbet, Greg Kroah-Hartman, Will Deacon, linux-doc,
	linux-kernel, linux-arm-kernel, coresight

On Thu, Dec 21, 2017 at 04:20:15PM +0800, Leo Yan wrote:
> ETMv4 hardware information and configuration needs to be saved as
> metadata; these metadata should be compatible with tool 'perf' and
> can be used for tracing data analysis.  ETMv4 usually works as tracer
> per CPU, we cannot wait to gather ETM info after the CPU has been panic
> and cannot execute dump operations for itself; so should gather
> metadata when the corresponding CPU is alive.
> 
> Since values in TRCIDR{0, 1, 2, 8} and TRCAUTHSTATUS are read-only and
> won't change at the runtime.  Those registers value are filled when
> tracers are instantiated.
> 
> The configuration and control registers TRCCONFIGR and TRCTRACEIDR are
> dynamically configured, we record their value when enabling coresight
> path.  When operating from sysFS tracer these two registers are recorded
> in etm4_enable_sysfs() and add kdump node into list, and remove the
> kdump node in etm4_disable_sysfs().  When operating from perf,
> etm_setup_aux() adds all tracers to the dump list and etm4_enable_perf()
> is used to record configuration registers and update dump buffer info,
> this can avoid unnecessary list addition and deletion operations.
> Removal of the tracers from the dump list is done in function
> free_event_data().
> 
> Suggested-by: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Leo Yan <leo.yan@linaro.org>
> ---
>  drivers/hwtracing/coresight/coresight-etm-perf.c | 12 +++++++++++-
>  drivers/hwtracing/coresight/coresight-etm4x.c    | 23 +++++++++++++++++++++++
>  drivers/hwtracing/coresight/coresight-etm4x.h    | 15 +++++++++++++++
>  3 files changed, 49 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
> index 8a0ad77..fec779b 100644
> --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
> +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
> @@ -137,6 +137,12 @@ static void free_event_data(struct work_struct *work)
>  	}
>  
>  	for_each_cpu(cpu, mask) {
> +		struct coresight_device *csdev;
> +
> +		csdev = per_cpu(csdev_src, cpu);
> +		if (csdev)
> +			coresight_kdump_del(csdev);
> +
>  		if (!(IS_ERR_OR_NULL(event_data->path[cpu])))
>  			coresight_release_path(event_data->path[cpu]);
>  	}
> @@ -195,7 +201,7 @@ static void etm_free_aux(void *data)
>  static void *etm_setup_aux(int event_cpu, void **pages,
>  			   int nr_pages, bool overwrite)
>  {
> -	int cpu;
> +	int cpu, ret;
>  	cpumask_t *mask;
>  	struct coresight_device *sink;
>  	struct etm_event_data *event_data = NULL;
> @@ -238,6 +244,10 @@ 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;
> +
> +		ret = coresight_kdump_add(csdev, cpu);

Aren't you missing the configuration for trcconfigr and trctraceidr?

> +		if (ret)
> +			goto err;
>  	}
>  
>  	if (!sink_ops(sink)->alloc_buffer)
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
> index cf364a5..cbde398 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
> @@ -258,10 +258,19 @@ static int etm4_enable_perf(struct coresight_device *csdev,
>  static int etm4_enable_sysfs(struct coresight_device *csdev)
>  {
>  	struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> +	struct etmv4_config *config = &drvdata->config;
> +	struct etmv4_metadata *metadata = &drvdata->metadata;
>  	int ret;
>  
>  	spin_lock(&drvdata->spinlock);
>  
> +	/* Update meta data and add into kdump list */
> +	metadata->trcconfigr = config->cfg;
> +	metadata->trctraceidr = drvdata->trcid;
> +
> +	coresight_kdump_add(csdev, drvdata->cpu);
> +	coresight_kdump_update(csdev, (char *)metadata, sizeof(*metadata));
> +
>  	/*
>  	 * Executing etm4_enable_hw on the cpu whose ETM is being enabled
>  	 * ensures that register writes occur when cpu is powered.
> @@ -384,6 +393,9 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
>  	 */
>  	smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1);
>  
> +	/* Delete from kdump list */
> +	coresight_kdump_del(csdev);
> +
>  	spin_unlock(&drvdata->spinlock);
>  	cpus_read_unlock();
>  
> @@ -438,6 +450,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 +603,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);
>  }
>  
> 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

This is a duplicate of the magic value found in cs-etm.h but I'm not sure of
what we'll do about that. It is probably time to come up
with a shared file between the kernel and the perf tools, just like
coresight-pmu.h.  You can have a stab at it or concentrate on my previous
comments for now - it's entirely up to you.

> +
> +struct etmv4_metadata {
> +	u64 magic;
> +	u64 cpu;
> +	u64 trcconfigr;
> +	u64 trctraceidr;
> +	u64 trcidr0;
> +	u64 trcidr1;
> +	u64 trcidr2;
> +	u64 trcidr8;
> +	u64 trcauthstatus;
> +};

Same here...  This is a duplicate of struct etmv4_drvdata.  Again not sure about
the best way to handle this.  I'll think about it.

> +
>  /**
>   * 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
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 3/6] coresight: Support panic kdump functionality
  2018-01-09 18:41   ` Mathieu Poirier
@ 2018-01-10  5:19     ` Leo Yan
  2018-01-10 15:43       ` Mathieu Poirier
  0 siblings, 1 reply; 13+ messages in thread
From: Leo Yan @ 2018-01-10  5:19 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Jonathan Corbet, Greg Kroah-Hartman, Will Deacon, linux-doc,
	linux-kernel, linux-arm-kernel, coresight

On Tue, Jan 09, 2018 at 11:41:26AM -0700, Mathieu Poirier wrote:
> On Thu, Dec 21, 2017 at 04:20:12PM +0800, Leo Yan wrote:
> > After kernel panic happens, coresight has many useful info can be used
> > for analysis.  For example, the trace info from ETB RAM can be used to
> > check the CPU execution flows before crash.  So we can save the tracing
> > data from sink devices, and rely on kdump to save DDR content and uses
> > "crash" tool to extract coresight dumping from vmcore file.
> > 
> > This patch is to add a simple framework to support panic dump
> > functionality; it registers panic notifier, and provide the general APIs
> > {coresight_kdump_add|coresight_kdump_del} as helper functions so any
> > coresight device can add itself into dump list or delete as needed.
> > 
> > This driver provides helper function coresight_kdump_update() to update
> > the dump buffer base address and buffer size.  This function can be used
> > by coresight driver, e.g. it can be used to save ETM meta data info at
> > runtime and these info can be prepared pre panic happening.
> > 
> > When kernel panic happens, the notifier iterates dump list and calls
> > callback function to dump device specific info.  The panic dump is
> > mainly used to dump trace data so we can get to know the execution flow
> > before the panic happens.
> > 
> > Signed-off-by: Leo Yan <leo.yan@linaro.org>
> > ---
> >  drivers/hwtracing/coresight/Kconfig                |   9 ++
> >  drivers/hwtracing/coresight/Makefile               |   1 +
> >  .../hwtracing/coresight/coresight-panic-kdump.c    | 154 +++++++++++++++++++++
> >  drivers/hwtracing/coresight/coresight-priv.h       |  13 ++
> >  include/linux/coresight.h                          |   7 +
> >  5 files changed, 184 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..4812529 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
> 
> At this time only ETMv4 supports the feature, so it is only ARM64.

Thanks for reviewing, Mathieu.

Will change to only for ARM64.

> > +	help
> > +	  This driver provides panic kdump functionality for CoreSight
> > +	  devices.  When a kernel panic happen a device supplied callback function
> > +	  is used to save trace data to memory. From there we rely on kdump 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..c21d20b
> > --- /dev/null
> > +++ b/drivers/hwtracing/coresight/coresight-panic-kdump.c
> > @@ -0,0 +1,154 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +// Copyright (c) 2017 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"
> > +
> > +typedef void (*coresight_cb_t)(void *data);
> > +
> > +/**
> > + * struct coresight_kdump_node - Node information for dump
> > + * @cpu:	The cpu this node is affined to.
> > + * @csdev:	Handler for coresight device.
> > + * @buf:	Pointer for dump buffer.
> > + * @buf_size:	Length of dump buffer.
> > + * @list:	Hook to the list.
> > + */
> > +struct coresight_kdump_node {
> > +	int cpu;
> > +	struct coresight_device *csdev;
> > +	char *buf;
> > +	unsigned int buf_size;
> > +	struct list_head list;
> > +};
> > +
> > +static DEFINE_SPINLOCK(coresight_kdump_lock);
> > +static LIST_HEAD(coresight_kdump_list);
> > +static struct notifier_block coresight_kdump_nb;
> > +
> > +int coresight_kdump_update(struct coresight_device *csdev, char *buf,
> > +			   unsigned int buf_size)
> > +{
> > +	struct coresight_kdump_node *node = csdev->dump_node;
> > +
> > +	if (!node) {
> > +		dev_err(&csdev->dev, "Failed to update dump node.\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	node->buf = buf;
> > +	node->buf_size = buf_size;
> > +	return 0;
> > +}
> > +
> > +int coresight_kdump_add(struct coresight_device *csdev, int cpu)
> > +{
> > +	struct coresight_kdump_node *node;
> > +	unsigned long flags;
> > +
> > +	node = kzalloc(sizeof(*node), GFP_KERNEL);
> > +	if (!node)
> > +		return -ENOMEM;
> > +
> > +	csdev->dump_node = (void *)node;
> > +	node->cpu = cpu;
> > +	node->csdev = csdev;
> > +
> > +	spin_lock_irqsave(&coresight_kdump_lock, flags);
> > +	list_add_tail(&node->list, &coresight_kdump_list);
> > +	spin_unlock_irqrestore(&coresight_kdump_lock, flags);
> > +	return 0;
> > +}
> > +
> > +void coresight_kdump_del(struct coresight_device *csdev)
> > +{
> > +	struct coresight_kdump_node *node, *next;
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&coresight_kdump_lock, flags);
> > +	list_for_each_entry_safe(node, next, &coresight_kdump_list, list) {
> > +		if (node->csdev == csdev) {
> > +			list_del(&node->list);
> > +			kfree(node);
> > +			break;
> > +		}
> > +	}
> > +	spin_unlock_irqrestore(&coresight_kdump_lock, flags);
> > +}
> > +
> > +static coresight_cb_t
> > +coresight_kdump_get_cb(struct coresight_device *csdev)
> > +{
> > +	coresight_cb_t cb = NULL;
> > +
> > +	switch (csdev->type) {
> > +	case CORESIGHT_DEV_TYPE_SINK:
> > +	case CORESIGHT_DEV_TYPE_LINKSINK:
> > +		cb = sink_ops(csdev)->panic_cb;
> > +		break;
> > +	case CORESIGHT_DEV_TYPE_SOURCE:
> > +		cb = source_ops(csdev)->panic_cb;
> > +		break;
> > +	case CORESIGHT_DEV_TYPE_LINK:
> > +		cb = link_ops(csdev)->panic_cb;
> > +		break;
> 
> I don't see why we need a callback for link devices - didn't I raised
> that question before?

Yes, sorry I have not deleted for link devices completely. Will remove
it.

> And I've been thinking further about this.  The way we call the panic callbacks
> won't work.  When a panic is triggered there might be trace data in the CS network
> that hasn't made it to the sink yet and calling the panic callbacks for sinks
> will lead to a loss of data.
> 
> That is why, when accessing from both sysFS and perf, the current implementation
> takes great care to stop the tracers first and then deal with the sink.  To fix
> this I suggest to call the panic callbacks only for sources.  What happens there
> will depend on what interface is used (sysFS or perf) - look at what is
> currently done to get a better understanding.

Will look into this.

If I understand correctly, we need firstly stop tracers and save trace
data from sink, right? If so we need use single callback function to
disable path and dump data for sink, will study current case and check
what's the clean method for kdump.

> > +	default:
> > +		dev_info(&csdev->dev, "Unsupport panic dump\n");
> 
> I would not bother with the dev_info()...

Will remove it.

> > +		break;
> > +	}
> > +
> > +	return cb;
> > +}
> > +
> > +/**
> > + * coresight_kdump_notify - Invoke panic dump callbacks, this is
> > + * the main function to fulfill the panic dump.  It distinguishs
> > + * to two types: one is pre panic dump which the callback function
> > + * handler is NULL and coresight drivers can use function
> > + * coresight_kdump_update() to directly update dump buffer base
> > + * address and buffer size, for this case this function does nothing
> > + * and directly bail out; another case is for post panic dump so
> > + * invoke callback on alive CPU.
> 
> Now that pre and post processing are gone the description above doesn't match
> what the function is doing.

Yeah, will remove 'pre' and 'post' to avoid confusion.

> > + *
> > + * Returns: 0 on success.
> > + */
> > +static int coresight_kdump_notify(struct notifier_block *nb,
> > +				  unsigned long mode, void *_unused)
> > +{
> > +	struct coresight_kdump_node *node;
> > +	struct coresight_device *csdev;
> > +	coresight_cb_t cb;
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&coresight_kdump_lock, flags);
> > +
> > +	list_for_each_entry(node, &coresight_kdump_list, list) {
> > +		csdev = node->csdev;
> > +		cb = coresight_kdump_get_cb(csdev);
> > +		if (cb)
> > +			cb(csdev);
> > +	}
> > +
> > +	spin_unlock_irqrestore(&coresight_kdump_lock, flags);
> > +	return 0;
> > +}
> > +
> > +static int __init coresight_kdump_init(void)
> > +{
> > +	int ret;
> > +
> > +	coresight_kdump_nb.notifier_call = coresight_kdump_notify;
> > +	ret = atomic_notifier_chain_register(&panic_notifier_list,
> > +					     &coresight_kdump_nb);
> > +	return ret;
> > +}
> > +late_initcall(coresight_kdump_init);
> > diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
> > index f1d0e21d..937750e 100644
> > --- a/drivers/hwtracing/coresight/coresight-priv.h
> > +++ b/drivers/hwtracing/coresight/coresight-priv.h
> > @@ -151,4 +151,17 @@ 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_add(struct coresight_device *csdev, int cpu);
> > +extern void coresight_kdump_del(struct coresight_device *csdev);
> > +extern int coresight_kdump_update(struct coresight_device *csdev,
> > +				  char *buf, unsigned int buf_size);
> > +#else
> > +static inline int
> > +coresight_kdump_add(struct coresight_device *csdev, int cpu) { return 0; }
> > +static inline void coresight_kdump_del(struct coresight_device *csdev) {}
> > +static inline int coresight_kdump_update(struct coresight_device *csdev,
> > +	char *buf, unsigned int buf_size) { return 0; }
> 
> static inline int
> coresight_kdump_update(struct coresight_device *csdev, char *buf,
>                        unsigned int buf_size) { return 0; }

Will fix.

> > +#endif
> > +
> >  #endif
> > diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> > index d950dad..43e40fa 100644
> > --- a/include/linux/coresight.h
> > +++ b/include/linux/coresight.h
> > @@ -171,6 +171,7 @@ 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 */
> > +	void *dump_node;
> 
> Please add a description for this entry.

Will do.

Thanks,
Leo Yan

> >  };
> >  
> >  #define to_coresight_device(d) container_of(d, struct coresight_device, dev)
> > @@ -189,6 +190,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 +207,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);
> >  };
> >  
> >  /**
> > @@ -212,10 +215,12 @@ struct coresight_ops_sink {
> >   * Operations available for links.
> >   * @enable:	enables flow between iport and oport.
> >   * @disable:	disables flow between iport and oport.
> > + * @panic_cb:	hook function for panic notifier.
> >   */
> >  struct coresight_ops_link {
> >  	int (*enable)(struct coresight_device *csdev, int iport, int oport);
> >  	void (*disable)(struct coresight_device *csdev, int iport, int oport);
> > +	void (*panic_cb)(void *data);
> >  };
> >  
> >  /**
> > @@ -227,6 +232,7 @@ struct coresight_ops_link {
> >   *		to the HW.
> >   * @enable:	enables tracing for a source.
> >   * @disable:	disables tracing for a source.
> > + * @panic_cb:	hook function for panic notifier.
> >   */
> >  struct coresight_ops_source {
> >  	int (*cpu_id)(struct coresight_device *csdev);
> > @@ -235,6 +241,7 @@ struct coresight_ops_source {
> >  		      struct perf_event *event,  u32 mode);
> >  	void (*disable)(struct coresight_device *csdev,
> >  			struct perf_event *event);
> > +	void (*panic_cb)(void *data);
> >  };
> >  
> >  struct coresight_ops {
> > -- 
> > 2.7.4
> > 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 6/6] coresight: etm4x: Support panic kdump
  2018-01-09 20:21   ` Mathieu Poirier
@ 2018-01-10  5:33     ` Leo Yan
  2018-01-10 15:46       ` Mathieu Poirier
  0 siblings, 1 reply; 13+ messages in thread
From: Leo Yan @ 2018-01-10  5:33 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Jonathan Corbet, Greg Kroah-Hartman, Will Deacon, linux-doc,
	linux-kernel, linux-arm-kernel, coresight

On Tue, Jan 09, 2018 at 01:21:28PM -0700, Mathieu Poirier wrote:
> On Thu, Dec 21, 2017 at 04:20:15PM +0800, Leo Yan wrote:
> > ETMv4 hardware information and configuration needs to be saved as
> > metadata; these metadata should be compatible with tool 'perf' and
> > can be used for tracing data analysis.  ETMv4 usually works as tracer
> > per CPU, we cannot wait to gather ETM info after the CPU has been panic
> > and cannot execute dump operations for itself; so should gather
> > metadata when the corresponding CPU is alive.
> > 
> > Since values in TRCIDR{0, 1, 2, 8} and TRCAUTHSTATUS are read-only and
> > won't change at the runtime.  Those registers value are filled when
> > tracers are instantiated.
> > 
> > The configuration and control registers TRCCONFIGR and TRCTRACEIDR are
> > dynamically configured, we record their value when enabling coresight
> > path.  When operating from sysFS tracer these two registers are recorded
> > in etm4_enable_sysfs() and add kdump node into list, and remove the
> > kdump node in etm4_disable_sysfs().  When operating from perf,
> > etm_setup_aux() adds all tracers to the dump list and etm4_enable_perf()
> > is used to record configuration registers and update dump buffer info,
> > this can avoid unnecessary list addition and deletion operations.
> > Removal of the tracers from the dump list is done in function
> > free_event_data().
> > 
> > Suggested-by: Mathieu Poirier <mathieu.poirier@linaro.org>
> > Signed-off-by: Leo Yan <leo.yan@linaro.org>
> > ---
> >  drivers/hwtracing/coresight/coresight-etm-perf.c | 12 +++++++++++-
> >  drivers/hwtracing/coresight/coresight-etm4x.c    | 23 +++++++++++++++++++++++
> >  drivers/hwtracing/coresight/coresight-etm4x.h    | 15 +++++++++++++++
> >  3 files changed, 49 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
> > index 8a0ad77..fec779b 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
> > +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
> > @@ -137,6 +137,12 @@ static void free_event_data(struct work_struct *work)
> >  	}
> >  
> >  	for_each_cpu(cpu, mask) {
> > +		struct coresight_device *csdev;
> > +
> > +		csdev = per_cpu(csdev_src, cpu);
> > +		if (csdev)
> > +			coresight_kdump_del(csdev);
> > +
> >  		if (!(IS_ERR_OR_NULL(event_data->path[cpu])))
> >  			coresight_release_path(event_data->path[cpu]);
> >  	}
> > @@ -195,7 +201,7 @@ static void etm_free_aux(void *data)
> >  static void *etm_setup_aux(int event_cpu, void **pages,
> >  			   int nr_pages, bool overwrite)
> >  {
> > -	int cpu;
> > +	int cpu, ret;
> >  	cpumask_t *mask;
> >  	struct coresight_device *sink;
> >  	struct etm_event_data *event_data = NULL;
> > @@ -238,6 +244,10 @@ 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;
> > +
> > +		ret = coresight_kdump_add(csdev, cpu);
> 
> Aren't you missing the configuration for trcconfigr and trctraceidr?

Ah, should update these two configurations in function
etm4_enable_perf()?

> > +		if (ret)
> > +			goto err;
> >  	}
> >  
> >  	if (!sink_ops(sink)->alloc_buffer)
> > diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
> > index cf364a5..cbde398 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm4x.c
> > +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
> > @@ -258,10 +258,19 @@ static int etm4_enable_perf(struct coresight_device *csdev,
> >  static int etm4_enable_sysfs(struct coresight_device *csdev)
> >  {
> >  	struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> > +	struct etmv4_config *config = &drvdata->config;
> > +	struct etmv4_metadata *metadata = &drvdata->metadata;
> >  	int ret;
> >  
> >  	spin_lock(&drvdata->spinlock);
> >  
> > +	/* Update meta data and add into kdump list */
> > +	metadata->trcconfigr = config->cfg;
> > +	metadata->trctraceidr = drvdata->trcid;
> > +
> > +	coresight_kdump_add(csdev, drvdata->cpu);
> > +	coresight_kdump_update(csdev, (char *)metadata, sizeof(*metadata));
> > +
> >  	/*
> >  	 * Executing etm4_enable_hw on the cpu whose ETM is being enabled
> >  	 * ensures that register writes occur when cpu is powered.
> > @@ -384,6 +393,9 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
> >  	 */
> >  	smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1);
> >  
> > +	/* Delete from kdump list */
> > +	coresight_kdump_del(csdev);
> > +
> >  	spin_unlock(&drvdata->spinlock);
> >  	cpus_read_unlock();
> >  
> > @@ -438,6 +450,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 +603,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);
> >  }
> >  
> > 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
> 
> This is a duplicate of the magic value found in cs-etm.h but I'm not sure of
> what we'll do about that. It is probably time to come up
> with a shared file between the kernel and the perf tools, just like
> coresight-pmu.h.  You can have a stab at it or concentrate on my previous
> comments for now - it's entirely up to you.

I will do some try for this for changing to use one shared single
header, if I have no confidence for this I will go back to keep this
code for new version patch.

> > +
> > +struct etmv4_metadata {
> > +	u64 magic;
> > +	u64 cpu;
> > +	u64 trcconfigr;
> > +	u64 trctraceidr;
> > +	u64 trcidr0;
> > +	u64 trcidr1;
> > +	u64 trcidr2;
> > +	u64 trcidr8;
> > +	u64 trcauthstatus;
> > +};
> 
> Same here...  This is a duplicate of struct etmv4_drvdata.  Again not sure about
> the best way to handle this.  I'll think about it.

Sure, I might check with you when I spin patches for this.

Thanks,
Leo Yan

> > +
> >  /**
> >   * 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
> > 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 3/6] coresight: Support panic kdump functionality
  2018-01-10  5:19     ` Leo Yan
@ 2018-01-10 15:43       ` Mathieu Poirier
  0 siblings, 0 replies; 13+ messages in thread
From: Mathieu Poirier @ 2018-01-10 15:43 UTC (permalink / raw)
  To: Leo Yan
  Cc: Jonathan Corbet, Greg Kroah-Hartman, Will Deacon,
	open list:DOCUMENTATION, linux-kernel, linux-arm-kernel,
	coresight

On 9 January 2018 at 22:19, Leo Yan <leo.yan@linaro.org> wrote:
> On Tue, Jan 09, 2018 at 11:41:26AM -0700, Mathieu Poirier wrote:
>> On Thu, Dec 21, 2017 at 04:20:12PM +0800, Leo Yan wrote:
>> > After kernel panic happens, coresight has many useful info can be used
>> > for analysis.  For example, the trace info from ETB RAM can be used to
>> > check the CPU execution flows before crash.  So we can save the tracing
>> > data from sink devices, and rely on kdump to save DDR content and uses
>> > "crash" tool to extract coresight dumping from vmcore file.
>> >
>> > This patch is to add a simple framework to support panic dump
>> > functionality; it registers panic notifier, and provide the general APIs
>> > {coresight_kdump_add|coresight_kdump_del} as helper functions so any
>> > coresight device can add itself into dump list or delete as needed.
>> >
>> > This driver provides helper function coresight_kdump_update() to update
>> > the dump buffer base address and buffer size.  This function can be used
>> > by coresight driver, e.g. it can be used to save ETM meta data info at
>> > runtime and these info can be prepared pre panic happening.
>> >
>> > When kernel panic happens, the notifier iterates dump list and calls
>> > callback function to dump device specific info.  The panic dump is
>> > mainly used to dump trace data so we can get to know the execution flow
>> > before the panic happens.
>> >
>> > Signed-off-by: Leo Yan <leo.yan@linaro.org>
>> > ---
>> >  drivers/hwtracing/coresight/Kconfig                |   9 ++
>> >  drivers/hwtracing/coresight/Makefile               |   1 +
>> >  .../hwtracing/coresight/coresight-panic-kdump.c    | 154 +++++++++++++++++++++
>> >  drivers/hwtracing/coresight/coresight-priv.h       |  13 ++
>> >  include/linux/coresight.h                          |   7 +
>> >  5 files changed, 184 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..4812529 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
>>
>> At this time only ETMv4 supports the feature, so it is only ARM64.
>
> Thanks for reviewing, Mathieu.
>
> Will change to only for ARM64.
>
>> > +   help
>> > +     This driver provides panic kdump functionality for CoreSight
>> > +     devices.  When a kernel panic happen a device supplied callback function
>> > +     is used to save trace data to memory. From there we rely on kdump 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..c21d20b
>> > --- /dev/null
>> > +++ b/drivers/hwtracing/coresight/coresight-panic-kdump.c
>> > @@ -0,0 +1,154 @@
>> > +// SPDX-License-Identifier: GPL-2.0
>> > +// Copyright (c) 2017 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"
>> > +
>> > +typedef void (*coresight_cb_t)(void *data);
>> > +
>> > +/**
>> > + * struct coresight_kdump_node - Node information for dump
>> > + * @cpu:   The cpu this node is affined to.
>> > + * @csdev: Handler for coresight device.
>> > + * @buf:   Pointer for dump buffer.
>> > + * @buf_size:      Length of dump buffer.
>> > + * @list:  Hook to the list.
>> > + */
>> > +struct coresight_kdump_node {
>> > +   int cpu;
>> > +   struct coresight_device *csdev;
>> > +   char *buf;
>> > +   unsigned int buf_size;
>> > +   struct list_head list;
>> > +};
>> > +
>> > +static DEFINE_SPINLOCK(coresight_kdump_lock);
>> > +static LIST_HEAD(coresight_kdump_list);
>> > +static struct notifier_block coresight_kdump_nb;
>> > +
>> > +int coresight_kdump_update(struct coresight_device *csdev, char *buf,
>> > +                      unsigned int buf_size)
>> > +{
>> > +   struct coresight_kdump_node *node = csdev->dump_node;
>> > +
>> > +   if (!node) {
>> > +           dev_err(&csdev->dev, "Failed to update dump node.\n");
>> > +           return -EINVAL;
>> > +   }
>> > +
>> > +   node->buf = buf;
>> > +   node->buf_size = buf_size;
>> > +   return 0;
>> > +}
>> > +
>> > +int coresight_kdump_add(struct coresight_device *csdev, int cpu)
>> > +{
>> > +   struct coresight_kdump_node *node;
>> > +   unsigned long flags;
>> > +
>> > +   node = kzalloc(sizeof(*node), GFP_KERNEL);
>> > +   if (!node)
>> > +           return -ENOMEM;
>> > +
>> > +   csdev->dump_node = (void *)node;
>> > +   node->cpu = cpu;
>> > +   node->csdev = csdev;
>> > +
>> > +   spin_lock_irqsave(&coresight_kdump_lock, flags);
>> > +   list_add_tail(&node->list, &coresight_kdump_list);
>> > +   spin_unlock_irqrestore(&coresight_kdump_lock, flags);
>> > +   return 0;
>> > +}
>> > +
>> > +void coresight_kdump_del(struct coresight_device *csdev)
>> > +{
>> > +   struct coresight_kdump_node *node, *next;
>> > +   unsigned long flags;
>> > +
>> > +   spin_lock_irqsave(&coresight_kdump_lock, flags);
>> > +   list_for_each_entry_safe(node, next, &coresight_kdump_list, list) {
>> > +           if (node->csdev == csdev) {
>> > +                   list_del(&node->list);
>> > +                   kfree(node);
>> > +                   break;
>> > +           }
>> > +   }
>> > +   spin_unlock_irqrestore(&coresight_kdump_lock, flags);
>> > +}
>> > +
>> > +static coresight_cb_t
>> > +coresight_kdump_get_cb(struct coresight_device *csdev)
>> > +{
>> > +   coresight_cb_t cb = NULL;
>> > +
>> > +   switch (csdev->type) {
>> > +   case CORESIGHT_DEV_TYPE_SINK:
>> > +   case CORESIGHT_DEV_TYPE_LINKSINK:
>> > +           cb = sink_ops(csdev)->panic_cb;
>> > +           break;
>> > +   case CORESIGHT_DEV_TYPE_SOURCE:
>> > +           cb = source_ops(csdev)->panic_cb;
>> > +           break;
>> > +   case CORESIGHT_DEV_TYPE_LINK:
>> > +           cb = link_ops(csdev)->panic_cb;
>> > +           break;
>>
>> I don't see why we need a callback for link devices - didn't I raised
>> that question before?
>
> Yes, sorry I have not deleted for link devices completely. Will remove
> it.
>
>> And I've been thinking further about this.  The way we call the panic callbacks
>> won't work.  When a panic is triggered there might be trace data in the CS network
>> that hasn't made it to the sink yet and calling the panic callbacks for sinks
>> will lead to a loss of data.
>>
>> That is why, when accessing from both sysFS and perf, the current implementation
>> takes great care to stop the tracers first and then deal with the sink.  To fix
>> this I suggest to call the panic callbacks only for sources.  What happens there
>> will depend on what interface is used (sysFS or perf) - look at what is
>> currently done to get a better understanding.
>
> Will look into this.
>
> If I understand correctly, we need firstly stop tracers and save trace
> data from sink, right? If so we need use single callback function to
> disable path and dump data for sink, will study current case and check
> what's the clean method for kdump.

You are correct - only the callback for sources should be used.  In
that callback processing is different whether trace collection was
started from sysFS or perf.  The code already exists, it's just a
matter of doing the right thing.

>
>> > +   default:
>> > +           dev_info(&csdev->dev, "Unsupport panic dump\n");
>>
>> I would not bother with the dev_info()...
>
> Will remove it.
>
>> > +           break;
>> > +   }
>> > +
>> > +   return cb;
>> > +}
>> > +
>> > +/**
>> > + * coresight_kdump_notify - Invoke panic dump callbacks, this is
>> > + * the main function to fulfill the panic dump.  It distinguishs
>> > + * to two types: one is pre panic dump which the callback function
>> > + * handler is NULL and coresight drivers can use function
>> > + * coresight_kdump_update() to directly update dump buffer base
>> > + * address and buffer size, for this case this function does nothing
>> > + * and directly bail out; another case is for post panic dump so
>> > + * invoke callback on alive CPU.
>>
>> Now that pre and post processing are gone the description above doesn't match
>> what the function is doing.
>
> Yeah, will remove 'pre' and 'post' to avoid confusion.
>
>> > + *
>> > + * Returns: 0 on success.
>> > + */
>> > +static int coresight_kdump_notify(struct notifier_block *nb,
>> > +                             unsigned long mode, void *_unused)
>> > +{
>> > +   struct coresight_kdump_node *node;
>> > +   struct coresight_device *csdev;
>> > +   coresight_cb_t cb;
>> > +   unsigned long flags;
>> > +
>> > +   spin_lock_irqsave(&coresight_kdump_lock, flags);
>> > +
>> > +   list_for_each_entry(node, &coresight_kdump_list, list) {
>> > +           csdev = node->csdev;
>> > +           cb = coresight_kdump_get_cb(csdev);
>> > +           if (cb)
>> > +                   cb(csdev);
>> > +   }
>> > +
>> > +   spin_unlock_irqrestore(&coresight_kdump_lock, flags);
>> > +   return 0;
>> > +}
>> > +
>> > +static int __init coresight_kdump_init(void)
>> > +{
>> > +   int ret;
>> > +
>> > +   coresight_kdump_nb.notifier_call = coresight_kdump_notify;
>> > +   ret = atomic_notifier_chain_register(&panic_notifier_list,
>> > +                                        &coresight_kdump_nb);
>> > +   return ret;
>> > +}
>> > +late_initcall(coresight_kdump_init);
>> > diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
>> > index f1d0e21d..937750e 100644
>> > --- a/drivers/hwtracing/coresight/coresight-priv.h
>> > +++ b/drivers/hwtracing/coresight/coresight-priv.h
>> > @@ -151,4 +151,17 @@ 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_add(struct coresight_device *csdev, int cpu);
>> > +extern void coresight_kdump_del(struct coresight_device *csdev);
>> > +extern int coresight_kdump_update(struct coresight_device *csdev,
>> > +                             char *buf, unsigned int buf_size);
>> > +#else
>> > +static inline int
>> > +coresight_kdump_add(struct coresight_device *csdev, int cpu) { return 0; }
>> > +static inline void coresight_kdump_del(struct coresight_device *csdev) {}
>> > +static inline int coresight_kdump_update(struct coresight_device *csdev,
>> > +   char *buf, unsigned int buf_size) { return 0; }
>>
>> static inline int
>> coresight_kdump_update(struct coresight_device *csdev, char *buf,
>>                        unsigned int buf_size) { return 0; }
>
> Will fix.
>
>> > +#endif
>> > +
>> >  #endif
>> > diff --git a/include/linux/coresight.h b/include/linux/coresight.h
>> > index d950dad..43e40fa 100644
>> > --- a/include/linux/coresight.h
>> > +++ b/include/linux/coresight.h
>> > @@ -171,6 +171,7 @@ 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 */
>> > +   void *dump_node;
>>
>> Please add a description for this entry.
>
> Will do.
>
> Thanks,
> Leo Yan
>
>> >  };
>> >
>> >  #define to_coresight_device(d) container_of(d, struct coresight_device, dev)
>> > @@ -189,6 +190,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 +207,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);
>> >  };
>> >
>> >  /**
>> > @@ -212,10 +215,12 @@ struct coresight_ops_sink {
>> >   * Operations available for links.
>> >   * @enable:        enables flow between iport and oport.
>> >   * @disable:       disables flow between iport and oport.
>> > + * @panic_cb:      hook function for panic notifier.
>> >   */
>> >  struct coresight_ops_link {
>> >     int (*enable)(struct coresight_device *csdev, int iport, int oport);
>> >     void (*disable)(struct coresight_device *csdev, int iport, int oport);
>> > +   void (*panic_cb)(void *data);
>> >  };
>> >
>> >  /**
>> > @@ -227,6 +232,7 @@ struct coresight_ops_link {
>> >   *         to the HW.
>> >   * @enable:        enables tracing for a source.
>> >   * @disable:       disables tracing for a source.
>> > + * @panic_cb:      hook function for panic notifier.
>> >   */
>> >  struct coresight_ops_source {
>> >     int (*cpu_id)(struct coresight_device *csdev);
>> > @@ -235,6 +241,7 @@ struct coresight_ops_source {
>> >                   struct perf_event *event,  u32 mode);
>> >     void (*disable)(struct coresight_device *csdev,
>> >                     struct perf_event *event);
>> > +   void (*panic_cb)(void *data);
>> >  };
>> >
>> >  struct coresight_ops {
>> > --
>> > 2.7.4
>> >

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 6/6] coresight: etm4x: Support panic kdump
  2018-01-10  5:33     ` Leo Yan
@ 2018-01-10 15:46       ` Mathieu Poirier
  0 siblings, 0 replies; 13+ messages in thread
From: Mathieu Poirier @ 2018-01-10 15:46 UTC (permalink / raw)
  To: Leo Yan
  Cc: Jonathan Corbet, Greg Kroah-Hartman, Will Deacon,
	open list:DOCUMENTATION, linux-kernel, linux-arm-kernel,
	coresight

On 9 January 2018 at 22:33, Leo Yan <leo.yan@linaro.org> wrote:
> On Tue, Jan 09, 2018 at 01:21:28PM -0700, Mathieu Poirier wrote:
>> On Thu, Dec 21, 2017 at 04:20:15PM +0800, Leo Yan wrote:
>> > ETMv4 hardware information and configuration needs to be saved as
>> > metadata; these metadata should be compatible with tool 'perf' and
>> > can be used for tracing data analysis.  ETMv4 usually works as tracer
>> > per CPU, we cannot wait to gather ETM info after the CPU has been panic
>> > and cannot execute dump operations for itself; so should gather
>> > metadata when the corresponding CPU is alive.
>> >
>> > Since values in TRCIDR{0, 1, 2, 8} and TRCAUTHSTATUS are read-only and
>> > won't change at the runtime.  Those registers value are filled when
>> > tracers are instantiated.
>> >
>> > The configuration and control registers TRCCONFIGR and TRCTRACEIDR are
>> > dynamically configured, we record their value when enabling coresight
>> > path.  When operating from sysFS tracer these two registers are recorded
>> > in etm4_enable_sysfs() and add kdump node into list, and remove the
>> > kdump node in etm4_disable_sysfs().  When operating from perf,
>> > etm_setup_aux() adds all tracers to the dump list and etm4_enable_perf()
>> > is used to record configuration registers and update dump buffer info,
>> > this can avoid unnecessary list addition and deletion operations.
>> > Removal of the tracers from the dump list is done in function
>> > free_event_data().
>> >
>> > Suggested-by: Mathieu Poirier <mathieu.poirier@linaro.org>
>> > Signed-off-by: Leo Yan <leo.yan@linaro.org>
>> > ---
>> >  drivers/hwtracing/coresight/coresight-etm-perf.c | 12 +++++++++++-
>> >  drivers/hwtracing/coresight/coresight-etm4x.c    | 23 +++++++++++++++++++++++
>> >  drivers/hwtracing/coresight/coresight-etm4x.h    | 15 +++++++++++++++
>> >  3 files changed, 49 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
>> > index 8a0ad77..fec779b 100644
>> > --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
>> > +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
>> > @@ -137,6 +137,12 @@ static void free_event_data(struct work_struct *work)
>> >     }
>> >
>> >     for_each_cpu(cpu, mask) {
>> > +           struct coresight_device *csdev;
>> > +
>> > +           csdev = per_cpu(csdev_src, cpu);
>> > +           if (csdev)
>> > +                   coresight_kdump_del(csdev);
>> > +
>> >             if (!(IS_ERR_OR_NULL(event_data->path[cpu])))
>> >                     coresight_release_path(event_data->path[cpu]);
>> >     }
>> > @@ -195,7 +201,7 @@ static void etm_free_aux(void *data)
>> >  static void *etm_setup_aux(int event_cpu, void **pages,
>> >                        int nr_pages, bool overwrite)
>> >  {
>> > -   int cpu;
>> > +   int cpu, ret;
>> >     cpumask_t *mask;
>> >     struct coresight_device *sink;
>> >     struct etm_event_data *event_data = NULL;
>> > @@ -238,6 +244,10 @@ 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;
>> > +
>> > +           ret = coresight_kdump_add(csdev, cpu);
>>
>> Aren't you missing the configuration for trcconfigr and trctraceidr?
>
> Ah, should update these two configurations in function
> etm4_enable_perf()?

Looking at what you've done for etm4_enable_sysfs() that is probably a
better choice.

>
>> > +           if (ret)
>> > +                   goto err;
>> >     }
>> >
>> >     if (!sink_ops(sink)->alloc_buffer)
>> > diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
>> > index cf364a5..cbde398 100644
>> > --- a/drivers/hwtracing/coresight/coresight-etm4x.c
>> > +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
>> > @@ -258,10 +258,19 @@ static int etm4_enable_perf(struct coresight_device *csdev,
>> >  static int etm4_enable_sysfs(struct coresight_device *csdev)
>> >  {
>> >     struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> > +   struct etmv4_config *config = &drvdata->config;
>> > +   struct etmv4_metadata *metadata = &drvdata->metadata;
>> >     int ret;
>> >
>> >     spin_lock(&drvdata->spinlock);
>> >
>> > +   /* Update meta data and add into kdump list */
>> > +   metadata->trcconfigr = config->cfg;
>> > +   metadata->trctraceidr = drvdata->trcid;
>> > +
>> > +   coresight_kdump_add(csdev, drvdata->cpu);
>> > +   coresight_kdump_update(csdev, (char *)metadata, sizeof(*metadata));
>> > +
>> >     /*
>> >      * Executing etm4_enable_hw on the cpu whose ETM is being enabled
>> >      * ensures that register writes occur when cpu is powered.
>> > @@ -384,6 +393,9 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
>> >      */
>> >     smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1);
>> >
>> > +   /* Delete from kdump list */
>> > +   coresight_kdump_del(csdev);
>> > +
>> >     spin_unlock(&drvdata->spinlock);
>> >     cpus_read_unlock();
>> >
>> > @@ -438,6 +450,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 +603,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);
>> >  }
>> >
>> > 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
>>
>> This is a duplicate of the magic value found in cs-etm.h but I'm not sure of
>> what we'll do about that. It is probably time to come up
>> with a shared file between the kernel and the perf tools, just like
>> coresight-pmu.h.  You can have a stab at it or concentrate on my previous
>> comments for now - it's entirely up to you.
>
> I will do some try for this for changing to use one shared single
> header, if I have no confidence for this I will go back to keep this
> code for new version patch.

Deal.

>
>> > +
>> > +struct etmv4_metadata {
>> > +   u64 magic;
>> > +   u64 cpu;
>> > +   u64 trcconfigr;
>> > +   u64 trctraceidr;
>> > +   u64 trcidr0;
>> > +   u64 trcidr1;
>> > +   u64 trcidr2;
>> > +   u64 trcidr8;
>> > +   u64 trcauthstatus;
>> > +};
>>
>> Same here...  This is a duplicate of struct etmv4_drvdata.  Again not sure about
>> the best way to handle this.  I'll think about it.
>
> Sure, I might check with you when I spin patches for this.
>
> Thanks,
> Leo Yan
>
>> > +
>> >  /**
>> >   * 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
>> >

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2018-01-10 15:46 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-21  8:20 [PATCH v3 0/6] Coresight: support panic kdump Leo Yan
2017-12-21  8:20 ` [PATCH v3 1/6] doc: Add Coresight documentation directory Leo Yan
2017-12-21  8:20 ` [PATCH v3 2/6] doc: Add documentation for Coresight panic kdump Leo Yan
2017-12-21  8:20 ` [PATCH v3 3/6] coresight: Support panic kdump functionality Leo Yan
2018-01-09 18:41   ` Mathieu Poirier
2018-01-10  5:19     ` Leo Yan
2018-01-10 15:43       ` Mathieu Poirier
2017-12-21  8:20 ` [PATCH v3 4/6] coresight: tmc: Hook callback for panic kdump Leo Yan
2017-12-21  8:20 ` [PATCH v3 5/6] coresight: Add and delete sink callback for panic kdump list Leo Yan
2017-12-21  8:20 ` [PATCH v3 6/6] coresight: etm4x: Support panic kdump Leo Yan
2018-01-09 20:21   ` Mathieu Poirier
2018-01-10  5:33     ` Leo Yan
2018-01-10 15:46       ` Mathieu Poirier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).