[Linux-Xtensa] Re: Audio Driver - applied your git patch, I'm looking into buildingyour config on an LX200...

Piet Delaney pdelaney at tensilica.com
Fri Sep 17 00:24:42 PDT 2010


Piet Delaney wrote:
> benn.huang wrote:
>> Hi Piet:
>>
>> I've just push some code modified by truby to the branch
>> 'Piets_Hack_of_Turbys_Audio_Interface_to_do_something_on_DC233' of the
>> repo 'kernel/xtensa-2.6.29-smp-chipsbank.git'. It's just to fix a
>> stack memory access violation issue when using the 'mailDataT' struct.
>> Very thanks for your help, Piet :)
> 
> Hi Benn, Truby, et. al:
> 
> Glad to help out. Your driver is getting further here on the DC233L.
> I'm Still getting the sleeping in atomic BUG():
> 
> I should likely fix the apparent bug of not showing a backtrace. I think
> folks at Emlix fixed that at kernel.org and I should assimilate it.
> 
> 1st run I didn't what what's going in with you code in the kernel.
> The application just ran and didn't do anything:
> --------------------------------------------------------------------------------
> # ./dsp_test
> open dsp dev
> init oss device:3 ok
> 
> open audio dsp dev
> 
> request chanw0x0
> 
> 
> Init chan
> BUG: sleeping function called from invalid context at mm/slab.c:3061
> in_atomic(): 0, irqs_disabled(): 3, pid: 80, name: dsp_test
> 
> Stack: 90220d3e d39f37f0 00000001 d02f1430 d399dc50 d3a0ec70 00000001 d02f1430
>         d39f0000 00000002 d38ac680 00000000 d38ac680 00000009 d03be020 d39f37b0
>         90044122 d39f3850 d344c6b4 00060300 00000000 d02f1030 00000000 00000000
> Call Trace:
> ----------------------------------------------------------------------------------

Here's were dump_stack() is failing with your BUG in __might_sleep():
------------------------------------------------------------------------------------------------
(gdb) where
#0  dump_stack () at arch/xtensa/kernel/traps.c:588
#1  0xd000ee56 in __might_sleep (file=0xd022a5fc "mm/slab.c", line=3061) at kernel/sched.c:8536
#2  0xd0074c39 in cache_alloc_debugcheck_before (cachep=0xd3800080, flags=32976) at mm/slab.c:3061
#3  0xd0074de9 in __kmalloc (size=40, flags=32976) at mm/slab.c:3415
#4  0xd017b751 in kmalloc (size=40, flags=32976) at include/linux/slab_def.h:55
#5  0xd017b83a in kzalloc (size=40, flags=208) at include/linux/slab.h:306
#6  0xd017b97d in SendPlayChanMail (chan=0xd389aee8) at drivers/media/audio/audio_dsp.c:248
#7  0xd017bca0 in audio_dsp_decode (chan_id=0, inp_stream=0xd3a30000 "ÿûÀD", inp_len=61440, outp_stream=0x0, outp_len=0xd39f7e24) at drivers/media/audio/audio_dsp.c:504
#8  0xd017ad04 in cbm60xx_dsp_write (file=0xd38536f0, buf=0x401b90 "ÿûÀD", count=61440, ppos=0xd39f7ed0) at drivers/media/audio/cbm60xx_dsp.c:708
#9  0xd007a038 in vfs_write (file=0xd38536f0, buf=0x401b90 "ÿûÀD", count=61440, pos=0xd39f7ed0) at fs/read_write.c:347
#10 0xd007a1b4 in sys_write (fd=4, buf=0x401b90 "ÿûÀD", count=61440) at fs/read_write.c:399
#11 0xd0002c5c in system_call () at arch/xtensa/kernel/entry.S:2103
#12 0xd000239d in _user_exception () at arch/xtensa/kernel/entry.S:321
#13 0xc0000001 in ?? ()
(gdb)
----------------------------------------------------------------------------------------------------

Looks to me your disabling pre-emption in cbm60xx_dsp_write() with the local_irq_save(flags)
and then ksalloc() is called with GFP_KERNEL. You have to allocate before disabling
pre-emption or use a GFP_ without the WAIT bit set, like GFP_ATOMIC which is discouraged
as it causes the kernel to use it's reserved pages.

				include/linux/gfp.h
-------------------------------------------------------------------------------
/* GFP_ATOMIC means both !wait (__GFP_WAIT not set) and use emergency pool */
#define GFP_ATOMIC      (__GFP_HIGH)
#define GFP_NOIO        (__GFP_WAIT)
#define GFP_NOFS        (__GFP_WAIT | __GFP_IO)
#define GFP_KERNEL      (__GFP_WAIT | __GFP_IO | __GFP_FS)
#define GFP_TEMPORARY   (__GFP_WAIT | __GFP_IO | __GFP_FS | \
                          __GFP_RECLAIMABLE)
#define GFP_USER        (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL)
#define GFP_HIGHUSER    (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL | \
                          __GFP_HIGHMEM)
#define GFP_HIGHUSER_MOVABLE    (__GFP_WAIT | __GFP_IO | __GFP_FS | \
                                  __GFP_HARDWALL | __GFP_HIGHMEM | \
                                  __GFP_MOVABLE)
