Bug #2013

Updated by zcrownover about 1 month ago

I am getting an oversized DMA transfer request loop when attempting to

play a DVD with mplayer.



Mar 3 20:19:50 neptune kernel: acd0: setting up DMA failed

Mar 3 20:19:50 neptune kernel: ata1: FAILURE - oversized DMA transfer

attempt 73728 > 65536

Mar 3 20:19:50 neptune kernel: acd0: setting up DMA failed

Mar 3 20:19:50 neptune kernel: ata1: FAILURE - oversized DMA transfer

attempt 73728 > 65536



I instrumented the kernel with some kprintf()s and a panic() in an

attempt to track this down. I've upload a coredump to

leaf:~josepht/crash/dvd_crash.tgz. I've gone back as far as

fe667cd2edce8ea4f3dcc86526ed9759c14f0bf4 but haven't yet been able to

track down exactly when this started happening. I was not seeing this

on a system built around Jan. 27 2011, though I'm not certain how old

the sources were prior to that build.



Here's the backtrace. Note this panic() was manually inserted.



Unread portion of the kernel message buffer:

ata1: FAILURE - oversized DMA transfer attempt 73728 > 65536

panic: JAT: panic

cpuid = 0

Trace beginning at frame 0xda2f18c0

panic(ffffffff) at panic+0x164

panic(c05cffe9,c4747878,c0609488,12000,10000) at panic+0x164

ata_dmaload(c4747878,d2afe800,12000,2,d7110000) at ata_dmaload+0x9e

ata_begin_transaction(d9c4b788) at ata_begin_transaction+0x33b

ata_start(c4747878) at ata_start+0x1ef

ata_queue_request(d9c4b788) at ata_queue_request+0x44a

atapi_action(c4786ce8,d6a084e0,c46a4310,c49825e8,c4623f40) at

atapi_action+0x815

xpt_run_dev_sendq(c0176f2b,20,1,0,a) at xpt_run_dev_sendq+0x1a7

xpt_action(d6a084e0) at xpt_action+0x25b

cdstart(d69f25e0,d6a084e0,d6a084e0,c4623f40,1,c498261c,1) at

cdstart+0x219

xpt_run_dev_allocq(d6c38dd0,d69f25e0,c49f79d0,da2f1ae8,c0176e39) at

xpt_run_dev_allocq+0x70

xpt_schedule(d69f25e0,1) at xpt_schedule+0xec

cdstrategy(da2f1af4) at cdstrategy+0xd2

dev_dstrategy(d6b5cb10,c49f7a50) at dev_dstrategy+0xed

dsched_strategy_raw(d6c38e0c,c49f7a50,da2f1b5c,c0325612,c49b1800) at

dsched_strategy_raw+0x41

noop_queue(c49b1800,d9dda700,c49f7a50,c49b1800) at noop_queue+0x11

dsched_queue(d6c38e0c,c49f7a50) at dsched_queue+0xfe

diskstrategy(da2f1b80) at diskstrategy+0x55

dev_dstrategy(d6b5cbf0,c49f7a00,d6b5cbf0,0,0) at dev_dstrategy+0xed

physio(da2f1c00,c02fbc61,da2f1be8,c0693f38,d6b5cbf0) at physio+0x1d8

physread(da2f1be8,c0693f38,d6b5cbf0,da2f1ca0,0) at physread+0x14

dev_dread(d6b5cbf0,da2f1ca0,0,d9d0acd8,0) at dev_dread+0x6c

devfs_fo_read(d4ef2320,da2f1ca0,d4e941d8,0,d4ef2320) at

devfs_fo_read+0x150

kern_preadv(3,da2f1ca0,0,da2f1cf0,292a2800) at kern_preadv+0xfb

sys_read(da2f1cf0,1e99f,0,d6a0dee0,200282) at sys_read+0x5d

syscall2(da2f1d40) at syscall2+0x240

Xint0x80_syscall() at Xint0x80_syscall+0x36

Debugger("panic")



Here's the diff from master as of Thu Mar 3 22:33:09 EST 2011



diff --git a/sys/dev/disk/nata/ata-chipset.c b/sys/dev/disk/nata/ata-chipset.c

index 91d4444..b155bf1 100644

--- a/sys/dev/disk/nata/ata-chipset.c

+++ b/sys/dev/disk/nata/ata-chipset.c

@@ -892,6 +892,7 @@ ata_ahci_dmainit(device_t dev)

/* note start and stop are not used here */

ch->dma->setprd = ata_ahci_dmasetprd;

ch->dma->max_iosize = 8192 * DEV_BSIZE;

+ kprintf("JAT: %s\n", __func__);

if (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_CAP_64BIT)

ch->dma->max_address = BUS_SPACE_MAXADDR;

}

@@ -1531,6 +1532,7 @@ ata_cyrix_setmode(device_t dev, int mode)



ch->dma->alignment = 16;

ch->dma->max_iosize = 126 * DEV_BSIZE;

+ kprintf("JAT: %s\n", __func__);



mode = ata_limit_mode(dev, mode, ATA_UDMA2);



@@ -3071,6 +3073,7 @@ ata_marvell_edma_dmainit(device_t dev)



/* chip does not reliably do 64K DMA transfers */

ch->dma->max_iosize = 126 * DEV_BSIZE;

+ kprintf("JAT: %s\n", __func__);

}

}



@@ -3121,6 +3124,7 @@ ata_national_setmode(device_t dev, int mode)



ch->dma->alignment = 16;

ch->dma->max_iosize = 126 * DEV_BSIZE;

+ kprintf("JAT: %s\n", __func__);



mode = ata_limit_mode(dev, mode, ATA_UDMA2);



@@ -4454,6 +4458,7 @@ ata_serverworks_allocate(device_t dev)

/* chip does not reliably do 64K DMA transfers */

if (ch->dma)

ch->dma->max_iosize = 126 * DEV_BSIZE;

+ kprintf("JAT: %s\n", __func__);



return 0;

}

diff --git a/sys/dev/disk/nata/ata-dma.c b/sys/dev/disk/nata/ata-dma.c

index 796eec1..bc0d841 100644

--- a/sys/dev/disk/nata/ata-dma.c

+++ b/sys/dev/disk/nata/ata-dma.c

@@ -76,6 +76,7 @@ ata_dmainit(device_t dev)

ch->dma->boundary = 128 * DEV_BSIZE;

ch->dma->segsize = 128 * DEV_BSIZE;

ch->dma->max_iosize = 128 * DEV_BSIZE;

+ kprintf("JAT: %s\n", __func__);

ch->dma->max_address = BUS_SPACE_MAXADDR_32BIT;

}



@@ -238,6 +239,7 @@ ata_dmaload(device_t dev, caddr_t data, int32_t count, int dir,

if (count > ch->dma->max_iosize) {

device_printf(dev, "FAILURE - oversized DMA transfer attempt %d > %d\n",

count, ch->dma->max_iosize);

+ panic("JAT: panic");

return EIO;

}



diff --git a/sys/dev/disk/nata/atapi-cd.c b/sys/dev/disk/nata/atapi-cd.c

index 12926ba..f2fc2f9 100644

--- a/sys/dev/disk/nata/atapi-cd.c

+++ b/sys/dev/disk/nata/atapi-cd.c

@@ -956,8 +956,10 @@ acd_set_ioparm(device_t dev)

struct acd_softc *cdp = device_get_ivars(dev);

struct disk_info info;



- if (ch->dma)

+ if (ch->dma) {

cdp->iomax = min(ch->dma->max_iosize, 65534);

+ kprintf("JAT: %s\n", __func__);

+ }

else

cdp->iomax = min(DFLTPHYS, 65534);



Thanks,

Joe

Back