[alsa-devel] A bug about cache inconsistency report
Takashi Iwai
tiwai at suse.de
Tue Aug 7 11:25:30 CEST 2018
On Tue, 07 Aug 2018 11:00:39 +0200,
Hans Hu(SH-RD) wrote:
>
> >Then the next step would be to fake sg-buffer from this straight
> >buffer. Revert the above, and modify sgbuf.c to the following:
> >- Allocate a large continuous buffer
> >- Assign each page in this large buffer
>
> >If this still works, it's not about vmap, but it just means that the
> >physically ordered pages do matter -- implicitly showing that the
> >snooping behavior isn't properly turned on / off on the controller.
>
> To fake SG-buffer, I did this test: restore all the codes to the original, then added some codes in snd_malloc_sgbuf_pages() like below, the result is badly niose.
Not really what I meant. Rather something like below (totally
untested).
Takashi
---
diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c
index 84fffabdd129..643f6cb2048c 100644
--- a/sound/core/sgbuf.c
+++ b/sound/core/sgbuf.c
@@ -68,7 +68,7 @@ void *snd_malloc_sgbuf_pages(struct device *device,
size_t *res_size)
{
struct snd_sg_buf *sgbuf;
- unsigned int i, pages, chunk, maxpages;
+ unsigned int i, pages;
struct snd_dma_buffer tmpb;
struct snd_sg_page *table;
struct page **pgtable;
@@ -90,38 +90,18 @@ void *snd_malloc_sgbuf_pages(struct device *device,
goto _failed;
sgbuf->page_table = pgtable;
- /* allocate pages */
- maxpages = MAX_ALLOC_PAGES;
- while (pages > 0) {
- chunk = pages;
- /* don't be too eager to take a huge chunk */
- if (chunk > maxpages)
- chunk = maxpages;
- chunk <<= PAGE_SHIFT;
- if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, device,
- chunk, &tmpb) < 0) {
- if (!sgbuf->pages)
- goto _failed;
- if (!res_size)
- goto _failed;
- size = sgbuf->pages * PAGE_SIZE;
- break;
- }
- chunk = tmpb.bytes >> PAGE_SHIFT;
- for (i = 0; i < chunk; i++) {
- table->buf = tmpb.area;
- table->addr = tmpb.addr;
- if (!i)
- table->addr |= chunk; /* mark head */
- table++;
- *pgtable++ = virt_to_page(tmpb.area);
- tmpb.area += PAGE_SIZE;
- tmpb.addr += PAGE_SIZE;
- }
- sgbuf->pages += chunk;
- pages -= chunk;
- if (chunk < maxpages)
- maxpages = chunk;
+ if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, device, size, &tmpb) < 0)
+ goto _failed;
+
+ for (i = 0; i < pages; i++) {
+ table->buf = tmpb.area;
+ table->addr = tmpb.addr;
+ if (!i)
+ table->addr |= pages; /* mark head */
+ table++;
+ *pgtable++ = virt_to_page(tmpb.area);
+ tmpb.area += PAGE_SIZE;
+ tmpb.addr += PAGE_SIZE;
}
sgbuf->size = size;
More information about the Alsa-devel
mailing list