diff mbox

[v2,1/5] dmaengine: add ep93xx DMA support

Message ID 4EC374F0.8000400@metasoft.pl
State New
Headers show

Commit Message

Rafal Prylowski Nov. 16, 2011, 8:31 a.m. UTC
Hello.

W dniu 2011-11-16 07:55, Mika Westerberg pisze:
> Yes, this is certainly a copy-paste bug or something. Thanks for fixing :)
> 
> Can you send a separate patch for this? Make sure you Cc Vinod Koul as he is
> the maintainer of slave dma subsystem.

Here is a separate patch:


> 
>> 2) Kernel oops when trying to stop running transfers by calling
>> dmaengine_terminate_all(...) - caused by dereferencing empty list
>> in ep93xx_dma_get_active
> 
> Can you post that OOPS log? I would like to understand this problem a bit
> better before we do any fixes for the driver.
> 

OOPS log:

Linux version 3.2.0-rc1EP-1+ (prylowski@server) (gcc version 4.4.2 (GCC) ) #1008
 Wed Nov 16 08:25:45 CET 2011
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: Metasoft FonTel EP Board
Memory policy: ECC disabled, Data cache writeback
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 8128
Kernel command line: mtdparts=physmap-flash.0:128K(uboot),1152K(kernel),15104K(r
ootfs) root=/dev/mtdblock2 rootfstype=jffs2 console=ttyAM0 init=/sbin/init early
printk lpj=496128 panic=2
PID hash table entries: 128 (order: -3, 512 bytes)
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
Memory: 32MB = 32MB total
Memory: 27452k/27452k available, 5316k reserved, 0K highmem
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
    vmalloc : 0xc2800000 - 0xfe800000   ( 960 MB)
    lowmem  : 0xc0000000 - 0xc2000000   (  32 MB)
    modules : 0xbf000000 -0xc0000000   (  16 MB)
      .text : 0xc0008000 - 0xc029d000   (2644 kB)
      .init : 0xc029d000 - 0xc02b6000   ( 100 kB)
      .data : 0xc02b6000 - 0xc02d1440   ( 110 kB)
       .bss : 0xc02d1464 - 0xc02df51c   (  57 kB)
SLUB: Genslabs=13, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
NR_IRQS:120
VIC @fefb0000: id 0x00041190, vendor 0x41
VIC @fefc0000: id 0x00041190, vendor 0x41
Console: colour dummy device 80x30
Calibrating delay loop (skipped) preset value.. 99.22 BogoMIPS (lpj=496128)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
NET: Registered protocol family 16
ep93xx clock: PLL1 running at 400 MHz, PLL2 at 192 MHz
ep93xx clock: FCLK 200 MHz, HCLK 100 MHz, PCLK 50 MHz
bio: create slab <bio-0> at 0
ep93xx-dma ep93xx-dma-m2p: EP93xx M2P DMA ready
ep93xx-dma ep93xx-dma-m2m: EP93xx M2M DMA ready
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
i2c-gpio i2c-gpio.0: using pins 49 (SDA) and 48 (SCL)
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 1024 (order: 1, 8192 bytes)
TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
TCP reno registered
UDP hashable entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
msgmni has been set to 53
io scheduler noop registered
io scheduler deadline registered (default)
Serial: AMBA driver
apb:uart1: ttyAM0 at MMIO 0x808c0000 (irq = 52) is a AMBA
console [ttyAM0] enabled
apb:uart2: ttyAM1 at MMIO 0x808d0000 (irq = 54) is a AMBA
apb:uart3: ttyAM2 at MMIO 0x808e0000 (irq = 55) is a AMBA
fontel-pri fontel-pri: FonTel PRI initialized correctly.
ep93xx-ide ep93xx-ide: version 0.5
scsi0 : ep93xx-ide
ata1: PATA max UDMA/66 irq 40
physmap platform flash device: 01000000 at 60000000
physmap-flash.0: Found 1 x16 devices at 0x0 in 16-bit bank. Manufacturer ID 0x00
0001 Chip ID 0x002101
Amd/Fujitsu Extended Query Table at 0x0040
  Amd/Fujitsu Extended Query version 1.3.
number of CFI chips: 1
3 cmdlinepart partitions found on MTD device physmap-flash.0
Creating 3 MTD partitions on "physmap-flash.0":
0x000000000000-0x000000020000 : "uboot"
0x000000020000-0x000000140000 : "kernel"
0x000000140000-0x000001000000 : "rootfs"
ep93xx-spi ep93xx-spi.0: EP93xx SPI Controller at 0x808a0000 irq 53
ep93xx-eth version 0.1 loading
eth0: ep93xx on-chip ethernet, IRQ 39, 8e:42:5c:13:29:4c
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
ep93xx-ohci ep93xx-ohci: EP93xx OHCI
ep93xx-ohci ep93xx-ohci: new USB bus registered, assigned bus number 1
ep93xx-ohci ep93xx-ohci: irq 56, io mem 0x80020000
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 3 ports detected
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
usbcore: registered new interface driver fontel
rtc-ds1307 0-0068: rtc core: registered ds1307 as rtc0
rtc-ds1307 0-0068: 56 bytes nvram
ep93xx-rtc ep93xx-rtc: rtc core: registered ep93xx-rtc as rtc1
Software Watchdog Timer: 0.07 initialized. soft_noboot=0 soft_margin=60 sec soft
_panic=0 (nowayout= 0)
TCP cubic registered
NET: Registered protocol family 17
NET: Registered protocol family 15
ep93xx-rtc ep93xx-rtc: setting system clock to 1970-01-01 00:00:07 UTC (7)
ata1.00: ATA-8: WDC WD3200BEVE-00A0HT0, 11.01A11, max UDMA/100
ata1.00: 625142448 sectors, multi 0: LBA48
ata1.00: configured for UDMA/66
scsi 0:0:0:0: Direct-Access     ATA      WDC WD3200BEVE-0 11.0 PQ: 0 ANSI: 5
sd 0:0:0:0: [sda] 625142448 512-byte logical blocks: (320 GB/298 GiB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO
 or FUA
Internal error: Oops - undefined instruction: 0 [#1]
CPU: 0    Not tainted  (3.2.0-rc1EP-1+ #1008)
PC is at 0xc184c868
LR is at ep93xx_dma_tasklet+0xec/0x164
pc : [<c184c868>]    lr : [<c012b528>]    psr: 00000013
sp : c02b7e70  ip : ffffffff  fp : c02b7ea4
r10: 00000100  r9 : 80000013  r8 : c02b7e50
r7 : c02b7e70  r6 : c02b7ea4  r5 : 000000a4  r4 : c02b7e70
r3 : c02b751d  r2 : 8ae34598  r1 : c184c6e0  r0 : c02b7ea4
Flags: nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: c000717f  Table: c0004000  DAC: 00000017
Process swapper (pid: 0, stack limit = 0xc02b6270)
Stack: (0xc02b7e70 to 0xc02b8000)
7e60:                                     c02b7ea4 c02b7e70 c0008b64 c02bd5c4
7e80: c02d60e0 00000000 00000000 c02bd44c c02d60e0 00000100 c02b7ec4 c02b7ea8
7ea0: c001c49c c012b44c 00000018 00000001 c02d60e0 c02b6000 c02b7f04 c02b7ec8
7ec0: c001cbc0 c001c3e4 c02b7eec c02b7ed8 00000006 0000000a c02bf674 c02c458c
7ee0: 00000011 00000000 c02b7f7c c0004000 41129200 c02b0c80 c02b7f14 c02b7f08
7f00: c001cdd0 c001cb38 c02b7f34 c02b7f18 c000983c c001cd98 c0009a60 60000013
7f20: fefb0001 c02b7f7c c02b7f44 c02b7f38 c0008190 c0009810 c02b7f9c c02b7f48
7f40: c0008b64 c0008190 c02c2bf8 00000002 c02b7f90 60000013 c02b6000 c02d1504
7f60: c02baa88 c02baa80 c0004000 41129200 c02b0c80 c02b7f9c c02b7fa0 c02b7f90
7f80: c0009a54 c0009a60 60000013 ffffffff c02b7fbc c02b7fa0 c000a03c c0009a40
7fa0: c02b80b0 c02b19dc c02b19d8 c02baa80 c02b7fcc c02b7fc0 c02384e4 c0009fd4
7fc0: c02b7ff4 c02b7fd0 c029d924 c0238494 c029d49c 00000000 00000000 c02b19dc
7fe0: c0007175 c02b803c 00000000 c02b7ff8 c000803c c029d700 00000000 00000000
Backtrace:
[<c012b43c>] (ep93xx_dma_tasklet+0x0/0x164) from [<c001c49c>] (tasklet_action+0x
c8/0xdc)
[<c001c3d4>] (tasklet_action+0x0/0xdc) from [<c001cbc0>] (__do_softirq+0x98/0x15
4)
 r7:c02b6000 r6:c02d60e0 r5:00000001 r4:00000018
[<c001cb28>] (__do_softirq+0x0/0x154) from [<c001cdd0>] (irq_exit+0x48/0x50)
[<c001cd88>] (irq_exit+0x0/0x50) from [<c000983c>] (handle_IRQ+0x3c/0x8c)
[<c0009800>] (handle_IRQ+0x0/0x8c) from [<c0008190>] (asm_do_IRQ+0x10/0x14)
 r7:c02b7f7c r6:fefb0001 r5:60000013 r4:c0009a60
[<c0008180>] (asm_do_IRQ+0x0/0x14) from [<c0008b64>] (__irq_svc+0x24/0xc0)
Exception stack(0xc02b7f48 to 0xc02b7f90)
7f40:                   c02c2bf8 00000002 c02b7f90 60000013 c02b6000 c02d1504
7f60: c02baa88 c02baa80 c0004000 41129200 c02b0c80 c02b7f9c c02b7fa0 c02b7f90
7f80: c0009a54 c0009a60 60000013 ffffffff
[<c0009a30>] (default_idle+0x0/0x34) from [<c000a03c>] (cpu_idle+0x78/0xb0)
[<c0009fc4>] (cpu_idle+0x0/0xb0) from [<c02384e4>] (rest_init+0x60/0x78)
 r7:c02baa80 r6:c02b19d8 r5:c02b19dc r4:c02b80b0
[<c0238484>] (rest_init+0x0/0x78) from [<c029d924>] (start_kernel+0x234/0x278)
[<c029d6f0>] (start_kernel+0x0/0x278) from [<c000803c>] (0xc000803c)
 r5:c02b803c r4:c0007175
Code: 42555300 54535953 643d4d45 65766972 (53007372)
---[ end trace a494979f60859f42 ]---
Kernel panic - not syncing: Fatal exception in interrupt
Rebooting in 2 seconds..


I'm trying to call dmaengine_terminate_all from function assigned as libata .bmdma_stop.
Maybe this is incorrect, and this bug report is invalid...

Regards,
Rafal Prylowski.

Comments

Rafal Prylowski Nov. 21, 2011, 7:44 a.m. UTC | #1
Hello.

> I wasn't able to reproduce this but can you try if following patch helps? I'm
> not sure if it is correct but at least we get more information about the
> problem.
> 
> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index 6181811..5b717da 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -1106,6 +1106,7 @@ static int ep93xx_dma_terminate_all(struct ep93xx_dma_chan *edmac)
>  	spin_lock_irqsave(&edmac->lock, flags);
>  	/* First we disable and flush the DMA channel */
>  	edmac->edma->hw_shutdown(edmac);
> +	tasklet_kill(&edmac->tasklet);
>  	clear_bit(EP93XX_DMA_IS_CYCLIC, &edmac->flags);
>  	list_splice_init(&edmac->active, &list);
>  	list_splice_init(&edmac->queue, &list);
> 

It doesn't help:

Linux version 3.2.0-rc2EP-1+ (prylowski@server) (gcc version 4.4.2 (GCC) ) #1015
 Mon Nov 21 08:30:57 CET 2011
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: Metasoft FonTel EP Board
Memory policy: ECC disabled, Data cache writeback
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 8128
Kernel command line: mtdparts=physmap-flash.0:128K(uboot),1152K(kernel),15104K(r
ootfs) root=/dev/mtdblock2 rootfstype=jffs2 console=ttyAM0 init=/sbin/init early
printk lpj=496128 panic=2
PID hash table entries: 128 (order: -3, 512 bytes)
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
Memory: 32MB = 32MB total
Memory: 27452k/27452k available, 5316k reserved, 0K highmem
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
    vmalloc : 0xc2800000 - 0xfe800000   ( 960 MB)
    lowmem  : 0xc0000000 - 0xc2000000   (  32 MB)
    modules : 0xbf000000 - 0xc0000000   (  16 MB)
      .text : 0xc0008000 - 0xc029d000   (2644 kB)
      .init : 0xc029d000 - 0xc02b6000   ( 100 kB)
      .data : 0xc02b6000 - 0xc02d1440   ( 110 kB)
       .bss : 0xc02d1464 - 0xc02df51c   (  57 kB)
SLUB: Genslabs=13, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
NR_IRQS:120
VIC @fefb0000: id 0x00041190, vendor 0x41
VIC @fefc0000: id 0x00041190, vendor 0x41
Console: colour dummy device 80x30
Calibrating delay loop (skipped) preset value.. 99.22 BogoMIPS (lpj=496128)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
NET: Registered protocol family 16
ep93xx clock: PLL1 running at 400 MHz, PLL2 at 192 MHz
ep93xx clock: FCLK 200 MHz, HCLK 100 MHz, PCLK 50 MHz
bio: create slab <bio-0> at 0
ep93xx-dma ep93xx-dma-m2p: EP93xx M2P DMA ready
ep93xx-dma ep93xx-dma-m2m: EP93xx M2M DMA ready
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
i2c-gpio i2c-gpio.0: using pins 49 (SDA) and 48 (SCL)
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 1024 (order: 1, 8192 bytes)
TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
TCP reno registered
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
msgmni has been set to 53
io scheduler noop registered
io scheduler deadline registered (default)
Serial: AMBA driver
apb:uart1: ttyAM0 at MMIO 0x808c0000 (irq = 52) is a AMBA
console [ttyAM0] enabled
apb:uart2: ttyAM1 at MMIO 0x808d0000 (irq = 54) is a AMBA
apb:uart3: ttyAM2 at MMIO 0x808e0000 (irq = 55) is a AMBA
fontel-pri fontel-pri: FonTel PRI initialized correctly.
ep93xx-ide ep93xx-ide: version 0.5
scsi0 : ep93xx-ide
ata1: PATA max UDMA/66 irq 40
physmap platform flash device: 01000000 at 60000000
physmap-flash.0: Found 1 x16 devices at 0x0 in 16-bit bank. Manufacturer ID 0x00
0001 Chip ID 0x002101
Amd/Fujitsu Extended Query Table at 0x0040
  Amd/Fujitsu Extended Query version 1.3.
number of CFI chips: 1
3 cmdlinepart partitions found on MTD device physmap-flash.0
Creating 3 MTD partitions on "physmap-flash.0":
0x000000000000-0x000000020000 : "uboot"
0x000000020000-0x000000140000 : "kernel"
0x000000140000-0x000001000000 : "rootfs"
ep93xx-spi ep93xx-spi.0: EP93xx SPI Controller at 0x808a0000 irq 53
ep93xx-eth version 0.1 loading
eth0: ep93xx on-chip ethernet, IRQ 39, aa:42:14:07:63:9d
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
ep93xx-ohci ep93xx-ohci: EP93xx OHCI
ep93xx-ohci ep93xx-ohci: new USB bus registered, assigned bus number 1
ep93xx-ohci ep93xx-ohci: irq 56, io mem 0x80020000
ata1.00: HPA detected: current 234439535, native 234441648
ata1.00: ATA-7: ST9120822AS, 3.ALC, max UDMA/133
ata1.00: 234439535 sectors, multi 0: LBA48
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 3 ports detected
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
ata1.00: configured for UDMA/66
scsi 0:0:0:0: Direct-Access     ATA      ST9120822AS      3.AL PQ: 0 ANSI: 5
usbcore: registered new interface driver fontel
sd 0:0:0:0: [sda] 234439535 512-byte logical blocks: (120 GB/111 GiB)
rtc-ds1307 0-0068: rtc core: registered ds1307 as rtc0
rtc-ds1307 0-0068: 56 bytes nvram
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO
 or FUA
ep93xx-rtc ep93xx-rtc: rtc core: registered ep93xx-rtc as rtc1
Software Watchdog Timer: 0.07 initialized. soft_noboot=0 soft_margin=60 sec soft
_panic=0 (nowayout= 0)
TCP cubic registered
NET: Registered protocol family 17
NET: Registered protocol family 15
ep93xx-rtc ep93xx-rtc: setting system clock to 1970-01-01 00:00:07 UTC (7)
Attempt to kill tasklet from interrupt
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 80000005 [#1]
CPU: 0    Not tainted  (3.2.0-rc2EP-1+ #1015)
PC is at 0x0
LR is at sys_sched_yield+0x38/0x48
pc : [<00000000>]    lr : [<c0015030>]    psr: 20000093
sp : c02b7ce8  ip : c02b7cf8  fp : c02b7cf4
r10: c1918000  r9 : c19180a4  r8 : 00002118
r7 : 00000004  r6 : c02b7d20  r5 : c184d6bc  r4 : c184d6b8
r3 : c023e458  r2 : c02b7ce8  r1 : 00000001  r0 : c02bcff0
Flags: nzCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: c000717f  Table: c0004000  DAC: 00000017
Process swapper (pid: 0, stack limit = 0xc02b6270)
Stack: (0xc02b7ce8 to 0xc02b8000)
7ce0:                   c02b7d04 c02b7cf8 c023bdcc c0015008 c02b7d1c c02b7d08
7d00: c001ca04 c023bdb4 60000093 c184d680 c02b7d44 c02b7d20 c012ac8c c001c9d8
7d20: c02b7d20 c02b7d20 c02b7d44 c1914070 c19180a4 c2860000 c02b7d64 c02b7d48
7d40: c0177c50 c012ac54 c19180a4 c1918000 00000004 00000004 c02b7d8c c02b7d68
7d60: c0176a64 c0177c20 00000000 c1914190 00000000 00000001 0000000b c19180a4
7d80: c02b7dd4 c02b7d90 c0176cc0 c01769c4 00000001 40000093 00000000 00000000
7da0: c1914190 00000000 c1822000 c1912a80 00000028 00000000 00000000 00000028
7dc0: c02d8148 c02c0084 c02b7e0c c02b7dd8 c00426d0 c0176ae0 c02b7dfc c02b7de8
7de0: c0035628 c02c0084 00000028 c02b7f48 c02b7eb4 c02bd44c c02d60e0 c02b0c90
7e00: c02b7e24 c02b7e10 c004285c c004268c c02c0084 00000028 c02b7e3c c02b7e28
7e20: c0045178 c004283c c02c4578 00000028 c02b7e4c c02b7e40 c0042254 c00450fc
7e40: c02b7e6c c02b7e50 c0009838 c0042228 c001cb80 20000013 fefc0001 c02b7eb4
7e60: c02b7e7c c02b7e70 c0008190 c0009810 c02b7f04 c02b7e80 c0008b64 c0008190
7e80: 00000000 00000000 00000000 20000013 00000040 00000040 c02d60e0 c02b6000
7ea0: c02bd44c c02d60e0 c02b0c90 c02b7f04 c02b7f08 c02b7ec8 c001cdd0 c001cb80
7ec0: 20000013 ffffffff c02b7eec c02b7ed8 c004496c 0000000a c02bf674 c02c4578
7ee0: 00000011 00000000 c02b7f7c c0004000 41129200 c02b0c90 c02b7f14 c02b7f08
7f00: c001cdd0 c001cb38 c02b7f34 c02b7f18 c000983c c001cd98 c0009a60 60000013
7f20: fefb0001 c02b7f7c c02b7f44 c02b7f38 c0008190 c0009810 c02b7f9c c02b7f48
7f40: c0008b64 c0008190 c02c2bf8 00000002 c02b7f90 60000013 c02b6000 c02d1504
7f60: c02baa88 c02baa80 c0004000 41129200 c02b0c90 c02b7f9c c02b7fa0 c02b7f90
7f80: c0009a54 c0009a60 60000013 ffffffff c02b7fbc c02b7fa0 c000a03c c0009a40
7fa0: c02b80b0 c02b19ec c02b19e8 c02baa80 c02b7fcc c02b7fc0 c02384b4 c0009fd4
7fc0: c02b7ff4 c02b7fd0 c029d924 c0238464 c029d49c 00000000 00000000 c02b19ec
7fe0: c0007175 c02b803c 00000000 c02b7ff8 c000803c c029d700 00000000 00000000
Backtrace:
[<c0014ff8>] (sys_sched_yield+0x0/0x48) from [<c023bdcc>] (yield+0x28/0x2c)
[<c023bda4>] (yield+0x0/0x2c) from [<c001ca04>] (tasklet_kill+0x3c/0x9c)
[<c001c9c8>] (tasklet_kill+0x0/0x9c) from [<c012ac8c>] (ep93xx_dma_control+0x48/
0x1c0)
 r5:c184d680 r4:60000093
[<c012ac44>] (ep93xx_dma_control+0x0/0x1c0) from [<c0177c50>] (ep93xx_pata_dma_s
top+0x40/0xb8)
 r6:c2860000 r5:c19180a4 r4:c1914070
[<c0177c10>] (ep93xx_pata_dma_stop+0x0/0xb8) from [<c0176a64>] (ata_bmdma_port_i
ntr+0xb0/0x11c)
 r7:00000004 r6:00000004 r5:c1918000 r4:c19180a4
[<c01769b4>] (ata_bmdma_port_intr+0x0/0x11c) from [<c0176cc0>] (ata_bmdma_interr
upt+0x1f0/0x274)
 r9:c19180a4 r8:0000000b r7:00000001 r6:00000000 r5:c1914190
r4:00000000
[<c0176ad0>] (ata_bmdma_interrupt+0x0/0x274) from [<c00426d0>] (handle_irq_event
_percpu+0x54/0x1b0)
[<c004267c>] (handle_irq_event_percpu+0x0/0x1b0) from [<c004285c>] (handle_irq_e
vent+0x30/0x40)
[<c004282c>] (handle_irq_event+0x0/0x40) from [<c0045178>] (handle_level_irq+0x8
c/0xe8)
 r5:00000028 r4:c02c0084
[<c00450ec>] (handle_level_irq+0x0/0xe8) from [<c0042254>] (generic_handle_irq+0
x3c/0x48)
 r5:00000028 r4:c02c4578
[<c0042218>] (generic_handle_irq+0x0/0x48) from [<c0009838>] (handle_IRQ+0x38/0x
8c)
[<c0009800>] (handle_IRQ+0x0/0x8c) from [<c0008190>] (asm_do_IRQ+0x10/0x14)
 r7:c02b7eb4 r6:fefc0001 r5:20000013 r4:c001cb80
[<c0008180>] (asm_do_IRQ+0x0/0x14) from [<c0008b64>] (__irq_svc+0x24/0xc0)
Exception stack(0xc02b7e80 to 0xc02b7ec8)
7e80: 00000000 00000000 00000000 20000013 00000040 00000040 c02d60e0 c02b6000
7ea0: c02bd44c c02d60e0 c02b0c90 c02b7f04 c02b7f08 c02b7ec8 c001cdd0 c001cb80
7ec0: 20000013 ffffffff
[<c001cb28>] (__do_softirq+0x0/0x154) from [<c001cdd0>] (irq_exit+0x48/0x50)
[<c001cd88>] (irq_exit+0x0/0x50) from [<c000983c>] (handle_IRQ+0x3c/0x8c)
[<c0009800>] (handle_IRQ+0x0/0x8c) from [<c0008190>] (asm_do_IRQ+0x10/0x14)
 r7:c02b7f7c r6:fefb0001 r5:60000013 r4:c0009a60
[<c0008180>] (asm_do_IRQ+0x0/0x14) from [<c0008b64>] (__irq_svc+0x24/0xc0)
Exception stack(0xc02b7f48 to 0xc02b7f90)
7f40:                   c02c2bf8 00000002 c02b7f90 60000013 c02b6000 c02d1504
7f60: c02baa88 c02baa80 c0004000 41129200 c02b0c90 c02b7f9c c02b7fa0 c02b7f90
7f80: c0009a54 c0009a60 60000013 ffffffff
[<c0009a30>] (default_idle+0x0/0x34) from [<c000a03c>] (cpu_idle+0x78/0xb0)
[<c0009fc4>] (cpu_idle+0x0/0xb0) from [<c02384b4>] (rest_init+0x60/0x78)
 r7:c02baa80 r6:c02b19e8 r5:c02b19ec r4:c02b80b0
[<c0238454>] (rest_init+0x0/0x78) from [<c029d924>] (start_kernel+0x234/0x278)
[<c029d6f0>] (start_kernel+0x0/0x278) from [<c000803c>] (0xc000803c)
 r5:c02b803c r4:c0007175
Code: bad PC value
---[ end trace 3d4b7b18cc0879b4 ]---
Kernel panic - not syncing: Fatal exception in interrupt
Rebooting in 2 seconds..

I'm calling dma_terminate_all from interrupt. It seems that tasklet_kill is not
allowed to be called from this context.

Thanks,
Rafał Pryłowski.
Vinod Koul Nov. 21, 2011, 8:32 a.m. UTC | #2
On Mon, 2011-11-21 at 10:01 +0200, Mika Westerberg wrote:
> On Mon, Nov 21, 2011 at 08:44:07AM +0100, Rafal Prylowski wrote:
> > 
> > I'm calling dma_terminate_all from interrupt. It seems that tasklet_kill is not
> > allowed to be called from this context.
> 
> Ah, right.
> 
> One more try - this time we set a flag which prevents the tasktlet from
> referencing an empty list.
Rather than this why not actually check for list_empty and process only
when it is not empty?
Also you should check the return of the ep93xx_dma_get_active() which
should return NULL if it didn't find anything in active list
> 
> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index 6181811..f7244b3 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -155,6 +155,8 @@ struct ep93xx_dma_chan {
>  	unsigned long			flags;
>  /* Channel is configured for cyclic transfers */
>  #define EP93XX_DMA_IS_CYCLIC		0
> +/* Channel is enabled */
> +#define EP93xx_DMA_IS_RUNNING		1
>  
>  	int				buffer;
>  	dma_cookie_t			last_completed;
> @@ -673,6 +675,9 @@ static void ep93xx_dma_tasklet(unsigned long data)
>  	void *callback_param;
>  	LIST_HEAD(list);
>  
> +	if (!test_bit(EP93XX_DMA_IS_RUNNING, &edmac->flags))
> +		return;
> +
>  	spin_lock_irq(&edmac->lock);
>  	desc = ep93xx_dma_get_active(edmac);
>  	if (desc->complete) {
> @@ -758,6 +763,8 @@ static dma_cookie_t ep93xx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
>  	edmac->chan.cookie = cookie;
>  	desc->txd.cookie = cookie;
>  
> +	set_bit(EP93XX_DMA_IS_RUNNING, &edmac->flags);
> +
>  	/*
>  	 * If nothing is currently prosessed, we push this descriptor
>  	 * directly to the hardware. Otherwise we put the descriptor
> @@ -1106,6 +1113,7 @@ static int ep93xx_dma_terminate_all(struct ep93xx_dma_chan *edmac)
>  	spin_lock_irqsave(&edmac->lock, flags);
>  	/* First we disable and flush the DMA channel */
>  	edmac->edma->hw_shutdown(edmac);
> +	clear_bit(EP93XX_DMA_IS_RUNNING, &edmac->flags);
>  	clear_bit(EP93XX_DMA_IS_CYCLIC, &edmac->flags);
>  	list_splice_init(&edmac->active, &list);
>  	list_splice_init(&edmac->queue, &list);
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Rafal Prylowski Nov. 21, 2011, 8:54 a.m. UTC | #3
>> I'm calling dma_terminate_all from interrupt. It seems that tasklet_kill is not
>> allowed to be called from this context.
> 
> Ah, right.
> 
> One more try - this time we set a flag which prevents the tasktlet from
> referencing an empty list.
> 
> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index 6181811..f7244b3 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -155,6 +155,8 @@ struct ep93xx_dma_chan {
>  	unsigned long			flags;
>  /* Channel is configured for cyclic transfers */
>  #define EP93XX_DMA_IS_CYCLIC		0
> +/* Channel is enabled */
> +#define EP93xx_DMA_IS_RUNNING		1
>  
>  	int				buffer;
>  	dma_cookie_t			last_completed;
> @@ -673,6 +675,9 @@ static void ep93xx_dma_tasklet(unsigned long data)
>  	void *callback_param;
>  	LIST_HEAD(list);
>  
> +	if (!test_bit(EP93XX_DMA_IS_RUNNING, &edmac->flags))
> +		return;
> +
>  	spin_lock_irq(&edmac->lock);
>  	desc = ep93xx_dma_get_active(edmac);
>  	if (desc->complete) {
> @@ -758,6 +763,8 @@ static dma_cookie_t ep93xx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
>  	edmac->chan.cookie = cookie;
>  	desc->txd.cookie = cookie;
>  
> +	set_bit(EP93XX_DMA_IS_RUNNING, &edmac->flags);
> +
>  	/*
>  	 * If nothing is currently prosessed, we push this descriptor
>  	 * directly to the hardware. Otherwise we put the descriptor
> @@ -1106,6 +1113,7 @@ static int ep93xx_dma_terminate_all(struct ep93xx_dma_chan *edmac)
>  	spin_lock_irqsave(&edmac->lock, flags);
>  	/* First we disable and flush the DMA channel */
>  	edmac->edma->hw_shutdown(edmac);
> +	clear_bit(EP93XX_DMA_IS_RUNNING, &edmac->flags);
>  	clear_bit(EP93XX_DMA_IS_CYCLIC, &edmac->flags);
>  	list_splice_init(&edmac->active, &list);
>  	list_splice_init(&edmac->queue, &list);
> 

This patch works partially for me. Drive is detected correctly, I can do simple test with
hdparm, mount partitions, create file with 'touch' command, but when trying to fill
partition with data I get:

# dd if=/dev/zero of=/mnt/b/zero4 bs=4M
Internal error: Oops - undefined instruction: 0 [#1]
CPU: 0    Not tainted  (3.2.0-rc2EP-1+ #1017)
PC is at 0xc1862868
LR is at ep93xx_dma_tasklet+0xc4/0x174
pc : [<c1862868>]    lr : [<c012b498>]    psr: 00000013
sp : c10c3b60  ip : ffffffff  fp : c10c3b94
r10: 00000100  r9 : 80000013  r8 : c10c3b40
r7 : c10c3b60  r6 : c10c3b94  r5 : 00000094  r4 : c10c3b60
r3 : c10c320d  r2 : a0e96520  r1 : c1862758  r0 : c10c3b94
Flags: nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: c000717f  Table: c1240000  DAC: 00000015
Process dd (pid: 619, stack limit = 0xc10c2270)
Stack: (0xc10c3b60 to 0xc10c4000)
3b60: c10c3b94 c10c3b60 00000001 c02bd5c4 c02d60e0 00000000 00000000 c02bd44c
3b80: c02d60e0 00000100 c10c3bb4 c10c3b98 c001c49c c012b3e4 00000018 00000001
3ba0: c02d60e0 c10c2000 c10c3bf4 c10c3bb8 c001cbc0 c001c3e4 c10c3bdc c10c3bc8
3bc0: 00000006 0000000a c02bf6e4 c02c4578 00000012 00000000 c10c3c6c 00000000
3be0: 00000000 00000000 c10c3c04 c10c3bf8 c001cdd0 c001cb38 c10c3c24 c10c3c08
3c00: c000983c c001cd98 c00e1160 80000013 fefb0001 c10c3c6c c10c3c34 c10c3c28
3c20: c0008190 c0009810 c10c3ccc c10c3c38 c0008b64 c0008190 c1a44058 00000003
3c40: ffffb58e ffffffc7 c156a000 c1a70060 c10c2000 c1a44000 00000000 00000000
3c60: 00000000 c10c3ccc c1a4404c c10c3c80 c0011a28 c00e1160 80000013 ffffffff
3c80: 00000000 00001000 c10c3cb4 c10c3c98 c00d9eac c00e0f88 c156a000 c1791250
3ca0: c156a000 00000000 c0242f4c c1a44600 03605000 00000000 00000000 00001000
3cc0: c10c3cec c10c3cd0 c00d9eac c00e0f88 c1791250 c02f9860 c156a000 03605000
3ce0: c10c3d2c c10c3cf0 c00d3d7c c00d9e94 00001000 00001000 c02f9860 c008df3c
3d00: c10c3d58 c0242d18 c10c2000 c1791308 00000000 c10c3d58 00001000 00204000
3d20: c10c3d9c c10c3d30 c0046f00 c00d3cbc 00001000 00001000 c02f9860 c008df3c
3d40: 00000000 00001000 c0242d18 c19e4000 03604000 00000000 c10c3f10 00000001
3d60: 00204000 001fc000 c008df3c c02f9860 00000073 c10c3ec8 c10c2000 c19e4000
3d80: 000001fe 00000000 c10c3f10 c1791308 c10c3e2c c10c3da0 c0049028 c0046e10
3da0: 03400000 00000000 c10c3ec8 00400000 00000000 c10c3dd0 c10c3dc4 00400000
3dc0: 03800000 00000000 00000001 c10c3ec8 c10c3e90 c02d8148 03400000 00000000
3de0: c10c3dec 00000001 c00443e8 00000001 c02d60e0 00000008 c02bf6e4 00400000
3e00: 00000000 c10c3e40 c17912ac c19e4000 03400000 c10c3e90 c10c3f10 00000001
3e20: c10c3e84 c10c3e30 c00492a4 c0048cf0 c10c3e3c c0045198 c0044954 00000000
3e40: 91827364 c10c3e44 c10c3e44 c10c3e4c c10c3e4c 00000000 c10c3e64 c10c3e90
3e60: c19e4000 c10c3f10 fffffdee c10c3f78 03400000 00000000 c10c3f44 c10c3e88
3e80: c0079114 c0049234 03400000 00000000 c0008190 40b90a78 00000000 00000001
3ea0: ffffffff c19e4000 00000000 00000000 00000000 00000000 c1aea000 c10c2000
3ec0: 00000000 00000000 03400000 00000000 c10c3f0c c10c3ee0 00400000 c0034478
3ee0: 00400000 c1a03658 00001000 40b95008 00001000 003ff000 c10c2000 c1818780
3f00: c19e4288 00000001 c01197e8 00000000 40796008 00400000 c01474b0 c19e4000
3f20: 00400000 40796008 c10c3f78 c0009124 c10c2000 00000000 c10c3f74 c10c3f48
3f40: c0079c7c c0079064 00000000 00000000 c0009124 c19e4000 03400000 00000000
3f60: 00000004 c0009124 c10c3fa4 c10c3f78 c0079df4 c0079bd0 03400000 00000000
3f80: 00000004 00000000 c10c2000 00400000 40796008 4004f7e0 00000000 c10c3fa8
3fa0: c0008fa0 c0079db8 00400000 40796008 00000001 40796008 00400000 000abfc4
3fc0: 00400000 40796008 4004f7e0 00000004 40796008 40796008 bedb5f34 00000000
3fe0: 00000001 bedb5ba0 0000ef78 40180dcc 60000010 00000001 00000000 00000000
Backtrace:
[<c012b3d4>] (ep93xx_dma_tasklet+0x0/0x174) from [<c001c49c>] (tasklet_action+0x
c8/0xdc)
[<c001c3d4>] (tasklet_action+0x0/0xdc) from [<c001cbc0>] (__do_softirq+0x98/0x15
4)
 r7:c10c2000 r6:c02d60e0 r5:00000001 r4:00000018
[<c001cb28>] (__do_softirq+0x0/0x154) from [<c001cdd0>] (irq_exit+0x48/0x50)
[<c001cd88>] (irq_exit+0x0/0x50) from [<c000983c>] (handle_IRQ+0x3c/0x8c)
[<c0009800>] (handle_IRQ+0x0/0x8c) from [<c0008190>] (asm_do_IRQ+0x10/0x14)
 r7:c10c3c6c r6:fefb0001 r5:80000013 r4:c00e1160
[<c0008180>] (asm_do_IRQ+0x0/0x14) from [<c0008b64>] (__irq_svc+0x24/0xc0)
Exception stack(0xc10c3c38 to 0xc10c3c80)
3c20:                                                       c1a44058 00000003
3c40: ffffb58e ffffffc7 c156a000 c1a70060 c10c2000 c1a44000 00000000 00000000
3c60: 00000000 c10c3ccc c1a4404c c10c3c80 c0011a28 c00e1160 80000013 ffffffff
[<c00e0f78>] (journal_stop+0x0/0x2bc) from [<c00d9eac>] (__ext3_journal_stop+0x2
8/0x58)
[<c00d9e84>] (__ext3_journal_stop+0x0/0x58) from [<c00d3d7c>] (ext3_writeback_wr
ite_end+0xd0/0x174)
 r7:03605000 r6:c156a000 r5:c02f9860 r4:c1791250
[<c00d3cac>] (ext3_writeback_write_end+0x0/0x174) from [<c0046f00>] (generic_fil
e_buffered_write+0x100/0x25c)
[<c0046e00>] (generic_file_buffered_write+0x0/0x25c) from [<c0049028>] (__generi
c_file_aio_write+0x348/0x544)
[<c0048ce0>] (__generic_file_aio_write+0x0/0x544) from [<c00492a4>] (generic_fil
e_aio_write+0x80/0xe8)
[<c0049224>] (generic_file_aio_write+0x0/0xe8) from [<c0079114>] (do_sync_write+
0xc0/0xf8)
[<c0079054>] (do_sync_write+0x0/0xf8) from [<c0079c7c>] (vfs_write+0xbc/0x150)
[<c0079bc0>] (vfs_write+0x0/0x150) from [<c0079df4>] (sys_write+0x4c/0x84)
 r8:c0009124 r7:00000004 r6:00000000 r5:03400000 r4:c19e4000
[<c0079da8>] (sys_write+0x0/0x84) from [<c0008fa0>] (ret_fast_syscall+0x0/0x2c)
 r6:4004f7e0 r5:40796008 r4:00400000
Code: 42555300 54535953 643d4d45 65766972 (53007372)
---[ end trace 8f90267a5628d8bf ]---
Kernel panic - not syncing: Fatal exception in interrupt

I don't get this exception when using my patch, posted in first email.
Mika Westerberg Nov. 22, 2011, 5:59 a.m. UTC | #4
On Mon, Nov 21, 2011 at 02:02:06PM +0530, Vinod Koul wrote:
> On Mon, 2011-11-21 at 10:01 +0200, Mika Westerberg wrote:
> > On Mon, Nov 21, 2011 at 08:44:07AM +0100, Rafal Prylowski wrote:
> > > 
> > > I'm calling dma_terminate_all from interrupt. It seems that tasklet_kill is not
> > > allowed to be called from this context.
> > 
> > Ah, right.
> > 
> > One more try - this time we set a flag which prevents the tasktlet from
> > referencing an empty list.

> Rather than this why not actually check for list_empty and process only
> when it is not empty?

I was thinking that it should be an error if the active list is empty when the
tasklet is run.

> Also you should check the return of the ep93xx_dma_get_active() which
> should return NULL if it didn't find anything in active list

Right - if the list is allowed to be empty.

I'll re-check the patch from Rafal. Maybe it's better to adapt with the fact
that dma_terminate_all() can be called in any context any time and modify the
driver accordingly (e.g like you say, return NULL if the list is empty handle
it correctly).
Rafal Prylowski Nov. 22, 2011, 8:45 a.m. UTC | #5
On 2011-11-22 07:47, Mika Westerberg wrote:
> Let me know if this works for you. Basically it's the patch from you except
> that we use a flag to indicate if the channel is running or not.
> 

It works correctly. All of my simple hdd tests completed without any problems.
Thanks.
Vinod Koul Nov. 23, 2011, 10:47 a.m. UTC | #6
On Tue, 2011-11-22 at 07:59 +0200, Mika Westerberg wrote:
> On Mon, Nov 21, 2011 at 02:02:06PM +0530, Vinod Koul wrote:
> > On Mon, 2011-11-21 at 10:01 +0200, Mika Westerberg wrote:
> > > On Mon, Nov 21, 2011 at 08:44:07AM +0100, Rafal Prylowski wrote:
> > > > 
> > > > I'm calling dma_terminate_all from interrupt. It seems that tasklet_kill is not
> > > > allowed to be called from this context.
> > > 
> > > Ah, right.
> > > 
> > > One more try - this time we set a flag which prevents the tasktlet from
> > > referencing an empty list.
> 
> > Rather than this why not actually check for list_empty and process only
> > when it is not empty?
> 
> I was thinking that it should be an error if the active list is empty when the
> tasklet is run.
well where would you return the error from tasklet?

> 
> > Also you should check the return of the ep93xx_dma_get_active() which
> > should return NULL if it didn't find anything in active list
> 
> Right - if the list is allowed to be empty.
> 
> I'll re-check the patch from Rafal. Maybe it's better to adapt with the fact
> that dma_terminate_all() can be called in any context any time and modify the
> driver accordingly (e.g like you say, return NULL if the list is empty handle
> it correctly).
Yes dma_terminate_all() is allowed to be called by the driver in any
context. It may wish to terminate at any point and this can potentially
lead to race condition when you do actual hardware right to terminate
just when hardware sent the interrupt. And your tasklet is scheduled
after the list becomes empty.
So its better approach to check for list in tasklet and return of
ep93xx_dma_get_active() for a valid descriptor
diff mbox

Patch

Index: linux-2.6/drivers/dma/ep93xx_dma.c
===================================================================
--- linux-2.6.orig/drivers/dma/ep93xx_dma.c
+++ linux-2.6/drivers/dma/ep93xx_dma.c
@@ -459,9 +459,6 @@  static int m2m_hw_setup(struct ep93xx_dm
 		 * This IDE part is totally untested. Values below are taken
 		 * from the EP93xx Users's Guide and might not be correct.
 		 */
-		control |= M2M_CONTROL_NO_HDSK;
-		control |= M2M_CONTROL_RSS_IDE;
-		control |= M2M_CONTROL_PW_16;
 
 		if (data->direction == DMA_TO_DEVICE) {
 			/* Worst case from the UG */
@@ -473,6 +470,9 @@  static int m2m_hw_setup(struct ep93xx_dm
 			control |= M2M_CONTROL_SAH;
 			control |= M2M_CONTROL_TM_RX;
 		}
+		control |= M2M_CONTROL_NO_HDSK;
+		control |= M2M_CONTROL_RSS_IDE;
+		control |= M2M_CONTROL_PW_16;
 		break;
 
 	default: