Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions src/trace/dma-trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Collaborator

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_progress is 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?


if (trace_data->enabled)
goto finish;

schedule_task(&trace_data->dmat_work, DMA_TRACE_PERIOD,
DMA_TRACE_PERIOD);
trace_data->enabled = 1;
Copy link
Member

Choose a reason for hiding this comment

The 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.
Is this intentional?


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,
Expand Down
20 changes: 14 additions & 6 deletions src/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Member

Choose a reason for hiding this comment

The 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);
}

Expand All @@ -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);
}

Expand Down