Skip to content
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

fixed bug that copy order incorrect at host component. #9426

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
19 changes: 14 additions & 5 deletions src/audio/host-legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ static uint32_t host_get_copy_bytes_one_shot(struct host_data *hd, struct comp_d
*/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check existing git commits in this project for examples on how to write git commit. SOF follows similar practises as Linux kernel and Zephyr. One git commit per logical change, proper summary line, explains what bug you are fixing, etc

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please explain what order is incorrect. AFAICT you're only moving the dma_buffer_copy_to() for the one shot case and this will break normal copy.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ranj063
sorry, I am new to GitHub.

As mentioned in https://github.com/orgs/thesofproject/discussions/9362,

For capture stream scenario, I find a bug that copying order incorrect in Host component.

The copy order should be: Local-buffer => DMA-buffer => Host-buffer.
But actually it is first DMA-buffer => Host-buffer, then Local-buffer => DMA-buffer.

I think host_copy_one_shot() is correct for playback, but incorrect for capture.

So my patch is let host copy change into Local-buffer => DMA-buffer => Host-buffer:
Just move (copy from Local-buffer to DMA-buffer)
from host_common_update() to host_copy_one_shot().

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kv2019i
sorry, I am new to GitHub.

I think we discuss bug and solution first.

Finally, if the patch is fine I will modify the commit log more normally.

static int host_copy_one_shot(struct host_data *hd, struct comp_dev *dev, copy_callback_t cb)
{
struct comp_buffer *source;
struct comp_buffer *sink;
uint32_t copy_bytes = 0;
int ret = 0;

Expand All @@ -212,6 +214,17 @@ static int host_copy_one_shot(struct host_data *hd, struct comp_dev *dev, copy_c
return ret;
}

if (dev->direction == SOF_IPC_STREAM_CAPTURE)
{
source = hd->local_buffer;
sink = hd->dma_buffer;
comp_info(dev, "bf cp local buf addr %p end %p w %p r %p", source->stream.addr, source->stream.end_addr, source->stream.w_ptr, source->stream.r_ptr);
comp_info(dev, "bf cp dma addr %p end %p w %p r %p", sink->stream.addr, sink->stream.end_addr, sink->stream.w_ptr, sink->stream.r_ptr);
ret = dma_buffer_copy_to(source, sink, hd->process, copy_bytes);
comp_info(dev, "af cp local buf addr %p end %p w %p r %p", source->stream.addr, source->stream.end_addr, source->stream.w_ptr, source->stream.r_ptr);
comp_info(dev, "af cp dma addr %p end %p w %p r %p", sink->stream.addr, sink->stream.end_addr, sink->stream.w_ptr, sink->stream.r_ptr);
}

ret = dma_copy_legacy(hd->chan, copy_bytes, DMA_COPY_ONE_SHOT);
if (ret < 0) {
comp_err(dev, "host_copy_one_shot(): dma_copy() failed, ret = %u", ret);
Expand All @@ -226,18 +239,14 @@ void host_common_update(struct host_data *hd, struct comp_dev *dev, uint32_t byt
{
struct comp_buffer *source;
struct comp_buffer *sink;
int ret;
int ret = 0;
bool update_mailbox = false;
bool send_ipc = false;

if (dev->direction == SOF_IPC_STREAM_PLAYBACK) {
source = hd->dma_buffer;
sink = hd->local_buffer;
ret = dma_buffer_copy_from(source, sink, hd->process, bytes, DUMMY_CHMAP);
} else {
source = hd->local_buffer;
sink = hd->dma_buffer;
ret = dma_buffer_copy_to(source, sink, hd->process, bytes, DUMMY_CHMAP);
}
Comment on lines -237 to 250
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chihualee any update, this part looks wrong as capture uses the DMA buffer for sink, unless your device has no DMA to copy data to host driver from DSP (i.e. you have shared memory) ?

Copy link
Author

@chihualee chihualee Oct 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lgirdwood

My capture mechanism is almost the same as original legacy-host,
first data from local buffer to DMA buffer,
then data from DMA buffer to Host buffer.

src/audio/host-legacy.c
Comment on lines -237 to 250

I think this part is doing that capture copying data from local buffer to DMA buffer.
I just move this part to src/audio/host-legacy.c
host_copy_one_shot() around at lines 214
Because it should do first.
image


/* assert dma_buffer_copy succeed */
Expand Down
1 change: 1 addition & 0 deletions src/drivers/generic/dummy-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ static ssize_t dummy_dma_copy_crt_elem(struct dma_chan_pdata *pdata,
*/
dcache_invalidate_region((void *)rptr, copy_size);

tr_info(&ddma_tr, "dummy dma wptr %x rptr %x size 0x%x", wptr, rptr, copy_size);
/* Perform the copy, being careful if we overflow the elem */
ret = memcpy_s((void *)wptr, remaining_size, (void *)rptr, copy_size);
assert(!ret);
Expand Down