Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Jun 1996 13:39:59 +0800
From:      Peter Wemm <peter@spinner.DIALix.COM>
To:        Terry Lambert <terry@lambert.org>
Cc:        phk@FreeBSD.ORG (Poul-Henning Kamp), nathan@netrail.net, freebsd-current@FreeBSD.ORG, freebsd-smp@FreeBSD.ORG
Subject:   Re: does freebsd support SMP? 
Message-ID:  <199606100540.NAA02800@spinner.DIALix.COM>
In-Reply-To: Your message of "Sun, 09 Jun 1996 13:01:55 MST." <199606092001.NAA01419@phaeton.artisoft.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
>> >> DOes freebsd supoort SMP?
>> >
>> >Yes.  There is a working SMP /usr/src/sys code tree that can be SUP'ed
>> >or CTM'ed.  You do a normal CVS checkout, then you add:
>> >
>> >options		SMP			# enable SMP
>> >options		NCPU=2			# or whatever max you want
>> >
>> >To your normal -current config file, config, makedepend, make, and
>> >install the SMP kernel.  Then rebbot.  You are running SMP.
>> 
>> Well, you clearly havn't tried it Terry :-)
>> 
>> Boot single user and then:
>> 	sysctl -w kern.smp_active=2
>> to start the second CPU...
>
>
>That didn't used to be in there... clearly, I haven't tried it
>recently.  8-).
>
>Thanks for telling me, though, since I just pulled down the sources
>yesterday, and the only reason I'm in today is to play with it.  I
>would have figured it out eventually.  4 hours or so.  8-) 8-).
>
>It seems that smp_active wants to be cpu.active, and wants to
>default to 1 (not zero).

Actually, no, it's just a hack so that we can progressively unlock
the cpu's and trace various stages of booting them.

>The locking code (mplock.s) only checks for non-zero.

Yes..  smp_active=1 means you can get the second cpu up in protected mode
and running virtual, but not scheduling yet.

>The code in swtch.s -- is it ever hit in the smp_active zero
>case?  It seems to be an error to have the old idle loop
>present at all... am I missing something in the UP case, where
>the kernel is still compiled with SMP set?
>
>Also, in the idle spin loop, re: processor power consumption and
>heating: any chance of integrating a Linux-style "halt instruction"
>test and using it in the case that it works?

Yes, this is a 'work-in-progress'.  The only reason it's spinning at all
at the moment is because a) it works for the moment, and b) we've been busy
on other things.  A lack of documentation doesn't help, we have just about
solved that problem, all we need is detail on the IO-APIC...

>Who is actively hacking where in the assembly code?  This seems like
>an easy fix that wouldn't drag me down into dealing with page tables.
>;-).

I've got a whole mess of uncommitted stuff yet that I've not quite
finished and debugged yet.  I've mentioned some of this to phk so far..
- generic apic IPI message sender, eg: to send (say) an int 0x20 to a
processor to snap it out of it's hlt loop and schedule a process. This
also makes the boot more robust as there are are timeouts now
- almost all special case code removed from locore.s and pmap.c.  Instead
of booting the second processor on _IdlePTD, and using the idle process's
stacks and ptd's, a PTD is cloned from _idlePTD, and a stack and pcb
allocated and initialised.  The clone PTD has the temporary 4MB V==P
mapping at 0 so that the kernel can turn on paging without getting killed
by the new pipeline flushes on the P6.  Since it has it's own pcb, it now
has it's own mplock nesting count.  This means that we can ressurect a real
idle loop with a hlt.
- sysctl string with handler function, rather than just an int variable.  This
means that simple commands can be written. (eg: sysctl -w cpu.smp=bootall)
- Simple parsing of the MP config block, although I dont use it yet.
- Support for 'N' cpus.  Since all per-cpu state is allocated after boot now,
booting the processors is somewhat simpler...
int cpu_alive[NCPU];	/* cpu touches this when it wakes up, then waits */
  .....
  my_id = cpunumber();
  for (i = 0; i < NCPU; i++) {
    if (i == my_id)
      continue;
    smp_cpu_startup(i);
    /* sleep a short while */
    if (cpu_alive[i]) {
      smp_alloc(i);	/* allocates and sets up ptd, stack, etc */
      smp_cpu_unlock(i);	/* releases it from lock, it sets up it's vm etc */
    } else {
      /* in case the cpu is alive but didn't survive boot, halt it */
      smp_cpu_halt(i);	/* does an init ipi to make the cpu execute a cli;hlt*/
    }
  }
This is pretty trivial, and does not cope with apic id's outside 0..NCPU.
I'd like to parse the MP block to find all the cpus, and reprogram the
apic id's of the ones outside the range to make them sequential if needed.
This means booting all cpus, keeping them locked, calculating a new
mapping, leaving the boot cpu alone, letting all cpus reset their apic_id
at once, then letting the boot cpu figure out the mess.
- (on a sidetrack) I'm trying to eliminate the user area to allow vmspace
sharing.  This is somewhat complicated by each cpu needing a tss pointer
in the gdt, so it may force dynamic allocation of the gdt. (or, reserve
NCPU slots and initialise them manually rather than statically. For now,
I've just left a 31 entry "hole" since the #if's were a nightmare to reserve
the correct amount in the static structure).  Once this is done, we can
have real threaded programs executing multiple threads on both cpus at
once.
- Somebody mentioned NCPU vs. MAXCPU..  I use NCPU as "the maximum number
of cpus that we can support", it's little more than a size of a couple of
int arrays.  It could quite reasonably be hardwired to a default of 32.
- I'm sure I've forgotten something.. :-)
 
Cheers,
-Peter



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199606100540.NAA02800>