#define GFP_IOFS        (__GFP_IO | __GFP_FS)
-----------------------------------------------------------------------------------

-piet



> 
> So I tried to kill it with <control-C> and hit a panic, not good:
> -------------------------------------------------------------------------------------------------------------------------------------
> (gdb) bt
> #0  panic (fmt=0xd02236c8 "BUG!") at kernel/panic.c:72
> #1  0xd00066b9 in dma_free_coherent (hwdev=0x0, size=1638400, vaddr=0xdac00000, dma_handle=46137344) at arch/xtensa/kernel/pci-dma.c:75
> #2  0xd017c26c in DiscardAudioBuf (s=0xdb9ea000) at drivers/media/audio/buffer.c:123
> #3  0xd017aa6d in cbm60xx_dsp_release (inode=0xd344fa00, filp=0xd39a2ce0) at drivers/media/audio/cbm60xx_dsp.c:416
> #4  0xd007b441 in __fput (file=0xd39a2ce0) at fs/file_table.c:280
> #5  0xd007b2c6 in fput (file=0xd39a2ce0) at fs/file_table.c:226
> #6  0xd00792e2 in filp_close (filp=0xd39a2ce0, id=0xd3816c40) at fs/open.c:1107
> #7  0xd0014ccf in close_files (files=0xd3816c40) at kernel/exit.c:502
> #8  0xd0014ddc in put_files_struct (files=0xd3816c40) at kernel/exit.c:530
> #9  0xd0014e81 in exit_files (tsk=0xd39cd040) at kernel/exit.c:564
> #10 0xd001580c in do_exit (code=2) at kernel/exit.c:1079
> #11 0xd0015ad5 in do_group_exit (exit_code=2) at kernel/exit.c:1179
> #12 0xd0021afc in get_signal_to_deliver (info=0xd39f3e50, return_ka=0xd39f3ed0, regs=0xd39f3f30, cookie=0x0) at kernel/signal.c:1902
> #13 0xd00057e4 in do_signal (regs=0xd39f3f30, oldset=0xd39cd274) at arch/xtensa/kernel/signal.c:524
> #14 0xd00023ad in _user_exception () at arch/xtensa/kernel/entry.S:342
> #15 0xc0000001 in ?? ()
> (gdb)
> -------------------------------------------------------------------------------------------
> 
> The panic is due to the address being > XCHAL_KSEG_SIZE:
> 
>    9 void dma_free_coherent(struct device *hwdev, size_t size,
>    70                          void *vaddr, dma_addr_t dma_handle)
>    71 {
>    72         long addr=(long)vaddr+XCHAL_KSEG_CACHED_VADDR-XCHAL_KSEG_BYPASS_VADDR;
>    73
>    74         if (addr < 0 || addr >= XCHAL_KSEG_SIZE)
>    75                 BUG();
>    76
>    77         free_pages(addr, get_order(size));
>    78 }
> 
> Looks like dma_alloc_coherent() allocated a page in the kernel in
> the 0XD000,0000 to 0xD7FFF,FFFF range and returns it in the range
> 0xd8000000 to 0xDFFFF,FFFF.
> 
> This function does the reverse mapping. So you address coming in
> vaddr at 0xdac00000 looks correct. And the address that it mapped
> to looks right, 0xd2c00000. It looks like the BUG() logic is wrong
> and should be:
> 
> 	long seg_offset = (long)vaddr - XCHAL_KSEG_BYPASS_VADDR;
> 	long addr = CHAL_KSEG_CACHED_VADDR + seg_offset;
> 
> 	if (seg_offset < 0 || seg_offset >= XCHAL_KSEG_SIZE)
> 		BUG()'
> 
> 	free_pages(addr, get_order(size));
> 
> I'll try changing it and see how that works. Sound right to you
> guys?
> 
> Looks like your no longer setting CPENABLE in buffer.c
> and allowing the kernel generic code to set the 0x80
> bit on your task's first access. Looks better to me.
> 
> Are you still seeing the (CPENABLE & 0x80) changing
> once you have been given access to the I/O port by
> the exception handler?
> 
> This current approach with dma_alloc_coherent()
> and dma_free_coherent() isn't likely optimal
> with the new V3 MMU.
> 
> XCHAL_KSEG_SIZE of 0x08000000 (2 GB) is fine but
> tying up TLB entries permanently for them might be
> a bit silly. Might be best to allocate some of the
> physical memory to ZONE DMA and the rest to ZONE_NORMAL
> and only double map the ZONE_DMA region.
> 
> 
> -piet
> 
> 
>> On Thu, 16 Sep 2010 02:29:00 -0700
>> Piet Delaney <pdelaney at tensilica.com> wrote:
>>
>>> benn.huang wrote:
>>>> Hi, Piet:
>>>>
>>>>    the dma_alloc_coherent function has been changed on our platform,
>>>>    you can try the following patch to fix the memory allocation
>>>> issue. (just comment out the if statement of the function)
>>> You guys seem pretty quite. It's 2:30am out here,
>>> seems like a good time to quite for the evening
>>> unless you have a bug fix you want to push shortly.
>>>
>>> -piet
>>>
>>>
>>>
>>
> 
> 



More information about the linux-xtensa mailing list