Subject: kern/14781: genfs_getpages reads-ahead too many pages on small pagesize system
To: None <gnats-bugs@gnats.netbsd.org>
From: None <fredette@netbsd.org>
List: netbsd-bugs
Date: 11/29/2001 21:48:00
>Number: 14781
>Category: kern
>Synopsis: genfs_getpages reads-ahead too many pages on small pagesize system
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Nov 29 18:49:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator: Matthew Fredette
>Release: NetBSD-current updated 20011128
>Organization:
Self
>Environment:
System: NetBSD still-remains.home 1.5Y NetBSD 1.5Y (FOURMEG) #1: Thu Nov 29 21:01:07 EST 2001 root@the-gates-of-delirium.home:/data/union-sun2-elf/src/sys/arch/sun2/compile/FOURMEG sun2
>Description:
genfs_getpages reads-ahead 64k at a time, i.e., 1 << (16 - PAGE_SHIFT)
pages. See genfs_vnops.c revision 1.40, line 852.
On a system where PAGE_SHIFT is 11, this means 32 pages. This
eventually causes the panic "too many pages" in a recursive call
to the same function, which has a limit of 16 pages. The panic
is at line 479 of the same file.
>How-To-Repeat:
Inspection.
>Fix:
I was able to work around the problem with the following patch,
which reads-ahead at most 16 pages at a time:
[snip]
Index: genfs_vnops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/genfs/genfs_vnops.c,v
retrieving revision 1.40
diff -u -r1.40 genfs_vnops.c
--- genfs_vnops.c 2001/11/10 13:33:41 1.40
+++ genfs_vnops.c 2001/11/30 02:40:56
@@ -851,15 +851,19 @@
raout:
if (!error && !async && !write && ((int)raoffset & 0xffff) == 0 &&
PAGE_SHIFT <= 16) {
+ off_t rasize;
int racount;
- racount = 1 << (16 - PAGE_SHIFT);
+ /* XXXUBC temp limit, from above */
+ racount = MIN(1 << (16 - PAGE_SHIFT), 16);
+ rasize = racount << PAGE_SHIFT;
(void) VOP_GETPAGES(vp, raoffset, NULL, &racount, 0,
VM_PROT_READ, 0, 0);
simple_lock(&uobj->vmobjlock);
- racount = 1 << (16 - PAGE_SHIFT);
- (void) VOP_GETPAGES(vp, raoffset + 0x10000, NULL, &racount, 0,
+ /* XXXUBC temp limit, from above */
+ racount = MIN(1 << (16 - PAGE_SHIFT), 16);
+ (void) VOP_GETPAGES(vp, raoffset + rasize, NULL, &racount, 0,
VM_PROT_READ, 0, 0);
simple_lock(&uobj->vmobjlock);
}
[snip]
>Release-Note:
>Audit-Trail:
>Unformatted: