diff --git a/src/trace/dma-trace.c b/src/trace/dma-trace.c index 779480e49468..a2eb33c7375c 100644 --- a/src/trace/dma-trace.c +++ b/src/trace/dma-trace.c @@ -475,26 +475,42 @@ void dma_trace_flush(void *t) void dma_trace_on(void) { struct dma_trace_data *trace_data = dma_trace_data_get(); + uint32_t flags; - if (!trace_data || trace_data->enabled) + if (!trace_data) return; - trace_data->enabled = 1; + spin_lock_irq(&trace_data->lock, flags); + + if (trace_data->enabled) + goto finish; + schedule_task(&trace_data->dmat_work, DMA_TRACE_PERIOD, DMA_TRACE_PERIOD); + trace_data->enabled = 1; +finish: + spin_unlock_irq(&trace_data->lock, flags); } void dma_trace_off(void) { struct dma_trace_data *trace_data = dma_trace_data_get(); + uint32_t flags; - if (!trace_data || !trace_data->enabled) + if (!trace_data) return; + spin_lock_irq(&trace_data->lock, flags); + + if (!trace_data->enabled) + goto finish; + schedule_task_cancel(&trace_data->dmat_work); trace_data->enabled = 0; +finish: + spin_unlock_irq(&trace_data->lock, flags); } static int dtrace_calc_buf_overflow(struct dma_trace_buf *buffer, diff --git a/src/trace/trace.c b/src/trace/trace.c index fb21dc5ce229..626ab1fadb2e 100644 --- a/src/trace/trace.c +++ b/src/trace/trace.c @@ -486,11 +486,15 @@ void trace_on(void) struct trace *trace = trace_get(); uint32_t flags; - spin_lock_irq(&trace->lock, flags); - - trace->enable = 1; + /* + * To avoid dead lock, we should not do this with trace->lock held, + * as there is log tracing inside the dma_trace_on(), which will ask + * for holding trace->lock also. + */ dma_trace_on(); + spin_lock_irq(&trace->lock, flags); + trace->enable = 1; spin_unlock_irq(&trace->lock, flags); } @@ -499,11 +503,15 @@ void trace_off(void) struct trace *trace = trace_get(); uint32_t flags; - spin_lock_irq(&trace->lock, flags); - - trace->enable = 0; + /* + * To avoid dead lock, we should not do this with trace->lock held, + * as there is log tracing inside the dma_trace_off(), which will ask + * for holding trace->lock also. + */ dma_trace_off(); + spin_lock_irq(&trace->lock, flags); + trace->enable = 0; spin_unlock_irq(&trace->lock, flags); }