Subject: kern/3759: bdwrite() gets bp->b_dev == NODEV, causing 4x disk slowdown.
To: None <gnats-bugs@gnats.netbsd.org>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: netbsd-bugs
Date: 06/17/1997 20:12:40
>Number:         3759
>Category:       kern
>Synopsis:       bdwrite() gets bp->b_dev == NODEV, references off ebd of bdevsw
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jun 17 20:20:02 1997
>Last-Modified:
>Originator:     
>Organization:
	Stanford DSG
>Release:        NetBSD-current as at 1997-06-15
>Environment:
	
System: NetBSD Cup.DSG.Stanford.EDU 1.2F NetBSD 1.2F (PLACEBO) #5: Wed Jun 11 16:16:09 PDT 1997 jonathan@Cup.DSG.Stanford.EDU:/usr/src/sys/arch/i386/compile/PLACEBO i386

Appears on NetBSD 1.2F on a pmax and amiga
(disregard line above).



>Description:

[[ Information below  due to Michael L. Hitch, mhitch@netbsd.org]]

Disk throughput (as reported by iostat and bonnie) is reduced by a
factor of 4 when DEBUG is not defined.

This is due to bdwrite() being called with a buffer where
bp->b_dev == NODEV.  bdwrite() tests for tape devices, and 
issues  bawrite() instead.

The bogus b_dev value of NODEV causes bdwrite() to reference junk
instead of a valid bdevsw entry.  On pmaxes, this junk often ends up
being framebuffer font data, which if interpreted as a bdevsw entry,
has the D_TAPE bit set.  This causes bdwrite() to issue bawrite()
instead, causing multiple writes to disk as the buffer fills, and a
factor of *FOUR* decrease in disk throughput.



>How-To-Repeat:

	Run bonnie, with  a patch in bdwrite() to look for
	bp->b_dev == NODEV.

>Fix:

	Fix the buffer code to set bp->dev properly.

	Defensive programming: maybe add an #ifdef DEBUG rangecheck
	to bdwrite(), and elsewhere in vfs_bio.c?
>Audit-Trail:
>Unformatted: