A few weeks ago I reported that bufinit() on sparc64 machines with >12GB of RAM goes into an infinite loop because of a 32-bit integer counter overflowing. On 5.x it was possible to work around this with the kern.maxbcache tunable, but this didn't work on 6.0 or above. It turns out the problem began here: ---- Revision 1.67 / (download) - annotate - [select for diffs], Mon Nov 8 18:20:02 2004 UTC (11 months ago) by des Branch: MAIN Changes since 1.66: +17 -17 lines Diff to previous 1.66 (colored) #include <vm/vm_param.h> instead of <machine/vmparam.h> (the former includes the latter, but also declares variables which are defined in kern/subr_param.c). Change som VM parameters from quad_t to unsigned long. They refer to quantities (size limits for text, heap and stack segments) which must necessarily be smaller than the size of the address space, so long is adequate on all platforms. MFC after: 1 week ---- which contained: -int maxswzone; /* max swmeta KVA storage */ -int maxbcache; /* max buffer cache KVA storage */ +long maxswzone; /* max swmeta KVA storage */ +long maxbcache; /* max buffer cache KVA storage */ However, des forgot to change the other definition of maxbcache in <sys/buf.h>: extern int maxbcache; /* Max KVA for buffer cache */ In fact, it's a good thing he didn't. On sparc64 if you make that variable a long it causes 32-bit integer overflows elsewhere, which lead to severe filesystem damage on systems with >12GB RAM. With the above bug this is reduced to a hang at boot. The hang is because maxbcache is not capped to a maximum value on sparc64, and a loop termination condition never occurs because of a 32-bit integer overflow. On amd64 it's capped to /* * Ceiling on size of buffer cache (really only effects write queueing, * the VM page cache is not effected), can be changed via * the kern.maxbcache /boot/loader.conf variable. */ #ifndef VM_BCACHE_SIZE_MAX #define VM_BCACHE_SIZE_MAX (400 * 1024 * 1024) #endif so large-memory amd64 systems never see it. ia64 and ppc would also hang at boot with >12GB, I think. On 5.x, the same hang exists, but you can work around it with the tunable. This tunable was broken by the long/int mismatch on 6.0, so sparc64 systems with >12GB were unusable. This patch reverts the above int->long change, and adds definitions for VM_BCACHE_SIZE_MAX and VM_SWZONE_SIZE_MAX on sparc64 copied from amd64. Actually, they should probably be added on other architectures too (ia64, ppc). Can someone please review? Kris Index: kern/subr_param.c =================================================================== RCS file: /home/ncvs/src/sys/kern/subr_param.c,v retrieving revision 1.71 diff -u -r1.71 subr_param.c --- kern/subr_param.c 16 Apr 2005 15:07:41 -0000 1.71 +++ kern/subr_param.c 11 Oct 2005 21:09:01 -0000 _at__at_ -75,8 +75,8 _at__at_ int ncallout; /* maximum # of timer events */ int nbuf; int nswbuf; -long maxswzone; /* max swmeta KVA storage */ -long maxbcache; /* max buffer cache KVA storage */ +int maxswzone; /* max swmeta KVA storage */ +int maxbcache; /* max buffer cache KVA storage */ int maxpipekva; /* Limit on pipe KVA */ u_long maxtsiz; /* max text size */ u_long dfldsiz; /* initial data size limit */ _at__at_ -106,11 +106,11 _at__at_ #ifdef VM_SWZONE_SIZE_MAX maxswzone = VM_SWZONE_SIZE_MAX; #endif - TUNABLE_LONG_FETCH("kern.maxswzone", &maxswzone); + TUNABLE_INT_FETCH("kern.maxswzone", &maxswzone); #ifdef VM_BCACHE_SIZE_MAX maxbcache = VM_BCACHE_SIZE_MAX; #endif - TUNABLE_LONG_FETCH("kern.maxbcache", &maxbcache); + TUNABLE_INT_FETCH("kern.maxbcache", &maxbcache); maxtsiz = MAXTSIZ; TUNABLE_ULONG_FETCH("kern.maxtsiz", &maxtsiz); Index: sparc64/include/param.h =================================================================== RCS file: /home/ncvs/src/sys/sparc64/include/param.h,v retrieving revision 1.19 diff -u -r1.19 param.h --- sparc64/include/param.h 20 Nov 2004 02:29:50 -0000 1.19 +++ sparc64/include/param.h 11 Oct 2005 20:54:30 -0000 _at__at_ -110,6 +110,22 _at__at_ #define KSTACK_GUARD_PAGES 1 /* pages of kstack guard; 0 disables */ #define PCPU_PAGES 1 +/* + * Ceiling on amount of swblock kva space, can be changed via + * the kern.maxswzone /boot/loader.conf variable. + */ +#ifndef VM_SWZONE_SIZE_MAX +#define VM_SWZONE_SIZE_MAX (32 * 1024 * 1024) +#endif + +/* + * Ceiling on size of buffer cache (really only effects write queueing, + * the VM page cache is not effected), can be changed via + * the kern.maxbcache /boot/loader.conf variable. + */ +#ifndef VM_BCACHE_SIZE_MAX +#define VM_BCACHE_SIZE_MAX (400 * 1024 * 1024) +#endif /* * Mach derived conversion macros Index: sparc64/include/vmparam.h =================================================================== RCS file: /home/ncvs/src/sys/sparc64/include/vmparam.h,v retrieving revision 1.14 diff -u -r1.14 vmparam.h --- sparc64/include/vmparam.h 27 Dec 2002 19:31:26 -0000 1.14 +++ sparc64/include/vmparam.h 11 Oct 2005 20:54:30 -0000 _at__at_ -171,6 +171,13 _at__at_ #endif /* + * Ceiling on amount of kmem_map kva space. + */ +#ifndef VM_KMEM_SIZE_MAX +#define VM_KMEM_SIZE_MAX (400 * 1024 * 1024) +#endif + +/* * Initial pagein size of beginning of executable file. */ #ifndef VM_INITIAL_PAGEIN
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:45 UTC