Changes

Jump to: navigation, search

MISC-TN-017: Persistent storage and read-write file systems

2,258 bytes removed, 16:51, 19 January 2022
no edit summary
Below is an example of how the TRACE32-based log method can be applied to a Linux system. The solution is based on light instrumentation of the <code>mmc_start_request()</code> and <code>mmc_request_done()</code> functions defined in the Linux <code>drivers/mmc/core/core.c</code> source code file. Relevant eMMC device accesses are captured through the instrumentation code and they are written to a static data structure making them immediately traceable if data trace is available in the SoC. If data tracing is not possible, the instrumentation code writes the data to the Arm®/Cortex® Context ID register.
The solution was successfully tested on the aforementioned embedded platform. The instrumentation code is provided in [[#Appendix 1: source code example|Appendix 1]]. The zero initialization of the <code>T32_mmc</code> structure is guaranteed by Linux, since this variable is allocated in the <code>bss</code> section. The instrumentation is normally disabled but can be enabled by writing the value "1" into the <code>enable</code> field of the <code>T32_mmc</code> structure. The identifier of the eMMC device to be traced must be written into the <code>dev</code> field. Both of these operations can be performed from a TRACE32 script with the following commands:
<pre class="workstation-terminal">
NOTE: ‘OR Cycle task’ is optional.
This implementation along with the software-based method was were tested on the following use case:
* Read/write workload to the mmc0 device was issued by using [https://github.com/stressapptest/stressapptest stressapptest] application (<code>stressapptest -s 20 -f /mnt/mmc0/file1 -f /mnt/mmc0/file2</code>) resulting in the creation of two files, 16 MByte each
<pre class="workstation-terminal">
cat /sys/kernel/debug/tracing/trace_pipe > /home/root/prove/ftrace.txt
</pre>
 
 
===== Verification =====
To verify the implementation of the TRACE32-based method, a specific test was run. In essence, the testbed was configured in order to run TRACE32 and <code>ftrace</code> tracing — more details in the following section — simultaneously for analyzing the same workload. The logs produced by the two methods were then compared to ensure they match. To this end,
 
These logs
==== Results and comparison with the software-based method (<code>ftrace</code>) ====
The functions average duration analysis of eMMC accesses highlights the greater weight required by <code>ftrace</code>. Additional, detailed charts are shown in the following section. They allow to determine that using <code>ftrace</code> also involves a greater dispersion of the execution times compared to both the kernel without <code>ftrace</code> and the kernel instrumented only with the code for TRACE32. In particular, the functions <code>mmc_start_request()</code> and <code>mmc_request_done()</code> have a few microseconds constant execution time without <code>ftrace</code>, and show a very variable execution time with <code>ftrace</code>, with a maximum time up to 279 us and 285 us respectively.
In conclusion===== Detailed time analysis ===== ====== <code>mmc_start_request</code> ======[[File:Lauterbach-eMMC-1-1.png|center|thumb|724x724px|No ftrace, the no TRACE32 instrumentation]][[File:Lauterbach-eMMC-1-2.png|center|thumb|725x725px|No ftrace, with TRACE32 instrumentation]][[File:Lauterbach-eMMC-1-3.png|center|thumb|725x725px|With ftrace, no TRACE32 instrumentation]] ====== <code>mmc_request_done</code> ======[[File:Lauterbach-eMMC-2-1.png|center|thumb|821x821px|No ftrace, no TRACE32 instrumentation]] [[File:Lauterbach-eMMC-2-2.png|center|thumb|819x819px|No ftrace, with TRACE32 instrumentation]] [[File:Lauterbach-eMMC-2-3.png|center|thumb|821x821px|With ftrace, no TRACE32 instrumentation]] ==== Conclusion ====The hardware method based on TRACE32 provides the same log data as recorded by <code>ftrace</code> but with minimal changes to the kernel (a few lines in a file) and a tiny time penalty. It also does not use any additional memory (in terms of RAM and file system storage) and allows for extremely long measurement times.
The following table summarizes the advantages and disadvantages of the two considered solutions: TRACE32 vs <code>ftrace</code>.
* For each eMMC operation, <code>ftrace</code> saves roughly 876 bytes of log information.
|}
 
===== Detailed time analysis =====
 
====== <code>mmc_start_request</code> ======
[[File:Lauterbach-eMMC-1-1.png|center|thumb|724x724px|No ftrace, no TRACE32 instrumentation]]
[[File:Lauterbach-eMMC-1-2.png|center|thumb|725x725px|No ftrace, with TRACE32 instrumentation]]
[[File:Lauterbach-eMMC-1-3.png|center|thumb|725x725px|With ftrace, no TRACE32 instrumentation]]
 
====== <code>mmc_request_done</code> ======
[[File:Lauterbach-eMMC-2-1.png|center|thumb|821x821px|No ftrace, no TRACE32 instrumentation]]
 
[[File:Lauterbach-eMMC-2-2.png|center|thumb|819x819px|No ftrace, with TRACE32 instrumentation]]
 
[[File:Lauterbach-eMMC-2-3.png|center|thumb|821x821px|With ftrace, no TRACE32 instrumentation]]
 
==== Logs analysis and conclusions ====
No matter how the accesses to the e.MMC are traced, once the logs are available they can be processed thoroughly to produce reports that are very useful to analyze how the host actually operates the device.
 
The following are some such reports from a test conducted on a e.MMC partition (<code>mmcblk0p1</code>) formatted with <code>ext4</code> file system:
 
<pre class="board-terminal">
mkfs.ext4 /dev/mmcblk0p1
</pre>
 
Please note that this formatting results in a 4 kByte block size:
<pre class="board-terminal">
root@imx8mqevk:~# dumpe2fs -x /dev/mmcblk0p1
 
dumpe2fs 1.43.5 (04-Aug-2017)
Filesystem volume name: <none>
...
Block size: 4096
...
</pre>
The ext4 block must not be confused with the e.MMC blocks, which are 512 bytes as per JEDEC specifications and are addressed according to the [https://en.wikipedia.org/wiki/Logical_block_addressing LBA] scheme.
 
The analyzed workload is the result of a combination of different tools performing read and write accesses (<code>/mnt/mmc0</code> is the mount point of the partition of interest):
<pre class="board-terminal">
root@imx8mqevk:~# stressapptest -s 20 -f /mnt/mmc0/file1 -f /mnt/mmc0/file2
root@imx8mqevk:~# find / -name "*" > /mnt/mmc0/find_results.txt
root@imx8mqevk:~# dd if=/dev/urandom of=/mnt/mmc0/dummyfile.bin bs=4k count=25000
root@imx8mqevk:~# rm /mnt/mmc0/dummyfile.bin
root@imx8mqevk:~# dd if=/dev/zero of=/mnt/mmc0/dummyfile.bin bs=4k count=25000
root@imx8mqevk:~# sync
</pre>
 
The following chart
 
4kB (dd)
512B (streassapptest)
Questo perché, non essendo specificato il parametro --write-block-size, dovrebbe valere il default:
read_block_size_ = kSectorSize; // default 1 sector (512 bytes)
write_block_size_ = kSectorSize; // this assumes read and write block size
 
 
 
==== Appendix 1: source code example ====
<syntaxhighlight lang="C">
4,650
edits

Navigation menu