From patchwork Mon Feb 4 16:50:27 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthieu CASTET X-Patchwork-Id: 2093981 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 99CEDDFE82 for ; Mon, 4 Feb 2013 16:52:58 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1U2PFa-0000Mr-Tw; Mon, 04 Feb 2013 16:50:34 +0000 Received: from co202.xi-lite.net ([149.6.83.202]) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1U2PFY-0000ME-8I for linux-arm-kernel@lists.infradead.org; Mon, 04 Feb 2013 16:50:33 +0000 Received: from ONYX.xi-lite.lan (unknown [193.34.35.244]) by co202.xi-lite.net (Postfix) with ESMTPS id 9EAD0260333; Mon, 4 Feb 2013 18:05:51 +0100 (CET) Received: from [172.20.223.18] (84.14.91.202) by mail.xi-lite.com (193.34.32.105) with Microsoft SMTP Server (TLS) id 8.1.336.0; Mon, 4 Feb 2013 16:55:42 +0000 Message-ID: <510FE6D3.9020904@parrot.com> Date: Mon, 4 Feb 2013 17:50:27 +0100 From: Matthieu CASTET User-Agent: Thunderbird 2.0.0.24 (X11/20100228) MIME-Version: 1.0 To: ALSA devel , "linux-arm-kernel@lists.infradead.org" Subject: alsa usb-audio sound corruption caused by cached vmalloc mapping X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130204_115032_418892_C5DB7062 X-CRM114-Status: GOOD ( 20.97 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Takashi Iwai , Benjamin Herrenschmidt , Russell King - ARM Linux X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Hi, on a armv5 soc, we have audio corruption while using a usb-audio sound card. After analysis, it comes from alsa vmalloc mapping. in the current kernel vmalloc mapping used by alsa are cached. This cause coherency problem on armv5 architecture because the cache are VIVT : - alsa kernel driver map a buffer with vmalloc. The memory attribute is cached - userspace map vmalloc buffer. The memory attribute is cached But because the cache are VIVT, these two mapping don't share the same cache line and won't see the same data. This corruption can be hidden by context switch because cache are flushed on context switch. On x86 or armv7, the cache are PIPT and there is no such problem. There was a commit "pcm - Call pgprot_noncached() for vmalloc'ed buffers" (c32d977b8157bf67cdf47729ce7dd054a26eb534), that made the userspace mapping not cached, but this caused issues because the kernel vmalloc mapping was still cached. Instead of revering this commit, we could have made the kernel vmalloc noncached (see attached patch). It fix the issue on armv5. But on some architecture (armv7 for example) you can't have mapping for the same physical memory cached (normal cached) and noncached (device memory). So the vmalloc and userspace mapping will conflict with the kernel direct RAM mapping. A workaround could be to use writecombine protection instead of noncached. This work because writecombine is mapped on armv7 as L_PTE_MT_BUFFERABLE (normal uncached) that is compatible with cached memory (the same trick is used for dmacoherent). But that's architecture specific may not work on others architectures. What's the best way the fix this issue on all architecture ? Matthieu commit f3d13b6752e20cdd193d0265cc6b8f1d814dd869 Author: Matthieu CASTET Date: Wed Jan 30 15:27:00 2013 +0100 make snd_pcm_lib_alloc_vmalloc_buffer memory uncached diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index 69e01c4..1740d39 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c @@ -425,7 +425,7 @@ int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream, return 0; /* already large enough */ vfree(runtime->dma_area); } - runtime->dma_area = __vmalloc(size, gfp_flags, PAGE_KERNEL); + runtime->dma_area = __vmalloc(size, gfp_flags, pgprot_noncached(PAGE_KERNEL)); if (!runtime->dma_area) return -ENOMEM; runtime->dma_bytes = size;