Skip to content

Commit 61e689c

Browse files
authored
Merge pull request #498 from bkokoszx/dma-buffer-overflow
dma-trace: handling dma trace buffer overflow
2 parents 64d9594 + ea52fb0 commit 61e689c

2 files changed

Lines changed: 80 additions & 20 deletions

File tree

src/include/sof/dma-trace.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,9 @@ void dma_trace_flush(void *t);
7979
void dtrace_event(const char *e, uint32_t size);
8080
void dtrace_event_atomic(const char *e, uint32_t length);
8181

82+
static inline uint32_t dtrace_calc_buf_margin(struct dma_trace_buf *buffer)
83+
{
84+
return buffer->end_addr - buffer->w_ptr;
85+
}
86+
8287
#endif

src/lib/dma-trace.c

Lines changed: 75 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343

4444
static struct dma_trace_data *trace_data = NULL;
4545

46+
/* amount of dropped entries */
47+
static uint32_t dropped_entries;
48+
4649
static int dma_trace_get_avail_data(struct dma_trace_data *d,
4750
struct dma_trace_buf *buffer,
4851
int avail);
@@ -365,34 +368,86 @@ void dma_trace_flush(void *t)
365368
dcache_writeback_invalidate_region((void *)t, size);
366369
}
367370

368-
static void dtrace_add_event(const char *e, uint32_t length)
371+
static int dtrace_calc_buf_overflow(struct dma_trace_buf *buffer,
372+
uint32_t length)
369373
{
370-
struct dma_trace_buf *buffer = &trace_data->dmatb;
371-
int margin;
374+
uint32_t margin;
375+
uint32_t overflow_margin;
376+
uint32_t overflow = 0;
372377

373378
margin = buffer->end_addr - buffer->w_ptr;
374379

375-
/* check for buffer wrap */
376-
if (margin > length) {
377-
/* no wrap */
378-
memcpy(buffer->w_ptr, e, length);
379-
dcache_writeback_invalidate_region(buffer->w_ptr, length);
380-
buffer->w_ptr += length;
381-
} else {
380+
/* overflow calculating */
381+
if (buffer->w_ptr < buffer->r_ptr)
382+
overflow_margin = buffer->r_ptr - buffer->w_ptr;
383+
else
384+
overflow_margin = margin + buffer->r_ptr - buffer->addr;
385+
386+
if (overflow_margin < length)
387+
overflow = length - overflow_margin;
382388

383-
/* data is bigger than remaining margin so we wrap */
384-
memcpy(buffer->w_ptr, e, margin);
385-
dcache_writeback_invalidate_region(buffer->w_ptr, margin);
386-
buffer->w_ptr = buffer->addr;
389+
return overflow;
390+
}
387391

388-
memcpy(buffer->w_ptr, e + margin, length - margin);
389-
dcache_writeback_invalidate_region(buffer->w_ptr,
390-
length - margin);
391-
buffer->w_ptr += length - margin;
392+
static void dtrace_add_event(const char *e, uint32_t length)
393+
{
394+
struct dma_trace_buf *buffer = &trace_data->dmatb;
395+
uint32_t margin;
396+
uint32_t overflow = 0;
397+
398+
margin = dtrace_calc_buf_margin(buffer);
399+
overflow = dtrace_calc_buf_overflow(buffer, length);
400+
401+
/* tracing dropped entries */
402+
if (dropped_entries) {
403+
if (!overflow) {
404+
/*
405+
* if any dropped entries have appeared and there
406+
* is not any overflow, their amount will be logged
407+
*/
408+
uint32_t tmp_dropped_entries = dropped_entries;
409+
410+
dropped_entries = 0;
411+
/*
412+
* this trace_error invocation causes recursion,
413+
* so after it we have to recalculate margin and
414+
* overflow
415+
*/
416+
trace_error(0, "Number of dropped logs: %u",
417+
tmp_dropped_entries);
418+
margin = dtrace_calc_buf_margin(buffer);
419+
overflow = dtrace_calc_buf_overflow(buffer, length);
420+
}
392421
}
393422

394-
buffer->avail += length;
395-
trace_data->messages++;
423+
/* checking overflow */
424+
if (!overflow) {
425+
/* check for buffer wrap */
426+
if (margin > length) {
427+
/* no wrap */
428+
memcpy(buffer->w_ptr, e, length);
429+
dcache_writeback_invalidate_region(buffer->w_ptr,
430+
length);
431+
buffer->w_ptr += length;
432+
} else {
433+
/* data is bigger than remaining margin so we wrap */
434+
memcpy(buffer->w_ptr, e, margin);
435+
dcache_writeback_invalidate_region(buffer->w_ptr,
436+
margin);
437+
buffer->w_ptr = buffer->addr;
438+
439+
memcpy(buffer->w_ptr, e + margin, length - margin);
440+
dcache_writeback_invalidate_region(buffer->w_ptr,
441+
length - margin);
442+
buffer->w_ptr += length - margin;
443+
}
444+
445+
buffer->avail += length;
446+
trace_data->messages++;
447+
} else {
448+
/* if there is not enough memory for new log, we drop it */
449+
dropped_entries++;
450+
}
396451
}
397452

398453
void dtrace_event(const char *e, uint32_t length)

0 commit comments

Comments
 (0)