* [PATCH] MIPS: Alchemy: fix dbdma ring destruction memory debugcheck.
@ 2010-01-26 17:34 Manuel Lauss
2010-01-26 17:44 ` David Daney
0 siblings, 1 reply; 7+ messages in thread
From: Manuel Lauss @ 2010-01-26 17:34 UTC (permalink / raw)
To: Linux-MIPS; +Cc: Manuel Lauss
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
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] MIPS: Alchemy: fix dbdma ring destruction memory debugcheck.
2010-01-26 17:34 [PATCH] MIPS: Alchemy: fix dbdma ring destruction memory debugcheck Manuel Lauss
@ 2010-01-26 17:44 ` David Daney
2010-01-26 17:58 ` Manuel Lauss
0 siblings, 1 reply; 7+ messages in thread
From: David Daney @ 2010-01-26 17:44 UTC (permalink / raw)
To: Manuel Lauss; +Cc: Linux-MIPS, Manuel Lauss
Manuel Lauss wrote:
> 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:
>
Correct me if I am wrong, but don't kmalloc et al. return blocks aligned
boundaries of the size rounded up the the next power of two? So if
you need 32-byte aligned addresses, just use a size value of 32 or
greater. You wouldn't have to add 63 and do masking and remember the
membase value as you do in the patch.
David Daney
> 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 *);
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] MIPS: Alchemy: fix dbdma ring destruction memory debugcheck.
@ 2010-01-26 17:58 ` Manuel Lauss
0 siblings, 0 replies; 7+ messages in thread
From: Manuel Lauss @ 2010-01-26 17:58 UTC (permalink / raw)
To: David Daney; +Cc: Linux-MIPS, Manuel Lauss
On Tue, Jan 26, 2010 at 6:44 PM, David Daney <ddaney@caviumnetworks.com> wrote:
> Manuel Lauss wrote:
>>
>> 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:
>>
>
> Correct me if I am wrong, but don't kmalloc et al. return blocks aligned
> boundaries of the size rounded up the the next power of two? So if you
> need 32-byte aligned addresses, just use a size value of 32 or greater. You
> wouldn't have to add 63 and do masking and remember the membase value as you
> do in the patch.
The description is not completely correct (I suck a writing those):
It allocates a number
of descriptor entries (64 bytes each) specified by the driver in a single block:
desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t),
GFP_KERNEL|GFP_DMA);
if (desc_base == 0)
return 0;
if (desc_base & 0x1f) {
So far the 3 users I have (mmc, spi, audio) always return true on the above
check (2 descriptors for audio for instance).
Manuel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] MIPS: Alchemy: fix dbdma ring destruction memory debugcheck.
@ 2010-01-26 17:58 ` Manuel Lauss
0 siblings, 0 replies; 7+ messages in thread
From: Manuel Lauss @ 2010-01-26 17:58 UTC (permalink / raw)
To: David Daney; +Cc: Linux-MIPS, Manuel Lauss
On Tue, Jan 26, 2010 at 6:44 PM, David Daney <ddaney@caviumnetworks.com> wrote:
> Manuel Lauss wrote:
>>
>> 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:
>>
>
> Correct me if I am wrong, but don't kmalloc et al. return blocks aligned
> boundaries of the size rounded up the the next power of two? So if you
> need 32-byte aligned addresses, just use a size value of 32 or greater. You
> wouldn't have to add 63 and do masking and remember the membase value as you
> do in the patch.
The description is not completely correct (I suck a writing those):
It allocates a number
of descriptor entries (64 bytes each) specified by the driver in a single block:
desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t),
GFP_KERNEL|GFP_DMA);
if (desc_base == 0)
return 0;
if (desc_base & 0x1f) {
So far the 3 users I have (mmc, spi, audio) always return true on the above
check (2 descriptors for audio for instance).
Manuel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] MIPS: Alchemy: fix dbdma ring destruction memory debugcheck.
@ 2010-01-26 18:40 ` Manuel Lauss
0 siblings, 0 replies; 7+ messages in thread
From: Manuel Lauss @ 2010-01-26 18:40 UTC (permalink / raw)
To: David Daney; +Cc: Linux-MIPS, Manuel Lauss
David,
On Tue, Jan 26, 2010 at 6:58 PM, Manuel Lauss
<manuel.lauss@googlemail.com> wrote:
> On Tue, Jan 26, 2010 at 6:44 PM, David Daney <ddaney@caviumnetworks.com> wrote:
>> Manuel Lauss wrote:
>>>
>>> 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:
>>>
>>
>> Correct me if I am wrong, but don't kmalloc et al. return blocks aligned
>> boundaries of the size rounded up the the next power of two? So if you
>> need 32-byte aligned addresses, just use a size value of 32 or greater. You
>> wouldn't have to add 63 and do masking and remember the membase value as you
>> do in the patch.
>
> The description is not completely correct (I suck a writing those):
> It allocates a number
> of descriptor entries (64 bytes each) specified by the driver in a single block:
>
> desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t),
> GFP_KERNEL|GFP_DMA);
> if (desc_base == 0)
> return 0;
>
> if (desc_base & 0x1f) {
>
> So far the 3 users I have (mmc, spi, audio) always return true on the above
> check (2 descriptors for audio for instance).
... but only if CONFIG_DEBUG_SLAB is enabled. You are correct in that
kmalloc() returns aligned blocks with a non-debug slab allocator and this
fix becomes superfluous. I'll try to confirm this with the other
allocators and
resend with a fixed description.
Thank you for the pointer!
Manuel Lauss
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] MIPS: Alchemy: fix dbdma ring destruction memory debugcheck.
@ 2010-01-26 18:40 ` Manuel Lauss
0 siblings, 0 replies; 7+ messages in thread
From: Manuel Lauss @ 2010-01-26 18:40 UTC (permalink / raw)
To: David Daney; +Cc: Linux-MIPS, Manuel Lauss
David,
On Tue, Jan 26, 2010 at 6:58 PM, Manuel Lauss
<manuel.lauss@googlemail.com> wrote:
> On Tue, Jan 26, 2010 at 6:44 PM, David Daney <ddaney@caviumnetworks.com> wrote:
>> Manuel Lauss wrote:
>>>
>>> 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:
>>>
>>
>> Correct me if I am wrong, but don't kmalloc et al. return blocks aligned
>> boundaries of the size rounded up the the next power of two? So if you
>> need 32-byte aligned addresses, just use a size value of 32 or greater. You
>> wouldn't have to add 63 and do masking and remember the membase value as you
>> do in the patch.
>
> The description is not completely correct (I suck a writing those):
> It allocates a number
> of descriptor entries (64 bytes each) specified by the driver in a single block:
>
> desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t),
> GFP_KERNEL|GFP_DMA);
> if (desc_base == 0)
> return 0;
>
> if (desc_base & 0x1f) {
>
> So far the 3 users I have (mmc, spi, audio) always return true on the above
> check (2 descriptors for audio for instance).
... but only if CONFIG_DEBUG_SLAB is enabled. You are correct in that
kmalloc() returns aligned blocks with a non-debug slab allocator and this
fix becomes superfluous. I'll try to confirm this with the other
allocators and
resend with a fixed description.
Thank you for the pointer!
Manuel Lauss
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] MIPS: Alchemy: fix dbdma ring destruction memory debugcheck.
2010-01-26 18:40 ` Manuel Lauss
(?)
@ 2010-01-26 18:45 ` David Daney
-1 siblings, 0 replies; 7+ messages in thread
From: David Daney @ 2010-01-26 18:45 UTC (permalink / raw)
To: Manuel Lauss; +Cc: Linux-MIPS, Manuel Lauss
Manuel Lauss wrote:
> David,
>
> On Tue, Jan 26, 2010 at 6:58 PM, Manuel Lauss
> <manuel.lauss@googlemail.com> wrote:
>> On Tue, Jan 26, 2010 at 6:44 PM, David Daney <ddaney@caviumnetworks.com> wrote:
>>> Manuel Lauss wrote:
>>>> 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:
>>>>
>>> Correct me if I am wrong, but don't kmalloc et al. return blocks aligned
>>> boundaries of the size rounded up the the next power of two? So if you
>>> need 32-byte aligned addresses, just use a size value of 32 or greater. You
>>> wouldn't have to add 63 and do masking and remember the membase value as you
>>> do in the patch.
>> The description is not completely correct (I suck a writing those):
>> It allocates a number
>> of descriptor entries (64 bytes each) specified by the driver in a single block:
>>
>> desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t),
>> GFP_KERNEL|GFP_DMA);
>> if (desc_base == 0)
>> return 0;
>>
>> if (desc_base & 0x1f) {
>>
>> So far the 3 users I have (mmc, spi, audio) always return true on the above
>> check (2 descriptors for audio for instance).
>
> ... but only if CONFIG_DEBUG_SLAB is enabled.
Oh no! I make this assumption in my drivers. If CONFIG_DEBUG_SLAB
causes it to not be true... Bad news.
David Daney
> You are correct in that
> kmalloc() returns aligned blocks with a non-debug slab allocator and this
> fix becomes superfluous. I'll try to confirm this with the other
> allocators and
> resend with a fixed description.
>
> Thank you for the pointer!
> Manuel Lauss
>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2010-01-26 18:46 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-01-26 17:34 [PATCH] MIPS: Alchemy: fix dbdma ring destruction memory debugcheck Manuel Lauss
2010-01-26 17:44 ` David Daney
2010-01-26 17:58 ` Manuel Lauss
2010-01-26 17:58 ` Manuel Lauss
2010-01-26 18:40 ` Manuel Lauss
2010-01-26 18:40 ` Manuel Lauss
2010-01-26 18:45 ` David Daney
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.