Subject: Re: Semi(?)-success with an SMP kernel
To: None <tech-kern@netbsd.org>
From: Simon Burge <simonb@wasabisystems.com>
List: tech-kern
Date: 09/28/2000 13:38:37
Simon Burge wrote:

> [ moved to tech-kern for sysctl vm.uvmexp failure ]
> 
> Bill Sommerfeld wrote:
> 
> > James Sharp wrote:
> >
> > > I tried getting top to run to show me what processes were running, but
> > > I get a "sysctl vm.uvmexp failed: Cannot allocate memory" message...i
> > > havent' really chased that down much.  Lack of sleep is catching up
> > > with me.
> > 
> > Someone resized "struct uvmexp" by adding a new counter to the middle,
> > which broke backwards-compat with the 1.5 version of "top"; you need
> > to rebuild top against the -current system headers.
> 
> My first thought was to suggest a struct uvmexp2 with fixed sized
> fields, which is still probably something we want to do.
> 
> But for the simple case here, I think the problem here is that sysctl
> is failing because top is requesting N bytes of data (the size of the
> uvmexp struct in 1.5), and the structure is now N + M bytes long.  Also,
> the data that top is looking for hasn't moved with the new additions.
> So, how about we put a comment in struct uvmexp2 just after "int wired;"
> saying "put nothing above here - it will break binary compat with 1.5",
> and change the sysctl so that it doesn't fail if there is a short data
> request?

With the trailing patch, on NetBSD/alpha I can run a 1.5_ALPHA2 top on a
1.5F machine.

A couple of things here -

 + Should we add another sysctl_rdstruct()-type function (maybe
   sysctl_rdminstruct()?) that would only return min(data_size,
   request_size) so min() isn't used in lots of places and it's
   obvious which sysctls may return short data.  This can also
   be worked around in userland by saying something like (error
   checking deleted):

	sysctl(mib, N, NULL, &size, NULL, 0);
	size = max(size, sizeof(data));
	tmpdata = malloc(size);
	sysctl(mib, N, tmpdata, &size, NULL, 0);
	memcpy(&data, tmpdata, sizeof(data));
	free(tmpdata);
   
   but this is not pretty...

 + All the fields in uvmexp are "int".  Is this big enough?  Sure MAXINT
   pages on a box is a _big_ number, but Compaq have a box that can
   handle 256GB of RAM - that's 2^25 pages already...

 + Everything in uvmexp is nicely grouped together - I'd still like to
   make a struct uvmexp2 with fixed size fields and the same rules as
   struct kinfo_proc2 where new fields can only be added to the end.

 + I had a desire that at least ps, top and w from a 1.5 box should
   work on every future version of NetBSD - for this to work there's
   a couple of things that need handling:

    + we either need a struct uvmexp2 in 1.5, or something that
      says all fields up to "wired" in the current uvmexp don't
      change size or move around.
    + struct clockinfo should be made fixed size, and that sysctl
      handler should so similar to the patch below.

I'd at least like to get the following in -current (perhaps with a
suitable XXX) so that the current top lossage is fixed.

Simon.
--
Simon Burge                            <simonb@wasabisystems.com>
NetBSD Sales, Support and Service:  http://www.wasabisystems.com/



Index: uvm_meter.c
===================================================================
RCS file: /cvsroot/syssrc/sys/uvm/uvm_meter.c,v
retrieving revision 1.13
diff -d -p -u -r1.13 uvm_meter.c
--- uvm_meter.c	2000/06/27 17:29:27	1.13
+++ uvm_meter.c	2000/09/28 02:11:08
@@ -141,11 +141,11 @@ uvm_sysctl(name, namelen, oldp, oldlenp,
 	case VM_METER:
 		uvm_total(&vmtotals);
 		return (sysctl_rdstruct(oldp, oldlenp, newp, &vmtotals,
-		    sizeof(vmtotals)));
+		    min(*oldlenp, sizeof(vmtotals))));
 
 	case VM_UVMEXP:
 		return (sysctl_rdstruct(oldp, oldlenp, newp, &uvmexp,
-		    sizeof(uvmexp)));
+		    min(*oldlenp, sizeof(uvmexp))));
 
 	case VM_NKMEMPAGES:
 		return (sysctl_rdint(oldp, oldlenp, newp, nkmempages));