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: