Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Jan 2009 14:17:13 +0300 (MSK)
From:      Eygene Ryabinkin <rea-fbsd@codelabs.ru>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/130735: [patch] pass M_NOWAIT to the malloc() call inside cdreaddvdstructure()
Message-ID:  <20090119111713.715D5DA81B@void.codelabs.ru>
Resent-Message-ID: <200901191120.n0JBK1jh074552@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan 19 11:20:01 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator:     Eygene Ryabinkin
>Release:        FreeBSD 7.1-STABLE amd64
>Organization:
Code Labs
>Environment:

System: FreeBSD 7.1-STABLE amd64

>Description:

cdreaddvdstructure() is called from cdioctl() with periph lock held
(sys/dev/cam/scsi/scsi_cd.c):
-----
	cam_periph_lock(periph);
	error = cdreaddvdstructure(periph, dvdstruct);
	cam_periph_unlock(periph);
-----
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 @
cam/cam_periph.h:182
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
-----

>How-To-Repeat:

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.

>Fix:

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@codelabs.ru>
Date: Sat, 17 Jan 2009 07:31:41 +0300

Signed-off-by: Eygene Ryabinkin <rea-fbsd@codelabs.ru>
---
 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;
 
-- 
1.6.0.5
--- scsi_cd-cdreaddvdstructure-use-M_NOWAIT.diff ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090119111713.715D5DA81B>