Skip to content

Commit ea52fb0

Browse files
committed
dma-trace: handling dma trace buffer overflow
In dtrace_add_event function I've added handling dma trace buffer overflow. If there is not enough memory, log will be dropped. Amount of dropped entries is counted and it will be logged. Signed-off-by: Bartosz Kokoszko <bartoszx.kokoszko@linux.intel.com>
1 parent b793f0c commit ea52fb0

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)