[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