From owner-cvs-all Wed Dec 16 10:00:41 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id KAA18183 for cvs-all-outgoing; Wed, 16 Dec 1998 10:00:41 -0800 (PST) (envelope-from owner-cvs-all@FreeBSD.ORG) Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id KAA18178; Wed, 16 Dec 1998 10:00:39 -0800 (PST) (envelope-from ken@FreeBSD.org) From: Kenneth Merry Received: (from ken@localhost) by freefall.freebsd.org (8.8.8/8.8.5) id KAA28535; Wed, 16 Dec 1998 10:00:40 -0800 (PST) Date: Wed, 16 Dec 1998 10:00:40 -0800 (PST) Message-Id: <199812161800.KAA28535@freefall.freebsd.org> To: cvs-committers@FreeBSD.ORG, cvs-all@FreeBSD.ORG Subject: cvs commit: src/sys/cam cam_periph.c Sender: owner-cvs-all@FreeBSD.ORG Precedence: bulk ken 1998/12/16 10:00:40 PST Modified files: sys/cam cam_periph.c Log: Probable fix for the "cdda2wav" panics that various people have been reporting since this past summer. (I think Daniel O'Conner was the first.) The problem appears to have been something like this: - cdda2wav by default passes in a buffer that is close to the 128K MAXPHYS limit. - many times, the buffer is not page aligned - vmapbuf() truncates the address, so that it is page aligned - that causes the total size of the buffer to be greater than MAXPHYS, which of course is a bad thing. Here's a quote from the PR (kern/9067): ================== In particular, note bp->b_bufsize = 0x0001f950 and bp->b_data = 0xf2219960 (which does not start on a page boundary). vunmapbuf() loops through all the pages without any difficulty until addr reaches 0xf2239000, and then the panic occurs. This seems to indicate that we are exceeding MAXPHYS since we actually started from the middle of a page (the data is being transfered to a non page aligned location). To complete the description, note that the system call originates from ReadCddaMMC12() (in scsi_cmds.c of cdda2wav) with a request to read 55 audio sectors of 2352 bytes (which is calculated to fall under MAXPHYS). This in turn ends up calling scsi_send() (in scsi-bsd.c) which calls cam_fill_csio() and cam_send_ccb(). This results in a CAMIOCOMMAND ioctl with a ccb function code of XPT_SCSI_IO. ================== The fix is to change the size check in cam_periph_mapmem() so that it is like the one in minphys(). In particular, it is something like: if ((buffer_length + (buf_ptr & PAGE_MASK)) > MAXPHYS) buffer is too big My fix is based on the one in the PR, but I cleaned up a fair number of things in cam_periph_mapmem(). The checks for each buffer to be mapped are now in a separate loop from the actual mapping operation. With the new arrangement, we don't have to bother with unmapping any previously mapped buffers if one of the checks fails. Many thanks to James Liu for tracking this down. I'd appreciate it if some vm-savvy folks would look this over. I believe this fix is correct, but I could be wrong. PR: kern/9067 (also, kern/8112) Reviewed by: gibbs Submitted by: "James T. Liu" Revision Changes Path 1.7 +39 -47 src/sys/cam/cam_periph.c To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe cvs-all" in the body of the message