linux-mips
[Top] [All Lists]

[PATCH] MIPS: Alchemy: fix dbdma ring destruction memory debugcheck.

To: Linux-MIPS <linux-mips@linux-mips.org>
Subject: [PATCH] MIPS: Alchemy: fix dbdma ring destruction memory debugcheck.
From: Manuel Lauss <manuel.lauss@googlemail.com>
Date: Tue, 26 Jan 2010 18:34:02 +0100
Cc: Manuel Lauss <manuel.lauss@gmail.com>
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer; bh=f8icMVMKDNqROxiMU/6+EnQWlN2+g+Y6ZsxlMrn3zL4=; b=I8Q3MhvAMNKocY5RXXBcZOOuSydCoNnrsOtG+LhznEVM6zlyiRNMY1YtyE75glfu2r bjIKRL42dLmPmLg+EuwKnL1gcebhrGZCzXbYaioQ4g/tZ5bOTsRdYOigAzOhKB50gz2N OvFOaMiDm91UppFaiqs+MTkbLCS4z5q+aAtRE=
Domainkey-signature: a=rsa-sha1; c=nofws; d=googlemail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=k39Uym9oAbLAFyZMB+rVaCVdLvRVRrFgSY6mYsNiUAuSMVu1u6KzScmekzArkHTYVT K5LcW4rexR+kVtpXgsohCmZT9HFbugDsGQ0jlxZs5wpsXu5rAuNcOUoxWsbkXqiQUUGm LEiL0DNGQX/b23l6FwsO0gmHOXmDC+XCSziE0=
Sender: linux-mips-bounce@linux-mips.org
DBDMA descriptors need to be located at 32-byte aligned addresses;
however kmalloc rarely delivers such addresses.  The dbdma code
works around that by allocating 63 bytes and re-aligning the
descriptor base afterwards.  Hoewever when freeing memory it does
not account for this adjustment and trips the kfree debugcheck:

Kernel bug detected[#1]:
[...]
Call Trace:
[<80186010>] cache_free_debugcheck+0x284/0x318
[<801869d8>] kfree+0xe8/0x2a0
[<8010b31c>] au1xxx_dbdma_chan_free+0x2c/0x7c
[<80388dc8>] au1x_pcm_dbdma_free+0x34/0x4c
[<80388fa8>] au1xpsc_pcm_close+0x28/0x38
[<80383cb8>] soc_codec_close+0x14c/0x1cc
[<8036dbb4>] snd_pcm_release_substream+0x60/0xac
[<8036dc40>] snd_pcm_release+0x40/0xa0
[<8018c7a8>] __fput+0x11c/0x228
[<80188f60>] filp_close+0x7c/0x98
[<80189018>] sys_close+0x9c/0xe4
[<801022a0>] stack_done+0x20/0x3c

Fix this by recording the address delivered by kmalloc() and using
it as parameter to kfree().

Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
---
 arch/mips/alchemy/common/dbdma.c                 |    7 +++++--
 arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h |    1 +
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c
index 40071bd..3b2ccc0 100644
--- a/arch/mips/alchemy/common/dbdma.c
+++ b/arch/mips/alchemy/common/dbdma.c
@@ -411,8 +411,11 @@ u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
                if (desc_base == 0)
                        return 0;
 
+               ctp->cdb_membase = desc_base;
                desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
-       }
+       } else
+               ctp->cdb_membase = desc_base;
+
        dp = (au1x_ddma_desc_t *)desc_base;
 
        /* Keep track of the base descriptor. */
@@ -829,7 +832,7 @@ void au1xxx_dbdma_chan_free(u32 chanid)
 
        au1xxx_dbdma_stop(chanid);
 
-       kfree((void *)ctp->chan_desc_base);
+       kfree((void *)ctp->cdb_membase);
 
        stp->dev_flags &= ~DEV_FLAGS_INUSE;
        dtp->dev_flags &= ~DEV_FLAGS_INUSE;
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h 
b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
index c098b45..8c6b110 100644
--- a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
+++ b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
@@ -305,6 +305,7 @@ typedef struct dbdma_chan_config {
        dbdev_tab_t             *chan_dest;
        au1x_dma_chan_t         *chan_ptr;
        au1x_ddma_desc_t        *chan_desc_base;
+       u32                     cdb_membase; /* kmalloc base of above */
        au1x_ddma_desc_t        *get_ptr, *put_ptr, *cur_ptr;
        void                    *chan_callparam;
        void                    (*chan_callback)(int, void *);
-- 
1.6.6


<Prev in Thread] Current Thread [Next in Thread>