This patchset introduces initial concepts in CoreSight system
configuration management support. to allow more detailed and complex
programming to be applied to CoreSight systems during trace capture.
Configurations consist of 2 elements:-
1) Features - programming combinations for devices, applied to a class of
device on the system (all ETMv4), or individual devices.
2) Configurations - a set of programmed features used when the named
configuration is selected.
Features and configurations are declared as a data table, a set of register,
resource and parameter requirements. Features and configurations are loaded
into the system by the virtual cs_syscfg device. This then matches features
to any registered devices and loads the feature into them.
Individual device classes that support feature and configuration register
with cs_syscfg.
Once loaded a configuration can be enabled for a specific trace run.
Configurations are registered with the perf cs_etm event as entries in
cs_etm/events. These can be selected on the perf command line as follows:-
perf record -e cs_etm/<config_name>/ ...
This patch set has one pre-loaded configuration and feature.
A named "strobing" feature is provided for ETMv4.
A named "autofdo" configuration is provided. This configuration enables
strobing on any ETM in used.
Thus the command:
perf record -e cs_etm/autofdo/ ...
will trace the supplied application while enabling the "autofdo" configuation
on each ETM as it is enabled by perf. This in turn will enable strobing for
the ETM - with default parameters. Parameters can be adjusted using configfs.
The sink used in the trace run will be automatically selected.
A configuration can supply up to 15 of preset parameter values, which will
subsitute in parameter values for any feature used in the configuration.
Selection of preset values as follows
perf record -e cs_etm/autofdo,preset=1/ ...
(valid presets 1-N, where N is the number supplied in the configuration, not
exceeding 15. preset=0 is the same as not selecting a preset.)
Applies to & tested against coresight/next-ETE-TRBE (5.12-rc3 base)
Changes since v6:
Fixed kernel test robot issues-
Reported-by: kernel test robot <lkp(a)intel.com>
Changes since v5:
1) Fix code style issues from auto-build reports, as
Reported-by: kernel test robot <lkp(a)intel.com>
2) Update comments to get consistent docs for API functions.
3) remove unused #define from autofdo example.
4) fix perf code style issues from patch 4 (Mathieu)
5) fix configfs code style issues from patch 9. (Mathieu)
Changes since v4: (based on comments from Matthieu and Suzuki).
No large functional changes - primarily code improvements and naming schema.
1) Updated entire set to ensure a consistent naming scheme was used for
variables and struct members that refer to the key objects in the system.
Suffixes _desc used for all references to feature and configuraion descriptors,
suffix _csdev used for all references to load feature and configs in the csdev
instances. (Mathieu & Suzuki).
2) Dropped the 'configurations' sub dir in cs_etm perf directories as superfluous
with the configfs containing the same information. (Mathieu).
3) Simplified perf handling code (suzuki)
4) Multiple simplifications and improvements for code readability (Matthieu
and Suzuki)
Changes since v3: (Primarily based on comments from Matthieu)
1) Locking mechanisms simplified.
2) Removed the possibility to enable features independently from
configurations.Only configurations can be enabled now. Simplifies programming
logic.
3) Configuration now uses an activate->enable mechanism. This means that perf
will activate a selected configuration at the start of a session (during
setup_aux), and disable at the end of a session (around free_aux)
The active configuration and associated features will be programmed into the
CoreSight device instances when they are enabled. This locks the configuration
into the system while in use. Parameters cannot be altered while this is
in place. This mechanism will be extended in future for dynamic load / unload
of configurations to prevent removal while in use.
4) Removed the custom bus / driver as un-necessary. A single device is
registered to own perf fs elements and configfs.
5) Various other minor issues addressed.
Changes since v2:
1) Added documentation file.
2) Altered cs_syscfg driver to no longer be coresight_device based, and moved
to its own custom bus to remove it from the main coresight bus. (Mathieu)
3) Added configfs support to inspect and control loaded configurations and
features. Allows listing of preset values (Yabin Cui)
4) Dropped sysfs support for adjusting feature parameters on the per device
basis, in favour of a single point adjustment in configfs that is pushed to all
device instances.
5) Altered how the config and preset command line options are handled in perf
and the drivers. (Mathieu and Suzuki).
6) Fixes for various issues and technical points (Mathieu, Yabin)
Changes since v1:
1) Moved preloaded configurations and features out of individual drivers.
2) Added cs_syscfg driver to manage configurations and features. Individual
drivers register with cs_syscfg indicating support for config, and provide
matching information that the system uses to load features into the drivers.
This allows individual drivers to be updated on an as needed basis - and
removes the need to consider devices that cannot benefit from configuration -
static replicators, funnels, tpiu.
3) Added perf selection of configuarations.
4) Rebased onto the coresight module loading set.
To follow in future revisions / sets:-
a) load of additional config and features by loadable module.
b) load of additional config and features by configfs
c) enhanced resource management for ETMv4 and checking features have sufficient
resources to be enabled.
d) ECT and CTI support for configuration and features.
Mike Leach (10):
coresight: syscfg: Initial coresight system configuration
coresight: syscfg: Add registration and feature loading for cs devices
coresight: config: Add configuration and feature generic functions
coresight: etm-perf: update to handle configuration selection
coresight: syscfg: Add API to activate and enable configurations
coresight: etm-perf: Update to activate selected configuration
coresight: etm4x: Add complex configuration handlers to etmv4
coresight: config: Add preloaded configurations
coresight: syscfg: Add initial configfs support
Documentation: coresight: Add documentation for CoreSight config
.../trace/coresight/coresight-config.rst | 244 ++++++
Documentation/trace/coresight/coresight.rst | 16 +
drivers/hwtracing/coresight/Makefile | 7 +-
.../hwtracing/coresight/coresight-cfg-afdo.c | 153 ++++
.../coresight/coresight-cfg-preload.c | 31 +
.../coresight/coresight-cfg-preload.h | 13 +
.../hwtracing/coresight/coresight-config.c | 275 ++++++
.../hwtracing/coresight/coresight-config.h | 253 ++++++
drivers/hwtracing/coresight/coresight-core.c | 12 +-
.../hwtracing/coresight/coresight-etm-perf.c | 150 +++-
.../hwtracing/coresight/coresight-etm-perf.h | 12 +-
.../hwtracing/coresight/coresight-etm4x-cfg.c | 182 ++++
.../hwtracing/coresight/coresight-etm4x-cfg.h | 30 +
.../coresight/coresight-etm4x-core.c | 38 +-
.../coresight/coresight-etm4x-sysfs.c | 3 +
.../coresight/coresight-syscfg-configfs.c | 396 +++++++++
.../coresight/coresight-syscfg-configfs.h | 45 +
.../hwtracing/coresight/coresight-syscfg.c | 804 ++++++++++++++++++
.../hwtracing/coresight/coresight-syscfg.h | 81 ++
include/linux/coresight.h | 7 +
20 files changed, 2716 insertions(+), 36 deletions(-)
create mode 100644 Documentation/trace/coresight/coresight-config.rst
create mode 100644 drivers/hwtracing/coresight/coresight-cfg-afdo.c
create mode 100644 drivers/hwtracing/coresight/coresight-cfg-preload.c
create mode 100644 drivers/hwtracing/coresight/coresight-cfg-preload.h
create mode 100644 drivers/hwtracing/coresight/coresight-config.c
create mode 100644 drivers/hwtracing/coresight/coresight-config.h
create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.c
create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.h
create mode 100644 drivers/hwtracing/coresight/coresight-syscfg-configfs.c
create mode 100644 drivers/hwtracing/coresight/coresight-syscfg-configfs.h
create mode 100644 drivers/hwtracing/coresight/coresight-syscfg.c
create mode 100644 drivers/hwtracing/coresight/coresight-syscfg.h
--
2.17.1
Hardware assisted tracing families such as ARM Coresight, Intel PT
provides rich tracing capabilities including instruction level
tracing and accurate timestamps which are very useful for profiling
and also pose a significant security risk. One such example of
security risk is when kernel mode tracing is not excluded and these
hardware assisted tracing can be used to analyze cryptographic code
execution. In this case, even the root user must not be able to infer
anything.
To explain it more clearly in the words of a security team member
(credits: Mattias Nissler),
"Consider a system where disk contents are encrypted and the encryption
key is set up by the user when mounting the file system. From that point
on the encryption key resides in the kernel. It seems reasonable to
expect that the disk encryption key be protected from exfiltration even
if the system later suffers a root compromise (or even against insiders
that have root access), at least as long as the attacker doesn't
manage to compromise the kernel."
Here the idea is to protect such important information from all users
including root users since root privileges does not have to mean full
control over the kernel [1] and root compromise does not have to be
the end of the world.
But "Peter said even the regular counters can be used for full branch trace,
the information isn't as accurate as PT and friends and not easier but
is good enough to infer plenty". This would mean that a global tunable
config for all kernel mode pmu tracing is more appropriate than the one
targeting the hardware assisted instruction tracing.
Currently we can exclude kernel mode tracing via perf_event_paranoid
sysctl but it has following limitations,
* No option to restrict kernel mode instruction tracing by the
root user.
* Not possible to restrict kernel mode instruction tracing when the
hardware assisted tracing IPs like ARM Coresight ETMs use an
additional interface via sysfs for tracing in addition to perf
interface.
So introduce a new config CONFIG_EXCLUDE_KERNEL_PMU_TRACE to exclude
kernel mode pmu tracing for all users including root which will be
generic and applicable to all hardware tracing families and which
can also be used with other interfaces like sysfs in case of ETMs.
Patch 1 adds this new config and the support in perf core to exclude
all kernel mode PMU tracing.
Patch 2 adds the perf evsel warning message when the perf tool users
attempt to perform a kernel mode trace with the config enabled to
exclude the kernel mode tracing.
Patch 3 and Patch 4 adds the support for excluding kernel mode for
ARM Coresight ETM{4,3}XX sysfs mode using the newly introduced generic
config.
[1] https://lwn.net/Articles/796866/
Changes in v2:
* Move from kernel mode instruction tracing to all kernel level PMU tracing (Peter)
* Move the check and warning to the caller mode_store() (Doug)
Sai Prakash Ranjan (4):
perf/core: Add support to exclude kernel mode PMU tracing
perf evsel: Print warning for excluding kernel mode instruction
tracing
coresight: etm4x: Add support to exclude kernel mode tracing
coresight: etm3x: Add support to exclude kernel mode tracing
drivers/hwtracing/coresight/coresight-etm3x-core.c | 3 +++
drivers/hwtracing/coresight/coresight-etm3x-sysfs.c | 6 ++++++
drivers/hwtracing/coresight/coresight-etm4x-core.c | 6 +++++-
drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 6 ++++++
init/Kconfig | 11 +++++++++++
kernel/events/core.c | 3 +++
tools/perf/util/evsel.c | 3 ++-
7 files changed, 36 insertions(+), 2 deletions(-)
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
This series adds a feature to ETR-PERF that sync the ETR buffer to perf
periodically. This is really handy when the system wide trace is used
because in this case the perf won't sync during the trace. In a per-thread
setup the traced program might not go to the kernel frequvently enought
to collect trace. Polling helps in both usecases. Can be used with strobing.
Tuning polling period is challanging, I'm working on an additional patch
that adds some metrics to help tune the polling period.
Daniel Kiss (4):
coresight: tmc-etr: Advance buffer pointer in sync buffer.
coresight: tmc-etr: Track perf handler.
coresight: etm-perf: Export etm_event_cpu_path.
coresight: Add ETR-PERF polling.
.../testing/sysfs-bus-coresight-devices-tmc | 8 +
drivers/hwtracing/coresight/Makefile | 2 +-
.../hwtracing/coresight/coresight-etm-perf.c | 10 +-
.../hwtracing/coresight/coresight-etm-perf.h | 1 +
.../coresight/coresight-etr-perf-polling.c | 316 ++++++++++++++++++
.../coresight/coresight-etr-perf-polling.h | 42 +++
.../hwtracing/coresight/coresight-tmc-core.c | 2 +
.../hwtracing/coresight/coresight-tmc-etr.c | 22 +-
drivers/hwtracing/coresight/coresight-tmc.h | 2 +
9 files changed, 401 insertions(+), 4 deletions(-)
create mode 100644 drivers/hwtracing/coresight/coresight-etr-perf-polling.c
create mode 100644 drivers/hwtracing/coresight/coresight-etr-perf-polling.h
--
2.25.1
Hi All,
Since my previous RFC, I've fixed --per-thread mode and solved
most of the open questions. I've also changed --dump-raw-trace
to use the same code path so it's also working now.
I think the only open questions are:
* General approach
* If aux records need to be saved, or if they can be pulled
from elsewhere.
I've also tested perf inject which is now working with troublesome
files.
Thanks
James
James Clark (7):
perf cs-etm: Split up etm queue setup function
perf cs-etm: Only search timestamp in current sample's queue.
perf cs-etm: Save aux records in each etm queue
perf cs-etm: don't process queues until cs_etm__flush_events
perf cs-etm: split decode by aux records.
perf cs-etm: Use existing decode code path for --dump-raw-trace
perf cs-etm: Suppress printing when resetting decoder
.../perf/util/cs-etm-decoder/cs-etm-decoder.c | 10 +-
tools/perf/util/cs-etm.c | 300 ++++++++++--------
2 files changed, 168 insertions(+), 142 deletions(-)
--
2.28.0
Hi,
Please ensure you reply to the list as well - this gives you a better
chance of getting a timely response & my find people who know more
about CSAL.
On Wed, 21 Apr 2021 at 20:36, Dominik Huber <dominik.huber(a)fau.de> wrote:
>
> Hello,
> Thanks for all the help. Especially the explanation of the trace was
> very insightful.
> For now, I am going to try implementing the sysfs tracing, since it
> seemed easier at first glance. I found the documentation for the .ini
> files within the snapshots, and am now trying to create my own version
> of them. But I'm struggling to get the addresses for all the devices,
> e.g. within cpu_0.ini. I've read in the discovery.md from CSAL that they
> can be extracted by reading the ROM table of my Cortex-A53, but I'm
> doing/understanding something wrong.
> I cross-compiled the CSAL library and the csinfo-folder (which btw
> only compiled after inserting "MODULE_LICENSE("");" into the csinfo.c
> file).
> Then I copied the resulting csinfo.ko to my Hikey620 where I tried
> "sudo make" and it returned:
> Load CoreSight reporting module... expect "Resource temporarily unavailable"
> insmod csinfo.ko
> insmod: ERROR: could not insert module csinfo.ko: Resource temporarily
> unavailable
> Makefile:17: recipe for target 'load' failed
> make: *** [load] Error 1
> If I understood correctly, that is intended, but should also give me the
> base address of the ROM-table afterward. But there was no other output.
> I do have CONFIG_DEVMEM enabled. I tried "sudo insmod csinfo.ko".
> directly as well, with the same result.
Looking at the code it appears that the output is printk(KERN_INFO ... )
Check the printk level is correct on your system.
> I could neither find the physical base address for the Cortex-A53 nor a
> way to read the "CBAR_EL1" register, which apparently contains that
> information. At least not without a debugger.
> Since I don't know the correct address, i just tried "sudo ./csscan.py
> 0x0", and this was the result:
> @0x0 0x000 0x000 r0.0 unexpected CIDR: 0x000000f8
> class:0
> What does this output mean?
>
As far as I can tell to get valid output from this tool, you need to
give it a valid input address / range of addresses.
CIDR is the component ID register - this is used by the tool to match
to known component values. If it says unexpected then it means just
that - the value found is not a recognised CIDR for the tool.
See the Coresight Spoecification for how CIDR and other IDR values are
useda nd waht is expected.
Regards
Mike
> For the address 0xE011000 I got:
> @0xe011000 0x200 0x000 r0.7 unexpected CIDR: 0x00001a3f
> ROM table
> Does this help me? Unfortunately, this is not persistent information,
> since after a reboot it showed something different.
> How can I find out the addresses, that I need for the .ini files?
>
> Regards,
>
> Dominik
>
> On 12/04/2021 11:44, Mike Leach wrote:
> > HI,
> >
> > On Sat, 10 Apr 2021 at 13:59, Dominik Huber <dominik.huber(a)fau.de> wrote:
> >>
> >> Am 09.04.2021 um 17:01 schrieb Mike Leach:
> >>> Hi Dominik
> >>>
> >>> On Fri, 9 Apr 2021 at 15:22, Dominik Huber<dominik.huber(a)fau.de> wrote:
> >>>> Hello,
> >>>> I want to gather trace data of closed source binaries using CoreSight
> >>>> ETMv4 on a Hikey620. I want to know the source and destination address
> >>>> for all taken jumps of the traced program, like in the output of "perf
> >>>> script". It would be great if I could get feedback on how to achieve this.
> >>>> I'm not sure where to turn to with such a broad CoreSight problem, so
> >>>> I'm sorry if you are not the right ones to turn to, but I'd be happy for
> >>>> any help or advice you might have.
> >>>>
> >>> This is exactly the right place to ask for help on this!
> >> I'm glad to hear that!
> >>>> My main problem is, that I don't know which approaches are promising to
> >>>> try. Below I describe two Ideas that I tried but where I got stuck after
> >>>> a while. Are they any good for my use case? If yes, then how can I solve
> >>>> the respective problems that have come up, or where can I look to solve
> >>>> them? If not, are there maybe better ways to approach this, which I've
> >>>> overlooked until now?
> >>>>
> >>>> After hearing a presentation from Mathieu Poirier, I thought sysFS was
> >>>> the (only) way to go. However, the decoded trace seems to show only the
> >>>> jump address, instead of both the source and destination addresses, and
> >>>> I did not find a register to change that.
> >>> What do you mean by decoded trace here & what are you using to decode the trace?
> >>> If you look at the ETM spec / OpenCSD documentation you will see that
> >>> to fully decode trace there is a two step process.
> >>> 1) convert the trace byte stream into trace packets. This will
> >>> require some minimal information regarding the configuration of the
> >>> ETM
> >>> 2) convert the trace packets into the fully decoded execution trace.
> >>> This requires access to the binary images executed during the trace
> >>> session.
> >>> The reason for this is that trace packets are highly compressed, and
> >>> contain the minimum of address information. Decode requires that the
> >>> decoder will walk the binary images to deduce which branches are taken
> >>> and not taken.
> >>> Only were address information cannot be deduced from this code is
> >>> included in the trace packets - and this is only ever target address
> >>> information - the source address can always be deduced from the code
> >>> walk.
> >> I used ptm2human for decoding. I also tried the c_api_pkt_print_test.c
> >> from OpenCSD, which decodes a single packet. However, depending on how I
> >> collected the trace data, it does not always produce decoded data.
> > ptm2human performs the 1st stage of decode - byte stream to trace
> > packets. The output from this is the same as the packet only decode
> > from the OpenCSD library / trc_pkt_lister app. This will print out the
> > trace packets - but be aware that in both cases the addresses that you
> > see in the trace are not all the branch addresses used in the executed
> > application.
> >
> >
> >> Once
> >> I have a working proof-of-concept, I intended to write myself an OpenCSD
> >> decoder. Because of that, and because the decoding often just seemed "to
> >> work", I postponed any thoughts about the packet processing.
> >> What are these "binary images"? Until now, I got only a cstrace.bin from
> >> /dev/[sink], which I used as only Input for any decoding. How can I get
> >> them? Can I, by using them, obtain the destination addresses of branch
> >> instructions?
> >>
> > cstrace.bin is the binary trace data. The binary images I refer to are
> > the memory images of the executed code - the decoder walks this memory
> > image to deduce the path of the executed trace based on the opcodes
> > encountered.
> > These are either the binary files of your application and any loaded
> > .so files, or may be a memory dump of the locations these were loaded
> > during the trace session. Either will do to decode.
> >
> > See https://github.com/Linaro/OpenCSD/blob/master/decoder/docs/prog_guide/prog_…
> >
> > So to successfully decode a trace session to obtain the source and
> > target branch addresses you want, you will need the following:-
> >
> > 1) The captured binary trace data.
> > 2) The configuration registers of the ETM
> > 3) The program binaries for all applications and .so libraries active
> > during the trace session and their load addresses.
> > Be aware that ETM will trace everything running on a core - so you it
> > may be necessary for any analysis of a particular program to filter
> > out anything unrelated.
> >
> >
> >>>> Also, the trace gathered seems to lose some of the branch addresses.
> >>>> Inserting a sleep instruction after each regular instruction into my
> >>>> test program, fixed that. But since it should also work for closed
> >>>> source binaries and has to be fast this is probably not an option.
> >>>>
> >>>> Then I tried to copy the way "perf record" is tracing, and extract the
> >>>> relevant code parts. But then I realized, that perf record doesn't use
> >>>> sysFS, apart from enabling the sink in "util/cs-etm.c" (which apparently
> >>>> is not used, and not even deactivated afterward).
> >>> perf uses the driver in the a similar way to sysfs. It does in fact
> >>> activate and de-activate the sources and sinks as the perf events are
> >>> run on any CPU.
> >>> perf also records the binaries used during the trace session - so that
> >>> full trace decode is possible. With sysfs you can get raw trace data -
> >>> but relating this to the binaries being executed is far more
> >>> difficult.
> >> So is it your recommendation to use large parts of the perf source code
> >> for my project because it already makes use of these "binary images"?
> > I was not recommending re-use of perf source code - I was recommending
> > using perf to capture and analyse trace. If this is not sufficient -
> > or you want to write your own application, then perf serves as an
> > example of the information you need to collect during a trace session
> > to successfully decode the trace. perf does two tasks - capture -
> > using perf record, and analysis using perf report. These are very
> > separate elements - the first happens in kernel space, the second,
> > often offline as a separate perf program, in user space.
> >
> >> Up until now, I only thought about using a few hundred lines, because I
> >> believe perf has a lot of overhead (both in performance and code length)
> >> just to get branch instructions from an executed binary.
> >>
> >> The most important factors for me are that
> >> 1) the trace includes all branches (including the jump destination), and
> >> 2) it is fast (faster than using hardware emulation and extracting the
> >> addresses from there)
> >>
> >> What about the approaches to use the CoreSight driver directly or to use
> >> CSAL for trace collection? Would they maybe be better suited?
> >>
> > The best method used for capturing trace is really an assessment for
> > you to decide based on your requirements. CSAL / direct driver access
> > / sysfs are all options - though I am not aware of anyone actually
> > using a direct driver access method so could not really advise here.
> >
> > Remember that whatever method you choose, in order to get the data
> > that you require you will need to collect the additional information I
> > describe above.
> > Once you have this data you can then pass it to the OpenCSD library
> > for full decode. This will output the executed trace ranges. You are
> > then free to analyse these ranges to synthesise source / target data
> > for branches.
> >
> > Below is a short example of the trace output from the library - I have
> > annotated this '***' to explain what is happening. This was generated
> > using trc_pkt_lister test program from OpenCSD, running on one of the
> > supplied test captures.
> >
> > The I_ packets are the trace packets - as would be output from
> > ptm2human, the OCSD_GEN_TRC packets are the output of the library -
> > fully decoded trace ranges.
> >
> > Idx:356; ID:12; [0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
> > 0x00 0x80 ]; I_ASYNC : Alignment Synchronisation.
> > *** start of trace - align the decoder to the incoming byte stream for
> > the ETM programmed with trace ID 0x12
> >
> > Idx:369; ID:12; [0x01 0x01 0x00 ]; I_TRACE_INFO : Trace Info.;
> > INFO=0x0 { CC.0 }
> > *** Some setup information regarding trace configuration - used
> > internally by the decoder.
> >
> > Idx:372; ID:12; [0xf7 ]; I_ATOM_F1 : Atom format 1.; E
> > *** atom packet - skipped - cannot decode until we get an address /
> > context packet
> >
> > Idx:373; ID:12; [0x85 0x22 0x12 0x4d 0x00 0x00 0x00 0x00 0x00 0x30 ];
> > I_ADDR_CTXT_L_64IS0 : Address & Context, Long, 64 bit, IS0.;
> > Addr=0x00000000004D2488; Ctxt: AArch64,EL0, NS;
> > *** address and context packet - this gives the trace start address
> > for the decoder + EL and ISA context.
> >
> > Idx:384; ID:12; [0xf7 ]; I_ATOM_F1 : Atom format 1.; E
> > *** Atom packet. This indicates that the program executed a number of
> > instructions until it encountered a P0 element instruction (a P0
> > element instruction - previously referred to as waypoints in PTM, are
> > instructions that change the address flow of the program. These are
> > primarily branch instructions but the full range of P0 instruction
> > types is defined by the ETM4 protocol). This instruction was executed.
> >
> > Idx:373; ID:12; OCSD_GEN_TRC_ELEM_PE_CONTEXT((ISA=A64) EL0N; 64-bit; )
> > *** OpenCSD library outputs the context information for the client
> > application. Where traced context also includes the Context ID
> > register which may contain the PID of the program running on the CPU
> > under dertain kernel configurations.
> >
> > Idx:384; ID:12; OCSD_GEN_TRC_ELEM_INSTR_RANGE(exec
> > range=0x4d2488:[0x4d2494] num_i(3) last_sz(4) (ISA=A64) E iBR A64:ret
> > )
> > *** OpenCSD outputs the executed instruction trace range three
> > instructions from addresses 0x4d2488 - 0x4d2493. This is output in
> > response to the atom packet.
> > This range was calculated by starting @ address 0x4d2488, walking
> > through the program image from that address, examining opcodes until
> > it found a P0 element (branch instruction) which it associates with
> > the atom packet.
> > This was an indirect branch (iBR A64:ret ) and also an aarch64 return
> > instruction. This branch was taken (E). At this point we do not know
> > the destination of the branch - so we are waiting for a target address
> > packet in the input stream.
> >
> > Idx:385; ID:12; [0x9d 0x48 0x5f 0x4d 0x00 0x00 0x00 0x00 0x00 ];
> > I_ADDR_L_64IS0 : Address, Long, 64 bit, IS0.; Addr=0x00000000004DBF20;
> > *** Address packet - this updates the decoder with the target of the
> > prior indirect branch - which can now continue decoding
> >
> > Idx:394; ID:12; [0xde ]; I_ATOM_F4 : Atom format 4.; NENE
> > *** 4 atom packets - representing 4 waypoint instructions that were
> > taken (E) or not taken (N). You will note that this single packet will
> > decode into 4 separate executed instruction ranges - with no further
> > address packets visible in the trace.
> >
> > Idx:394; ID:12; OCSD_GEN_TRC_ELEM_INSTR_RANGE(exec
> > range=0x4dbf20:[0x4dbf24] num_i(1) last_sz(4) (ISA=A64) N BR <cond>)
> > *** OpenCSD executed instruction range - 1 instruction - was a not
> > taken branch. This range started @ 0x04DBF20 - taken from the address
> > packet above.
> > At this point the client program using the library can deduce the most
> > recent taken branch information - as 0x4d2490=>0x4dbf20
> >
> > Idx:394; ID:12; OCSD_GEN_TRC_ELEM_INSTR_RANGE(exec
> > range=0x4dbf24:[0x4dbf2c] num_i(2) last_sz(4) (ISA=A64) E BR b+link )
> > *** OpenCSD executed instruction range - 2 instruction - last
> > instruction was a taken branch + link - in this case the decoder can
> > calculate the target address from the instruction opcode - so no
> > address data needs to appear in the trace.
> >
> > Idx:394; ID:12; OCSD_GEN_TRC_ELEM_INSTR_RANGE(exec
> > range=0x4d1d88:[0x4d1db4] num_i(11) last_sz(4) (ISA=A64) N BR
> > <cond>)
> > *** OpenCSD executed instruction range - 11 instrucitons, starting at
> > the address calculated from the previous range. So the start of the
> > range was the result of a branch 0x4dbf28=>0x4d1d88
> > Ends in a not taken branch.
> >
> > Idx:394; ID:12; OCSD_GEN_TRC_ELEM_INSTR_RANGE(exec
> > range=0x4d1db4:[0x4d1dbc] num_i(2) last_sz(4) (ISA=A64) E BR <cond>)
> > *** OpenCSD executed instruction range - 2 instructions, last is a
> > direct branch which will allow us to calculate the target address.
> >
> > Throughout this process the decoder maintains a current trace address
> > from the incoming address packets, and by walking through the executed
> > opcodes - calculating branch targets where possible. This is why the
> > program and library binaries (or a memeory dump or their load
> > locations ) is required for full trace decode and obtaining the
> > information you require.
> >
> > Again, I would recommend reading the ETM protocol spec and the OpenCSD
> > libarary documentation to get a full understanding of the protocols
> > and how decoding works.
> >
> > Regards
> >
> >
> >
> > Mike
> >
> >>> If you are interested in tracing a particular binary & this is a
> >>> userspace program then you may wish to try:-
> >>> perf record -e cs_etm//u --per-thread <program-to-trace>
> >>> to ensure that any trace collected is related to the program you are
> >>> interested in. You can then use the facilites of perf report / perf
> >>> script to examine the trace.
> >> Thanks, but I luckily already knew about that one.
> >>> Regards
> >>>
> >>> Mike
> >>>
> >>>
> >>>
> >>>> So there is another way to gather trace, maybe by interacting with the
> >>>> CoreSight driver directly. But looking into the "perf report" source
> >>>> code I couldn't find it yet.
> >>>>
> >>>> Thanks and regards,
> >>>>
> >>>> Dominik
> >>>>
> >>>> _______________________________________________
> >>>> CoreSight mailing list
> >>>> CoreSight(a)lists.linaro.org
> >>>> https://lists.linaro.org/mailman/listinfo/coresight
> >>> --
> >>> Mike Leach
> >>> Principal Engineer, ARM Ltd.
> >>> Manchester Design Centre. UK
> >
> >
> > --
> > Mike Leach
> > Principal Engineer, ARM Ltd.
> > Manchester Design Centre. UK
--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK
The perf tool records the Arm CoreSight trace data with snapshot mode
with the option '-S', when receiving USR2 signal, it is observed the
captured trace data size is very varied: from several MBs to ~20MBs.
This can be reproduced with the command:
perf record -e cs_etm// -S \
-- dd if=/dev/zero of=/dev/null > /dev/null 2>&1 &
PERFPID=$!
sleep 1
kill -USR2 $PERFPID
It's different for only specifying option '-S' than options '-a -S'. If
without option '-a', perf tool creates separate AUX buffers for every
CPU, but the tracer will be enabled only when the profiled program is
scheduled onto the corresponding CPU, this might lead to record very
old trace data when snapshot.
Let's see below diagram:
snapshot
CPU0: ______###P1###__________________________________________|
CPU1: __________________________###P3###____________###P5###__|
CPU2: ____________________________________###P4###____________|
CPU3: ________________###P2###________________________________V
In this diagram, the program runs for 5 periods (from P1 to P5), these 5
periods show the task run on different CPUs, e.g. during P1 period the
program runs on CPU0, and during P2 period the program is migrated to
CPU1, and so on. At the end of P1 period when the program is switched
out from CPU0, the ETR trace data is saved into AUX trace buffer, this
AUX buffer is a dedicated buffer for CPU0's tracer. With the same
logic, P2's trace data is saved into CPU3's tracer buffer, P4's trace
data is saved into CPU2's buffer, P3 and P5's trace data is saved into
CPU1's. Therefore, when snapshot, it saves the trace data from all AUX
ring buffers (in this case, it have total 4 AUX ring buffers) into perf
data file.
This is why we can see varied trace data size, it's quite dependent on
the task scheduling on CPUs, if the task is spinned to only one CPU and
without scheduling out, it will only record trace data from only one
AUX trace buffer. If the task is frequently scheduled in and out, then
it gives more chance to fill trace data into the AUX buffer.
In this example, it also causes the discontinuous trace data. If P3's
trace data is lost after P5's trace data overwrites the AUX trace data,
thus perf tool fails to record continuous trace data if only have
trace data for P1/P2/P4/P5.
For snapshot mode, usually the user only wants to capture the trace data
for the specific time point and prior to the that point the tracer
should work with free run mode. This means it's not necessary to
capture trace data for task's scheduling in and out until the perf tool
explicitly disables tracers for snapshot. This can be fulfilled by
checking the variable "event->ctx->is_active", when the task is
scheduled out this variable is set to zero, and when snapshot this
variable is still non-zero value. So the driver can only record trace
data only when "event->ctx->is_active" is non-zero.
After applying this change, the perf tool can record the consistent
trace data size for snapshot.
Signed-off-by: Leo Yan <leo.yan(a)linaro.org>
---
.../hwtracing/coresight/coresight-etm-perf.c | 21 ++++++++++++++++---
.../hwtracing/coresight/coresight-etm-perf.h | 2 ++
2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 0f603b4094f2..5fceefe9513c 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -245,6 +245,7 @@ static void *etm_setup_aux(struct perf_event *event, void **pages,
if (!event_data)
return NULL;
INIT_WORK(&event_data->work, free_event_data);
+ event_data->overwrite = overwrite;
/* First get the selected sink from user space. */
if (event->attr.config2) {
@@ -424,9 +425,23 @@ static void etm_event_stop(struct perf_event *event, int mode)
if (!sink_ops(sink)->update_buffer)
return;
- size = sink_ops(sink)->update_buffer(sink, handle,
- event_data->snk_config);
- perf_aux_output_end(handle, size);
+ /*
+ * In the snapshot mode, here should avoid to record trace data
+ * when the profiled program is scheduled out and only capture
+ * trace data when the perf tool receives USR2 signal.
+ *
+ * This is distinguished by variable "event->ctx->is_active",
+ * its value is zero for profiled task scheduling out, and it
+ * is a non-zero value when perf tool invokes ioctl
+ * PERF_EVENT_IOC_DISABLE.
+ */
+ if (!event_data->overwrite || event->ctx->is_active) {
+ size = sink_ops(sink)->update_buffer(sink, handle,
+ event_data->snk_config);
+ perf_aux_output_end(handle, size);
+ } else {
+ perf_aux_output_end(handle, 0);
+ }
}
/* Disabling the path make its elements available to other sessions */
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.h b/drivers/hwtracing/coresight/coresight-etm-perf.h
index 3e4f2ad5e193..2cc3af05495f 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.h
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.h
@@ -49,12 +49,14 @@ struct etm_filters {
* @mask: Hold the CPU(s) this event was set for.
* @snk_config: The sink configuration.
* @path: An array of path, each slot for one CPU.
+ * @overwrite: Flag for snapshot mode.
*/
struct etm_event_data {
struct work_struct work;
cpumask_t mask;
void *snk_config;
struct list_head * __percpu *path;
+ bool overwrite;
};
#if IS_ENABLED(CONFIG_CORESIGHT)
--
2.25.1