kernel BUG while reading from SPI into static buffer
Hi, I am trying to read some data via SPI on an a modified (custom SPI device attached) AT91SAM9G20-EK board. If I pass a local array buffer, declared as "char buffer[100];" as the rx_buf pointer for the spi transfer, the code works fine. But if I just change the declaration to "static char buffer[100]" instead, I get the following crash: kernel BUG at arch/arm/mm/dma-mapping.c:425! Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = c0004000 [00000000] *pgd=00000000 Internal error: Oops: 817 [#1] last sysfs file: Modules linked in: testmod [last unloaded: testmod] CPU: 0 Not tainted (2.6.37.2 #8) PC is at __bug+0x1c/0x28 LR is at __bug+0x18/0x28 pc : [<c0031d88>] lr : [<c0031d84>] psr: 20000093 sp : c3a6fea8 ip : 00001e7b fp : 00000000 r10: ffffffff r9 : 00000000 r8 : c38ca6a0 r7 : c395e4e8 r6 : c3a6ff28 r5 : 00000032 r4 : c3a6ff54 r3 : 00000000 r2 : 00000001 r1 : 60000093 r0 : 00000033 Flags: nzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 0005317f Table: 23a3c000 DAC: 00000017 Process tx_thread (pid: 460, stack limit = 0xc3a6e270) Stack: (0xc3a6fea8 to 0xc3a70000) fea0: c3a6ff24 c0034344 c0274848 c3a6ff54 bf00c7f8 c0189dd4 fec0: c395e4e8 60000013 c3a6ff28 c395e400 c395e400 00000000 00000000 c0188bf0 fee0: c3a6ff2c 60000013 c3a6ff28 c395e400 c38ca6a0 c0188c54 c3a6ff04 c0188e38 ff00: 00000000 00000000 c3a6ff08 c3a6ff08 c3a6ff94 c3a6ff70 c3a6ff28 bf00c7f8 ff20: 00000032 bf00a0d4 c3a6ff94 c3a6ff70 c38ca6a0 00000000 c0188fdc c3a6ff04 ff40: 00000000 ffffff8d 00000000 00000000 00000000 00000000 bf00c7f8 00000032 ff60: ffffffff ffffffff 00000000 00000000 c3a6ff28 c3a6ff94 c3a6ff9f c3a6ff9f ff80: 00000001 23a6ff9f 23a6ff9f 00000000 00000000 c3a6ff70 c3a6ff28 20a6ff50 ffa0: c3a6ffd4 c39bfdc4 c38ca6a0 bf00a0e0 00000000 bf00a168 720a0000 01a6cafe ffc0: c3a6ffd4 c00556e0 c002f884 00000000 c38ca6a0 00000000 c3a6ffd8 c3a6ffd8 ffe0: 00000000 c39bfdc4 c0055660 c002f884 00000013 c002f884 0001151c 000000d0 [<c0031d88>] (__bug+0x1c/0x28) from [<c0034344>] (___dma_single_cpu_to_dev+0x3c/0x68) [<c0034344>] (___dma_single_cpu_to_dev+0x3c/0x68) from [<c0189dd4>] (atmel_spi_transfer+0xf8/0x1cc) [<c0189dd4>] (atmel_spi_transfer+0xf8/0x1cc) from [<c0188bf0>] (__spi_async+0xa0/0xb0) [<c0188bf0>] (__spi_async+0xa0/0xb0) from [<c0188c54>] (spi_async_locked+0x14/0x2c) [<c0188c54>] (spi_async_locked+0x14/0x2c) from [<c0188e38>] (__spi_sync+0x60/0xa0) [<c0188e38>] (__spi_sync+0x60/0xa0) from [<bf00a0d4>] (read_bytes+0xac/0xb8 [testmod]) [<bf00a0d4>] (read_bytes+0xac/0xb8 [testmod]) from [<bf00a168>] (tx_thread+0x88/0x110 [testmod]) [<bf00a168>] (tx_thread+0x88/0x110 [testmod]) from [<c00556e0>] (kthread+0x80/0x88) [<c00556e0>] (kthread+0x80/0x88) from [<c002f884>] (kernel_thread_exit+0x0/0x8) Code: e1a01000 e59f000c eb090854 e3a03000 (e5833000) ---[ end trace 0dac538caa941b38 ]--- Does this behaviour make sense to anyone? Is this a bug or is it just me doing the wrong thing? Regards, Felix.
Hi.... On Fri, May 13, 2011 at 14:03, Felix Varghese <felixv1986@gmail.com> wrote:
Hi,
I am trying to read some data via SPI on an a modified (custom SPI device attached) AT91SAM9G20-EK board. If I pass a local array buffer, declared as "char buffer[100];" as the rx_buf pointer for the spi transfer, the code works fine. But if I just change the declaration to "static char buffer[100]" instead, I get the following crash:
kernel BUG at arch/arm/mm/dma-mapping.c:425! Unable to handle kernel NULL pointer dereference at virtual address 00000000
Hmm, I think this is the corresponding line: BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1) ); alright...so it roughly says that the address (buffer) falls into invalid virt address. And, virt_addr_valid is: static inline int virt_addr_valid(const volatile void *kaddr) { extern void *high_memory; /* copied from <linux/mm.h> */ return ((unsigned long)kaddr >= PAGE_OFFSET && kaddr < high_memory); } OK, a bit clear now.... so, I can say base on the above code snippet, buffer...when declared as static, somehow falls into non ZONE_NORMAL......i.e non directly mapped memory area... Feel free to try to observer whether this statement is correct or not... and you should check the address of "buffer" when declared as static I guess.... -- regards, Mulyadi Santosa Freelance Linux trainer and consultant blog: the-hydra.blogspot.com training: mulyaditraining.blogspot.com
Need to add... On Fri, May 13, 2011 at 21:32, Mulyadi Santosa <mulyadi.santosa@gmail.com> wrote:
OK, a bit clear now.... so, I can say base on the above code snippet, buffer...when declared as static, somehow falls into non ZONE_NORMAL......i.e non directly mapped memory area...
what I precisely mean, it falls into non DMA able zone... -- regards, Mulyadi Santosa Freelance Linux trainer and consultant blog: the-hydra.blogspot.com training: mulyaditraining.blogspot.com
On Fri, May 13, 2011 at 12:33:15PM +0530, Felix Varghese wrote:
Hi,
I am trying to read some data via SPI on an a modified (custom SPI device attached) AT91SAM9G20-EK board. If I pass a local array buffer, declared as "char buffer[100];" as the rx_buf pointer for the spi transfer, the code works fine. But if I just change the declaration to "static char buffer[100]" instead, I get the following crash:
Don't statically allocate memory for spi, you need to dynamically allocate it with 'kmalloc'. The fact that the first time didn't crash for you was just lucky. hope this helps, greg k-h
On 13 May 2011 20:02, Mulyadi Santosa <mulyadi.santosa@gmail.com> wrote:
Feel free to try to observer whether this statement is correct or not... and you should check the address of "buffer" when declared as static I guess....
I did, and here's the result: Local Buffer - 0xc3a61edd Static Buffer - 0xbf03eac1 So they indeed seem to be way apart in memory :). On 13 May 2011 20:38, Greg KH <greg@kroah.com> wrote:
Don't statically allocate memory for spi, you need to dynamically allocate it with 'kmalloc'.
The fact that the first time didn't crash for you was just lucky.
I'm guessing you say this because static variables are not in DMA capable memory. But how exactly do we figure out which part of memory is DMA-capable and which isn't? Also, is this a restriction imposed by the kernel or by the hardware? Thanks & Regards, Felix.
On Mon, May 16, 2011 at 11:25:32AM +0530, Felix Varghese wrote:
On 13 May 2011 20:38, Greg KH <greg@kroah.com> wrote:
Don't statically allocate memory for spi, you need to dynamically allocate it with 'kmalloc'.
The fact that the first time didn't crash for you was just lucky.
I'm guessing you say this because static variables are not in DMA capable memory. But how exactly do we figure out which part of memory is DMA-capable and which isn't?
If you create the memory with a call to kmalloc() it is dma-capable. So always do that.
Also, is this a restriction imposed by the kernel or by the hardware?
The hardware. USB also has this rule. thanks, greg k-h
participants (3)
-
Felix Varghese -
Greg KH -
Mulyadi Santosa