kern/130735: [patch] pass M_NOWAIT to the malloc() call inside cdreaddvdstructure()

Eygene Ryabinkin rea-fbsd at
Mon Jan 19 03:20:30 PST 2009

>Number:         130735
>Category:       kern
>Synopsis:       [patch] pass M_NOWAIT to the malloc() call inside cdreaddvdstructure()
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan 19 11:20:01 UTC 2009
>Originator:     Eygene Ryabinkin
>Release:        FreeBSD 7.1-STABLE amd64
Code Labs

System: FreeBSD 7.1-STABLE amd64


cdreaddvdstructure() is called from cdioctl() with periph lock held
	error = cdreaddvdstructure(periph, dvdstruct);
but malloc() inside cdreaddvdstructure() uses M_WAITOK.

The following diagnostics is thrown with WITNESS enabled:
uma_zalloc_arg: zone "16" with the following non-sleepable locks held:
exclusive sleep mutex ATAPICAM lock r = 0 (0xffffff000475a2a8) locked @
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0x2a
witness_warn() at witness_warn+0x23a
uma_zalloc_arg() at uma_zalloc_arg+0x338
malloc() at malloc+0x80
cdioctl() at cdioctl+0x13c3
g_disk_ioctl() at g_disk_ioctl+0x4c
g_dev_ioctl() at g_dev_ioctl+0x83
devfs_ioctl_f() at devfs_ioctl_f+0x71
kern_ioctl() at kern_ioctl+0x91
ioctl() at ioctl+0xe8
syscall() at syscall+0x1ce
Xfast_syscall() at Xfast_syscall+0xab
--- syscall (54, FreeBSD ELF64, ioctl), rip = 0x801c2b27c, rsp =
0x7fffffffa268, rbp = 0x8072e7800 ---
acd0: FAILURE - READ_BIG timed out


Try to play scratchy DVD/CD disk that will cause read timeouts.  WITNESS
will complain, if it is enabled.  System could hang after some timeouts.
Or may be it won't hang -- it depends on the actual thread layout.

I am using atapicam emulation layer, but this should be also reproducible
with native SCSI CD/DVD devices.


The following simple patch works for me.  I am living with it for around
a week and tried to play many scratchy disks -- no errors or hangups,
just 'acd0: FAILURE - READ_BIG timed out' messages, but this is expected.

--- scsi_cd-cdreaddvdstructure-use-M_NOWAIT.diff begins here ---
>From 42386566b7816a95a7245df0163d8049d9d59376 Mon Sep 17 00:00:00 2001
From: Eygene Ryabinkin <rea-fbsd at>
Date: Sat, 17 Jan 2009 07:31:41 +0300

Signed-off-by: Eygene Ryabinkin <rea-fbsd at>
 sys/cam/scsi/scsi_cd.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
index f97ed41..f084cae 100644
--- a/sys/cam/scsi/scsi_cd.c
+++ b/sys/cam/scsi/scsi_cd.c
@@ -4063,7 +4063,7 @@ cdreaddvdstructure(struct cam_periph *periph, struct dvd_struct *dvdstruct)
 	if (length != 0) {
-		databuf = malloc(length, M_DEVBUF, M_WAITOK | M_ZERO);
+		databuf = malloc(length, M_DEVBUF, M_NOWAIT | M_ZERO);
 	} else
 		databuf = NULL;
--- scsi_cd-cdreaddvdstructure-use-M_NOWAIT.diff ends here ---

More information about the freebsd-bugs mailing list