aboutsummaryrefslogtreecommitdiff
path: root/external/trace/dump_trace.c
diff options
context:
space:
mode:
authorJordan Niethe <jniethe5@gmail.com>2019-04-02 10:43:23 +1100
committerStewart Smith <stewart@linux.ibm.com>2019-05-20 14:21:53 +1000
commit085dbf049050ef6f4e2a0ced06b084dcb1e4ce23 (patch)
treedb17b05416202eff7b896ec379d93202f5755441 /external/trace/dump_trace.c
parent3f61c832bf1f973546b8dcb577fba4ece04cb5dc (diff)
downloadskiboot-085dbf049050ef6f4e2a0ced06b084dcb1e4ce23.zip
skiboot-085dbf049050ef6f4e2a0ced06b084dcb1e4ce23.tar.gz
skiboot-085dbf049050ef6f4e2a0ced06b084dcb1e4ce23.tar.bz2
external/trace: mmap trace buffers in dump_trace
The current lseek/read approach used in dump_trace does not correctly handle certain aspects of the buffers. It does not use the start and end position that is part of the buffer so it will not begin from the correct location. It does not move back to the beginning of the trace buffer file as the buffer wraps around. It also does not handle the overflow case of the writer overwriting when the reader is up to. Mmap the trace buffer file so that the existing reading functions in extra/trace.c can be used. These functions already handle the cases of wrapping and overflow. This reduces code duplication and uses functions that are already unit tested. However this requires a kernel where the trace buffer sysfs nodes are able to be mmaped (see https://patchwork.ozlabs.org/patch/1056786/) Signed-off-by: Jordan Niethe <jniethe5@gmail.com> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
Diffstat (limited to 'external/trace/dump_trace.c')
-rw-r--r--external/trace/dump_trace.c55
1 files changed, 24 insertions, 31 deletions
diff --git a/external/trace/dump_trace.c b/external/trace/dump_trace.c
index 4779dc4..650cd7a 100644
--- a/external/trace/dump_trace.c
+++ b/external/trace/dump_trace.c
@@ -14,42 +14,24 @@
* limitations under the License.
*/
+#include <trace.h>
#include <err.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
#include <unistd.h>
+#include <stdlib.h>
#include "../../ccan/endian/endian.h"
#include "../../ccan/short_types/short_types.h"
-#include <trace_types.h>
+#include "trace.h"
-/* Handles trace from debugfs (one record at a time) or file */
-static bool get_trace(int fd, union trace *t, int *len)
-{
- void *dest = t;
- int r;
-
- /* Move down any extra we read last time. */
- if (*len >= sizeof(t->hdr) && *len >= t->hdr.len_div_8 * 8) {
- u8 rlen = t->hdr.len_div_8 * 8;
- memmove(dest, dest + rlen, *len - rlen);
- *len -= rlen;
- }
-
- r = read(fd, dest + *len, sizeof(*t) - *len);
- if (r < 0)
- return false;
-
- *len += r;
- /* We should have a complete record. */
- return *len >= sizeof(t->hdr) && *len >= t->hdr.len_div_8 * 8;
-}
static void display_header(const struct trace_hdr *h)
{
@@ -152,20 +134,31 @@ static void dump_uart(struct trace_uart *t)
int main(int argc, char *argv[])
{
- int fd, len = 0;
+ struct trace_reader tr;
+ struct trace_info *ti;
+ struct stat sb;
union trace t;
- const char *in = "/sys/kernel/debug/powerpc/opal-trace";
+ int fd;
- if (argc > 2)
- errx(1, "Usage: dump_trace [file]");
+ if (argc != 2)
+ errx(1, "Usage: dump_trace file");
- if (argv[1])
- in = argv[1];
- fd = open(in, O_RDONLY);
+ fd = open(argv[1], O_RDONLY);
if (fd < 0)
- err(1, "Opening %s", in);
+ err(1, "Opening %s", argv[1]);
+
+ if (fstat(fd, &sb) < 0)
+ err(1, "Stating %s", argv[1]);
+
+ ti = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (ti == MAP_FAILED)
+ err(1, "Mmaping %s", argv[1]);
+
+ memset(&tr, 0, sizeof(struct trace_reader));
+ tr.tb = &ti->tb;
+
- while (get_trace(fd, &t, &len)) {
+ while (trace_get(&t, &tr)) {
display_header(&t.hdr);
switch (t.hdr.type) {
case TRACE_REPEAT: