-
Notifications
You must be signed in to change notification settings - Fork 349
fix the deadlock issue when mailbox trace is configured. #4700
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you're setting this flag protected by the spinlock, but you test it on like 480 without any protection. |
||
|
|
||
| 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, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so the trace is enabled after the 'dma trace'. that seems surprising? |
||
| 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); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we have a good understanding of what this lock is protecting, vs. what the other trace lock is protecting? The use of this lock doesn't seem to be fully consistent. E.g.
dtrace_event()this lock is also covering the test of.copy_in_progress, but not in a consistent way, because both locations where.copy_in_progressis set to 1 aren't protected by that lock, so, holding the lock while testing it doesn't help. Why do we have to lock here at all?