From de7119fbdf99e8bd1b0225399fe791a81b019c5d Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Tue, 31 Aug 2021 13:52:46 +0800 Subject: [PATCH 1/2] dma-trace: hold the lock during switching on/off the trace Hold the dma-trace lock when performing on/off switching, to make sure the status is consistent. Signed-off-by: Keyon Jie --- src/trace/dma-trace.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/trace/dma-trace.c b/src/trace/dma-trace.c index 779480e49468..5107eda0d76f 100644 --- a/src/trace/dma-trace.c +++ b/src/trace/dma-trace.c @@ -475,26 +475,34 @@ 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) return; - trace_data->enabled = 1; + spin_lock_irq(&trace_data->lock, flags); + schedule_task(&trace_data->dmat_work, DMA_TRACE_PERIOD, DMA_TRACE_PERIOD); + trace_data->enabled = 1; + 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) return; + spin_lock_irq(&trace_data->lock, flags); + schedule_task_cancel(&trace_data->dmat_work); trace_data->enabled = 0; + spin_unlock_irq(&trace_data->lock, flags); } static int dtrace_calc_buf_overflow(struct dma_trace_buf *buffer, From 47679c49e44f49a27ec425ce479dd793f20843e5 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Tue, 31 Aug 2021 14:19:43 +0800 Subject: [PATCH 2/2] trace: don't hold trace->lock during dma_trace_on/off As there is trace calling in the dma_trace_on/off() internal, we should not do that with trace->lock held, to avoid deadlock. Signed-off-by: Keyon Jie --- src/trace/trace.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/trace/trace.c b/src/trace/trace.c index fb21dc5ce229..32f968c9f6e4 100644 --- a/src/trace/trace.c +++ b/src/trace/trace.c @@ -486,11 +486,11 @@ void trace_on(void) struct trace *trace = trace_get(); uint32_t flags; - spin_lock_irq(&trace->lock, flags); - - trace->enable = 1; + /* should not do this with trace->lock held as there is trace calling internal */ dma_trace_on(); + spin_lock_irq(&trace->lock, flags); + trace->enable = 1; spin_unlock_irq(&trace->lock, flags); } @@ -499,11 +499,11 @@ void trace_off(void) struct trace *trace = trace_get(); uint32_t flags; - spin_lock_irq(&trace->lock, flags); - - trace->enable = 0; + /* should not do this with trace->lock held as there is trace calling internal */ dma_trace_off(); + spin_lock_irq(&trace->lock, flags); + trace->enable = 0; spin_unlock_irq(&trace->lock, flags); }