Skip to content

Commit 2993190

Browse files
author
Jyri Sarha
committed
logging: probe: Add buffer to collect logs before probes DMA is up
Allocate a 4kb buffer to collect the logs arriving before probes DMA is up. Send the contents of the buffer when the callback indicating that DMA is running is set and free the buffer. Busy wait the DMA progress in case the buffer does not fit into the DMA buffer at once. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
1 parent 803e3f4 commit 2993190

File tree

1 file changed

+75
-2
lines changed

1 file changed

+75
-2
lines changed

src/logging/log_backend_probe.c

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
#include <sof/lib/notifier.h>
1515
#include <sof/probe/probe.h>
1616

17+
#ifdef PROBE_LOG_DEBUG
18+
#include <stdio.h>
19+
#endif
20+
1721
/*
1822
* A lock is needed as log_process() and log_panic() have no internal locks
1923
* to prevent concurrency. Meaning if log_process is called after
@@ -33,10 +37,79 @@ static uint8_t log_buf[LOG_BUF_SIZE];
3337

3438
static probe_logging_hook_t probe_hook;
3539

40+
static void log_push(uint8_t *data, size_t length)
41+
{
42+
int pos = 0;
43+
44+
do {
45+
int ret = probe_hook(data + pos, length - pos);
46+
47+
if (ret < 0)
48+
break;
49+
pos += ret;
50+
} while (pos < length);
51+
}
52+
53+
#define PRE_BUFFER_SIZE 4096
54+
static struct probe_pre_buffer {
55+
uint8_t *buf;
56+
uint32_t wpos;
57+
uint32_t len;
58+
} prebuf;
59+
60+
static void pre_buffer_drain(void)
61+
{
62+
#ifdef PROBE_LOG_DEBUG
63+
uint64_t stamp = sof_cycle_get_64();
64+
char msg[80];
65+
int mlen;
66+
67+
mlen = snprintf(msg, sizeof(msg), "[Drain %u bytes of pre buffered logs]\n", prebuf.wpos);
68+
if (prebuf.len > prebuf.wpos)
69+
mlen += snprintf(&msg[mlen], sizeof(msg) - mlen, "[%u bytes dropped]\n",
70+
prebuf.len - prebuf.wpos);
71+
log_push(msg, mlen);
72+
#endif
73+
74+
log_push(prebuf.buf, prebuf.wpos);
75+
rfree(prebuf.buf);
76+
prebuf.buf = NULL;
77+
prebuf.len = 0;
78+
prebuf.wpos = 0;
79+
80+
#ifdef PROBE_LOG_DEBUG
81+
mlen = snprintf(msg, sizeof(msg), "[Buffer drained in %llu us]\n",
82+
k_cyc_to_us_near64(sof_cycle_get_64() - stamp));
83+
84+
log_push(msg, mlen);
85+
#endif
86+
}
87+
88+
static void pre_buffer(uint8_t *data, size_t length)
89+
{
90+
int ret;
91+
92+
prebuf.len += length;
93+
if (!prebuf.buf) {
94+
prebuf.buf = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, PRE_BUFFER_SIZE);
95+
if (!prebuf.buf)
96+
return;
97+
}
98+
ret = memcpy_s(&prebuf.buf[prebuf.wpos], PRE_BUFFER_SIZE - prebuf.wpos, data, length);
99+
if (!ret)
100+
prebuf.wpos += length;
101+
}
102+
36103
static int probe_char_out(uint8_t *data, size_t length, void *ctx)
37104
{
38-
if (probe_hook)
39-
probe_hook(data, length);
105+
if (!probe_hook) {
106+
pre_buffer(data, length);
107+
} else {
108+
if (prebuf.wpos)
109+
pre_buffer_drain();
110+
111+
log_push(data, length);
112+
}
40113

41114
return length;
42115
}

0 commit comments

Comments
 (0)