[Skiboot] [PATCH 13/15] external/trace: Change dump_trace to use mmap
Jordan Niethe
jniethe5 at gmail.com
Mon Mar 25 11:14:23 AEDT 2019
The current lseek/read approach used in dump_trace makes no attempt to
handle the ring buffer aspect of the trace buffers. 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. This
reduces code duplication. However this requires a kernel where the trace
buffer sysfs nodes are able to be mmaped (see
https://patchwork.ozlabs.org/patch/1056786/)
---
core/test/run-trace.c | 2 +-
core/trace.c | 4 +--
external/trace/Makefile | 2 +-
external/trace/dump_trace.c | 54 +++++++++++++++----------------------
include/trace_types.h | 7 +----
5 files changed, 27 insertions(+), 42 deletions(-)
diff --git a/core/test/run-trace.c b/core/test/run-trace.c
index 19bd2e67dbdd..1f47293e406a 100644
--- a/core/test/run-trace.c
+++ b/core/test/run-trace.c
@@ -182,7 +182,7 @@ static void test_parallel(void)
for (i = 0; i < CPUS; i++) {
fake_cpus[i].trace = p + i * len;
- fake_cpus[i].trace->tb.max_size = cpu_to_be32(sizeof(union trace));
+ fake_cpus[i].trace->tb.max_size = cpu_to_be64(sizeof(union trace));
fake_cpus[i].is_secondary = false;
memset(&trace_readers[i], 0, sizeof(struct trace_reader));
trace_readers[i].tb = &fake_cpus[i].trace->tb;
diff --git a/core/trace.c b/core/trace.c
index dfb5cfad045c..72c8b34b8b81 100644
--- a/core/trace.c
+++ b/core/trace.c
@@ -39,7 +39,7 @@ static struct {
void init_boot_tracebuf(struct cpu_thread *boot_cpu)
{
init_lock(&boot_tracebuf.trace_info.lock);
- boot_tracebuf.trace_info.tb.max_size = cpu_to_be32(MAX_SIZE);
+ boot_tracebuf.trace_info.tb.max_size = cpu_to_be64(MAX_SIZE);
boot_cpu->trace = &boot_tracebuf.trace_info;
}
@@ -227,7 +227,7 @@ void init_trace_buffers(void)
any = t->trace;
memset(t->trace, 0, size);
init_lock(&t->trace->lock);
- t->trace->tb.max_size = cpu_to_be32(MAX_SIZE);
+ t->trace->tb.max_size = cpu_to_be64(MAX_SIZE);
trace_add_desc(any, size, t->pir);
} else
prerror("TRACE: cpu 0x%x allocation failed\n", t->pir);
diff --git a/external/trace/Makefile b/external/trace/Makefile
index 3828fea534ea..bff52f3a6ab2 100644
--- a/external/trace/Makefile
+++ b/external/trace/Makefile
@@ -1,7 +1,7 @@
HOSTEND=$(shell uname -m | sed -e 's/^i.*86$$/LITTLE/' -e 's/^x86.*/LITTLE/' -e 's/^ppc64le/LITTLE/' -e 's/^ppc.*/BIG/')
CFLAGS=-g -Wall -DHAVE_$(HOSTEND)_ENDIAN -I../../include -I../../
-dump_trace: dump_trace.c
+dump_trace: dump_trace.c trace.c
clean:
rm -f dump_trace *.o
diff --git a/external/trace/dump_trace.c b/external/trace/dump_trace.c
index 4779dc42ec6d..f38b38187691 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,28 @@ static void dump_uart(struct trace_uart *t)
int main(int argc, char *argv[])
{
- int fd, len = 0;
+ int fd;
+ struct trace_reader tr;
+ struct trace_info *ti;
union trace t;
- const char *in = "/sys/kernel/debug/powerpc/opal-trace";
- if (argc > 2)
- errx(1, "Usage: dump_trace [file]");
+ if (argc != 2)
+ errx(1, "Usage: dump_trace file");
+
+ fd = open(argv[1], O_RDONLY);
+ if(fd < 0)
+ err(1, "Opening %s", argv[1]);
+
+ ti = mmap(NULL, sizeof(struct trace_info) + TBUF_SZ + MAX_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;
- if (argv[1])
- in = argv[1];
- fd = open(in, O_RDONLY);
- if (fd < 0)
- err(1, "Opening %s", in);
- while (get_trace(fd, &t, &len)) {
+ while (trace_get(&t, &tr)) {
display_header(&t.hdr);
switch (t.hdr.type) {
case TRACE_REPEAT:
diff --git a/include/trace_types.h b/include/trace_types.h
index 9364186aedbe..e9fb8f353e62 100644
--- a/include/trace_types.h
+++ b/include/trace_types.h
@@ -34,13 +34,8 @@ struct tracebuf {
__be64 end;
/* This is where the writer wrote to previously. */
__be64 last;
- /* This is where the reader is up to. */
- __be64 rpos;
- /* If the last one we read was a repeat, this shows how many. */
- __be32 last_repeat;
/* Maximum possible size of a record. */
- __be32 max_size;
-
+ __be64 max_size;
char buf[/* TBUF_SZ + max_size */];
};
--
2.20.1
More information about the Skiboot
mailing list