Subject: Re: buffer cache memory management revision
To: Simon Burge <simonb@wasabisystems.com>
From: Paul Kranenburg <pk@cs.few.eur.nl>
List: tech-kern
Date: 12/01/2003 08:24:54
> I had to remove the allocsys() calls from sbmips/sbmips/machdep.c to

Right, I missed that one.

> build for sbmips and then shift the results of buf_memcalc() by pagesize
> on the mips pmap Sysmapsize calculation (the sysmap size is in pages).
> I dunno if other archs (alpha, vax) need pages or bytes for their

The alpha pmap needs the same change, the vax's should be fine.
I've included an updated patch below.


> The resulting kernel works fine on sbmips and evbmips/walnut so far, but
> I haven't put it under too much load - just built a couple of packages.

Great.

> Oh, and "sysstat bufcache" will need updating :-)  I'll try to have
> a look at that if you don't.

Yes. I have a set of rough patches for that; it'll use `sysctl_dobuf()'
to fetch an array of buffers from the kernel.

-pk

--------
Index: arch/mips/mips/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/pmap.c,v
retrieving revision 1.153
diff -c -r1.153 pmap.c
*** arch/mips/mips/pmap.c	1 Nov 2003 14:48:16 -0000	1.153
--- arch/mips/mips/pmap.c	1 Dec 2003 07:20:06 -0000
***************
*** 308,315 ****
  	 * We also reserve space for kmem_alloc_pageable() for vm_fork().
  	 */
  	Sysmapsize = (VM_PHYS_SIZE + (ubc_nwins << ubc_winshift) +
! 		nbuf * MAXBSIZE + 16 * NCARGS + PAGER_MAP_SIZE) / NBPG +
! 		(maxproc * UPAGES) + nkmempages;
  
  #ifdef SYSVSHM
  	Sysmapsize += shminfo.shmall;
--- 308,315 ----
  	 * We also reserve space for kmem_alloc_pageable() for vm_fork().
  	 */
  	Sysmapsize = (VM_PHYS_SIZE + (ubc_nwins << ubc_winshift) +
! 		      buf_memcalc() + 16 * NCARGS + PAGER_MAP_SIZE) / NBPG +
! 		     (maxproc * UPAGES) + nkmempages;
  
  #ifdef SYSVSHM
  	Sysmapsize += shminfo.shmall;
Index: arch/alpha/alpha/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/alpha/pmap.c,v
retrieving revision 1.205
diff -c -r1.205 pmap.c
*** arch/alpha/alpha/pmap.c	29 Oct 2003 04:48:40 -0000	1.205
--- arch/alpha/alpha/pmap.c	1 Dec 2003 07:20:07 -0000
***************
*** 812,819 ****
  	 * kernel.  We also reserve space for kmem_alloc_pageable()
  	 * for vm_fork().
  	 */
! 	lev3mapsize = (VM_PHYS_SIZE + (ubc_nwins << ubc_winshift) +
! 		nbuf * MAXBSIZE + 16 * NCARGS + PAGER_MAP_SIZE) / PAGE_SIZE +
  		(maxproc * UPAGES) + nkmempages;
  
  #ifdef SYSVSHM
--- 812,820 ----
  	 * kernel.  We also reserve space for kmem_alloc_pageable()
  	 * for vm_fork().
  	 */
! 	lev3mapsize =
! 		(VM_PHYS_SIZE + (ubc_nwins << ubc_winshift) +
! 		 buf_memcalc() + 16 * NCARGS + PAGER_MAP_SIZE) / PAGE_SIZE +
  		(maxproc * UPAGES) + nkmempages;
  
  #ifdef SYSVSHM
