From owner-freebsd-smp Tue Aug 21 10:37:54 2001 Delivered-To: freebsd-smp@freebsd.org Received: from earth.backplane.com (earth-nat-cw.backplane.com [208.161.114.67]) by hub.freebsd.org (Postfix) with ESMTP id D071937B401; Tue, 21 Aug 2001 10:36:52 -0700 (PDT) (envelope-from dillon@earth.backplane.com) Received: (from dillon@localhost) by earth.backplane.com (8.11.4/8.11.2) id f7LHaoC64628; Tue, 21 Aug 2001 10:36:50 -0700 (PDT) (envelope-from dillon) Date: Tue, 21 Aug 2001 10:36:50 -0700 (PDT) From: Matt Dillon Message-Id: <200108211736.f7LHaoC64628@earth.backplane.com> To: Jake Burkholder Cc: John Baldwin , freebsd-smp@FreeBSD.ORG, freebsd-alpha@FreeBSD.ORG Subject: Re: Preliminary proposed rollup of kernel submap initialization code References: <200108210157.f7L1vAh10384@k7.locore.ca> Sender: owner-freebsd-smp@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org :Yay! I was just about to do almost exactly the same thing! : :Looks ok to me. I'll take care of the sparc64 changes. : :You might want to move some of the callout initialization to :kern_timeout.c. Ok, here is an adjusted patch. This compiles clean (for i386 anyway), but has NOT been tested yet. Specifically, I rearranged the caddr_t v address manipulation a bit. I'll be able to test and commit it to -current this evening. -Matt Index: alpha/alpha/machdep.c =================================================================== RCS file: /home/ncvs/src/sys/alpha/alpha/machdep.c,v retrieving revision 1.138 diff -u -r1.138 machdep.c --- alpha/alpha/machdep.c 2001/08/13 22:41:14 1.138 +++ alpha/alpha/machdep.c 2001/08/20 23:39:42 @@ -228,9 +228,7 @@ static void identifycpu __P((void)); -static vm_offset_t buffer_sva, buffer_eva; -vm_offset_t clean_sva, clean_eva; -static vm_offset_t pager_sva, pager_eva; +struct kva_md_info kmi; /* * Hooked into the shutdown chain; if the system is to be halted, @@ -248,13 +246,6 @@ cpu_startup(dummy) void *dummy; { - register unsigned i; - register caddr_t v; - vm_offset_t maxaddr; - vm_size_t size = 0; - vm_offset_t firstaddr; - vm_offset_t minaddr; - /* * Good {morning,afternoon,evening,night}. */ @@ -281,6 +272,9 @@ } } + vm_ksubmap_init(&kmi); + +#if 0 /* * Calculate callout wheel size */ @@ -387,6 +381,7 @@ } mtx_init(&callout_lock, "callout", MTX_SPIN | MTX_RECURSE); +#endif #if defined(USERCONFIG) #if defined(USERCONFIG_BOOT) Index: alpha/alpha/pmap.c =================================================================== RCS file: /home/ncvs/src/sys/alpha/alpha/pmap.c,v retrieving revision 1.62 diff -u -r1.62 pmap.c --- alpha/alpha/pmap.c 2001/07/27 01:08:59 1.62 +++ alpha/alpha/pmap.c 2001/08/20 23:23:56 @@ -774,7 +774,7 @@ static PMAP_INLINE int pmap_track_modified(vm_offset_t va) { - if ((va < clean_sva) || (va >= clean_eva)) + if ((va < kmi.clean_sva) || (va >= kmi.clean_eva)) return 1; else return 0; Index: i386/i386/machdep.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/machdep.c,v retrieving revision 1.472 diff -u -r1.472 machdep.c --- i386/i386/machdep.c 2001/08/21 07:20:06 1.472 +++ i386/i386/machdep.c 2001/08/21 07:21:52 @@ -198,9 +198,8 @@ /* must be 2 less so 0 0 can signal end of chunks */ #define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2) -static vm_offset_t buffer_sva, buffer_eva; -vm_offset_t clean_sva, clean_eva; -static vm_offset_t pager_sva, pager_eva; +struct kva_md_info kmi; + static struct trapframe proc0_tf; #ifndef SMP static struct globaldata __globaldata; @@ -213,14 +212,6 @@ cpu_startup(dummy) void *dummy; { - register unsigned i; - register caddr_t v; - vm_offset_t maxaddr; - vm_size_t size = 0; - int firstaddr; - vm_offset_t minaddr; - int physmem_est; /* in pages */ - /* * Good {morning,afternoon,evening,night}. */ @@ -250,6 +241,9 @@ } } + vm_ksubmap_init(&kmi); + +#if 0 /* * Calculate callout wheel size */ @@ -387,6 +381,7 @@ } mtx_init(&callout_lock, "callout", MTX_SPIN | MTX_RECURSE); +#endif #if defined(USERCONFIG) userconfig(); Index: i386/i386/pmap.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/pmap.c,v retrieving revision 1.284 diff -u -r1.284 pmap.c --- i386/i386/pmap.c 2001/07/27 01:08:59 1.284 +++ i386/i386/pmap.c 2001/08/20 23:10:49 @@ -546,7 +546,7 @@ static PMAP_INLINE int pmap_track_modified(vm_offset_t va) { - if ((va < clean_sva) || (va >= clean_eva)) + if ((va < kmi.clean_sva) || (va >= kmi.clean_eva)) return 1; else return 0; Index: kern/kern_timeout.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_timeout.c,v retrieving revision 1.69 diff -u -r1.69 kern_timeout.c --- kern/kern_timeout.c 2001/08/10 21:06:59 1.69 +++ kern/kern_timeout.c 2001/08/21 17:10:20 @@ -62,6 +62,55 @@ static struct callout *nextsoftcheck; /* Next callout to be checked. */ /* + * kern_timeout_callwheel_alloc() - kernel low level callwheel initialization + * + * This code is called very early in the kernel initialization sequence, + * and may be called more then once. + */ +caddr_t +kern_timeout_callwheel_alloc(caddr_t v) +{ + /* + * Calculate callout wheel size + */ + for (callwheelsize = 1, callwheelbits = 0; + callwheelsize < ncallout; + callwheelsize <<= 1, ++callwheelbits) + ; + callwheelmask = callwheelsize - 1; + + callout = (struct callout *)v; + v = (caddr_t)(callout + ncallout); + callwheel = (struct callout_tailq *)v; + v = (caddr_t)(callwheel + callwheelsize); + return(v); +} + +/* + * kern_timeout_callwheel_init() - initialize previously reserved callwheel + * space. + * + * This code is called just once, after the space reserved for the + * callout wheel has been finalized. + */ +void +kern_timeout_callwheel_init(void) +{ + int i; + + SLIST_INIT(&callfree); + for (i = 0; i < ncallout; i++) { + callout_init(&callout[i], 0); + callout[i].c_flags = CALLOUT_LOCAL_ALLOC; + SLIST_INSERT_HEAD(&callfree, &callout[i], c_links.sle); + } + for (i = 0; i < callwheelsize; i++) { + TAILQ_INIT(&callwheel[i]); + } + mtx_init(&callout_lock, "callout", MTX_SPIN | MTX_RECURSE); +} + +/* * The callout mechanism is based on the work of Adam M. Costello and * George Varghese, published in a technical report entitled "Redesigning * the BSD Callout and Timer Facilities" and modified slightly for inclusion Index: kern/vfs_bio.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_bio.c,v retrieving revision 1.285 diff -u -r1.285 vfs_bio.c --- kern/vfs_bio.c 2001/07/27 15:57:17 1.285 +++ kern/vfs_bio.c 2001/08/21 17:26:53 @@ -319,19 +319,73 @@ } /* - * Initialize buffer headers and related structures. + * Calculating buffer cache scaling values and reserve space for buffer + * headers. This is called during low level kernel initialization and + * may be called more then once. We CANNOT write to the memory area + * being reserved at this time. */ - caddr_t -bufhashinit(caddr_t vaddr) +kern_vfs_bio_buffer_alloc(caddr_t v, int physmem_est) { - /* first, make a null hash table */ + /* + * The nominal buffer size (and minimum KVA allocation) is BKVASIZE. + * For the first 64MB of ram nominally allocate sufficient buffers to + * cover 1/4 of our ram. Beyond the first 64MB allocate additional + * buffers to cover 1/20 of our ram over 64MB. When auto-sizing + * the buffer cache we limit the eventual kva reservation to + * maxbcache bytes. + * + * factor represents the 1/4 x ram conversion. + */ + if (nbuf == 0) { + int factor = 4 * BKVASIZE / PAGE_SIZE; + + nbuf = 50; + if (physmem_est > 1024) + nbuf += min((physmem_est - 1024) / factor, + 16384 / factor); + if (physmem_est > 16384) + nbuf += (physmem_est - 16384) * 2 / (factor * 5); + + if (maxbcache && nbuf > maxbcache / BKVASIZE) + nbuf = maxbcache / BKVASIZE; + } + + /* + * Do not allow the buffer_map to be more then 1/2 the size of the + * kernel_map. + */ + if (nbuf > (kernel_map->max_offset - kernel_map->min_offset) / + (BKVASIZE * 2)) { + nbuf = (kernel_map->max_offset - kernel_map->min_offset) / + (BKVASIZE * 2); + printf("Warning: nbufs capped at %d\n", nbuf); + } + + /* + * swbufs are used as temporary holders for I/O, such as paging I/O. + * We have no less then 16 and no more then 256. + */ + nswbuf = max(min(nbuf/4, 256), 16); + + /* + * Reserve space for the buffer cache buffers + */ + swbuf = (void *)v; + v = (caddr_t)(swbuf + nswbuf); + buf = (void *)v; + v = (caddr_t)(buf + nbuf); + + /* + * Calculate the hash table size and reserve space + */ for (bufhashmask = 8; bufhashmask < nbuf / 4; bufhashmask <<= 1) ; - bufhashtbl = (void *)vaddr; - vaddr = vaddr + sizeof(*bufhashtbl) * bufhashmask; + bufhashtbl = (void *)v; + v = (caddr_t)(bufhashtbl + bufhashmask); --bufhashmask; - return(vaddr); + + return(v); } void Index: sys/buf.h =================================================================== RCS file: /home/ncvs/src/sys/sys/buf.h,v retrieving revision 1.119 diff -u -r1.119 buf.h --- sys/buf.h 2001/08/20 00:41:12 1.119 +++ sys/buf.h 2001/08/21 17:25:30 @@ -513,7 +513,7 @@ struct uio; -caddr_t bufhashinit __P((caddr_t)); +caddr_t kern_vfs_bio_buffer_alloc __P((caddr_t v, int physmem_est)); void bufinit __P((void)); void bwillwrite __P((void)); int buf_dirty_count_severe __P((void)); Index: sys/systm.h =================================================================== RCS file: /home/ncvs/src/sys/sys/systm.h,v retrieving revision 1.148 diff -u -r1.148 systm.h --- sys/systm.h 2001/08/10 06:37:04 1.148 +++ sys/systm.h 2001/08/21 17:25:20 @@ -208,6 +208,8 @@ void callout_handle_init __P((struct callout_handle *)); struct callout_handle timeout __P((timeout_t *, void *, int)); void untimeout __P((timeout_t *, void *, struct callout_handle)); +caddr_t kern_timeout_callwheel_alloc __P((caddr_t v)); +void kern_timeout_callwheel_init __P((void)); /* Stubs for obsolete functions that used to be for interrupt management */ static __inline void spl0(void) { return; } Index: vm/vm.h =================================================================== RCS file: /home/ncvs/src/sys/vm/vm.h,v retrieving revision 1.18 diff -u -r1.18 vm.h --- vm/vm.h 2001/07/04 16:20:27 1.18 +++ vm/vm.h 2001/08/20 23:35:44 @@ -113,4 +113,21 @@ typedef struct vm_page *vm_page_t; #endif +/* + * Information passed from the machine-independant VM initialization code + * for use by machine-dependant code (mainly for MMU support) + */ +struct kva_md_info { + vm_offset_t buffer_sva; + vm_offset_t buffer_eva; + vm_offset_t clean_sva; + vm_offset_t clean_eva; + vm_offset_t pager_sva; + vm_offset_t pager_eva; +}; + +extern struct kva_md_info kmi; +extern void vm_ksubmap_init(struct kva_md_info *kmi); + #endif /* VM_H */ + Index: vm/vm_init.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_init.c,v retrieving revision 1.28 diff -u -r1.28 vm_init.c --- vm/vm_init.c 2001/07/04 16:20:27 1.28 +++ vm/vm_init.c 2001/08/21 17:33:48 @@ -74,8 +74,12 @@ #include #include #include +#include +#include #include +#include +#include #include #include #include @@ -119,3 +123,88 @@ pmap_init(avail_start, avail_end); vm_pager_init(); } + +void +vm_ksubmap_init(struct kva_md_info *kmi) +{ + vm_offset_t firstaddr; + caddr_t v; + vm_size_t size = 0; + int physmem_est; + vm_offset_t minaddr; + vm_offset_t maxaddr; + + /* + * Allocate space for system data structures. + * The first available kernel virtual address is in "v". + * As pages of kernel virtual memory are allocated, "v" is incremented. + * As pages of memory are allocated and cleared, + * "firstaddr" is incremented. + * An index into the kernel page table corresponding to the + * virtual memory address maintained in "v" is kept in "mapaddr". + */ + + /* + * Make two passes. The first pass calculates how much memory is + * needed and allocates it. The second pass assigns virtual + * addresses to the various data structures. + */ + firstaddr = 0; +again: + v = (caddr_t)firstaddr; + + v = kern_timeout_callwheel_alloc(v); + + /* + * Discount the physical memory larger than the size of kernel_map + * to avoid eating up all of KVA space. + */ + if (kernel_map->first_free == NULL) { + printf("Warning: no free entries in kernel_map.\n"); + physmem_est = physmem; + } else { + physmem_est = min(physmem, btoc(kernel_map->max_offset - + kernel_map->min_offset)); + } + + v = kern_vfs_bio_buffer_alloc(v, physmem_est); + + /* + * End of first pass, size has been calculated so allocate memory + */ + if (firstaddr == 0) { + size = (vm_size_t)((char *)v - firstaddr); + firstaddr = kmem_alloc(kernel_map, round_page(size)); + if (firstaddr == 0) + panic("startup: no room for tables"); + goto again; + } + + /* + * End of second pass, addresses have been assigned + */ + if ((vm_size_t)((char *)v - firstaddr) != size) + panic("startup: table size inconsistency"); + + clean_map = kmem_suballoc(kernel_map, &kmi->clean_sva, &kmi->clean_eva, + (nbuf*BKVASIZE) + (nswbuf*MAXPHYS) + pager_map_size); + buffer_map = kmem_suballoc(clean_map, &kmi->buffer_sva, + &kmi->buffer_eva, (nbuf*BKVASIZE)); + buffer_map->system_map = 1; + pager_map = kmem_suballoc(clean_map, &kmi->pager_sva, &kmi->pager_eva, + (nswbuf*MAXPHYS) + pager_map_size); + pager_map->system_map = 1; + exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, + (16*(ARG_MAX+(PAGE_SIZE*3)))); + + /* + * XXX: Mbuf system machine-specific initializations should + * go here, if anywhere. + */ + + /* + * Initialize the callouts we just allocated. + */ + kern_timeout_callwheel_init(); +} + To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-smp" in the body of the message