2003-01-04 23:29:39

by Andrew Morton

[permalink] [raw]
Subject: updated CDROMREADAUDIO DMA patch

A refresh and retest of this patch, against 2.4.21-pre2. It would
be helpful if a few (or a lot of) people could test this, and report
on the result. Otherwise it'll never get anywhere...






Reading audio from IDE CDROMs always uses PIO. This patch teaches the kernel
to use DMA for the CDROMREADAUDIO ioctl.

Total time to read a CD using cdparanoia improves by up to 20%. But
sometimes there is no change.

Total CPU load decreases greatly. On a 700 MHz VIA C3 with 82C6xx
Southbridge the CPU load during the rip falls from 85% to 9%.

On an 850MHz P3 with piix chipset CPU load falls from 76% to 8%.

These loads cannot be observed with `top' or `ps' - it all happens at
interrupt time. I measure with `cyclesoak'.

Recovery from media errors has been tested, works OK.

Recovery from DMA errors has been simulated. It falls back to PIO mode OK.

The cdrom needs to be set into DMA mode (hdparm -d1 /dev/cdrom) for this code
to have an effect. I find that

hdparm -c1 -u1 -d1 /dev/cdrom

works nicely.


drivers/cdrom/cdrom.c | 151 +++++++++++++++++++++++++++++++++-----------------
drivers/ide/ide-cd.c | 62 +++++++++++++++++++-
drivers/ide/ide-cd.h | 1
include/linux/cdrom.h | 9 ++
4 files changed, 171 insertions(+), 52 deletions(-)

--- 24/drivers/cdrom/cdrom.c~ide-akpm Sat Jan 4 14:57:36 2003
+++ 24-akpm/drivers/cdrom/cdrom.c Sat Jan 4 14:57:36 2003
@@ -1911,6 +1911,107 @@ static int cdrom_do_cmd(struct cdrom_dev
return ret;
}

+/*
+ * CDROM audio read, with DMA support. Added in 2.4.18-pre4, akpm.
+ *
+ * Initially, we try to perform multiframe bus-mastering. If the IDE
+ * layer experiences a DMA error, we fall back to single-frame DMA.
+ * If the IDE layer again detects a DMA error, we fall back to multiframe
+ * PIO.
+ *
+ * We do not want to disable drive-level DMA at any stage, because
+ * some devices can perform non-packet DMA quite happily, but appear
+ * to not be able to perform packet DMA correctly.
+ *
+ * If the drive is not using_dma, we never attempt packet DMA.
+ */
+static int cdda_read_audio(int cmd,
+ struct cdrom_device_info *cdi,
+ struct cdrom_generic_command *cgc,
+ struct cdrom_read_audio *ra)
+{
+ int lba;
+ unsigned frames_todo;
+ int ret;
+ void *xferbuf = 0;
+ unsigned nr_local_frames;
+ char *useraddr;
+
+ ret = -EINVAL;
+ if (ra->addr_format == CDROM_MSF) {
+ lba = msf_to_lba(ra->addr.msf.minute,
+ ra->addr.msf.second,
+ ra->addr.msf.frame);
+ } else if (ra->addr_format == CDROM_LBA) {
+ lba = ra->addr.lba;
+ } else {
+ goto out;
+ }
+
+ if (lba < 0 || ra->nframes <= 0)
+ goto out;
+
+ /*
+ * We can't sensibly support more that 64k because we later
+ * use a buffer_head to map the temp buffer. And b_count is
+ * unsigned short.
+ */
+ nr_local_frames = ra->nframes;
+ if (nr_local_frames * CD_FRAMESIZE_RAW > 32768)
+ nr_local_frames = 32768 / CD_FRAMESIZE_RAW;
+
+ if (cdi->dma_mode == CDROM_DMA_SINGLE)
+ nr_local_frames = 1;
+
+ do {
+ xferbuf = kmalloc(CD_FRAMESIZE_RAW * nr_local_frames, GFP_KERNEL);
+ } while (!xferbuf && nr_local_frames--);
+ ret = -ENOMEM;
+ if (!xferbuf)
+ goto out;
+
+ cgc->buffer = xferbuf;
+ cgc->data_direction = CGC_DATA_READ;
+ if (cdi->dma_mode != CDROM_DMA_NONE)
+ cgc->do_dma = 1;
+ frames_todo = ra->nframes;
+ useraddr = ra->buf;
+retry:
+ while (frames_todo) {
+ unsigned frames_now = min(frames_todo, nr_local_frames);
+
+ cgc->dma_error = 0;
+ ret = cdrom_read_block(cdi, cgc, lba, frames_now, 1, CD_FRAMESIZE_RAW);
+ if (ret) {
+ /*
+ * Here we implement DMA size fallback
+ */
+ if (cgc->dma_error && cdi->dma_mode == CDROM_DMA_MULTI) {
+ printk(KERN_WARNING "CDROM: falling back to "
+ "single frame DMA\n");
+ cdi->dma_mode = CDROM_DMA_SINGLE;
+ nr_local_frames = 1;
+ goto retry;
+ } else if (cgc->dma_error && cdi->dma_mode == CDROM_DMA_SINGLE) {
+ printk(KERN_WARNING "CDROM: disabled DMA\n");
+ cdi->dma_mode = CDROM_DMA_NONE;
+ goto retry;
+ }
+ goto out;
+ }
+ ret = -EFAULT;
+ if (copy_to_user(useraddr, cgc->buffer, CD_FRAMESIZE_RAW * frames_now))
+ goto out;
+ useraddr += CD_FRAMESIZE_RAW * frames_now;
+ frames_todo -= frames_now;
+ lba += frames_now;
+ }
+ ret = 0;
+out:
+ kfree(xferbuf);
+ return ret;
+}
+
static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
unsigned long arg)
{
@@ -1977,57 +2078,9 @@ static int mmc_ioctl(struct cdrom_device
}
case CDROMREADAUDIO: {
struct cdrom_read_audio ra;
- int lba, nr;

IOCTL_IN(arg, struct cdrom_read_audio, ra);
-
- if (ra.addr_format == CDROM_MSF)
- lba = msf_to_lba(ra.addr.msf.minute,
- ra.addr.msf.second,
- ra.addr.msf.frame);
- else if (ra.addr_format == CDROM_LBA)
- lba = ra.addr.lba;
- else
- return -EINVAL;
-
- /* FIXME: we need upper bound checking, too!! */
- if (lba < 0 || ra.nframes <= 0)
- return -EINVAL;
-
- /*
- * start with will ra.nframes size, back down if alloc fails
- */
- nr = ra.nframes;
- do {
- cgc.buffer = kmalloc(CD_FRAMESIZE_RAW * nr, GFP_KERNEL);
- if (cgc.buffer)
- break;
-
- nr >>= 1;
- } while (nr);
-
- if (!nr)
- return -ENOMEM;
-
- if (!access_ok(VERIFY_WRITE, ra.buf, ra.nframes*CD_FRAMESIZE_RAW)) {
- kfree(cgc.buffer);
- return -EFAULT;
- }
- cgc.data_direction = CGC_DATA_READ;
- while (ra.nframes > 0) {
- if (nr > ra.nframes)
- nr = ra.nframes;
-
- ret = cdrom_read_block(cdi, &cgc, lba, nr, 1, CD_FRAMESIZE_RAW);
- if (ret)
- break;
- __copy_to_user(ra.buf, cgc.buffer, CD_FRAMESIZE_RAW*nr);
- ra.buf += CD_FRAMESIZE_RAW * nr;
- ra.nframes -= nr;
- lba += nr;
- }
- kfree(cgc.buffer);
- return ret;
+ return cdda_read_audio(cmd, cdi, &cgc, &ra);
}
case CDROMSUBCHNL: {
struct cdrom_subchnl q;
--- 24/drivers/ide/ide-cd.c~ide-akpm Sat Jan 4 14:57:36 2003
+++ 24-akpm/drivers/ide/ide-cd.c Sat Jan 4 14:57:36 2003
@@ -1449,9 +1449,25 @@ static ide_startstop_t cdrom_pc_intr (id
int ireason, len, stat, thislen;
struct request *rq = HWGROUP(drive)->rq;
struct packet_command *pc = (struct packet_command *)rq->buffer;
+ struct cdrom_info *info = drive->driver_data;
+ int dma = info->dma;
+ int dma_error;
ide_startstop_t startstop;
u8 lowcyl = 0, highcyl = 0;

+ if (dma) {
+ info->dma = 0;
+ if ((dma_error = HWIF(drive)->ide_dma_end(drive))) {
+ /*
+ * We don't disable drive DMA for packet DMA errors.
+ * It's handled in cdda_read_audio()
+ */
+ /* HWIF(drive)->dmaproc(ide_dma_off, drive); */
+ pc->stat = 2; /* 2 -> DMA error */
+ printk(KERN_ERR "CDROM packet DMA error\n");
+ }
+ }
+
/* Check for errors. */
if (cdrom_decode_status(&startstop, drive, 0, &stat))
return startstop;
@@ -1463,6 +1479,14 @@ static ide_startstop_t cdrom_pc_intr (id

len = lowcyl + (256 * highcyl);

+ if (dma) {
+ /*
+ * If DMA succeeded, we have all the data
+ */
+ pc->buffer += pc->buflen;
+ pc->buflen = 0;
+ }
+
/* If DRQ is clear, the command has completed.
Complain if we still have data left to transfer. */
if ((stat & DRQ_STAT) == 0) {
@@ -1568,7 +1592,11 @@ static ide_startstop_t cdrom_do_packet_c
struct packet_command *pc = (struct packet_command *)rq->buffer;
struct cdrom_info *info = drive->driver_data;

- info->dma = 0;
+ if (rq->bh) {
+ info->dma = 1;
+ } else {
+ info->dma = 0;
+ }
info->cmd = 0;
pc->stat = 0;
len = pc->buflen;
@@ -1591,6 +1619,13 @@ void cdrom_sleep (int time)
} while (sleep);
}

+/*
+ * end_buffer_io_sync() is not exported
+ */
+static void cdrom_end_buffer_io_sync(struct buffer_head *bh, int uptodate)
+{
+}
+
static
int cdrom_queue_packet_command(ide_drive_t *drive, struct packet_command *pc)
{
@@ -1603,7 +1638,25 @@ int cdrom_queue_packet_command(ide_drive

/* Start of retry loop. */
do {
+ struct buffer_head bh;
+
ide_init_drive_cmd (&req);
+
+ if (pc->do_dma) {
+ /* Hack up a buffer_head for IDE DMA's use */
+ memset(&bh, 0, sizeof(bh));
+ bh.b_size = pc->buflen;
+ bh.b_data = pc->buffer;
+ bh.b_state = (1 << BH_Lock) | (1 << BH_Mapped) |
+ (1 << BH_Req);
+ bh.b_end_io = cdrom_end_buffer_io_sync;
+#if 0 /* Needed by end_buffer_io_sync, but not cdrom_end_buffer_io_sync */
+ atomic_set(&bh.b_count, 1);
+ init_waitqueue_head(&bh.b_wait);
+#endif
+ req.bh = &bh;
+ }
+
req.cmd = PACKET_COMMAND;
req.buffer = (char *)pc;
ide_do_drive_cmd(drive, &req, ide_wait);
@@ -2352,7 +2405,12 @@ static int ide_cdrom_packet(struct cdrom
pc.quiet = cgc->quiet;
pc.timeout = cgc->timeout;
pc.sense = cgc->sense;
- return cgc->stat = cdrom_queue_packet_command(drive, &pc);
+ if (cgc->do_dma && drive->using_dma)
+ pc.do_dma = 1;
+ cgc->stat = cdrom_queue_packet_command(drive, &pc);
+ if (pc.stat == 2) /* DMA error: fall back to lower mode */
+ cgc->dma_error = 1;
+ return cgc->stat;
}

static
--- 24/drivers/ide/ide-cd.h~ide-akpm Sat Jan 4 14:57:36 2003
+++ 24-akpm/drivers/ide/ide-cd.h Sat Jan 4 14:59:29 2003
@@ -111,6 +111,7 @@ struct packet_command {
int quiet;
int timeout;
struct request_sense *sense;
+ int do_dma;
unsigned char c[12];
};

--- 24/include/linux/cdrom.h~ide-akpm Sat Jan 4 14:57:36 2003
+++ 24-akpm/include/linux/cdrom.h Sat Jan 4 15:01:11 2003
@@ -287,6 +287,8 @@ struct cdrom_generic_command
unsigned char data_direction;
int quiet;
int timeout;
+ int do_dma; /* Try to use DMA */
+ int dma_error; /* A DMA_specific error occurred */
void *reserved[1];
};

@@ -743,10 +745,15 @@ struct cdrom_device_info {
char name[20]; /* name of the device type */
/* per-device flags */
__u8 sanyo_slot : 2; /* Sanyo 3 CD changer support */
- __u8 reserved : 6; /* not used yet */
+ __u8 dma_mode : 2; /* See below */
+ __u8 reserved : 4; /* not used yet */
struct cdrom_write_settings write;
};

+#define CDROM_DMA_MULTI 0 /* Multiframe DMA (default) */
+#define CDROM_DMA_SINGLE 1 /* Single frame DMA */
+#define CDROM_DMA_NONE 2 /* Multiframe PIO */
+
struct cdrom_device_ops {
/* routines */
int (*open) (struct cdrom_device_info *, int);

_


2003-01-05 13:07:23

by Tony Spinillo

[permalink] [raw]
Subject: RE: updated CDROMREADAUDIO DMA patch

Andrew,

I tried the patch on 2.4.21pre2. In the short time that it has been on,
it seems
to be working. To test, I did this before the patch:
cdda2wav -D /dev/cdrom -e -N, then fired up Quake3,
the game was very stuttery. CD music played fine. After patching,
the game played smooth, game sounds were smooth
as well as the CD music.

I will bat it around more and report any problems.

Thanks!

Tony

lspci - INTEL 845PESVL motherboard:
00:00.0 Host bridge: Intel Corp. 82845G/GL [Brookdale-G] Chipset Host
Bridge (rev 02)
Subsystem: Intel Corp. 82845G/GL [Brookdale-G] Chipset Host Bridge
Flags: bus master, fast devsel, latency 0
Memory at e0000000 (32-bit, prefetchable) [size=256M]
Capabilities: [e4] #09 [6105]
Capabilities: [a0] AGP version 2.0

00:01.0 PCI bridge: Intel Corp. 82845G/GL [Brookdale-G] Chipset AGP
Bridge (rev 02) (prog-if 00 [Normal decode])
Flags: bus master, 66Mhz, fast devsel, latency 32
Bus: primary=00, secondary=01, subordinate=01, sec-latency=32
Memory behind bridge: fc500000-fe5fffff
Prefetchable memory behind bridge: cc100000-dc2fffff

00:1d.0 USB Controller: Intel Corp. 82801DB USB (Hub #1) (rev 02)
(prog-if 00 [UHCI])
Subsystem: Intel Corp.: Unknown device 5356
Flags: bus master, medium devsel, latency 0, IRQ 16
I/O ports at e800 [size=32]

00:1d.1 USB Controller: Intel Corp. 82801DB USB (Hub #2) (rev 02)
(prog-if 00 [UHCI])
Subsystem: Intel Corp.: Unknown device 5356
Flags: bus master, medium devsel, latency 0, IRQ 19
I/O ports at e880 [size=32]

00:1d.2 USB Controller: Intel Corp. 82801DB USB (Hub #3) (rev 02)
(prog-if 00 [UHCI])
Subsystem: Intel Corp.: Unknown device 5356
Flags: bus master, medium devsel, latency 0, IRQ 18
I/O ports at ec00 [size=32]

00:1d.7 USB Controller: Intel Corp. 82801DB USB EHCI Controller (rev
02) (prog-if 20 [EHCI])
Subsystem: Intel Corp.: Unknown device 5356
Flags: bus master, medium devsel, latency 0, IRQ 23
Memory at febffc00 (32-bit, non-prefetchable) [size=1K]
Capabilities: [50] Power Management version 2
Capabilities: [58] #0a [2080]

00:1e.0 PCI bridge: Intel Corp. 82801BA/CA/DB PCI Bridge (rev 82)
(prog-if 00 [Normal decode])
Flags: bus master, fast devsel, latency 0
Bus: primary=00, secondary=02, subordinate=02, sec-latency=32
I/O behind bridge: 0000d000-0000dfff
Memory behind bridge: fe600000-feafffff
Prefetchable memory behind bridge: dc300000-dc3fffff

00:1f.0 ISA bridge: Intel Corp. 82801DB ISA Bridge (LPC) (rev 02)
Flags: bus master, medium devsel, latency 0

00:1f.1 IDE interface: Intel Corp. 82801DB ICH4 IDE (rev 02) (prog-if
8a [Master SecP PriP])
Subsystem: Intel Corp.: Unknown device 5356
Flags: bus master, medium devsel, latency 0, IRQ 18
I/O ports at <unassigned> [size=8]
I/O ports at <unassigned> [size=4]
I/O ports at <unassigned> [size=8]
I/O ports at <unassigned> [size=4]
I/O ports at ffa0 [size=16]
Memory at 40000000 (32-bit, non-prefetchable) [disabled] [size=1K]

00:1f.3 SMBus: Intel Corp. 82801DB SMBus (rev 02)
Subsystem: Intel Corp.: Unknown device 5356
Flags: medium devsel, IRQ 17
I/O ports at e480 [size=32]

01:00.0 VGA compatible controller: nVidia Corporation NV25 [GeForce4
Ti4600] (rev a2) (prog-if 00 [VGA])
Flags: bus master, 66Mhz, medium devsel, latency 248, IRQ 16
Memory at fd000000 (32-bit, non-prefetchable) [size=16M]
Memory at d0000000 (32-bit, prefetchable) [size=128M]
Memory at dc280000 (32-bit, prefetchable) [size=512K]
Expansion ROM at fe5e0000 [disabled] [size=128K]
Capabilities: [60] Power Management version 2
Capabilities: [44] AGP version 2.0

02:01.0 SCSI storage controller: Adaptec AHA-3960D / AIC-7899A U160/m
(rev 01)
Subsystem: Adaptec AHA-3960D U160/m
Flags: bus master, 66Mhz, medium devsel, latency 32, IRQ 22
BIST result: 00
I/O ports at d400 [disabled] [size=256]
Memory at feafe000 (64-bit, non-prefetchable) [size=4K]
Expansion ROM at feaa0000 [disabled] [size=128K]
Capabilities: [dc] Power Management version 2

02:01.1 SCSI storage controller: Adaptec AHA-3960D / AIC-7899A U160/m
(rev 01)
Subsystem: Adaptec AHA-3960D U160/m
Flags: bus master, 66Mhz, medium devsel, latency 32, IRQ 21
BIST result: 00
I/O ports at d800 [disabled] [size=256]
Memory at feaff000 (64-bit, non-prefetchable) [size=4K]
Expansion ROM at feac0000 [disabled] [size=128K]
Capabilities: [dc] Power Management version 2

02:03.0 Multimedia audio controller: IC Ensemble Inc ICE1712 [Envy24]
(rev 02)
Subsystem: IC Ensemble Inc: Unknown device d634
Flags: bus master, medium devsel, latency 32, IRQ 19
I/O ports at dc00 [size=32]
I/O ports at d080 [size=16]
I/O ports at d000 [size=16]
I/O ports at df00 [size=64]
Capabilities: [80] Power Management version 1

02:05.0 Ethernet controller: Intel Corp. 82557/8/9 [Ethernet Pro 100]
(rev 08)
Subsystem: IBM 10/100 EtherJet Management Adapter
Flags: bus master, medium devsel, latency 32, IRQ 18
Memory at feafd000 (32-bit, non-prefetchable) [size=4K]
I/O ports at de80 [size=64]
Memory at fe900000 (32-bit, non-prefetchable) [size=1M]
Expansion ROM at fe800000 [disabled] [size=1M]
Capabilities: [dc] Power Management version 2

02:08.0 Ethernet controller: Intel Corp. 82801BD PRO/100 VE (LOM)
Ethernet Controller (rev 82)
Subsystem: Intel Corp.: Unknown device 3015
Flags: bus master, medium devsel, latency 32, IRQ 20
Memory at feafc000 (32-bit, non-prefetchable) [size=4K]
I/O ports at de00 [size=64]
Capabilities: [dc] Power Management version 2

2003-01-05 23:00:09

by Nuno Monteiro

[permalink] [raw]
Subject: Re: updated CDROMREADAUDIO DMA patch

[First of all, excuse me for breaking the thread, I had already deleted
your original mail when I ran into this. Sorry for the inconvenience :)]

On January 4th 2003 Andrew Morton wrote:
> A refresh and retest of this patch, against 2.4.21-pre2. It would
> be helpful if a few (or a lot of) people could test this, and report
> on the result. Otherwise it'll never get anywhere...

Ok, I tested it earlier on today and I ran into an oops & kernel panic. I
can read audio cd's just fine (using xmms, gtcd, whatever) for hours, but
whenever I try to rip anything using cdparanoia, it goes down south.

This is 2.4.21-pre2aa2 with some reiserfs fixes Hans posted on lkml a
while ago, mind you, and not vanilla 2.4.21-pre2. The patch applied
cleanly, though -- not even with offset. Its a run-of-the-mill 48x cdrom
(dont even know the brand), connected as slave on the primary IDE
channel, which is a PIIX4. Let me know if you need any other info!

So, here it is, your moment of zen ;)


Unable to handle kernel NULL pointer dereference at virtual address
00000014
c0190b2d
*pde = 00000000
Oops: 0000 2.4.21-pre2aa2 #1 Sun Jan 5 20:53:19 WET 2003
CPU: 0
EIP: 0010:[<c0190b2d>] Not tainted
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010046
eax: 00000004 ebx: 00000000 ecx: 0000f000 edx: c0293500
esi: c29457a4 edi: c2945800 ebp: 00000004 esp: c0229ec4
ds: 0018 es: 0018 ss: 0018
Process swapper (pid: 0, stackpage=c0229000)
Stack: c2945800 c02936f8 00000002 00000001 c2a4850c c2945800 00000001
c02936f8 c2945800 00000001 c02936f8 c02936f8 c2a488a4 c02936f8
00000001 c29458b8 00000930 00000001 c2a4981e c02936f8 00000001
c02936f8 c11f7160 00000286 Call Trace: [<c2a4850c>] [<c2a488a4>]
[<c2a4981e>] [<c0119ef8>] [<c019cbbf>]
[<c2a496f0>] [<c010843e>] [<c01085ae>] [<c0105220>] [<c010a7a8>]
[<c0105220>]
[<c0105243>] [<c0105287>] [<c0105000>] [<c0105019>]
Code: 8b 43 14 85 c0 7d 0c 0f 0b 54 01 20 b7 1f c0 8d 74 26 00 8b

>> EIP; c0190b2d <end_that_request_first+91/11c> <=====

>> edx; c0293500 <ide_hwifs+0/2be8>
>> esi; c29457a4 <[sb].data.end+53c1b1/63ea6d>
>> edi; c2945800 <[sb].data.end+53c20d/63ea6d>
>> esp; c0229ec4 <init_task_union+1ec4/2000>

Trace; c2a4850c <[ide-cd]ide_cdrom_end_request+58/a8>
Trace; c2a488a4 <[ide-cd]cdrom_end_request+58/60>
Trace; c2a4981e <[ide-cd]cdrom_pc_intr+12e/24c>
Trace; c0119ef8 <timer_bh+24/394>
Trace; c019cbbf <ide_intr+c3/110>
Trace; c2a496f0 <[ide-cd]cdrom_pc_intr+0/24c>
Trace; c010843e <handle_IRQ_event+32/5c>
Trace; c01085ae <do_IRQ+72/b4>
Trace; c0105220 <default_idle+0/28>
Trace; c010a7a8 <call_do_IRQ+5/d>
Trace; c0105220 <default_idle+0/28>
Trace; c0105243 <default_idle+23/28>
Trace; c0105287 <cpu_idle+1f/34>
Trace; c0105000 <_stext+0/0>
Trace; c0105019 <rest_init+19/1c>

Code; c0190b2d <end_that_request_first+91/11c>
00000000 <_EIP>:
Code; c0190b2d <end_that_request_first+91/11c> <=====
0: 8b 43 14 mov 0x14(%ebx),%eax <=====
Code; c0190b30 <end_that_request_first+94/11c>
3: 85 c0 test %eax,%eax
Code; c0190b32 <end_that_request_first+96/11c>
5: 7d 0c jge 13 <_EIP+0x13>
Code; c0190b34 <end_that_request_first+98/11c>
7: 0f 0b ud2a Code; c0190b36
<end_that_request_first+9a/11c>
9: 54 push %esp
Code; c0190b37 <end_that_request_first+9b/11c>
a: 01 20 add %esp,(%eax)
Code; c0190b39 <end_that_request_first+9d/11c>
c: b7 1f mov $0x1f,%bh
Code; c0190b3b <end_that_request_first+9f/11c>
e: c0 8d 74 26 00 8b 00 rorb $0x0,0x8b002674(%ebp)

Kernel panic: Aiee, killing interrupt handler!




--
Nuno

2003-01-05 23:46:09

by J.A. Magallon

[permalink] [raw]
Subject: Re: updated CDROMREADAUDIO DMA patch


On 2003.01.06 Nuno Monteiro wrote:
> [First of all, excuse me for breaking the thread, I had already deleted
> your original mail when I ran into this. Sorry for the inconvenience :)]
>
> On January 4th 2003 Andrew Morton wrote:
> > A refresh and retest of this patch, against 2.4.21-pre2. It would
> > be helpful if a few (or a lot of) people could test this, and report
> > on the result. Otherwise it'll never get anywhere...
>
> Ok, I tested it earlier on today and I ran into an oops & kernel panic. I
> can read audio cd's just fine (using xmms, gtcd, whatever) for hours, but
> whenever I try to rip anything using cdparanoia, it goes down south.
>
> This is 2.4.21-pre2aa2 with some reiserfs fixes Hans posted on lkml a
> while ago, mind you, and not vanilla 2.4.21-pre2. The patch applied
> cleanly, though -- not even with offset. Its a run-of-the-mill 48x cdrom
> (dont even know the brand), connected as slave on the primary IDE
> channel, which is a PIIX4. Let me know if you need any other info!
>

Just a me-too, but with the old version. If I try to rip anything with
grip (using cdda2wav as backend), the box just locks. No SysRq.
Curious: one other PIIX4.

Still have to try with this new version.

--
J.A. Magallon <[email protected]> \ Software is like sex:
werewolf.able.es \ It's better when it's free
Mandrake Linux release 9.1 (Cooker) for i586
Linux 2.4.21-pre2-jam2 (gcc 3.2.1 (Mandrake Linux 9.1 3.2.1-2mdk))

2003-01-12 23:11:04

by J.A. Magallon

[permalink] [raw]
Subject: Re: updated CDROMREADAUDIO DMA patch


On 2003.01.05 Andrew Morton wrote:
> A refresh and retest of this patch, against 2.4.21-pre2. It would
> be helpful if a few (or a lot of) people could test this, and report
> on the result. Otherwise it'll never get anywhere...
>
> Reading audio from IDE CDROMs always uses PIO. This patch teaches the kernel
> to use DMA for the CDROMREADAUDIO ioctl.
>

cdparanoia oopses on top of latest -aa:

Checking /dev/cdrom for cdrom...
Testing /dev/cdrom for cooked ioctl() interface
CDROM sensed: ATAPI compatible CREATIVE CD5230E
Verifying drive can read CDDA...
Unable to handle kernel NULL pointer dereference at virtual address 00000014
*pde = 00000000
...

Decoded oops:

ksymoops 2.4.8 on i686 2.4.21-pre3-jam1. Options used
-V (default)
-k /proc/ksyms (default)
-l /proc/modules (default)
-o /lib/modules/2.4.21-pre3-jam1/ (default)
-m /boot/System.map-2.4.21-pre3-jam1 (default)

Warning: You did not tell me where to find symbol information. I will
assume that the log matches the kernel and modules that are running
right now and I'll use the default options above for symbol resolution.
If the current kernel and/or modules do not match the log, you can get
more accurate output by telling me the kernel version and where to find
map, modules, ksyms etc. ksymoops -h explains the options.

Unable to handle kernel NULL pointer dereference at virtual address 00000014
*pde = 00000000
Oops: 0000 2.4.21-pre3-jam1 #1 SMP sab ene 11 01:11:42 CET 2003
CPU: 1
EIP: 0010:[<401c06c0>] Not tainted
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010046
eax: 00000001 ebx: 00000000 ecx: 00000001 edx: 40334600
esi: 47a016d0 edi: 47a01730 ebp: 00000004 esp: 419bbe98
ds: 0010 es: 0010 ss: 0018
Process swapper (pid: 0, stackpage=4199000)
Stack: 419cbfc8 402a2a14 00000001 419bbed0 00000002 47a01730 40334800 00000206
00000001 428105d5 47a01730 00000001 40334800 00000930 47a017ec 40334800
00000001 42811b96 40334800 00000001 00000000 419bbf00 00000003 ffffff80
Call Trace: [<428105d5>] [<42811b96>] [<401dd790>] [<401d6546>] [<42811ab0>]
[<40109520>] [<40109748>] [<40105340>] [<4010c2a8>] [<40105340>]
[<4010536c>] [<401053e2>] [<4011f845>] [<4011fab0>]
Code: 8b 43 14 85 c0 78 71 8b 46 2c 89 47 4c c7 46 2c 00 00 00 00


>>EIP; 401c06c0 <end_that_request_first+80/150> <=====

>>edx; 40334600 <ide_hwifs+0/2c88>
>>esp; 419bbe98 <_end+1681c9c/1cc9e64>

Trace; 428105d5 <[dmi_scan]dmi_ident+1f0f95/410a20>
Trace; 42811b96 <[dmi_scan]dmi_ident+1f2556/410a20>
Trace; 401dd790 <__ide_dma_test_irq+20/80>
Trace; 401d6546 <ide_intr+e6/180>
Trace; 42811ab0 <[dmi_scan]dmi_ident+1f2470/410a20>
Trace; 40109520 <handle_IRQ_event+70/b0>
Trace; 40109748 <do_IRQ+98/f0>
Trace; 40105340 <default_idle+0/50>
Trace; 4010c2a8 <call_do_IRQ+5/d>
Trace; 40105340 <default_idle+0/50>
Trace; 4010536c <default_idle+2c/50>
Trace; 401053e2 <cpu_idle+32/50>
Trace; 4011f845 <call_console_drivers+65/120>
Trace; 4011fab0 <printk+140/180>

Code; 401c06c0 <end_that_request_first+80/150>
00000000 <_EIP>:
Code; 401c06c0 <end_that_request_first+80/150> <=====
0: 8b 43 14 mov 0x14(%ebx),%eax <=====
Code; 401c06c3 <end_that_request_first+83/150>
3: 85 c0 test %eax,%eax
Code; 401c06c5 <end_that_request_first+85/150>
5: 78 71 js 78 <_EIP+0x78>
Code; 401c06c7 <end_that_request_first+87/150>
7: 8b 46 2c mov 0x2c(%esi),%eax
Code; 401c06ca <end_that_request_first+8a/150>
a: 89 47 4c mov %eax,0x4c(%edi)
Code; 401c06cd <end_that_request_first+8d/150>
d: c7 46 2c 00 00 00 00 movl $0x0,0x2c(%esi)


1 warning issued. Results may not be reliable.

--
J.A. Magallon <[email protected]> \ Software is like sex:
werewolf.able.es \ It's better when it's free
Mandrake Linux release 9.1 (Cooker) for i586
Linux 2.4.21-pre3-jam1 (gcc 3.2.1 (Mandrake Linux 9.1 3.2.1-2mdk))

2003-01-13 01:07:36

by Andrew Morton

[permalink] [raw]
Subject: Re: updated CDROMREADAUDIO DMA patch

On Sun January 12 2003 15:16, J.A. Magallon wrote:
>
> On 2003.01.05 Andrew Morton wrote:
> > A refresh and retest of this patch, against 2.4.21-pre2. It would
> > be helpful if a few (or a lot of) people could test this, and report
> > on the result. Otherwise it'll never get anywhere...
> >
> > Reading audio from IDE CDROMs always uses PIO. This patch teaches the kernel
> > to use DMA for the CDROMREADAUDIO ioctl.
> >
>
> cdparanoia oopses on top of latest -aa:
>
> Checking /dev/cdrom for cdrom...
> Testing /dev/cdrom for cooked ioctl() interface
> CDROM sensed: ATAPI compatible CREATIVE CD5230E
> Verifying drive can read CDDA...
> Unable to handle kernel NULL pointer dereference at virtual address 00000014

Yup, we seem to have a bit of a problem there. It works fine on the five
machines which I tried it on.

Oh well, thanks for testing. It's unlikely that I will do any further work
on this.