Index: arch/sbmips/sbmips/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sbmips/sbmips/machdep.c,v
retrieving revision 1.22
diff -c -r1.22 machdep.c
*** arch/sbmips/sbmips/machdep.c	26 Sep 2003 16:00:28 -0000	1.22
--- arch/sbmips/sbmips/machdep.c	1 Dec 2003 07:20:07 -0000
***************
*** 162,170 ****
  void
  mach_init(long fwhandle, long magic, long bootdata, long reserved)
  {
! 	caddr_t kernend, v, p0;
  	u_long first, last;
- 	vsize_t size;
  	extern char edata[], end[];
  	int i;
  	uint32_t config;
--- 162,169 ----
  void
  mach_init(long fwhandle, long magic, long bootdata, long reserved)
  {
! 	caddr_t kernend, p0;
  	u_long first, last;
  	extern char edata[], end[];
  	int i;
  	uint32_t config;
***************
*** 331,347 ****
  	curpcb = &lwp0.l_addr->u_pcb;
  	curpcb->pcb_context[11] = MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */
  
- 	/*
- 	 * Allocate space for system data structures.  These data structures
- 	 * are allocated here instead of cpu_startup() because physical
- 	 * memory is directly addressable.  We don't have to map these into
- 	 * virtual address space.
- 	 */
- 	size = (vsize_t)allocsys(NULL, NULL);
- 	v = (caddr_t)pmap_steal_memory(size, NULL, NULL);
- 	if ((allocsys(v, NULL) - v) != size)
- 		panic("mach_init: table size inconsistency");
- 
  	pmap_bootstrap();
  
  	/*
--- 330,335 ----
***************
*** 365,373 ****
  void
  cpu_startup(void)
  {
- 	u_int i, base, residual;
  	vaddr_t minaddr, maxaddr;
- 	vsize_t size;
  	char pbuf[9];
  
  	/*
--- 353,359 ----
***************
*** 377,422 ****
  	format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
  	printf("%s memory", pbuf);
  
! 	/*
! 	 * Allocate virtual address space for file I/O buffers.
! 	 * Note they are different than the array of headers, 'buf',
! 	 * and usually occupy more virtual memory than physical.
! 	 */
! 	size = MAXBSIZE * nbuf;
! 	if (uvm_map(kernel_map, (vaddr_t *)(void *)&buffers, round_page(size),
! 		    NULL, UVM_UNKNOWN_OFFSET, 0,
! 		    UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE,
! 		    UVM_ADV_NORMAL, 0)) != 0)
! 		panic("startup: cannot allocate VM for buffers");
! 	minaddr = (vaddr_t)buffers;
! 	base = bufpages / nbuf;
! 	residual = bufpages % nbuf;
! 	for (i = 0; i < nbuf; i++) {
! 		vsize_t curbufsize;
! 		vaddr_t curbuf;
! 		struct vm_page *pg;
! 
! 		/*
! 		 * Each buffer has MAXBSIZE bytes of VM space allocated.  Of
! 		 * that MAXBSIZE space, we allocate and map (base+1) pages
! 		 * for the first "residual" buffers, and then we allocate
! 		 * "base" pages for the rest.
! 		 */
! 		curbuf = (vaddr_t) buffers + (i * MAXBSIZE);
! 		curbufsize = PAGE_SIZE * ((i < residual) ? (base + 1) : base);
! 
! 		while (curbufsize) {
! 			pg = uvm_pagealloc(NULL, 0, NULL, 0);
! 			if (pg == NULL)
! 				panic("cpu_startup: not enough memory for "
! 					"buffer cache");
! 			pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg),
! 			    VM_PROT_READ|VM_PROT_WRITE);
! 			curbuf += PAGE_SIZE;
! 			curbufsize -= PAGE_SIZE;
! 		}
! 	}
! 
  	/*
  	 * Allocate a submap for exec arguments.  This map effectively
  	 * limits the number of processes exec'ing at any time.
--- 363,369 ----
  	format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
  	printf("%s memory", pbuf);
  
! 	minaddr = 0;
  	/*
  	 * Allocate a submap for exec arguments.  This map effectively
  	 * limits the number of processes exec'ing at any time.
***************
*** 438,450 ****
  
  	format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free));
  	printf(", %s free", pbuf);
- 	format_bytes(pbuf, sizeof(pbuf), bufpages * PAGE_SIZE);
- 	printf(", %s in %u buffers\n", pbuf, nbuf);
- 
- 	/*
- 	 * Set up buffers, so they can be used to read disk labels.
- 	 */
- 	bufinit();
  }
  
  int	waittime = -1;
--- 385,390 ----